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

Last change on this file since 17 was 17, checked in by phaller, 26 years ago

Code cleanup #1 for build, mainly addresses linkage problems

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