source: trunk/src/kernel32/HandleManager.cpp@ 4

Last change on this file since 4 was 4, checked in by ktk, 26 years ago

Import

File size: 40.9 KB
Line 
1/* $Id: HandleManager.cpp,v 1.1 1999-05-24 20:19:41 ktk Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 */
8/*
9 * Win32 Unified Handle Manager for OS/2
10 *
11 * 1998/02/11 PH Patrick Haller (haller@zebra.fh-weingarten.de)
12 *
13 * @(#) HandleManager.Cpp 1.0.0 1998/02/11 PH start
14 */
15
16#undef DEBUG_LOCAL
17//#define DEBUG_LOCAL
18
19
20/*****************************************************************************
21 * Remark *
22 *****************************************************************************
23
24 1998/02/11 PH Even overlapped I/O could be simulated by another subsystem
25 thread with a request queue. We'll see if required ...
26
27
28 Flush (flush handle buffer)
29 WaitForSingleObject
30 WaitForMultipleObjects (?)
31
32 1998/02/12 PH IBM and Microsoft disagree about the definition of FILE_TYPE_xxx
33 Interesting, Open32 returns Microsoft's values ...
34
35 1998/02/12 PH Handles should be equipped with a locking mechanism, in particular
36 as we publish a pointer into the handle table via HMHandleQueryHandleData
37
38 */
39
40
41/*****************************************************************************
42 * Includes *
43 *****************************************************************************/
44
45#include <os2win.h>
46#include <stdlib.h>
47#include <string.h>
48#include "unicode.h"
49
50#include "HandleManager.H"
51
52#include <string.h>
53
54
55/*****************************************************************************
56 * Defines *
57 *****************************************************************************/
58
59 /* this is the size of our currently static handle table */
60#define MAX_OS2_HMHANDLES 256
61
62 /* this is for the handle translation table, could by dynamic though */
63#define MAX_TRANSLATION_HANDLES 8192
64
65
66
67/*****************************************************************************
68 * Structures *
69 *****************************************************************************/
70
71
72typedef struct _HMHANDLE
73{
74 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
75 HMHANDLEDATA hmHandleData; /* attributes of the handle */
76} HMHANDLE, *PHMHANDLE;
77
78
79typedef struct _HMDEVICE
80{
81 struct _HMDEVICE *pNext; /* pointer to next device in chain */
82
83 PSZ pszDeviceName; /* name or alias of the pseudo-device */
84 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
85} HMDEVICE, *PHMDEVICE;
86
87
88typedef struct _HMTRANSHANDLE
89{
90/* @@@PH
91 UCHAR ucSubsystemID; to determine "lost" handles
92 */
93 /* the index position in the array is the 16bit windows part of the handle */
94 ULONG hHandle32; /* 32-bit OS/2 part of the handle */
95} HMTRANSHANDLE, *PHMTRANSHANDLE;
96
97
98/*****************************************************************************
99 * This pseudo-device logs all device requests to the logfile and returns *
100 * ERROR_INVALID_FUNCTION to virtually all requests -> debugging *
101 *****************************************************************************/
102class HMDeviceDebugClass : public HMDeviceHandler
103{
104 public:
105 HMDeviceDebugClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName) {}
106};
107
108
109/*****************************************************************************
110 * Process Global Structures *
111 *****************************************************************************/
112
113
114 /* the device name is repeated here to enable device alias names */
115static PHMDEVICE TabWin32Devices = NULL;
116static HMHANDLE TabWin32Handles[MAX_OS2_HMHANDLES]; /* static handle table */
117
118
119struct _HMGlobals
120{
121 HANDLE hStandardIn; /* stdin handle to CONIN$ */
122 HANDLE hStandardOut; /* stdout handle to CONOUT$ */
123 HANDLE hStandardError; /* stderr handle to CONOUT$ */
124
125 BOOL fIsInitialized; /* if HM is initialized already ? */
126 /* this MUST !!! be false initially */
127
128
129 ULONG ulHandleLast; /* index of last used handle */
130 HMTRANSHANDLE TabTranslationHandles[MAX_TRANSLATION_HANDLES];
131} HMGlobals;
132
133
134/*****************************************************************************
135 * Local Prototypes *
136 *****************************************************************************/
137
138 /* get appropriate device handler by the device name */
139static HMDeviceHandler *_HMDeviceFind(PSZ pszDeviceName);
140
141 /* get next free handle from the handle table */
142static int _HMHandleGetFree(void);
143
144 /* get handle table entry from handle */
145static int _HMHandleQuery(HANDLE hHandle);
146
147
148
149/*****************************************************************************
150 * Name : static HMDeviceHandler * _HMDeviceFind
151 * Purpose : obtain appropriate device handler from the table by searching
152 * for a device name or alias
153 * Parameters: PSZ pszDeviceName
154 * Variables :
155 * Result : HMDeviceHandler * - pointer to the handler object
156 * Remark :
157 * Status :
158 *
159 * Author : Patrick Haller [Wed, 1998/02/11 20:42]
160 *****************************************************************************/
161
162static HMDeviceHandler *_HMDeviceFind (PSZ pszDeviceName)
163{
164 PHMDEVICE pHMDevice; /* iterator over the device table */
165
166 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
167 pHMDevice != NULL;
168 pHMDevice = pHMDevice->pNext)
169 {
170 if (stricmp(pHMDevice->pszDeviceName, /* case-insensitive search */
171 pszDeviceName) == 0)
172 return (pHMDevice->pDeviceHandler); /* OK, we've found our device */
173 }
174
175 return ((HMDeviceHandler *) NULL); /* haven't found anything */
176}
177
178
179/*****************************************************************************
180 * Name : static int _HMHandleGetFree
181 * Purpose : get index to first free handle in the handle table
182 * Parameters:
183 * Variables :
184 * Result : int iIndex - index to the table or -1 in case of error
185 * Remark :
186 * Status :
187 *
188 * Author : Patrick Haller [Wed, 1998/02/11 20:43]
189 *****************************************************************************/
190
191static int _HMHandleGetFree(void)
192{
193 int iLoop;
194
195 for (iLoop = 0;
196 iLoop < MAX_OS2_HMHANDLES;
197 iLoop++)
198 {
199 /* free handle found ? */
200 if (0 == TabWin32Handles[iLoop].hmHandleData.hHandle)
201 return (iLoop); /* OK, then return it to the caller */
202 }
203
204 return (-1); /* haven't found any free handle */
205}
206
207
208/*****************************************************************************
209 * Name : static int _HMHandleQuery
210 * Purpose : gets the index of handle table entry as fast as possible from
211 * the specified handle
212 * Parameters: HANDLE hHandle
213 * Variables :
214 * Result : index or -1 in case of error
215 * Remark :
216 * Status :
217 *
218 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
219 *****************************************************************************/
220
221static int _HMHandleQuery(HANDLE hHandle)
222{
223 ULONG ulIndex; /* index into the handle table */
224
225 /* check the handle */
226 ulIndex = hHandle & ~HM_HANDLE_MASK; /* mask out the signature bits */
227 if (ulIndex != HM_HANDLE_ID) /* one of our handles ? */
228 return (-1); /* nope, ERROR_INVALID_HANDLE */
229
230 ulIndex = hHandle & HM_HANDLE_MASK; /* get the relevant bits */
231 if (ulIndex > MAX_OS2_HMHANDLES) /* check the table range */
232 return (-1); /* nope, ERROR_INVALID_HANDLE */
233
234 /* Oops, invalid handle ! */
235 if (TabWin32Handles[ulIndex].hmHandleData.hHandle != hHandle)
236 return (-1); /* nope, ERROR_INVALID_HANDLE */
237
238 return ( (int) ulIndex); /* OK, we've got our handle index */
239}
240
241
242/*****************************************************************************
243 * Name : DWORD HMDeviceRegister
244 * Purpose : register a device with the handle manager
245 * Parameters: PSZ pszDeviceName
246 * HMDeviceHandler *pDeviceHandler
247 * Variables :
248 * Result : API returncode
249 * Remark :
250 * Status :
251 *
252 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
253 *****************************************************************************/
254
255DWORD HMDeviceRegister(PSZ pszDeviceName,
256 HMDeviceHandler *pDeviceHandler)
257{
258 PHMDEVICE pHMDevice; /* our new device to be allocated */
259
260 if ( (pszDeviceName == NULL) || /* check parameters */
261 (pDeviceHandler == NULL) )
262 return (ERROR_INVALID_PARAMETER); /* raise error conditon */
263
264
265 pHMDevice = (PHMDEVICE) malloc (sizeof (HMDEVICE) ); /* allocate memory */
266 if (pHMDevice == NULL) /* check proper allocation */
267 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
268
269 pHMDevice->pszDeviceName = strdup(pszDeviceName); /* copy name */
270 if (pHMDevice->pszDeviceName == NULL) /* check proper allocation */
271 {
272 free (pHMDevice); /* free previously allocated memory */
273 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
274 }
275
276 pHMDevice->pDeviceHandler = pDeviceHandler; /* store pointer to device */
277 pHMDevice->pNext = TabWin32Devices; /* establish linkage */
278
279 TabWin32Devices = pHMDevice; /* insert new node as root in the list */
280
281 return (NO_ERROR);
282}
283
284
285/*****************************************************************************
286 * Name : DWORD HMInitialize
287 * Purpose : Initialize the handlemanager
288 * Parameters: -
289 * Variables : -
290 * Result : always NO_ERROR
291 * Remark : this routine just stores the standard handles in the
292 * internal table within the HandleManager
293 * Status :
294 *
295 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
296 *****************************************************************************/
297
298DWORD HMInitialize(void)
299{
300 if (HMGlobals.fIsInitialized != TRUE)
301 {
302 dprintf(("KERNEL32:HandleManager:HMInitialize() storing handles.\n"));
303
304 memset(&HMGlobals, /* zero out the structure first */
305 0,
306 sizeof(HMGlobals));
307
308 /* copy standard handles from OS/2's Open32 Subsystem */
309 HMSetStdHandle(STD_INPUT_HANDLE, GetStdHandle(STD_INPUT_HANDLE));
310 HMSetStdHandle(STD_OUTPUT_HANDLE, GetStdHandle(STD_OUTPUT_HANDLE));
311 HMSetStdHandle(STD_ERROR_HANDLE, GetStdHandle(STD_ERROR_HANDLE));
312
313 HMGlobals.fIsInitialized = TRUE; /* OK, done */
314 }
315 return (NO_ERROR);
316}
317
318
319/*****************************************************************************
320 * Name : DWORD HMTerminate
321 * Purpose : Terminate the handlemanager
322 * Parameters:
323 * Variables :
324 * Result :
325 * Remark :
326 * Status :
327 *
328 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
329 *****************************************************************************/
330
331DWORD HMTerminate(void)
332{
333 /* @@@PH we could deallocate the device list here */
334
335 return (NO_ERROR);
336}
337
338
339/*****************************************************************************
340 * Name : HANDLE _HMGetStdHandle
341 * Purpose : replacement for Open32's GetStdHandle function
342 * Parameters: DWORD nStdHandle
343 * Variables :
344 * Result : HANDLE to standard device
345 * Remark :
346 * Status :
347 *
348 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
349 *****************************************************************************/
350
351HANDLE HMGetStdHandle(DWORD nStdHandle)
352{
353 switch (nStdHandle)
354 {
355 case STD_INPUT_HANDLE: return (HMGlobals.hStandardIn);
356 case STD_OUTPUT_HANDLE: return (HMGlobals.hStandardOut);
357 case STD_ERROR_HANDLE: return (HMGlobals.hStandardError);
358
359 default:
360 {
361 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
362 return (INVALID_HANDLE_VALUE); /* raise error condition */
363 }
364 }
365}
366
367
368/*****************************************************************************
369 * Name : HANDLE _HMSetStdHandle
370 * Purpose : replacement for Open32's SetStdHandle function
371 * Parameters: DWORD nStdHandle
372 * HANDLE hHandle
373 * Variables :
374 * Result : BOOL fSuccess
375 * Remark :
376 * Status :
377 *
378 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
379 *****************************************************************************/
380
381BOOL HMSetStdHandle(DWORD nStdHandle,
382 HANDLE hHandle)
383{
384 switch (nStdHandle)
385 {
386 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
387 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
388 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
389
390 default:
391 {
392 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
393 return (FALSE); /* raise error condition */
394 }
395 }
396}
397
398
399/*****************************************************************************
400 * Name : HANDLE HMCreateFile
401 * Purpose : Wrapper for the CreateFile() API
402 * Parameters:
403 * Variables :
404 * Result :
405 * Remark : Fix parameters passed to the HMDeviceManager::CreateFile
406 * Supply access mode and share mode validation routines
407 * Status :
408 *
409 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
410 *****************************************************************************/
411
412HANDLE HMCreateFile(LPCSTR lpFileName,
413 DWORD dwDesiredAccess,
414 DWORD dwShareMode,
415 PVOID lpSecurityAttributes,
416 DWORD dwCreationDisposition,
417 DWORD dwFlagsAndAttributes,
418 HANDLE hTemplateFile)
419{
420 int iIndex; /* index into the handle table */
421 int iIndexNew; /* index into the handle table */
422 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
423 HANDLE hResult;
424 DWORD rc; /* API return code */
425 PHMHANDLEDATA pHMHandleData;
426 HMHANDLEDATA HMHandleTemp; /* temporary buffer for handle data */
427
428 /* create new handle by either lpFileName or hTemplateFile */
429 if (lpFileName == NULL) /* this indicates creation from template */
430 {
431 iIndex = _HMHandleQuery(hTemplateFile); /* query table for template */
432 if (-1 == iIndex) /* this device is unknown to us */
433 {
434 SetLastError (ERROR_INVALID_HANDLE);
435 return INVALID_HANDLE_VALUE;
436 }
437 else
438 {
439 /* to pass to handler */
440 pHMHandleData = &TabWin32Handles[iIndex].hmHandleData;
441 pDeviceHandler = TabWin32Handles[iIndex].pDeviceHandler;
442 }
443 }
444 else
445 {
446 pDeviceHandler = _HMDeviceFind((PSZ)lpFileName); /* find device */
447
448 if (NULL == pDeviceHandler) /* this name is unknown to us */
449 {
450 SetLastError(ERROR_FILE_NOT_FOUND);
451 return (INVALID_HANDLE_VALUE); /* signal error */
452 }
453 else
454 pHMHandleData = NULL;
455 }
456
457
458 iIndexNew = _HMHandleGetFree(); /* get free handle */
459 if (-1 == iIndexNew) /* oops, no free handles ! */
460 {
461 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
462 return (INVALID_HANDLE_VALUE); /* signal error */
463 }
464
465
466 /* initialize the complete HMHANDLEDATA structure */
467 if (lpFileName == NULL) /* create from template */
468 memcpy (&TabWin32Handles[iIndexNew].hmHandleData,
469 &TabWin32Handles[iIndex].hmHandleData,
470 sizeof(HMHANDLEDATA));
471 else
472 {
473 HMHandleTemp.dwType = FILE_TYPE_UNKNOWN; /* unknown handle type */
474 HMHandleTemp.dwAccess = dwDesiredAccess;
475 HMHandleTemp.dwShare = dwShareMode;
476 HMHandleTemp.dwCreation = dwCreationDisposition;
477 HMHandleTemp.dwFlags = dwFlagsAndAttributes;
478 HMHandleTemp.lpHandlerData = NULL;
479 }
480
481 /* we've got to mark the handle as occupied here, since another device */
482 /* could be created within the device handler -> deadlock */
483
484 /* write appropriate entry into the handle table if open succeeded */
485 hResult = (ULONG)iIndexNew | HM_HANDLE_ID;
486 HMHandleTemp.hHandle = hResult;
487 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
488
489 /* now copy back our temporary handle data */
490 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
491 &HMHandleTemp,
492 sizeof(HMHANDLEDATA));
493
494 rc = pDeviceHandler->CreateFile(lpFileName, /* call the device handler */
495 &HMHandleTemp,
496 lpSecurityAttributes,
497 pHMHandleData);
498
499#ifdef DEBUG_LOCAL
500 dprintf(("KERNEL32/HandleManager:CheckPoint2: %s lpHandlerData=%08xh\n",
501 lpFileName,
502 HMHandleTemp.lpHandlerData));
503#endif
504
505 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
506 {
507 TabWin32Handles[iIndexNew].hmHandleData.hHandle = INVALID_HANDLE_VALUE;
508 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
509 return (INVALID_HANDLE_VALUE); /* signal error */
510 }
511 else
512 {
513 /* copy data fields that might have been modified by CreateFile */
514 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
515 &HMHandleTemp,
516 sizeof(HMHANDLEDATA));
517 }
518
519
520#ifdef DEBUG_LOCAL
521 dprintf(("KERNEL32/HandleManager: CreateFile(%s)=%08xh\n",
522 lpFileName,
523 hResult));
524#endif
525
526 return hResult; /* return valid handle */
527}
528
529
530/*****************************************************************************
531 * Name : HANDLE HMCloseFile
532 * Purpose : Wrapper for the CloseHandle() API
533 * Parameters:
534 * Variables :
535 * Result :
536 * Remark :
537 * Status :
538 *
539 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
540 *****************************************************************************/
541
542BOOL HMCloseHandle(HANDLE hObject)
543{
544 int iIndex; /* index into the handle table */
545 BOOL fResult; /* result from the device handler's CloseHandle() */
546 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
547
548 /* validate handle */
549 iIndex = _HMHandleQuery(hObject); /* get the index */
550 if (-1 == iIndex) /* error ? */
551 {
552 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
553 return (FALSE); /* signal failure */
554 }
555
556 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
557 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
558
559 if (fResult == TRUE) /* remove handle if close succeeded */
560 pHMHandle->hmHandleData.hHandle = 0; /* mark handle as free */
561
562 return (fResult); /* deliver return code */
563}
564
565
566/*****************************************************************************
567 * Name : HANDLE HMReadFile
568 * Purpose : Wrapper for the ReadHandle() API
569 * Parameters:
570 * Variables :
571 * Result :
572 * Remark :
573 * Status :
574 *
575 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
576 *****************************************************************************/
577
578BOOL HMReadFile(HANDLE hFile,
579 LPCVOID lpBuffer,
580 DWORD nNumberOfBytesToRead,
581 LPDWORD lpNumberOfBytesRead,
582 LPOVERLAPPED lpOverlapped)
583{
584 int iIndex; /* index into the handle table */
585 BOOL fResult; /* result from the device handler's CloseHandle() */
586 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
587
588 /* validate handle */
589 iIndex = _HMHandleQuery(hFile); /* get the index */
590 if (-1 == iIndex) /* error ? */
591 {
592 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
593 return (FALSE); /* signal failure */
594 }
595
596 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
597 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
598 lpBuffer,
599 nNumberOfBytesToRead,
600 lpNumberOfBytesRead,
601 lpOverlapped);
602
603 return (fResult); /* deliver return code */
604}
605
606
607/*****************************************************************************
608 * Name : HANDLE HMWriteFile
609 * Purpose : Wrapper for the WriteHandle() API
610 * Parameters:
611 * Variables :
612 * Result :
613 * Remark :
614 * Status :
615 *
616 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
617 *****************************************************************************/
618
619BOOL HMWriteFile(HANDLE hFile,
620 LPCVOID lpBuffer,
621 DWORD nNumberOfBytesToWrite,
622 LPDWORD lpNumberOfBytesWritten,
623 LPOVERLAPPED lpOverlapped)
624{
625 int iIndex; /* index into the handle table */
626 BOOL fResult; /* result from the device handler's CloseHandle() */
627 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
628
629 /* validate handle */
630 iIndex = _HMHandleQuery(hFile); /* get the index */
631 if (-1 == iIndex) /* error ? */
632 {
633 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
634 return (FALSE); /* signal failure */
635 }
636
637 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
638 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
639 lpBuffer,
640 nNumberOfBytesToWrite,
641 lpNumberOfBytesWritten,
642 lpOverlapped);
643
644 return (fResult); /* deliver return code */
645}
646
647
648/*****************************************************************************
649 * Name : HANDLE HMGetFileType
650 * Purpose : Wrapper for the GetFileType() API
651 * Parameters:
652 * Variables :
653 * Result :
654 * Remark :
655 * Status :
656 *
657 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
658 *****************************************************************************/
659
660DWORD HMGetFileType(HANDLE hFile)
661{
662 int iIndex; /* index into the handle table */
663 DWORD dwResult; /* result from the device handler's API */
664 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
665
666 /* validate handle */
667 iIndex = _HMHandleQuery(hFile); /* get the index */
668 if (-1 == iIndex) /* error ? */
669 {
670 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
671 return (FILE_TYPE_UNKNOWN); /* signal failure */
672 }
673
674 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
675 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
676
677 return (dwResult); /* deliver return code */
678}
679
680
681/*****************************************************************************
682 * Name : HMDeviceHandler::_DeviceReuqest
683 * Purpose : entry method for special request functions
684 * Parameters: ULONG ulRequestCode
685 * various parameters as required
686 * Variables :
687 * Result :
688 * Remark : the standard behaviour is to return an error code for non-
689 * existant request codes
690 * Status :
691 *
692 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
693 *****************************************************************************/
694DWORD HMDeviceRequest (HANDLE hFile,
695 ULONG ulRequestCode,
696 ULONG arg1,
697 ULONG arg2,
698 ULONG arg3,
699 ULONG arg4)
700{
701 int iIndex; /* index into the handle table */
702 DWORD dwResult; /* result from the device handler's API */
703 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
704
705 /* validate handle */
706 iIndex = _HMHandleQuery(hFile); /* get the index */
707 if (-1 == iIndex) /* error ? */
708 {
709 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
710 return (FILE_TYPE_UNKNOWN); /* signal failure */
711 }
712
713 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
714 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
715 ulRequestCode,
716 arg1,
717 arg2,
718 arg3,
719 arg4);
720
721 return (dwResult); /* deliver return code */
722}
723
724
725/*****************************************************************************
726 * Name : HMDeviceHandler::HMDeviceHandler
727 * Purpose : default constructor for a device handler object
728 * Parameters: LPCSTR lpDeviceName
729 * Variables :
730 * Result :
731 * Remark : this is only to identify the device for debugging purposes
732 * Status :
733 *
734 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
735 *****************************************************************************/
736
737HMDeviceHandler::HMDeviceHandler(LPCSTR lpDeviceName)
738{
739 /* only a reference on the device name */
740 HMDeviceHandler::lpHMDeviceName = lpDeviceName;
741}
742
743
744/*****************************************************************************
745 * Name : HMDeviceHandler::_DeviceReuqest
746 * Purpose : entry method for special request functions
747 * Parameters: ULONG ulRequestCode
748 * various parameters as required
749 * Variables :
750 * Result :
751 * Remark : the standard behaviour is to return an error code for non-
752 * existant request codes
753 * Status :
754 *
755 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
756 *****************************************************************************/
757DWORD HMDeviceHandler::_DeviceRequest (PHMHANDLEDATA pHMHandleData,
758 ULONG ulRequestCode,
759 ULONG arg1,
760 ULONG arg2,
761 ULONG arg3,
762 ULONG arg4)
763{
764 dprintf(("KERNEL32:HandleManager::_DeviceRequest %s(%08x,%08x) - stub?\n",
765 lpHMDeviceName,
766 pHMHandleData,
767 ulRequestCode));
768
769 return(ERROR_INVALID_FUNCTION);
770}
771
772
773/*****************************************************************************
774 * Name : DWORD HMDeviceHandler::CreateFile
775 * Purpose : this is called from the handle manager if a CreateFile() is
776 * performed on a handle
777 * Parameters: LPCSTR lpFileName name of the file / device
778 * PHMHANDLEDATA pHMHandleData data of the NEW handle
779 * PVOID lpSecurityAttributes ignored
780 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
781 * Variables :
782 * Result :
783 * Remark :
784 * Status : NO_ERROR - API succeeded
785 * other - what is to be set in SetLastError
786 *
787 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
788 *****************************************************************************/
789
790DWORD HMDeviceHandler::CreateFile (LPCSTR lpFileName,
791 PHMHANDLEDATA pHMHandleData,
792 PVOID lpSecurityAttributes,
793 PHMHANDLEDATA pHMHandleDataTemplate)
794{
795 dprintf(("KERNEL32:HandleManager::CreateFile %s(%s,%08x,%08x,%08x) - stub?\n",
796 lpHMDeviceName,
797 lpFileName,
798 pHMHandleData,
799 lpSecurityAttributes,
800 pHMHandleDataTemplate));
801
802 return(ERROR_INVALID_FUNCTION);
803}
804
805
806/*****************************************************************************
807 * Name : DWORD HMDeviceHandler::CloseHandle
808 * Purpose : close the handle
809 * Parameters: PHMHANDLEDATA pHMHandleData
810 * Variables :
811 * Result : API returncode
812 * Remark :
813 * Status :
814 *
815 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
816 *****************************************************************************/
817
818DWORD HMDeviceHandler::CloseHandle(PHMHANDLEDATA pHMHandleData)
819{
820 dprintf(("KERNEL32:HandleManager::CloseHandle %s(%08x) - stub?\n",
821 lpHMDeviceName,
822 pHMHandleData));
823
824 return(ERROR_INVALID_FUNCTION);
825}
826
827
828/*****************************************************************************
829 * Name : DWORD HMDeviceHandler::ReadFile
830 * Purpose : read data from handle / device
831 * Parameters: PHMHANDLEDATA pHMHandleData,
832 * LPCVOID lpBuffer,
833 * DWORD nNumberOfBytesToRead,
834 * LPDWORD lpNumberOfBytesRead,
835 * LPOVERLAPPED lpOverlapped
836 * Variables :
837 * Result : API returncode
838 * Remark :
839 * Status :
840 *
841 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
842 *****************************************************************************/
843
844DWORD HMDeviceHandler::ReadFile(PHMHANDLEDATA pHMHandleData,
845 LPCVOID lpBuffer,
846 DWORD nNumberOfBytesToRead,
847 LPDWORD lpNumberOfBytesRead,
848 LPOVERLAPPED lpOverlapped)
849{
850 dprintf(("KERNEL32:HandleManager::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
851 lpHMDeviceName,
852 pHMHandleData,
853 lpBuffer,
854 nNumberOfBytesToRead,
855 lpNumberOfBytesRead,
856 lpOverlapped));
857
858 return(ERROR_INVALID_FUNCTION);
859}
860
861
862/*****************************************************************************
863 * Name : DWORD HMDeviceHandler::WriteFile
864 * Purpose : write data to handle / device
865 * Parameters: PHMHANDLEDATA pHMHandleData,
866 * LPCVOID lpBuffer,
867 * DWORD nNumberOfBytesToWrite,
868 * LPDWORD lpNumberOfBytesWritten,
869 * LPOVERLAPPED lpOverlapped
870 * Variables :
871 * Result : API returncode
872 * Remark :
873 * Status :
874 *
875 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
876 *****************************************************************************/
877
878DWORD HMDeviceHandler::WriteFile(PHMHANDLEDATA pHMHandleData,
879 LPCVOID lpBuffer,
880 DWORD nNumberOfBytesToWrite,
881 LPDWORD lpNumberOfBytesWritten,
882 LPOVERLAPPED lpOverlapped)
883{
884 dprintf(("KERNEL32:HandleManager::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
885 lpHMDeviceName,
886 pHMHandleData,
887 lpBuffer,
888 nNumberOfBytesToWrite,
889 lpNumberOfBytesWritten,
890 lpOverlapped));
891
892 return(ERROR_INVALID_FUNCTION);
893}
894
895
896/*****************************************************************************
897 * Name : DWORD HMDeviceHandler::GetFileType
898 * Purpose : determine the handle type
899 * Parameters: PHMHANDLEDATA pHMHandleData
900 * Variables :
901 * Result : API returncode
902 * Remark :
903 * Status :
904 *
905 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
906 *****************************************************************************/
907
908DWORD HMDeviceHandler::GetFileType(PHMHANDLEDATA pHMHandleData)
909{
910 dprintf(("KERNEL32:HandleManager::GetFileType %s(%08x)\n",
911 lpHMDeviceName,
912 pHMHandleData));
913
914 return pHMHandleData->dwType;
915}
916
917
918
919/*****************************************************************************/
920/* handle translation buffer management */
921/* */
922/* Since some Win32 applications rely (!) on 16-bit handles, we've got to do */
923/* 32-bit to 16-bit and vs vsa translation here. */
924/* Filehandle-based functions should be routed via the handlemanager instead */
925/* of going to Open32 directly. */
926/*****************************************************************************/
927
928
929/*****************************************************************************
930 * Name : DWORD HMHandleAllocate
931 * Purpose : allocate a handle in the translation table
932 * Parameters: PULONG pHandle16 - to return the allocated handle
933 * ULONG hHandle32 - the associated OS/2 handle
934 * Variables :
935 * Result : API returncode
936 * Remark : no parameter checking is done, phHandle may not be invalid
937 * hHandle32 shouldn't be 0
938 * Status :
939 *
940 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
941 *****************************************************************************/
942
943DWORD HMHandleAllocate (PULONG phHandle16,
944 ULONG hHandle32)
945{
946 register ULONG ulHandle;
947
948#ifdef DEBUG_LOCAL
949 dprintf(("KERNEL32::HMHandleAllocate (%08xh,%08xh)\n",
950 phHandle16,
951 hHandle32));
952#endif
953
954 ulHandle = HMGlobals.ulHandleLast; /* get free handle */
955
956 do
957 {
958 /* check if handle is free */
959 if (HMGlobals.TabTranslationHandles[ulHandle].hHandle32 == 0)
960 {
961 *phHandle16 = ulHandle;
962 HMGlobals.TabTranslationHandles[ulHandle].hHandle32 = hHandle32;
963 HMGlobals.ulHandleLast = ulHandle; /* to shorten search times */
964
965 return (NO_ERROR); /* OK */
966 }
967
968 ulHandle++; /* skip to next entry */
969
970 if (ulHandle >= MAX_TRANSLATION_HANDLES) /* check boundary */
971 ulHandle = 0;
972 }
973 while (ulHandle != HMGlobals.ulHandleLast);
974
975 return (ERROR_TOO_MANY_OPEN_FILES); /* OK, we're done */
976}
977
978
979/*****************************************************************************
980 * Name : DWORD HMHandleFree
981 * Purpose : free a handle from the translation table
982 * Parameters: ULONG hHandle16 - the handle to be freed
983 * Variables :
984 * Result : API returncode
985 * Remark : no parameter checking is done, hHandle16 MAY NEVER exceed
986 * the MAX_TRANSLATION_HANDLES boundary
987 * Status :
988 *
989 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
990 *****************************************************************************/
991
992DWORD HMHandleFree (ULONG hHandle16)
993{
994 ULONG rc; /* API returncode */
995
996#ifdef DEBUG_LOCAL
997 dprintf(("KERNEL32::HMHandleFree (%08xh)\n",
998 hHandle16));
999#endif
1000
1001 rc = HMHandleValidate(hHandle16); /* verify handle */
1002 if (rc != NO_ERROR) /* check errors */
1003 return (rc); /* raise error condition */
1004
1005 HMGlobals.TabTranslationHandles[hHandle16].hHandle32 = 0; /* OK, done */
1006
1007 return (NO_ERROR);
1008}
1009
1010
1011/*****************************************************************************
1012 * Name : DWORD HMHandleValidate
1013 * Purpose : validate a handle through the translation table
1014 * Parameters: ULONG hHandle16 - the handle to be verified
1015 * Variables :
1016 * Result : API returncode
1017 * Remark :
1018 * Status :
1019 *
1020 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1021 *****************************************************************************/
1022
1023DWORD HMHandleValidate (ULONG hHandle16)
1024{
1025#ifdef DEBUG_LOCAL
1026 dprintf(("KERNEL32::HMHandleValidate (%08xh)\n",
1027 hHandle16));
1028#endif
1029
1030 if (hHandle16 >= MAX_TRANSLATION_HANDLES) /* check boundary */
1031 return (ERROR_INVALID_HANDLE); /* raise error condition */
1032
1033 if (HMGlobals.TabTranslationHandles[hHandle16].hHandle32 == 0) /* valid ? */
1034 return (ERROR_INVALID_HANDLE); /* raise error condition */
1035
1036 return (NO_ERROR);
1037}
1038
1039
1040/*****************************************************************************
1041 * Name : DWORD HMHandleTranslateToWin
1042 * Purpose : translate a 32-bit OS/2 handle to the associated windows handle
1043 * Parameters: ULONG hHandle32 - the OS/2 handle
1044 * PULONG phHandle16 - the associated windows handle
1045 * Variables :
1046 * Result : API returncode
1047 * Remark :
1048 * Status :
1049 *
1050 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1051 *****************************************************************************/
1052
1053DWORD HMHandleTranslateToWin (ULONG hHandle32,
1054 PULONG phHandle16)
1055{
1056 ULONG rc; /* API returncode */
1057 register ULONG ulIndex; /* index counter over the table */
1058
1059#ifdef DEBUG_LOCAL
1060 dprintf(("KERNEL32::HMHandleTranslateToWin (%08xh, %08xh)\n",
1061 hHandle32,
1062 phHandle16));
1063#endif
1064
1065 for (ulIndex = 0;
1066 ulIndex < MAX_TRANSLATION_HANDLES;
1067 ulIndex++)
1068 {
1069 /* look for the handle */
1070 if (HMGlobals.TabTranslationHandles[ulIndex].hHandle32 == hHandle32)
1071 {
1072 *phHandle16 = ulIndex; /* deliver result */
1073 return (NO_ERROR); /* OK */
1074 }
1075 }
1076
1077 return (ERROR_INVALID_HANDLE); /* raise error condition */
1078}
1079
1080
1081/*****************************************************************************
1082 * Name : DWORD HMHandleTranslateToOS2
1083 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
1084 * Parameters: ULONG hHandle16 - the windows handle
1085 * PULONG phHandle32 - the associated OS/2 handle
1086 * Variables :
1087 * Result : API returncode
1088 * Remark :
1089 * Status :
1090 *
1091 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1092 *****************************************************************************/
1093
1094DWORD HMHandleTranslateToOS2 (ULONG hHandle16,
1095 PULONG phHandle32)
1096{
1097#ifdef DEBUG_LOCAL
1098 dprintf(("KERNEL32::HMHandleTranslateToOS2 (%08xh, %08xh)\n",
1099 hHandle16,
1100 phHandle32));
1101#endif
1102
1103 if (HMHandleValidate(hHandle16) == NO_ERROR) /* verify handle */
1104 {
1105 *phHandle32 = HMGlobals.TabTranslationHandles[hHandle16].hHandle32;
1106 return (NO_ERROR);
1107 }
1108
1109 return (ERROR_INVALID_HANDLE); /* raise error condition */
1110}
1111
1112
1113/*****************************************************************************
1114 * Name : DWORD HMHandleTranslateToOS2i
1115 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
1116 * Parameters: ULONG hHandle16 - the windows handle
1117 * Variables :
1118 * Result : OS/2 handle
1119 * Remark : no checkinf
1120 * Status :
1121 *
1122 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1123 *****************************************************************************/
1124
1125DWORD HMHandleTranslateToOS2i (ULONG hHandle16)
1126{
1127#ifdef DEBUG_LOCAL
1128 dprintf(("KERNEL32::HMHandleTranslateToOS2i (%08xh)\n",
1129 hHandle16));
1130#endif
1131
1132 return(HMGlobals.TabTranslationHandles[hHandle16].hHandle32);
1133}
Note: See TracBrowser for help on using the repository browser.