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

Last change on this file since 21374 was 21374, checked in by vladest, 15 years ago

Handle index overrun can cause crash sometimes. Ticket #4

File size: 135.8 KB
Line 
1/* $Id: HandleManager.cpp,v 1.104 2003-06-02 16:25:15 sandervl Exp $ */
2
3/*
4 * Win32 Unified Handle Manager for OS/2
5 *
6 * 1998/02/11 PH Patrick Haller (haller@zebra.fh-weingarten.de)
7 *
8 * @(#) HandleManager.Cpp 1.0.0 1998/02/11 PH start
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14//#undef DEBUG_LOCAL
15//#define DEBUG_LOCAL
16
17
18/*****************************************************************************
19 * Remark *
20 *****************************************************************************
21
22 1998/02/11 PH Even overlapped I/O could be simulated by another subsystem
23 thread with a request queue. We'll see if required ...
24
25
26 Flush (flush handle buffer)
27 WaitForSingleObject
28 WaitForMultipleObjects (?)
29
30 1998/02/12 PH IBM and Microsoft disagree about the definition of FILE_TYPE_xxx
31 Interesting, Open32 returns Microsoft's values ...
32
33 1998/02/12 PH Handles should be equipped with a locking mechanism, in particular
34 as we publish a pointer into the handle table via HMHandleQueryHandleData
35
36 */
37
38
39/*****************************************************************************
40 * Includes *
41 *****************************************************************************/
42
43#include <os2win.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include <unicode.h>
48#include <dbglog.h>
49
50#include <HandleManager.H>
51#include "handlenames.h"
52#include "HMDevice.h"
53#include "HMDisk.h"
54#include "HMOpen32.h"
55#include "HMEvent.h"
56#include "HMFile.h"
57#include "HMMutex.h"
58#include "HMSemaphore.h"
59#include "HMMMap.h"
60#include "HMComm.h"
61#include "HMParPort.h"
62#include "HMNul.h"
63#include "HMToken.h"
64#include "HMThread.h"
65#include "HMNPipe.h"
66#include "HMStd.h"
67#include "HMMailslot.h"
68
69#include "hmhandle.h"
70
71#include <vmutex.h>
72#include <win\thread.h>
73
74#include <odinapi.h>
75
76#include <_ras.h>
77
78#define DBG_LOCALLOG DBG_handlemanager
79#include "dbglocal.h"
80
81/*****************************************************************************
82 * Defines *
83 *****************************************************************************/
84
85// this is the size of our currently static handle table
86#define MAX_OS2_HMHANDLES (16*1024)
87#define ERROR_SYS_INTERNAL 328
88
89/*****************************************************************************
90 * Structures *
91 *****************************************************************************/
92
93
94typedef struct _HMDEVICE
95{
96 struct _HMDEVICE *pNext; /* pointer to next device in chain */
97
98 LPSTR pszDeviceName; /* name or alias of the pseudo-device */
99 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
100 VOID *pDevData; /* Pointer To Device data */
101} HMDEVICE, *PHMDEVICE;
102
103
104/*****************************************************************************
105 * This pseudo-device logs all device requests to the logfile and returns *
106 * ERROR_INVALID_FUNCTION to virtually all requests -> debugging *
107 *****************************************************************************/
108class HMDeviceDebugClass : public HMDeviceHandler
109{
110 public:
111 HMDeviceDebugClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName) {}
112};
113
114
115/*****************************************************************************
116 * Process Global Structures *
117 *****************************************************************************/
118
119
120 /* the device name is repeated here to enable device alias names */
121static PHMDEVICE TabWin32Devices = NULL;
122static int lastIndex = 1;
123static HMHANDLE *TabWin32Handles = NULL; /* static handle table */
124VMutex handleMutex;
125
126struct _HMGlobals
127{
128 HANDLE hStandardIn; /* stdin handle to CONIN$ */
129 HANDLE hStandardOut; /* stdout handle to CONOUT$ */
130 HANDLE hStandardError; /* stderr handle to CONOUT$ */
131
132 BOOL fIsInitialized; /* if HM is initialized already ? */
133 /* this MUST !!! be false initially */
134
135 HMDeviceHandler *pHMStandard; /* default handle manager instance */
136 HMDeviceHandler *pHMOpen32; /* default handle manager instance */
137 HMDeviceHandler *pHMEvent; /* static instances of subsystems */
138 HMDeviceHandler *pHMFile;
139 HMDeviceHandler *pHMInfoFile;
140 HMDeviceHandler *pHMDisk;
141 HMDeviceHandler *pHMMutex;
142 HMDeviceHandler *pHMSemaphore;
143 HMDeviceHandler *pHMFileMapping; /* static instances of subsystems */
144 HMDeviceHandler *pHMComm; /* serial communication */
145 HMDeviceHandler *pHMToken; /* security tokens */
146 HMDeviceHandler *pHMThread;
147 HMDeviceHandler *pHMNamedPipe;
148 HMDeviceHandler *pHMMailslot;
149 HMDeviceHandler *pHMParPort; /* parallel communication */
150 HMDeviceHandler *pHMNul; /* nul device */
151
152 ULONG ulHandleLast; /* index of last used handle */
153} HMGlobals;
154
155
156#ifdef RAS
157
158RAS_TRACK_HANDLE rthHandles = 0;
159
160ULONG WIN32API LogObjectContent_Handle (ULONG objident, ULONG objhandle, void *objdata, ULONG cbobjdata, FNRASLOG_EXTERNAL *pRasLog)
161{
162 pRasLog (" %8.8x: data=%p, type=%x, internal type=%x", objhandle, TabWin32Handles[objhandle].hmHandleData.hHMHandle, GetFileType(objhandle), TabWin32Handles[objhandle].hmHandleData.dwInternalType);
163 return 0;
164}
165
166#endif
167
168#define FREEHANDLE(a) do { \
169 TabWin32Handles[a].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE; \
170 RasRemoveObject(rthHandles, a); \
171 } while (0)
172
173/*****************************************************************************
174 * Local Prototypes *
175 *****************************************************************************/
176
177 /* get appropriate device handler by the device name */
178static HMDeviceHandler* _Optlink _HMDeviceFind(LPSTR pszDeviceName);
179
180 /* get next free handle from the handle table */
181static ULONG _Optlink _HMHandleGetFree(void);
182
183 /* get handle table entry from handle */
184static ULONG _Optlink _HMHandleQuery(HANDLE hHandle);
185
186// Get GlobalDeviceData
187static VOID *_HMDeviceGetData (LPSTR pszDeviceName);
188
189
190/*****************************************************************************
191 * Name : static HMDeviceHandler * _HMDeviceFind
192 * Purpose : obtain appropriate device handler from the table by searching
193 * for a device name or alias
194 * Parameters: PSZ pszDeviceName
195 * Variables :
196 * Result : HMDeviceHandler * - pointer to the handler object
197 * Remark :
198 * Status :
199 *
200 * Author : Patrick Haller [Wed, 1998/02/11 20:42]
201 *****************************************************************************/
202
203static HMDeviceHandler *_HMDeviceFind (LPSTR pszDeviceName)
204{
205 PHMDEVICE pHMDevice; /* iterator over the device table */
206 int namelength = strlen(pszDeviceName);
207
208 if (pszDeviceName != NULL)
209 {
210 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
211 pHMDevice != NULL;
212 pHMDevice = pHMDevice->pNext)
213 {
214 if(pHMDevice->pDeviceHandler->FindDevice(pHMDevice->pszDeviceName, pszDeviceName, namelength) == TRUE)
215 {
216 return pHMDevice->pDeviceHandler;
217 }
218 }
219 }
220 return (HMGlobals.pHMOpen32); /* haven't found anything, return default */
221}
222/*****************************************************************************
223 * Name : static VOID *_HMDeviceGetData
224 * Purpose : obtain pointer to device data from the table by searching
225 * for a device name or alias
226 * Parameters: PSZ pszDeviceName
227 * Variables :
228 * Result : VOID * - pointer to the handlers device data
229 * Remark :
230 * Status :
231 *
232 * Author : Markus Montkowski
233 *****************************************************************************/
234
235static VOID *_HMDeviceGetData (LPSTR pszDeviceName)
236{
237 PHMDEVICE pHMDevice; /* iterator over the device table */
238 int namelength = strlen(pszDeviceName);
239
240 if (pszDeviceName != NULL)
241 {
242 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
243 pHMDevice != NULL;
244 pHMDevice = pHMDevice->pNext)
245 {
246 if(pHMDevice->pDeviceHandler->FindDevice(pHMDevice->pszDeviceName, pszDeviceName, namelength) == TRUE)
247 {
248 return (pHMDevice->pDevData); /* OK, we've found our device */
249 }
250 }
251 }
252 return (NULL); /* haven't found anything, return NULL */
253}
254
255/*****************************************************************************
256 * Name : static int _HMHandleGetFree
257 * Purpose : get index to first free handle in the handle table
258 * Parameters:
259 * Variables :
260 * Result : int iIndex - index to the table or -1 in case of error
261 * Remark :
262 * Status :
263 *
264 * Author : Patrick Haller [Wed, 1998/02/11 20:43]
265 *****************************************************************************/
266
267static ULONG _HMHandleGetFree(void)
268{
269 register ULONG ulLoop;
270
271 handleMutex.enter();
272
273 //find next free handle; do not reuse handles until we have no choice
274 if(lastIndex >= MAX_OS2_HMHANDLES) {
275 lastIndex = 1;
276 }
277
278 for (ulLoop = lastIndex;ulLoop < MAX_OS2_HMHANDLES; ulLoop++)
279 {
280 /* free handle found ? */
281 if (INVALID_HANDLE_VALUE == TabWin32Handles[ulLoop].hmHandleData.hHMHandle)
282 {
283 //Mark handle as allocated here.
284 memset(&TabWin32Handles[ulLoop].hmHandleData, 0, sizeof(TabWin32Handles[ulLoop].hmHandleData));
285 TabWin32Handles[ulLoop].hmHandleData.hHMHandle = ulLoop;
286 TabWin32Handles[ulLoop].hmHandleData.dwInternalType = HMTYPE_UNKNOWN;
287 TabWin32Handles[ulLoop].hmHandleData.hWin32Handle = (HANDLE)ulLoop;
288 lastIndex = ulLoop+1;
289 handleMutex.leave();
290 RasAddObject (rthHandles, ulLoop, NULL, 0);
291 return (ulLoop); /* OK, then return it to the caller */
292 }
293 }
294
295 handleMutex.leave();
296 dprintf(("KERNEL32:HandleManager:_HMHandleGetFree() no free handle (%d already allocated)\n", ulLoop));
297#ifdef RAS
298 RasLog ("KERNEL32:HandleManager:_HMHandleGetFree() no free handle");
299 RasLogObjects (rthHandles, RAS_FLAG_LOG_OBJECTS);
300#endif
301 return (INVALID_HANDLE_VALUE); /* haven't found any free handle */
302}
303
304/*****************************************************************************
305 * Name : static int _HMHandleGetFree
306 * Purpose : get pointer to first free handle in the handle table
307 * Parameters:
308 * Variables :
309 * Result : pointer to the table or NULL in case of error
310 * Remark :
311 * Status :
312 *
313 * Author : SvL
314 *****************************************************************************/
315PHMHANDLE HMHandleGetFreePtr(ULONG dwType)
316{
317 ULONG handle;
318 PHMHANDLE pHandle;
319
320 handle = _HMHandleGetFree();
321 if(handle == INVALID_HANDLE_VALUE) {
322 return NULL;
323 }
324 pHandle = &TabWin32Handles[handle];
325 switch(dwType) {
326 case HMTYPE_MEMMAP:
327 pHandle->pDeviceHandler = HMGlobals.pHMFileMapping;
328 break;
329 case HMTYPE_DEVICE:
330 pHandle->pDeviceHandler = HMGlobals.pHMFile;
331 break;
332 case HMTYPE_PROCESSTOKEN:
333 case HMTYPE_THREADTOKEN:
334 pHandle->pDeviceHandler = HMGlobals.pHMToken;
335 break;
336 case HMTYPE_THREAD:
337 pHandle->pDeviceHandler = HMGlobals.pHMThread;
338 break;
339 case HMTYPE_PIPE:
340 pHandle->pDeviceHandler = HMGlobals.pHMNamedPipe;
341 break;
342 case HMTYPE_EVENTSEM:
343 pHandle->pDeviceHandler = HMGlobals.pHMEvent;
344 break;
345 case HMTYPE_MUTEXSEM:
346 pHandle->pDeviceHandler = HMGlobals.pHMMutex;
347 break;
348 case HMTYPE_SEMAPHORE:
349 pHandle->pDeviceHandler = HMGlobals.pHMSemaphore;
350 break;
351 case HMTYPE_COMPORT:
352 pHandle->pDeviceHandler = HMGlobals.pHMComm;
353 break;
354 case HMTYPE_PARPORT:
355 pHandle->pDeviceHandler = HMGlobals.pHMParPort;
356 break;
357 case HMTYPE_MAILSLOT:
358 pHandle->pDeviceHandler = HMGlobals.pHMMailslot;
359 break;
360
361 case HMTYPE_UNKNOWN:
362 default:
363 DebugInt3();
364 HMHandleFree(handle);
365 return NULL;
366 }
367
368 pHandle->hmHandleData.dwInternalType = dwType;
369 return pHandle;
370}
371
372/*****************************************************************************
373 * Name : HMHandleGetUserData
374 * Purpose : Get the dwUserData dword for a specific handle
375 * Parameters: HANDLE hHandle
376 * Variables :
377 * Result : -1 or dwUserData
378 * Remark :
379 * Status :
380 *
381 * Author : SvL
382 *****************************************************************************/
383DWORD HMHandleGetUserData(ULONG hHandle)
384{
385 if (hHandle >= MAX_OS2_HMHANDLES) /* check the table range */
386 {
387 /* Standard handle? */
388 switch (hHandle)
389 {
390 case STD_INPUT_HANDLE: hHandle = HMGlobals.hStandardIn; break;
391 case STD_OUTPUT_HANDLE: hHandle = HMGlobals.hStandardOut; break;
392 case STD_ERROR_HANDLE: hHandle = HMGlobals.hStandardError; break;
393 default:
394 return(-1);
395 }
396 if (hHandle >= MAX_OS2_HMHANDLES)
397 return(-1);
398 }
399 /* Oops, invalid handle ! */
400 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
401 return(-1); /* nope, ERROR_INVALID_HANDLE */
402
403 return TabWin32Handles[hHandle].hmHandleData.dwUserData;
404}
405
406/*****************************************************************************
407 * Name : HMHandleGetUserData
408 * Purpose : Get the dwUserData dword for a specific handle
409 * Parameters: HANDLE hHandle
410 * Variables :
411 * Result : -1 or dwUserData
412 * Remark :
413 * Status :
414 *
415 * Author : SvL
416 *****************************************************************************/
417DWORD HMHandleSetUserData(ULONG hHandle, ULONG dwUserData)
418{
419 if (hHandle >= MAX_OS2_HMHANDLES) /* check the table range */
420 {
421 /* Standard handle? */
422 switch (hHandle)
423 {
424 case STD_INPUT_HANDLE: hHandle = HMGlobals.hStandardIn; break;
425 case STD_OUTPUT_HANDLE: hHandle = HMGlobals.hStandardOut; break;
426 case STD_ERROR_HANDLE: hHandle = HMGlobals.hStandardError; break;
427 default:
428 return(-1);
429 }
430 if (hHandle >= MAX_OS2_HMHANDLES)
431 return(-1);
432 }
433
434 /* Oops, invalid handle ! */
435 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
436 return(-1); /* nope, ERROR_INVALID_HANDLE */
437
438 TabWin32Handles[hHandle].hmHandleData.dwUserData = dwUserData;
439 return NO_ERROR;
440}
441
442/*****************************************************************************
443 * Name : static int _HMHandleQuery
444 * Purpose : gets the index of handle table entry as fast as possible from
445 * the specified handle
446 * Parameters: HANDLE hHandle
447 * Variables :
448 * Result : index or -1 in case of error
449 * Remark : Should fail for standard handles (in/out/err)!!!!!!!!!!
450 * HMGetFileType depends on this!!!
451 * Status :
452 *
453 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
454 *****************************************************************************/
455
456static ULONG INLINE _HMHandleQuery(HANDLE hHandle)
457{
458 if (hHandle >= MAX_OS2_HMHANDLES) /* check the table range */
459 {
460 /* Standard handle? */
461 switch (hHandle)
462 {
463 case STD_INPUT_HANDLE: hHandle = HMGlobals.hStandardIn; break;
464 case STD_OUTPUT_HANDLE: hHandle = HMGlobals.hStandardOut; break;
465 case STD_ERROR_HANDLE: hHandle = HMGlobals.hStandardError; break;
466 default:
467 return(INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
468 }
469 if (hHandle >= MAX_OS2_HMHANDLES) /* check the table range */
470 return(INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
471 }
472
473 /* Oops, invalid handle ! */
474 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
475 return(INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
476
477 return( hHandle); /* OK, we've got our handle index */
478}
479
480/*****************************************************************************
481 * Name : HMHandleQueryPtr
482 * Purpose : gets the pointer of handle table entry as fast as possible from
483 * the specified handle
484 * Parameters: HANDLE hHandle
485 * Variables :
486 * Result : pointer or NULL in case of error
487 * Remark :
488 * Status :
489 *
490 * Author : SvL
491 *****************************************************************************/
492
493PHMHANDLE HMHandleQueryPtr(HANDLE hHandle)
494{
495 if (hHandle >= MAX_OS2_HMHANDLES)
496 {
497 /* Standard handle? */
498 switch (hHandle)
499 {
500 case STD_INPUT_HANDLE: hHandle = HMGlobals.hStandardIn; break;
501 case STD_OUTPUT_HANDLE: hHandle = HMGlobals.hStandardOut; break;
502 case STD_ERROR_HANDLE: hHandle = HMGlobals.hStandardError; break;
503 default:
504 SetLastError(ERROR_INVALID_HANDLE);
505 return(NULL);
506 }
507 if (hHandle >= MAX_OS2_HMHANDLES)
508 {
509 SetLastError(ERROR_INVALID_HANDLE);
510 return(NULL);
511 }
512 }
513 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
514 {
515 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
516 return(NULL); /* nope, ERROR_INVALID_HANDLE */
517 }
518 return( &TabWin32Handles[hHandle]); /* OK, we've got our handle index */
519}
520
521
522/*****************************************************************************
523 * Name : DWORD HMDeviceRegister
524 * Purpose : register a device with the handle manager
525 * Parameters: PSZ pszDeviceName
526 * HMDeviceHandler *pDeviceHandler
527 * Variables :
528 * Result : API returncode
529 * Remark :
530 * Status :
531 *
532 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
533 *****************************************************************************/
534
535DWORD HMDeviceRegisterEx(LPSTR pszDeviceName,
536 HMDeviceHandler *pDeviceHandler,
537 VOID *pDevData)
538{
539 PHMDEVICE pHMDevice; /* our new device to be allocated */
540
541 if ( (pszDeviceName == NULL) || /* check parameters */
542 (pDeviceHandler == NULL) )
543 return (ERROR_INVALID_PARAMETER); /* raise error conditon */
544
545
546 pHMDevice = (PHMDEVICE) malloc (sizeof (HMDEVICE) ); /* allocate memory */
547 if (pHMDevice == NULL) /* check proper allocation */
548 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
549
550 pHMDevice->pszDeviceName = strdup(pszDeviceName); /* copy name */
551 if (pHMDevice->pszDeviceName == NULL) /* check proper allocation */
552 {
553 free (pHMDevice); /* free previously allocated memory */
554 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
555 }
556
557 pHMDevice->pDeviceHandler = pDeviceHandler; /* store pointer to device */
558 pHMDevice->pNext = TabWin32Devices; /* establish linkage */
559 pHMDevice->pDevData = pDevData;
560
561 TabWin32Devices = pHMDevice; /* insert new node as root in the list */
562
563 return (NO_ERROR);
564}
565
566DWORD HMDeviceRegister(LPSTR pszDeviceName,
567 HMDeviceHandler *pDeviceHandler)
568{
569 return HMDeviceRegisterEx(pszDeviceName, pDeviceHandler, NULL);
570}
571
572/*****************************************************************************
573 * Name : DWORD HMInitialize
574 * Purpose : Initialize the handlemanager
575 * Parameters: -
576 * Variables : -
577 * Result : always NO_ERROR
578 * Remark : this routine just stores the standard handles in the
579 * internal table within the HandleManager
580 * Status :
581 *
582 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
583 *****************************************************************************/
584
585DWORD HMInitialize(void)
586{
587 ULONG ulIndex;
588
589 if (HMGlobals.fIsInitialized != TRUE)
590 {
591
592#ifdef RAS
593 RasRegisterObjectTracking(&rthHandles, "KERNEL32 handles",
594 0, RAS_TRACK_FLAG_LOGOBJECTCONTENT,
595 LogObjectContent_Handle, NULL);
596#endif
597
598 handleMutex.enter();
599
600 TabWin32Handles = (HMHANDLE *)VirtualAlloc(NULL, MAX_OS2_HMHANDLES*sizeof(HMHANDLE), MEM_COMMIT, PAGE_READWRITE);
601 if(TabWin32Handles == NULL) {
602 DebugInt3();
603 return ERROR_NOT_ENOUGH_MEMORY;
604 }
605
606 // fill handle table
607 for(ulIndex = 0; ulIndex < MAX_OS2_HMHANDLES; ulIndex++) {
608 TabWin32Handles[ulIndex].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
609 }
610 handleMutex.leave();
611
612 dprintf(("KERNEL32:HandleManager:HMInitialize() storing handles.\n"));
613
614 memset(&HMGlobals, /* zero out the structure first */
615 0,
616 sizeof(HMGlobals));
617
618 HMGlobals.fIsInitialized = TRUE; /* OK, done */
619
620#if 1
621 //This is a very bad idea. \\\\.\\NTICE -> NTICE, if the file exits, then
622 //it will open the file instead of the device driver
623 /* add standard symbolic links first, so local symbolic links in the
624 * device handlers get precedence over the default here.
625 *
626 * Device handlers are supposed to place the appropriate
627 * symbolic links such as "\\.\\COM1", "COM1"
628 *
629 * - "\\.\f:\temp\readme.txt" is a valid file
630 * - "com1" is a valid device in case serial port 1 exists,
631 * otherwise it'd be a valid file.
632 * - "\\.\filename" is the only misleading case (to be verified)
633 *
634 * Note:
635 * the Open32 "device" definately MUST be the last device to be
636 * asked to accept the specified name.
637 */
638 {
639 // strings are placed in read-only segment
640 PSZ pszDrive = strdup("\\\\.\\x:");
641 PSZ pszDrive2 = strdup("\\\\.\\x:");
642 for (char ch = 'A'; ch <= 'Z'; ch++)
643 {
644 pszDrive[4] = ch;
645 pszDrive2[4] = ch;
646 HandleNamesAddSymbolicLink(pszDrive, pszDrive+4);
647 HandleNamesAddSymbolicLink(pszDrive2, pszDrive2+4);
648 }
649 free(pszDrive);
650 free(pszDrive2);
651 HandleNamesAddSymbolicLink("\\\\?\\UNC\\", "\\\\");
652 //SvL: Can be used in Windows 2000 to open device drivers
653 HandleNamesAddSymbolicLink("\\\\.\\Global", "\\\\.");
654 }
655#endif
656
657 /* copy standard handles from OS/2's Open32 Subsystem */
658 HMGlobals.pHMStandard = new HMDeviceStandardClass("\\\\STANDARD_HANDLE\\");
659 HMSetStdHandle(STD_INPUT_HANDLE, O32_GetStdHandle(STD_INPUT_HANDLE));
660 HMSetStdHandle(STD_OUTPUT_HANDLE, O32_GetStdHandle(STD_OUTPUT_HANDLE));
661 HMSetStdHandle(STD_ERROR_HANDLE, O32_GetStdHandle(STD_ERROR_HANDLE));
662
663 /* create handle manager instance for Open32 handles */
664 HMGlobals.pHMOpen32 = new HMDeviceOpen32Class("\\\\.\\");
665 HMGlobals.pHMEvent = new HMDeviceEventClass("\\\\EVENT\\");
666 HMGlobals.pHMFile = new HMDeviceFileClass("\\\\FILE\\");
667 HMGlobals.pHMInfoFile = new HMDeviceInfoFileClass("\\\\INFOFILE\\");
668 HMGlobals.pHMDisk = new HMDeviceDiskClass("\\\\DISK\\");
669 HMGlobals.pHMMutex = new HMDeviceMutexClass("\\\\MUTEX\\");
670 HMGlobals.pHMSemaphore = new HMDeviceSemaphoreClass("\\\\SEM\\");
671 HMGlobals.pHMFileMapping= new HMDeviceMemMapClass("\\\\MEMMAP\\");
672 HMGlobals.pHMComm = new HMDeviceCommClass("\\\\COM\\");
673 HMGlobals.pHMToken = new HMDeviceTokenClass("\\\\TOKEN\\");
674 HMGlobals.pHMThread = new HMDeviceThreadClass("\\\\THREAD\\");
675 HMGlobals.pHMNamedPipe = new HMDeviceNamedPipeClass("\\\\PIPE\\");
676 HMGlobals.pHMMailslot = new HMMailslotClass("\\MAILSLOT\\");
677 HMGlobals.pHMParPort = new HMDeviceParPortClass("\\\\LPT\\");
678 HMGlobals.pHMNul = new HMDeviceNulClass("\\\\NUL\\");
679 }
680 return (NO_ERROR);
681}
682
683
684/*****************************************************************************
685 * Name : DWORD HMTerminate
686 * Purpose : Terminate the handlemanager
687 * Parameters:
688 * Variables :
689 * Result :
690 * Remark :
691 * Status :
692 *
693 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
694 *****************************************************************************/
695
696DWORD HMTerminate(void)
697{
698 /* @@@PH we could deallocate the device list here */
699#ifdef DEBUG
700 dprintf(("List of leaked handles"));
701 for(int i = 0; i < MAX_OS2_HMHANDLES; i++)
702 {
703 /* check if handle is free */
704 if (TabWin32Handles[i].hmHandleData.hHMHandle != INVALID_HANDLE_VALUE)
705 {
706 dprintf(("Handle %x(%p) type %x internal type %x", i, TabWin32Handles[i].hmHandleData.hHMHandle, GetFileType(i), TabWin32Handles[i].hmHandleData.dwInternalType));
707 }
708 }
709#endif
710 RasLogObjects (rthHandles, RAS_FLAG_LOG_OBJECTS);
711
712 if(HMGlobals.pHMOpen32)
713 delete HMGlobals.pHMOpen32;
714 if(HMGlobals.pHMEvent)
715 delete HMGlobals.pHMEvent;
716 if(HMGlobals.pHMFile)
717 delete HMGlobals.pHMFile;
718 if(HMGlobals.pHMInfoFile)
719 delete HMGlobals.pHMInfoFile;
720 if(HMGlobals.pHMMutex)
721 delete HMGlobals.pHMMutex;
722 if(HMGlobals.pHMSemaphore)
723 delete HMGlobals.pHMSemaphore;
724 if(HMGlobals.pHMFileMapping)
725 delete HMGlobals.pHMFileMapping;
726 if(HMGlobals.pHMComm)
727 delete HMGlobals.pHMComm;
728 if(HMGlobals.pHMToken)
729 delete HMGlobals.pHMToken;
730 if(HMGlobals.pHMThread)
731 delete HMGlobals.pHMThread;
732 if(HMGlobals.pHMNamedPipe)
733 delete HMGlobals.pHMNamedPipe;
734 if(HMGlobals.pHMMailslot)
735 delete HMGlobals.pHMMailslot;
736 if(HMGlobals.pHMDisk)
737 delete HMGlobals.pHMDisk;
738 if(HMGlobals.pHMStandard);
739 delete HMGlobals.pHMStandard;
740 if(HMGlobals.pHMParPort)
741 delete HMGlobals.pHMParPort;
742 if(HMGlobals.pHMNul)
743 delete HMGlobals.pHMNul;
744
745 return (NO_ERROR);
746}
747
748
749/*****************************************************************************/
750/* handle translation buffer management */
751/* */
752/* Since some Win32 applications rely (!) on 16-bit handles, we've got to do */
753/* 32-bit to 16-bit and vs vsa translation here. */
754/* Filehandle-based functions should be routed via the handlemanager instead */
755/* of going to Open32 directly. */
756/*****************************************************************************/
757
758
759/*****************************************************************************
760 * Name : DWORD HMHandleAllocate
761 * Purpose : allocate a handle in the translation table
762 * Parameters: PULONG pHandle16 - to return the allocated handle
763 * ULONG hHandle32 - the associated OS/2 handle
764 * Variables :
765 * Result : API returncode
766 * Remark : no parameter checking is done, phHandle may not be invalid
767 * hHandle32 shouldn't be 0
768 * Should be protected with a HM-Mutex !
769 * Status :
770 *
771 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
772 *****************************************************************************/
773
774DWORD HMHandleAllocate (PULONG phHandle16,
775 ULONG hHandleOS2)
776{
777 register ULONG ulHandle;
778
779#ifdef DEBUG_LOCAL
780 dprintf(("KERNEL32: HMHandleAllocate (%08xh,%08xh)\n",
781 phHandle16,
782 hHandleOS2));
783#endif
784
785 if (!phHandle16)
786 return (ERROR_TOO_MANY_OPEN_FILES);
787 // @@@PH 2001-09-27
788 // prevent too quick re-use of last handle
789 ulHandle = HMGlobals.ulHandleLast + 1; /* get free handle */
790
791 handleMutex.enter();
792
793 if(ulHandle == 0 || ulHandle >= MAX_OS2_HMHANDLES) {
794 ulHandle = 1; //SvL: Start searching from index 1
795 }
796 do
797 {
798 /* check if handle is free */
799 if (TabWin32Handles[ulHandle].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
800 {
801 *phHandle16 = ulHandle;
802 TabWin32Handles[ulHandle].hmHandleData.hHMHandle = hHandleOS2;
803 TabWin32Handles[ulHandle].hmHandleData.lpDeviceData = NULL;
804 HMGlobals.ulHandleLast = ulHandle; /* to shorten search times */
805
806 handleMutex.leave();
807 RasAddObject (rthHandles, ulHandle, NULL, 0);
808 return (NO_ERROR); /* OK */
809 }
810
811 ulHandle++; /* skip to next entry */
812
813 if (ulHandle >= MAX_OS2_HMHANDLES) /* check boundary */
814 ulHandle = 1;
815 }
816 while (ulHandle != HMGlobals.ulHandleLast);
817
818 handleMutex.leave();
819
820#ifdef DEBUG
821 dprintf(("ERROR: Out of handles!!!!"));
822 for (int i = 0; i < MAX_OS2_HMHANDLES; i++)
823 {
824 /* check if handle is free */
825 if (TabWin32Handles[i].hmHandleData.hHMHandle != INVALID_HANDLE_VALUE)
826 {
827 dprintf(("Handle %d type %d internal type %d", i, GetFileType(i), TabWin32Handles[i].hmHandleData.dwInternalType));
828 }
829 }
830#endif
831#ifdef RAS
832 RasLog ("KERNEL32:HandleManager:HMHandleAllocate() no free handle");
833 RasLogObjects (rthHandles, RAS_FLAG_LOG_OBJECTS);
834#endif
835 return (ERROR_TOO_MANY_OPEN_FILES); /* OK, we're done */
836}
837
838
839/*****************************************************************************
840 * Name : DWORD HMHandleFree
841 * Purpose : free a handle from the translation table
842 * Parameters: ULONG hHandle16 - the handle to be freed
843 * Variables :
844 * Result : API returncode
845 * Remark : no parameter checking is done, hHandle16 MAY NEVER exceed
846 * the MAX_TRANSLATION_HANDLES boundary
847 * Status :
848 *
849 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
850 *****************************************************************************/
851
852DWORD HMHandleFree (ULONG hHandle16)
853{
854 ULONG rc; /* API returncode */
855
856#ifdef DEBUG_LOCAL
857 dprintf(("KERNEL32: HMHandleFree (%08xh)\n",
858 hHandle16));
859#endif
860
861 rc = HMHandleValidate(hHandle16); /* verify handle */
862 if (rc != NO_ERROR) /* check errors */
863 return (rc); /* raise error condition */
864
865 FREEHANDLE(hHandle16);
866// TabWin32Handles[hHandle16].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
867// RasRemoveObjects(rthHandles, hHandle16);
868 /* OK, done */
869
870 return (NO_ERROR);
871}
872
873
874/*****************************************************************************
875 * Name : DWORD HMHandleValidate
876 * Purpose : validate a handle through the translation table
877 * Parameters: ULONG hHandle - the handle to be verified
878 * Variables :
879 * Result : API returncode
880 * Remark :
881 * Status :
882 *
883 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
884 *****************************************************************************/
885
886DWORD HMHandleValidate (ULONG hHandle)
887{
888#ifdef DEBUG_LOCAL
889 dprintf(("KERNEL32: HMHandleValidate (%08xh)\n", hHandle));
890#endif
891
892 if (hHandle >= MAX_OS2_HMHANDLES) /* check boundary */
893 {
894 /* Standard handle? */
895 switch (hHandle)
896 {
897 case STD_INPUT_HANDLE: hHandle = HMGlobals.hStandardIn; break;
898 case STD_OUTPUT_HANDLE: hHandle = HMGlobals.hStandardOut; break;
899 case STD_ERROR_HANDLE: hHandle = HMGlobals.hStandardError; break;
900 default:
901 return(ERROR_INVALID_HANDLE);
902 }
903 if (hHandle >= MAX_OS2_HMHANDLES)
904 return(ERROR_INVALID_HANDLE);
905 }
906
907 if (TabWin32Handles[hHandle].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
908 /* valid ? */
909 return(ERROR_INVALID_HANDLE); /* raise error condition */
910
911 return(NO_ERROR);
912}
913//*****************************************************************************
914//*****************************************************************************
915PHMHANDLEDATA HMQueryHandleData(HANDLE handle)
916{
917 int iIndex;
918
919 iIndex = _HMHandleQuery(handle); /* get the index */
920 if (-1 == iIndex) /* error ? */
921 {
922 return NULL;
923 }
924 return &TabWin32Handles[iIndex].hmHandleData; /* call device handler */
925}
926
927/*****************************************************************************
928 * Name : DWORD HMHandleTranslateToWin
929 * Purpose : translate a 32-bit OS/2 handle to the associated windows handle
930 * Parameters: ULONG hHandle32 - the OS/2 handle
931 * PULONG phHandle16 - the associated windows handle
932 * Variables :
933 * Result : API returncode
934 * Remark :
935 * Status :
936 *
937 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
938 *****************************************************************************/
939
940DWORD HMHandleTranslateToWin (ULONG hHandleOS2,
941 PULONG phHandle16)
942{
943 ULONG rc; /* API returncode */
944 register ULONG ulIndex; /* index counter over the table */
945
946#ifdef DEBUG_LOCAL
947 dprintf(("KERNEL32: HMHandleTranslateToWin (%08xh, %08xh)\n",
948 hHandleOS2,
949 phHandle16));
950#endif
951
952 for (ulIndex = 1;
953 ulIndex < MAX_OS2_HMHANDLES;
954 ulIndex++)
955 {
956 /* look for the handle */
957 if (TabWin32Handles[ulIndex].hmHandleData.hHMHandle == hHandleOS2)
958 {
959 *phHandle16 = ulIndex; /* deliver result */
960 return (NO_ERROR); /* OK */
961 }
962 }
963
964 return (ERROR_INVALID_HANDLE); /* raise error condition */
965}
966
967
968/*****************************************************************************
969 * Name : DWORD HMHandleTranslateToOS2
970 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
971 * Parameters: ULONG hHandle16 - the windows handle
972 * PULONG phHandle32 - the associated OS/2 handle
973 * Variables :
974 * Result : API returncode
975 * Remark :
976 * Status :
977 *
978 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
979 *****************************************************************************/
980
981DWORD HMHandleTranslateToOS2 (ULONG hHandle16,
982 PULONG phHandleOS2)
983{
984#ifdef DEBUG_LOCAL
985 dprintf(("KERNEL32: HMHandleTranslateToOS2 (%08xh, %08xh)\n",
986 hHandle16,
987 phHandleOS2));
988#endif
989
990 if (HMHandleValidate(hHandle16) == NO_ERROR) /* verify handle */
991 {
992 *phHandleOS2 = TabWin32Handles[hHandle16].hmHandleData.hHMHandle;
993 return (NO_ERROR);
994 }
995
996 return (ERROR_INVALID_HANDLE); /* raise error condition */
997}
998
999
1000/*****************************************************************************
1001 * Name : DWORD HMHandleTranslateToOS2i
1002 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
1003 * Parameters: ULONG hHandle16 - the windows handle
1004 * Variables :
1005 * Result : OS/2 handle
1006 * Remark : no checkinf
1007 * Status :
1008 *
1009 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1010 *****************************************************************************/
1011
1012DWORD HMHandleTranslateToOS2i (ULONG hHandle16)
1013{
1014#ifdef DEBUG_LOCAL
1015 dprintf(("KERNEL32: HMHandleTranslateToOS2i (%08xh)\n",
1016 hHandle16));
1017#endif
1018
1019 return(TabWin32Handles[hHandle16].hmHandleData.hHMHandle);
1020}
1021
1022/*****************************************************************************
1023 * Name : HANDLE _HMGetStdHandle
1024 * Purpose : replacement for Open32's GetStdHandle function
1025 * Parameters: DWORD nStdHandle
1026 * Variables :
1027 * Result : HANDLE to standard device
1028 * Remark :
1029 * Status :
1030 *
1031 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
1032 *****************************************************************************/
1033
1034HANDLE HMGetStdHandle(DWORD nStdHandle)
1035{
1036 switch (nStdHandle)
1037 {
1038 case STD_INPUT_HANDLE: return (HMGlobals.hStandardIn);
1039 case STD_OUTPUT_HANDLE: return (HMGlobals.hStandardOut);
1040 case STD_ERROR_HANDLE: return (HMGlobals.hStandardError);
1041
1042 default:
1043 {
1044 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
1045 return (INVALID_HANDLE_VALUE); /* raise error condition */
1046 }
1047 }
1048}
1049
1050
1051/*****************************************************************************
1052 * Name : HANDLE _HMSetStdHandle
1053 * Purpose : replacement for Open32's SetStdHandle function
1054 * Parameters: DWORD nStdHandle
1055 * HANDLE hHandle
1056 * Variables :
1057 * Result : BOOL fSuccess
1058 * Remark :
1059 * Status :
1060 *
1061 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
1062 *****************************************************************************/
1063
1064BOOL HMSetStdHandle(DWORD nStdHandle, HANDLE hHandleOpen32)
1065{
1066 PHMHANDLEDATA pHMHandleData;
1067 HANDLE hHandle;
1068
1069 hHandle = _HMHandleGetFree(); /* get free handle */
1070 if (hHandle == -1) /* oops, no free handles ! */
1071 {
1072 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1073 return 0;
1074 }
1075
1076 /* initialize the complete HMHANDLEDATA structure */
1077 pHMHandleData = &TabWin32Handles[hHandle].hmHandleData;
1078 pHMHandleData->dwAccess = 0;
1079 pHMHandleData->dwShare = 0;
1080 pHMHandleData->dwCreation = 0;
1081 pHMHandleData->dwFlags = 0;
1082 pHMHandleData->dwUserData = nStdHandle;
1083 pHMHandleData->hHMHandle = hHandleOpen32;
1084 pHMHandleData->lpHandlerData = NULL;
1085
1086 TabWin32Handles[hHandle].pDeviceHandler = HMGlobals.pHMStandard;
1087
1088 switch (nStdHandle)
1089 {
1090 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
1091 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
1092 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
1093
1094 default:
1095 {
1096 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
1097 return (FALSE); /* raise error condition */
1098 }
1099 }
1100}
1101
1102/*****************************************************************************
1103 * Name : HANDLE _HMUdptStdHandle
1104 * Purpose :
1105 * Parameters: DWORD nStdHandle
1106 * HANDLE hHandle
1107 * Variables :
1108 * Result : BOOL fSuccess
1109 * Remark :
1110 * Status :
1111 *
1112 * Author : Dmitry Froloff [Thu, 2003/03/03 17:44]
1113 *****************************************************************************/
1114
1115BOOL HMUpdtStdHandle(DWORD nStdHandle, HANDLE hHandle)
1116{
1117 switch (nStdHandle)
1118 {
1119 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
1120 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
1121 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
1122
1123 default:
1124 {
1125 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
1126 return (FALSE); /* raise error condition */
1127 }
1128 }
1129}
1130
1131
1132/*****************************************************************************
1133 * Name : HANDLE HMDuplicateHandle
1134 * Purpose : replacement for Open32's HMDuplicateHandle function
1135 * Parameters:
1136 *
1137 * Variables :
1138 * Result : BOOL fSuccess
1139 * Remark :
1140 * Status :
1141 *
1142 * Author : Sander van Leeuwen [Wed, 1999/08/25 15:44]
1143 *****************************************************************************/
1144
1145BOOL HMDuplicateHandle(HANDLE srcprocess,
1146 HANDLE srchandle,
1147 HANDLE destprocess,
1148 PHANDLE desthandle,
1149 DWORD fdwAccess,
1150 BOOL fInherit,
1151 DWORD fdwOptions)
1152{
1153 int iIndex; /* index into the handle table */
1154 int iIndexNew; /* index into the handle table */
1155 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1156 PHMHANDLEDATA pHMHandleData;
1157 BOOL rc; /* API return code */
1158
1159 if(HMHandleValidate(srchandle) != NO_ERROR)
1160 {
1161 dprintf(("KERNEL32: HMDuplicateHandle: invalid handle %x", srchandle));
1162 SetLastError(ERROR_INVALID_HANDLE); /* use this as error message */
1163 return FALSE;
1164 }
1165
1166 pDeviceHandler = TabWin32Handles[srchandle].pDeviceHandler; /* device is predefined */
1167 iIndexNew = _HMHandleGetFree(); /* get free handle */
1168 if (-1 == iIndexNew) /* oops, no free handles ! */
1169 {
1170 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1171 return FALSE; /* signal error */
1172 }
1173
1174 /* initialize the complete HMHANDLEDATA structure */
1175 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
1176 if (fdwOptions & DUPLICATE_SAME_ACCESS)
1177 pHMHandleData->dwAccess = TabWin32Handles[srchandle].hmHandleData.dwAccess;
1178 else
1179 pHMHandleData->dwAccess = fdwAccess;
1180
1181 pHMHandleData->dwShare = TabWin32Handles[srchandle].hmHandleData.dwShare;
1182 pHMHandleData->dwCreation = TabWin32Handles[srchandle].hmHandleData.dwCreation;
1183 pHMHandleData->dwFlags = TabWin32Handles[srchandle].hmHandleData.dwFlags;
1184 pHMHandleData->lpHandlerData = TabWin32Handles[srchandle].hmHandleData.lpHandlerData;
1185 pHMHandleData->dwInternalType = TabWin32Handles[srchandle].hmHandleData.dwInternalType;
1186
1187
1188 /* we've got to mark the handle as occupied here, since another device */
1189 /* could be created within the device handler -> deadlock */
1190
1191 /* write appropriate entry into the handle table if open succeeded */
1192 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
1193 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1194 /* call the device handler */
1195 rc = pDeviceHandler->DuplicateHandle(srchandle,
1196 &TabWin32Handles[iIndexNew].hmHandleData,
1197 srcprocess,
1198 &TabWin32Handles[srchandle].hmHandleData,
1199 destprocess,
1200 fdwAccess,
1201 fInherit,
1202 fdwOptions & ~DUPLICATE_CLOSE_SOURCE, 0);
1203
1204 //Don't let Open32 close it for us, but do it manually (regardless of error; see SDK docs))
1205 if (fdwOptions & DUPLICATE_CLOSE_SOURCE)
1206 HMCloseHandle(srchandle);
1207
1208 if(rc == FALSE) /* oops, creation failed within the device handler */
1209 {
1210// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1211 FREEHANDLE(iIndexNew);
1212 return FALSE; /* signal error */
1213 }
1214 else
1215 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1216
1217 *desthandle = iIndexNew;
1218 return TRUE; /* return valid handle */
1219}
1220
1221/*****************************************************************************
1222 * Name : HANDLE HMCreateFile
1223 * Purpose : Wrapper for the CreateFile() API
1224 * Parameters:
1225 * Variables :
1226 * Result :
1227 * Remark : Fix parameters passed to the HMDeviceManager::CreateFile
1228 * Supply access mode and share mode validation routines
1229 * Status :
1230 *
1231 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1232 *****************************************************************************/
1233
1234HANDLE HMCreateFile(LPCSTR lpFileName,
1235 DWORD dwDesiredAccess,
1236 DWORD dwShareMode,
1237 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1238 DWORD dwCreationDisposition,
1239 DWORD dwFlagsAndAttributes,
1240 HANDLE hTemplateFile)
1241{
1242 int iIndex; /* index into the handle table */
1243 int iIndexNew; /* index into the handle table */
1244 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1245 HANDLE hResult;
1246 DWORD rc; /* API return code */
1247 PHMHANDLEDATA pHMHandleData;
1248 HMHANDLEDATA HMHandleTemp; /* temporary buffer for handle data */
1249 VOID *pDevData;
1250
1251 /* create new handle by either lpFileName or hTemplateFile */
1252 if (lpFileName == NULL) /* this indicates creation from template */
1253 {
1254 iIndex = _HMHandleQuery(hTemplateFile); /* query table for template */
1255 if (-1 == iIndex) /* this device is unknown to us */
1256 {
1257 SetLastError (ERROR_INVALID_HANDLE);
1258 return INVALID_HANDLE_VALUE;
1259 }
1260 else
1261 {
1262 /* to pass to handler */
1263 pHMHandleData = &TabWin32Handles[iIndex].hmHandleData;
1264 pDeviceHandler = TabWin32Handles[iIndex].pDeviceHandler;
1265 }
1266 }
1267 else
1268 {
1269 // name resolving
1270 CHAR szFilename[260];
1271 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1272 szFilename,
1273 sizeof(szFilename),
1274 TRUE))
1275 {
1276 // use the resolved name
1277 lpFileName = szFilename;
1278 }
1279
1280
1281 pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1282 if (NULL == pDeviceHandler) /* this name is unknown to us */
1283 {
1284 SetLastError(ERROR_FILE_NOT_FOUND);
1285 return (INVALID_HANDLE_VALUE); /* signal error */
1286 }
1287 else
1288 pHMHandleData = NULL;
1289
1290 pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1291
1292 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1293 /* PF When create flag is set we do not care about zero in desired access
1294 verified in Win2k */
1295 if(dwDesiredAccess == 0 && dwCreationDisposition != CREATE_NEW) {
1296 dprintf(("File information access!"));
1297 pDeviceHandler = HMGlobals.pHMInfoFile;
1298 }
1299 else pDeviceHandler = HMGlobals.pHMFile;
1300 }
1301 }
1302
1303
1304 iIndexNew = _HMHandleGetFree(); /* get free handle */
1305 if (-1 == iIndexNew) /* oops, no free handles ! */
1306 {
1307 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1308 return (INVALID_HANDLE_VALUE); /* signal error */
1309 }
1310
1311
1312 /* initialize the complete HMHANDLEDATA structure */
1313 if (lpFileName == NULL) /* create from template */
1314 memcpy (&HMHandleTemp,
1315 &TabWin32Handles[iIndex].hmHandleData,
1316 sizeof(HMHANDLEDATA));
1317 else
1318 {
1319 memset(&HMHandleTemp, 0, sizeof(HMHandleTemp));
1320 HMHandleTemp.dwAccess = dwDesiredAccess;
1321 HMHandleTemp.dwShare = dwShareMode;
1322 HMHandleTemp.dwCreation = dwCreationDisposition;
1323 HMHandleTemp.dwFlags = dwFlagsAndAttributes;
1324 HMHandleTemp.hWin32Handle = iIndexNew;
1325 HMHandleTemp.lpDeviceData = pDevData;
1326 }
1327
1328 /* we've got to mark the handle as occupied here, since another device */
1329 /* could be created within the device handler -> deadlock */
1330
1331 /* write appropriate entry into the handle table if open succeeded */
1332 HMHandleTemp.hHMHandle = iIndexNew;
1333 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1334 /* now copy back our temporary handle data */
1335 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1336 &HMHandleTemp,
1337 sizeof(HMHANDLEDATA));
1338
1339 rc = pDeviceHandler->CreateFile(lpFileName, /* call the device handler */
1340 &HMHandleTemp,
1341 lpSecurityAttributes,
1342 pHMHandleData);
1343
1344#ifdef DEBUG_LOCAL
1345 dprintf(("KERNEL32/HandleManager:CheckPoint2: %s lpHandlerData=%08xh\n",
1346 lpFileName,
1347 HMHandleTemp.lpHandlerData));
1348#endif
1349
1350 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
1351 {
1352 FREEHANDLE(iIndexNew);
1353// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1354
1355 // Note:
1356 // device handlers have to return an Win32-style error code
1357 // from CreateFile() !
1358 SetLastError(rc);
1359 return (INVALID_HANDLE_VALUE); /* signal error */
1360 }
1361 else
1362 {
1363 /* copy data fields that might have been modified by CreateFile */
1364 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1365 &HMHandleTemp,
1366 sizeof(HMHANDLEDATA));
1367
1368 if(lpSecurityAttributes && lpSecurityAttributes->bInheritHandle) {
1369 dprintf(("Set inheritance for child processes"));
1370 HMSetHandleInformation(iIndexNew, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
1371 }
1372
1373 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1374 }
1375
1376 return (HFILE)iIndexNew; /* return valid handle */
1377}
1378
1379
1380/*****************************************************************************
1381 * Name : HANDLE HMOpenFile
1382 * Purpose : Wrapper for the OpenFile() API
1383 * Parameters:
1384 * Variables :
1385 * Result :
1386 * Remark : Fix parameters passed to the HMDeviceManager::OpenFile
1387 * Supply access mode and share mode validation routines
1388 * Status :
1389 *
1390 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1391 *****************************************************************************/
1392
1393
1394/***********************************************************************
1395 * FILE_ConvertOFMode
1396 *
1397 * Convert OF_* mode into flags for CreateFile.
1398 */
1399static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
1400{
1401 switch(mode & 0x03)
1402 {
1403 case OF_READ: *access = GENERIC_READ; break;
1404 case OF_WRITE: *access = GENERIC_WRITE; break;
1405 case OF_READWRITE: *access = GENERIC_READ | GENERIC_WRITE; break;
1406 default: *access = 0; break;
1407 }
1408 switch(mode & 0x70)
1409 {
1410 case OF_SHARE_EXCLUSIVE: *sharing = 0; break;
1411 case OF_SHARE_DENY_WRITE: *sharing = FILE_SHARE_READ; break;
1412 case OF_SHARE_DENY_READ: *sharing = FILE_SHARE_WRITE; break;
1413 case OF_SHARE_DENY_NONE:
1414 case OF_SHARE_COMPAT:
1415 default: *sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; break;
1416 }
1417}
1418
1419HFILE WIN32API OpenFile(LPCSTR lpFileName, OFSTRUCT* pOFStruct,
1420 UINT fuMode)
1421{
1422 int iIndex; /* index into the handle table */
1423 int iIndexNew; /* index into the handle table */
1424 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1425 VOID *pDevData;
1426 PHMHANDLEDATA pHMHandleData;
1427 DWORD rc; /* API return code */
1428
1429
1430 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
1431 lpFileName, pOFStruct, fuMode));
1432
1433 // name resolving
1434 CHAR szFilename[260];
1435 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1436 szFilename,
1437 sizeof(szFilename),
1438 TRUE))
1439 {
1440 // use the resolved name
1441 lpFileName = szFilename;
1442 }
1443
1444
1445 if(fuMode & OF_REOPEN) {
1446 pDeviceHandler = _HMDeviceFind((LPSTR)pOFStruct->szPathName); /* find device */
1447 }
1448 else pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1449 if (NULL == pDeviceHandler) /* this name is unknown to us */
1450 {
1451 SetLastError(ERROR_FILE_NOT_FOUND);
1452 return (INVALID_HANDLE_VALUE); /* signal error */
1453 }
1454 else
1455 pHMHandleData = NULL;
1456
1457 if(fuMode & OF_REOPEN) {
1458 pDevData = _HMDeviceGetData((LPSTR)pOFStruct->szPathName);
1459 }
1460 else pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1461
1462
1463 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1464 pDeviceHandler = HMGlobals.pHMFile;
1465 }
1466
1467 iIndexNew = _HMHandleGetFree(); /* get free handle */
1468 if (-1 == iIndexNew) /* oops, no free handles ! */
1469 {
1470 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1471 return (INVALID_HANDLE_VALUE); /* signal error */
1472 }
1473
1474 /* initialize the complete HMHANDLEDATA structure */
1475 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
1476
1477 FILE_ConvertOFMode(fuMode, /* map OF_flags */
1478 &pHMHandleData->dwAccess,
1479 &pHMHandleData->dwShare);
1480
1481 //SvL; Must be OPEN_EXISTING because mmaps depend on it (to duplicate
1482 // the file handle when this handle is a parameter for CreateFileMappingA/W
1483 pHMHandleData->dwCreation = OPEN_EXISTING;
1484 pHMHandleData->dwFlags = 0;
1485 pHMHandleData->lpHandlerData = NULL;
1486 pHMHandleData->lpDeviceData = pDevData;
1487
1488 /* we've got to mark the handle as occupied here, since another device */
1489 /* could be created within the device handler -> deadlock */
1490
1491 /* write appropriate entry into the handle table if open succeeded */
1492 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
1493 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1494
1495 rc = pDeviceHandler->OpenFile(lpFileName, /* call the device handler */
1496 &TabWin32Handles[iIndexNew].hmHandleData,
1497 pOFStruct,
1498 fuMode);
1499
1500#ifdef DEBUG_LOCAL
1501 dprintf(("KERNEL32/HandleManager:CheckPoint3: %s lpHandlerData=%08xh rc=%08xh\n",
1502 lpFileName,
1503 &TabWin32Handles[iIndexNew].hmHandleData.lpHandlerData,
1504 rc));
1505#endif
1506
1507 /*
1508 * Based on testcase (5) and MSDN:
1509 * "OF_PARSE Fills the OFSTRUCT structure but carries out no other action."
1510 */
1511 if (fuMode & OF_PARSE) {
1512 FREEHANDLE(iIndexNew);
1513// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1514 return 0;
1515 }
1516
1517 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
1518 {
1519 FREEHANDLE(iIndexNew);
1520// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1521 SetLastError(pOFStruct->nErrCode);
1522 return (INVALID_HANDLE_VALUE); /* signal error */
1523 }
1524 else {
1525 if(fuMode & (OF_DELETE|OF_EXIST)) {
1526 //file handle already closed
1527 FREEHANDLE(iIndexNew);
1528// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1529 return TRUE; //TODO: correct?
1530 }
1531
1532 if(fuMode & OF_VERIFY) {
1533 FREEHANDLE(iIndexNew);
1534// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1535 return 1; //TODO: correct?
1536 }
1537 }
1538
1539#ifdef DEBUG_LOCAL
1540 dprintf(("KERNEL32/HandleManager: OpenFile(%s)=%08xh\n",
1541 lpFileName,
1542 iIndexNew));
1543#endif
1544
1545 return iIndexNew; /* return valid handle */
1546}
1547
1548/*****************************************************************************
1549 * Name : DWORD HMGetHandleInformation
1550 * Purpose : The GetHandleInformation function obtains information about certain
1551 * properties of an object handle. The information is obtained as a set of bit flags.
1552 * Parameters: HANDLE hObject
1553 * LPDWORD lpdwFlags
1554 * Variables :
1555 * Result : TRUE / FALSE
1556 * Remark :
1557 * Status :
1558 *
1559 * Author : SvL
1560 *****************************************************************************/
1561BOOL HMGetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags)
1562{
1563 int iIndex; /* index into the handle table */
1564 BOOL fResult; /* result from the device handler's CloseHandle() */
1565 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1566
1567 /* validate handle */
1568 iIndex = _HMHandleQuery(hObject); /* get the index */
1569 if (-1 == iIndex) /* error ? */
1570 {
1571 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1572 return (FALSE); /* signal failure */
1573 }
1574
1575 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1576
1577 //Handle information is stored in the handle structure; return it here
1578 if(lpdwFlags) {
1579 *lpdwFlags = pHMHandle->hmHandleData.dwHandleInformation;
1580 }
1581
1582 SetLastError(ERROR_SUCCESS);
1583 return TRUE; /* deliver return code */
1584}
1585
1586/*****************************************************************************
1587 * Name : BOOL HMSetHandleInformation
1588 * Purpose : The SetHandleInformation function sets certain properties of an
1589 * object handle. The information is specified as a set of bit flags.
1590 * Parameters: HANDLE hObject handle to an object
1591 * DWORD dwMask specifies flags to change
1592 * DWORD dwFlags specifies new values for flags
1593 * Variables :
1594 * Result : TRUE / FALSE
1595 * Remark :
1596 * Status :
1597 *
1598 * Author : SvL
1599 *****************************************************************************/
1600BOOL HMSetHandleInformation (HANDLE hObject,
1601 DWORD dwMask,
1602 DWORD dwFlags)
1603{
1604 int iIndex; /* index into the handle table */
1605 BOOL fResult; /* result from the device handler's CloseHandle() */
1606 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1607
1608 /* validate handle */
1609 iIndex = _HMHandleQuery(hObject); /* get the index */
1610 if (-1 == iIndex) /* error ? */
1611 {
1612 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1613 return (FALSE); /* signal failure */
1614 }
1615
1616 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1617 //SvL: Check if pDeviceHandler is set
1618 if (pHMHandle->pDeviceHandler)
1619 {
1620 fResult = pHMHandle->pDeviceHandler->SetHandleInformation(&pHMHandle->hmHandleData,
1621 dwMask, dwFlags);
1622 }
1623 else
1624 {
1625 dprintf(("HMSetHandleInformation(%08xh): pDeviceHandler not set", hObject));
1626 fResult = TRUE;
1627 }
1628
1629 if(fResult == TRUE) {
1630 SetLastError(ERROR_SUCCESS);
1631 }
1632 return (fResult); /* deliver return code */
1633}
1634
1635/*****************************************************************************
1636 * Name : HANDLE HMGetFileNameFromHandle
1637 * Purpose : Query the name of the file associated with the system handle (if any)
1638 * Parameters:
1639 * Variables :
1640 * Result :
1641 * Remark :
1642 * Status :
1643 *
1644 * Author : SvL
1645 *****************************************************************************/
1646BOOL HMGetFileNameFromHandle(HANDLE hObject, LPSTR lpszFileName, DWORD cbFileName)
1647{
1648 int iIndex; /* index into the handle table */
1649 BOOL fResult; /* result from the device handler's CloseHandle() */
1650 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1651
1652
1653 if(lpszFileName == NULL) {
1654 DebugInt3();
1655 SetLastError(ERROR_INVALID_PARAMETER);
1656 return FALSE;
1657 }
1658 /* validate handle */
1659 iIndex = _HMHandleQuery(hObject); /* get the index */
1660 if (-1 == iIndex) /* error ? */
1661 {
1662 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1663 return (FALSE); /* signal failure */
1664 }
1665
1666 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1667 //SvL: Check if pDeviceHandler is set
1668 if (pHMHandle->pDeviceHandler)
1669 {
1670 fResult = pHMHandle->pDeviceHandler->GetFileNameFromHandle(&pHMHandle->hmHandleData,
1671 lpszFileName, cbFileName);
1672 }
1673 else
1674 {
1675 dprintf(("HMGetFileNameFromHandle(%08xh): pDeviceHandler not set", hObject));
1676 fResult = FALSE;
1677 }
1678
1679 if(fResult == TRUE) {
1680 SetLastError(ERROR_SUCCESS);
1681 }
1682 return (fResult); /* deliver return code */
1683}
1684
1685/*****************************************************************************
1686 * Name : HANDLE HMCloseFile
1687 * Purpose : Wrapper for the CloseHandle() API
1688 * Parameters:
1689 * Variables :
1690 * Result :
1691 * Remark :
1692 * Status :
1693 *
1694 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1695 *****************************************************************************/
1696
1697BOOL HMCloseHandle(HANDLE hObject)
1698{
1699 int iIndex; /* index into the handle table */
1700 BOOL fResult; /* result from the device handler's CloseHandle() */
1701 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1702
1703 /* validate handle */
1704 iIndex = _HMHandleQuery(hObject); /* get the index */
1705 if (-1 == iIndex) /* error ? */
1706 {
1707 //@@@PH it may occur someone closes e.g. a semaphore handle
1708 // which is not registered through the HandleManager yet.
1709 // so we try to pass on to Open32 instead.
1710 dprintf(("KERNEL32: HandleManager:HMCloseHandle(%08xh) passed on to Open32.\n",
1711 hObject));
1712
1713 fResult = O32_CloseHandle(hObject);
1714 return (fResult);
1715
1716 //SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1717 //return (FALSE); /* signal failure */
1718 }
1719
1720 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1721
1722 if(pHMHandle->hmHandleData.dwHandleInformation & HANDLE_FLAG_PROTECT_FROM_CLOSE) {
1723 dprintf(("Handle not closed because of HANDLE_FLAG_PROTECT_FROM_CLOSE"));
1724 SetLastError(ERROR_SUCCESS);
1725 return TRUE;
1726 }
1727
1728 //SvL: Check if pDeviceHandler is set
1729 if (pHMHandle->pDeviceHandler)
1730 {
1731 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
1732 }
1733 else
1734 {
1735 dprintf(("HMCloseHAndle(%08xh): pDeviceHandler not set", hObject));
1736 fResult = TRUE;
1737 }
1738
1739 if (fResult == TRUE) /* remove handle if close succeeded */
1740 {
1741 FREEHANDLE(iIndex);
1742// pHMHandle->hmHandleData.hHMHandle = INVALID_HANDLE_VALUE; /* mark handle as free */
1743 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1744 }
1745
1746 return (fResult); /* deliver return code */
1747}
1748
1749
1750/*****************************************************************************
1751 * Name : HANDLE HMReadFile
1752 * Purpose : Wrapper for the ReadHandle() API
1753 * Parameters:
1754 * Variables :
1755 * Result :
1756 * Remark :
1757 * Status :
1758 *
1759 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1760 *****************************************************************************/
1761
1762BOOL HMReadFile(HANDLE hFile,
1763 LPVOID lpBuffer,
1764 DWORD nNumberOfBytesToRead,
1765 LPDWORD lpNumberOfBytesRead,
1766 LPOVERLAPPED lpOverlapped,
1767 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1768{
1769 int iIndex; /* index into the handle table */
1770 BOOL fResult; /* result from the device handler's CloseHandle() */
1771 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1772
1773 /* validate handle */
1774 iIndex = _HMHandleQuery(hFile); /* get the index */
1775 if (-1 == iIndex) /* error ? */
1776 {
1777 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1778 return (FALSE); /* signal failure */
1779 }
1780
1781 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1782
1783 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1784 return ERROR_SYS_INTERNAL;
1785
1786 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
1787 lpBuffer,
1788 nNumberOfBytesToRead,
1789 lpNumberOfBytesRead,
1790 lpOverlapped, lpCompletionRoutine);
1791
1792 return (fResult); /* deliver return code */
1793}
1794
1795/*****************************************************************************
1796 * Name : HANDLE HMWriteFile
1797 * Purpose : Wrapper for the WriteHandle() API
1798 * Parameters:
1799 * Variables :
1800 * Result :
1801 * Remark :
1802 * Status :
1803 *
1804 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1805 *****************************************************************************/
1806
1807BOOL HMWriteFile(HANDLE hFile,
1808 LPCVOID lpBuffer,
1809 DWORD nNumberOfBytesToWrite,
1810 LPDWORD lpNumberOfBytesWritten,
1811 LPOVERLAPPED lpOverlapped,
1812 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1813{
1814 int iIndex; /* index into the handle table */
1815 BOOL fResult; /* result from the device handler's CloseHandle() */
1816 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1817
1818 /* validate handle */
1819 iIndex = _HMHandleQuery(hFile); /* get the index */
1820 if (-1 == iIndex) /* error ? */
1821 {
1822 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1823 return (FALSE); /* signal failure */
1824 }
1825
1826 /* watcom hack:
1827 * watcom may write -1 bytes to a device during flushall(), we should return
1828 * ERROR_NOT_ENOUGH_MEMORY or ERROR_NO_ACCESS
1829 */
1830 if (nNumberOfBytesToWrite == 0xffffffff)
1831 {
1832 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1833 return FALSE;
1834 }
1835
1836 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1837
1838 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1839 return ERROR_SYS_INTERNAL;
1840
1841 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
1842 lpBuffer,
1843 nNumberOfBytesToWrite,
1844 lpNumberOfBytesWritten,
1845 lpOverlapped, lpCompletionRoutine);
1846
1847 return (fResult); /* deliver return code */
1848}
1849
1850
1851/*****************************************************************************
1852 * Name : HANDLE HMGetFileType
1853 * Purpose : Wrapper for the GetFileType() API
1854 * Parameters:
1855 * Variables :
1856 * Result :
1857 * Remark :
1858 * Status :
1859 *
1860 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1861 *****************************************************************************/
1862
1863DWORD WIN32API GetFileType(HANDLE hFile)
1864{
1865 int iIndex; /* index into the handle table */
1866 DWORD dwResult; /* result from the device handler's API */
1867 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1868
1869 /* validate handle */
1870 iIndex = _HMHandleQuery(hFile); /* get the index */
1871 if (-1 == iIndex) /* error ? */
1872 {
1873 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1874 return FILE_TYPE_UNKNOWN; /* signal failure */
1875 }
1876
1877 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1878
1879 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1880 return ERROR_SYS_INTERNAL;
1881
1882 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1883
1884 return (dwResult); /* deliver return code */
1885}
1886
1887
1888/*****************************************************************************
1889 * Name : HMDeviceHandler::_DeviceReuqest
1890 * Purpose : entry method for special request functions
1891 * Parameters: ULONG ulRequestCode
1892 * various parameters as required
1893 * Variables :
1894 * Result :
1895 * Remark : the standard behaviour is to return an error code for non-
1896 * existant request codes
1897 * Status :
1898 *
1899 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1900 *****************************************************************************/
1901
1902DWORD HMDeviceRequest (HANDLE hFile,
1903 ULONG ulRequestCode,
1904 ULONG arg1,
1905 ULONG arg2,
1906 ULONG arg3,
1907 ULONG arg4)
1908{
1909 int iIndex; /* index into the handle table */
1910 DWORD dwResult; /* result from the device handler's API */
1911 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1912
1913 /* validate handle */
1914 iIndex = _HMHandleQuery(hFile); /* get the index */
1915 if (-1 == iIndex) /* error ? */
1916 {
1917 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1918 return (INVALID_HANDLE_ERROR); /* signal failure */
1919 }
1920
1921 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1922
1923 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1924 return ERROR_SYS_INTERNAL;
1925
1926 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1927 ulRequestCode,
1928 arg1,
1929 arg2,
1930 arg3,
1931 arg4);
1932 return (dwResult); /* deliver return code */
1933}
1934
1935
1936/*****************************************************************************
1937 * Name : HMDeviceHandler::GetFileInformationByHandle
1938 * Purpose : router function for GetFileInformationByHandle
1939 * Parameters:
1940 * Variables :
1941 * Result :
1942 * Remark :
1943 * Status :
1944 *
1945 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1946 *****************************************************************************/
1947
1948BOOL WIN32API GetFileInformationByHandle (HANDLE hFile,
1949 BY_HANDLE_FILE_INFORMATION *pHFI)
1950{
1951 int iIndex; /* index into the handle table */
1952 DWORD dwResult; /* result from the device handler's API */
1953 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1954
1955 /* validate handle */
1956 iIndex = _HMHandleQuery(hFile); /* get the index */
1957 if (-1 == iIndex) /* error ? */
1958 {
1959 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1960 return FALSE; /* signal failure */
1961 }
1962
1963 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1964
1965 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1966 return ERROR_SYS_INTERNAL;
1967
1968 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
1969 pHFI);
1970
1971 return (dwResult); /* deliver return code */
1972}
1973
1974
1975/*****************************************************************************
1976 * Name : HMDeviceHandler::SetEndOfFile
1977 * Purpose : router function for SetEndOfFile
1978 * Parameters:
1979 * Variables :
1980 * Result :
1981 * Remark :
1982 * Status :
1983 *
1984 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1985 *****************************************************************************/
1986
1987BOOL WIN32API SetEndOfFile (HANDLE hFile)
1988{
1989 int iIndex; /* index into the handle table */
1990 BOOL bResult; /* result from the device handler's API */
1991 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1992
1993 /* validate handle */
1994 iIndex = _HMHandleQuery(hFile); /* get the index */
1995 if (-1 == iIndex) /* error ? */
1996 {
1997 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1998 return FALSE; /* signal failure */
1999 }
2000
2001 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2002
2003 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2004 return ERROR_SYS_INTERNAL;
2005
2006 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
2007
2008 return (bResult); /* deliver return code */
2009}
2010
2011
2012/*****************************************************************************
2013 * Name : HMDeviceHandler::SetFileTime
2014 * Purpose : router function for SetFileTime
2015 * Parameters:
2016 * Variables :
2017 * Result :
2018 * Remark :
2019 * Status :
2020 *
2021 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2022 *****************************************************************************/
2023
2024BOOL WIN32API SetFileTime (HANDLE hFile,
2025 const FILETIME *pFT1,
2026 const FILETIME *pFT2,
2027 const FILETIME *pFT3)
2028{
2029 int iIndex; /* index into the handle table */
2030 BOOL bResult; /* result from the device handler's API */
2031 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2032
2033 /* validate handle */
2034 iIndex = _HMHandleQuery(hFile); /* get the index */
2035 if (-1 == iIndex) /* error ? */
2036 {
2037 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2038 return FALSE; /* signal failure */
2039 }
2040
2041 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2042
2043 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2044 return ERROR_SYS_INTERNAL;
2045
2046 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
2047 (LPFILETIME)pFT1,
2048 (LPFILETIME)pFT2,
2049 (LPFILETIME)pFT3);
2050
2051 return (bResult); /* deliver return code */
2052}
2053
2054/*****************************************************************************
2055 * Name : HMDeviceHandler::GetFileTime
2056 * Purpose : router function for SetFileTime
2057 * Parameters:
2058 * Variables :
2059 * Result :
2060 * Remark :
2061 * Status :
2062 *
2063 * Author : SvL
2064 *****************************************************************************/
2065
2066BOOL WIN32API GetFileTime (HANDLE hFile, FILETIME *pFT1,
2067 FILETIME *pFT2, FILETIME *pFT3)
2068{
2069 int iIndex; /* index into the handle table */
2070 BOOL bResult; /* result from the device handler's API */
2071 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2072
2073 /* validate handle */
2074 iIndex = _HMHandleQuery(hFile); /* get the index */
2075 if (-1 == iIndex) /* error ? */
2076 {
2077 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2078 return FALSE; /* signal failure */
2079 }
2080
2081 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2082
2083 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2084 return ERROR_SYS_INTERNAL;
2085
2086 bResult = pHMHandle->pDeviceHandler->GetFileTime(&pHMHandle->hmHandleData,
2087 (LPFILETIME)pFT1,
2088 (LPFILETIME)pFT2,
2089 (LPFILETIME)pFT3);
2090
2091 return (bResult); /* deliver return code */
2092}
2093
2094
2095/*****************************************************************************
2096 * Name : HMDeviceHandler::GetFileSize
2097 * Purpose : router function for GetFileSize
2098 * Parameters:
2099 * Variables :
2100 * Result :
2101 * Remark :
2102 * Status :
2103 *
2104 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2105 *****************************************************************************/
2106
2107DWORD WIN32API GetFileSize (HANDLE hFile, PDWORD pSize)
2108{
2109 int iIndex; /* index into the handle table */
2110 DWORD dwResult; /* result from the device handler's API */
2111 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2112
2113 /* validate handle */
2114 iIndex = _HMHandleQuery(hFile); /* get the index */
2115 if (-1 == iIndex) /* error ? */
2116 {
2117 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2118 return -1; //INVALID_SET_FILE_POINTER
2119 }
2120
2121 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2122
2123 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2124 return ERROR_SYS_INTERNAL;
2125
2126 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
2127 pSize);
2128
2129 return (dwResult); /* deliver return code */
2130}
2131
2132/***********************************************************************
2133 * GetFileSizeEx (KERNEL32.@)
2134 */
2135#define INVALID_FILE_SIZE ((DWORD)~0UL)
2136BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
2137{
2138 lpFileSize->LowPart = GetFileSize(hFile, ((PDWORD)&lpFileSize->HighPart));
2139 return (lpFileSize->LowPart != INVALID_FILE_SIZE);
2140}
2141
2142/*****************************************************************************
2143 * Name : HMDeviceHandler::SetFilePointer
2144 * Purpose : router function for SetFilePointer
2145 * Parameters:
2146 * Variables :
2147 * Result :
2148 * Remark :
2149 * Status :
2150 *
2151 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2152 *****************************************************************************/
2153
2154DWORD WIN32API SetFilePointer (HANDLE hFile,
2155 LONG lDistanceToMove,
2156 PLONG lpDistanceToMoveHigh,
2157 DWORD dwMoveMethod)
2158{
2159 int iIndex; /* index into the handle table */
2160 DWORD dwResult; /* result from the device handler's API */
2161 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2162
2163 /* validate handle */
2164 iIndex = _HMHandleQuery(hFile); /* get the index */
2165 if (-1 == iIndex) /* error ? */
2166 {
2167 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2168 return (INVALID_HANDLE_ERROR); /* signal failure */
2169 }
2170
2171 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2172
2173 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2174 return ERROR_SYS_INTERNAL;
2175
2176 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
2177 lDistanceToMove,
2178 lpDistanceToMoveHigh,
2179 dwMoveMethod);
2180
2181 return (dwResult); /* deliver return code */
2182}
2183
2184/***********************************************************************
2185 * SetFilePointerEx (KERNEL32.@)
2186 */
2187BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
2188 LARGE_INTEGER *newpos, DWORD method )
2189{
2190 LONG pos;
2191 LONG newp;
2192 BOOL res;
2193
2194 dprintf(("KERNEL32::SetFilePointerEx"));
2195
2196 pos = (LONG)distance.LowPart;
2197 res = SetFilePointer(hFile, pos, &newp, method);
2198 if (res != -1)
2199 {
2200 if (newpos) newpos->LowPart = (LONG)res;
2201 return TRUE;
2202 }
2203 return FALSE;
2204}
2205
2206
2207/*****************************************************************************
2208 * Name : HMDeviceHandler::LockFile
2209 * Purpose : router function for LockFile
2210 * Parameters:
2211 * Variables :
2212 * Result :
2213 * Remark :
2214 * Status :
2215 *
2216 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2217 *****************************************************************************/
2218
2219BOOL WIN32API LockFile (HANDLE hFile,
2220 DWORD arg2,
2221 DWORD arg3,
2222 DWORD arg4,
2223 DWORD arg5)
2224{
2225 int iIndex; /* index into the handle table */
2226 DWORD dwResult; /* result from the device handler's API */
2227 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2228
2229 /* validate handle */
2230 iIndex = _HMHandleQuery(hFile); /* get the index */
2231 if (-1 == iIndex) /* error ? */
2232 {
2233 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2234 return FALSE; /* signal failure */
2235 }
2236
2237 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2238
2239 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2240 return ERROR_SYS_INTERNAL;
2241
2242 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
2243 arg2,
2244 arg3,
2245 arg4,
2246 arg5);
2247
2248 return (dwResult); /* deliver return code */
2249}
2250
2251
2252/*****************************************************************************
2253 * Name : BOOL LockFileEx
2254 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
2255 * Parameters: HANDLE hFile handle of file to lock
2256 * DWORD dwFlags functional behavior modification flags
2257 * DWORD dwReserved reserved, must be set to zero
2258 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2259 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2260 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2261 * Variables :
2262 * Result : TRUE / FALSE
2263 * Remark :
2264 * Status : UNTESTED STUB
2265 *
2266 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2267 *****************************************************************************/
2268
2269BOOL WIN32API LockFileEx(HANDLE hFile,
2270 DWORD dwFlags,
2271 DWORD dwReserved,
2272 DWORD nNumberOfBytesToLockLow,
2273 DWORD nNumberOfBytesToLockHigh,
2274 LPOVERLAPPED lpOverlapped)
2275{
2276 int iIndex; /* index into the handle table */
2277 BOOL dwResult; /* result from the device handler's API */
2278 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2279
2280 /* validate handle */
2281 iIndex = _HMHandleQuery(hFile); /* get the index */
2282 if (-1 == iIndex) /* error ? */
2283 {
2284 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2285 return FALSE; /* signal failure */
2286 }
2287
2288 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2289
2290 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2291 return ERROR_SYS_INTERNAL;
2292
2293 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
2294 dwFlags,
2295 dwReserved,
2296 nNumberOfBytesToLockLow,
2297 nNumberOfBytesToLockHigh,
2298 lpOverlapped);
2299
2300 return (dwResult); /* deliver return code */
2301}
2302
2303
2304
2305/*****************************************************************************
2306 * Name : HMDeviceHandler::UnlockFile
2307 * Purpose : router function for UnlockFile
2308 * Parameters:
2309 * Variables :
2310 * Result :
2311 * Remark :
2312 * Status :
2313 *
2314 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2315 *****************************************************************************/
2316
2317BOOL WIN32API UnlockFile (HANDLE hFile,
2318 DWORD arg2,
2319 DWORD arg3,
2320 DWORD arg4,
2321 DWORD arg5)
2322{
2323 int iIndex; /* index into the handle table */
2324 BOOL dwResult; /* result from the device handler's API */
2325 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2326
2327 /* validate handle */
2328 iIndex = _HMHandleQuery(hFile); /* get the index */
2329 if (-1 == iIndex) /* error ? */
2330 {
2331 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2332 return FALSE; /* signal failure */
2333 }
2334
2335 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2336
2337 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2338 return ERROR_SYS_INTERNAL;
2339
2340 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
2341 arg2,
2342 arg3,
2343 arg4,
2344 arg5);
2345
2346 return (dwResult); /* deliver return code */
2347}
2348
2349
2350/*****************************************************************************
2351 * Name : BOOL UnlockFileEx
2352 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
2353 * Parameters: HANDLE hFile handle of file to lock
2354 * DWORD dwReserved reserved, must be set to zero
2355 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2356 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2357 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2358 * Variables :
2359 * Result : TRUE / FALSE
2360 * Remark :
2361 * Status : UNTESTED STUB
2362 *
2363 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2364 *****************************************************************************/
2365
2366BOOL WIN32API UnlockFileEx(HANDLE hFile,
2367 DWORD dwReserved,
2368 DWORD nNumberOfBytesToLockLow,
2369 DWORD nNumberOfBytesToLockHigh,
2370 LPOVERLAPPED lpOverlapped)
2371{
2372 int iIndex; /* index into the handle table */
2373 BOOL dwResult; /* result from the device handler's API */
2374 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2375
2376 /* validate handle */
2377 iIndex = _HMHandleQuery(hFile); /* get the index */
2378 if (-1 == iIndex) /* error ? */
2379 {
2380 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2381 return FALSE; /* signal failure */
2382 }
2383
2384 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2385
2386 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2387 return ERROR_SYS_INTERNAL;
2388
2389 dwResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
2390 dwReserved,
2391 nNumberOfBytesToLockLow,
2392 nNumberOfBytesToLockHigh,
2393 lpOverlapped);
2394
2395 return (dwResult); /* deliver return code */
2396}
2397
2398
2399/*****************************************************************************
2400 * Name : HMDeviceHandler::WaitForSingleObject
2401 * Purpose : router function for WaitForSingleObject
2402 * Parameters:
2403 * Variables :
2404 * Result :
2405 * Remark :
2406 * Status :
2407 *
2408 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2409 *****************************************************************************/
2410
2411DWORD HMWaitForSingleObject(HANDLE hObject,
2412 DWORD dwTimeout)
2413{
2414 int iIndex; /* index into the handle table */
2415 BOOL dwResult; /* result from the device handler's API */
2416 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2417
2418 /* validate handle */
2419 iIndex = _HMHandleQuery(hObject); /* get the index */
2420 if (-1 == iIndex) /* error ? */
2421 {
2422 dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n",
2423 hObject));
2424
2425 if(dwTimeout == INFINITE) {
2426 //Workaround for applications that block the PM input queue
2427 //while waiting for a child process to terminate.
2428 //(WaitSingleObject now calls MsgWaitMultipleObjects and
2429 // processes messages while waiting for the process to die)
2430 //(Napster install now doesn't block PM anymore (forcing a reboot))
2431
2432 HMODULE hUser32 = LoadLibraryA("USER32.DLL");
2433
2434 BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
2435 LONG (* WINAPI pfnDispatchMessageA)(const MSG*);
2436
2437 *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
2438 *(FARPROC *)&pfnDispatchMessageA = GetProcAddress(hUser32,"DispatchMessageA");
2439
2440 TEB *teb = GetThreadTEB();
2441
2442 if(!teb || !pfnPeekMessageA || !pfnDispatchMessageA) {
2443 dprintf(("ERROR: !teb || !pfnPeekMessageA || !pfnDispatchMessageA"));
2444 DebugInt3();
2445 return WAIT_FAILED;
2446 }
2447
2448 //TODO: Ignoring all messages could be dangerous. But processing them,
2449 //while the app doesn't expect any, isn't safe either.
2450//-> must active check in pmwindow.cpp if this is enabled again!
2451// teb->o.odin.fIgnoreMsgs = TRUE;
2452
2453 while(TRUE) {
2454 dwResult = HMMsgWaitForMultipleObjects(1, &hObject, FALSE,
2455 INFINITE, QS_ALLINPUT);
2456 if(dwResult == WAIT_OBJECT_0 + 1) {
2457 MSG msg ;
2458
2459 while (pfnPeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
2460 {
2461 if (msg.message == WM_QUIT) {
2462 dprintf(("ERROR: WaitForSingleObject call abandoned because WM_QUIT msg was received!!"));
2463// teb->o.odin.fIgnoreMsgs = FALSE;
2464 FreeLibrary(hUser32);
2465 return WAIT_ABANDONED;
2466 }
2467
2468 /* otherwise dispatch it */
2469 pfnDispatchMessageA(&msg);
2470
2471 } // end of PeekMessage while loop
2472 }
2473 else {
2474 dprintf(("WaitForSingleObject: Process %x terminated", hObject));
2475 break;
2476 }
2477 }
2478// teb->o.odin.fIgnoreMsgs = FALSE;
2479 FreeLibrary(hUser32);
2480 return dwResult;
2481 }
2482 else {
2483 // maybe handles from CreateProcess() ...
2484 dwResult = O32_WaitForSingleObject(hObject, dwTimeout);
2485 return (dwResult);
2486 }
2487 }
2488 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2489
2490 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2491 return ERROR_SYS_INTERNAL;
2492
2493 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObject(&pHMHandle->hmHandleData,
2494 dwTimeout);
2495
2496 return (dwResult); /* deliver return code */
2497}
2498
2499
2500/*****************************************************************************
2501 * Name : HMDeviceHandler::WaitForSingleObjectEx
2502 * Purpose : router function for WaitForSingleObjectEx
2503 * Parameters:
2504 * Variables :
2505 * Result :
2506 * Remark :
2507 * Status :
2508 *
2509 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2510 *****************************************************************************/
2511
2512DWORD HMWaitForSingleObjectEx(HANDLE hObject,
2513 DWORD dwTimeout,
2514 BOOL fAlertable)
2515{
2516 int iIndex; /* index into the handle table */
2517 DWORD dwResult; /* result from the device handler's API */
2518 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2519
2520 /* validate handle */
2521 iIndex = _HMHandleQuery(hObject); /* get the index */
2522 if (-1 == iIndex) /* error ? */
2523 {
2524 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2525 return WAIT_FAILED; /* signal failure */
2526 }
2527
2528 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2529
2530 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2531 return ERROR_SYS_INTERNAL;
2532
2533 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObjectEx(&pHMHandle->hmHandleData,
2534 dwTimeout,
2535 fAlertable);
2536
2537 return (dwResult); /* deliver return code */
2538}
2539
2540
2541/*****************************************************************************
2542 * Name : HMDeviceHandler::FlushFileBuffers
2543 * Purpose : router function for FlushFileBuffers
2544 * Parameters:
2545 * Variables :
2546 * Result :
2547 * Remark :
2548 * Status :
2549 *
2550 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2551 *****************************************************************************/
2552
2553BOOL WIN32API FlushFileBuffers(HANDLE hFile)
2554{
2555 int iIndex; /* index into the handle table */
2556 DWORD dwResult; /* result from the device handler's API */
2557 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2558
2559 /* validate handle */
2560 iIndex = _HMHandleQuery(hFile); /* get the index */
2561 if (-1 == iIndex) /* error ? */
2562 {
2563 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2564 return FALSE; /* signal failure */
2565 }
2566
2567 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2568
2569 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2570 return ERROR_SYS_INTERNAL;
2571
2572 dwResult = pHMHandle->pDeviceHandler->FlushFileBuffers(&pHMHandle->hmHandleData);
2573
2574 return (dwResult); /* deliver return code */
2575}
2576
2577
2578/*****************************************************************************
2579 * Name : HMDeviceHandler::GetOverlappedResult
2580 * Purpose : router function for GetOverlappedResult
2581 * Parameters:
2582 * Variables :
2583 * Result :
2584 * Remark :
2585 * Status :
2586 *
2587 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2588 *****************************************************************************/
2589
2590BOOL HMGetOverlappedResult(HANDLE hObject,
2591 LPOVERLAPPED lpOverlapped,
2592 LPDWORD arg3,
2593 BOOL arg4)
2594{
2595 int iIndex; /* index into the handle table */
2596 DWORD dwResult; /* result from the device handler's API */
2597 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2598
2599 /* validate handle */
2600 iIndex = _HMHandleQuery(hObject); /* get the index */
2601 if (-1 == iIndex) /* error ? */
2602 {
2603 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2604 return FALSE; /* signal failure */
2605 }
2606
2607 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2608
2609 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2610 return ERROR_SYS_INTERNAL;
2611
2612 dwResult = pHMHandle->pDeviceHandler->GetOverlappedResult(&pHMHandle->hmHandleData,
2613 lpOverlapped,
2614 arg3,
2615 arg4);
2616
2617 return (dwResult); /* deliver return code */
2618}
2619
2620
2621/*****************************************************************************
2622 * Name : HMReleaseMutex
2623 * Purpose : router function for ReleaseMutex
2624 * Parameters:
2625 * Variables :
2626 * Result :
2627 * Remark :
2628 * Status :
2629 *
2630 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2631 *****************************************************************************/
2632
2633BOOL WIN32API ReleaseMutex(HANDLE hObject)
2634{
2635 int iIndex; /* index into the handle table */
2636 DWORD dwResult; /* result from the device handler's API */
2637 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2638
2639 /* validate handle */
2640 iIndex = _HMHandleQuery(hObject); /* get the index */
2641 if (-1 == iIndex) /* error ? */
2642 {
2643 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2644 return FALSE; /* signal failure */
2645 }
2646
2647 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2648
2649 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2650 return ERROR_SYS_INTERNAL;
2651
2652 dwResult = pHMHandle->pDeviceHandler->ReleaseMutex(&pHMHandle->hmHandleData);
2653
2654 return (dwResult); /* deliver return code */
2655}
2656
2657
2658
2659
2660/*****************************************************************************
2661 * Name : HANDLE HMCreateMutex
2662 * Purpose : Wrapper for the CreateMutex() API
2663 * Parameters:
2664 * Variables :
2665 * Result :
2666 * Remark :
2667 * Status :
2668 *
2669 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2670 *****************************************************************************/
2671
2672HANDLE WIN32API CreateMutexA(LPSECURITY_ATTRIBUTES lpsa,
2673 BOOL bInitialOwner,
2674 LPCTSTR lpName)
2675{
2676 int iIndex; /* index into the handle table */
2677 int iIndexNew; /* index into the handle table */
2678 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2679 PHMHANDLEDATA pHMHandleData;
2680 DWORD rc; /* API return code */
2681
2682
2683 if(lpName) { //check if shared mutex semaphore already exists
2684 dprintf(("Event semaphore name %s", lpName));
2685
2686 //TODO: No inheritance??
2687 HANDLE handle = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, lpName);
2688 if(handle) {
2689 dprintf(("CreateMutex: return handle of existing mutex semaphore %x", handle));
2690 SetLastError(ERROR_ALREADY_EXISTS);
2691 return handle;
2692 }
2693 }
2694
2695 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2696
2697 iIndexNew = _HMHandleGetFree(); /* get free handle */
2698 if (-1 == iIndexNew) /* oops, no free handles ! */
2699 {
2700 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2701 return 0; /* signal error */
2702 }
2703
2704
2705 /* initialize the complete HMHANDLEDATA structure */
2706 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2707 pHMHandleData->dwAccess = 0;
2708 pHMHandleData->dwShare = 0;
2709 pHMHandleData->dwCreation = 0;
2710 pHMHandleData->dwFlags = 0;
2711 pHMHandleData->lpHandlerData = NULL;
2712 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2713
2714
2715 /* we've got to mark the handle as occupied here, since another device */
2716 /* could be created within the device handler -> deadlock */
2717
2718 /* write appropriate entry into the handle table if open succeeded */
2719 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2720 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2721
2722 /* call the device handler */
2723 rc = pDeviceHandler->CreateMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2724 lpsa,
2725 bInitialOwner,
2726 lpName);
2727 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2728 {
2729 FREEHANDLE(iIndexNew);
2730// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2731 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2732 return 0; /* signal error */
2733 }
2734 else
2735 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2736
2737 return iIndexNew; /* return valid handle */
2738}
2739
2740
2741
2742/*****************************************************************************
2743 * Name : HANDLE HMOpenMutex
2744 * Purpose : Wrapper for the OpenMutex() API
2745 * Parameters:
2746 * Variables :
2747 * Result :
2748 * Remark :
2749 * Status :
2750 *
2751 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2752 *****************************************************************************/
2753
2754HANDLE WIN32API OpenMutexA(DWORD fdwAccess,
2755 BOOL fInherit,
2756 LPCTSTR lpName)
2757{
2758 int iIndex; /* index into the handle table */
2759 int iIndexNew; /* index into the handle table */
2760 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2761 PHMHANDLEDATA pHMHandleData;
2762 DWORD rc; /* API return code */
2763
2764
2765 if(lpName) {
2766 dprintf(("Mutex semaphore name %s", lpName));
2767 }
2768
2769 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2770
2771 iIndexNew = _HMHandleGetFree(); /* get free handle */
2772 if (-1 == iIndexNew) /* oops, no free handles ! */
2773 {
2774 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2775 return 0; /* signal error */
2776 }
2777
2778
2779 /* initialize the complete HMHANDLEDATA structure */
2780 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2781 pHMHandleData->dwAccess = fdwAccess;
2782 pHMHandleData->dwShare = 0;
2783 pHMHandleData->dwCreation = 0;
2784 pHMHandleData->dwFlags = 0;
2785 pHMHandleData->lpHandlerData = NULL;
2786 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2787
2788
2789 /* we've got to mark the handle as occupied here, since another device */
2790 /* could be created within the device handler -> deadlock */
2791
2792 /* write appropriate entry into the handle table if open succeeded */
2793 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2794 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2795
2796 /* call the device handler */
2797 rc = pDeviceHandler->OpenMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2798 fInherit,
2799 lpName);
2800 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2801 {
2802 FREEHANDLE(iIndexNew);
2803// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2804 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2805 return 0; /* signal error */
2806 }
2807 else
2808 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2809
2810 return iIndexNew; /* return valid handle */
2811}
2812
2813
2814/*****************************************************************************
2815 * Name : HANDLE HMCreateSemaphore
2816 * Purpose : Wrapper for the CreateSemaphore() API
2817 * Parameters:
2818 * Variables :
2819 * Result :
2820 * Remark :
2821 * Status :
2822 *
2823 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2824 *****************************************************************************/
2825
2826HANDLE WIN32API CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpsa,
2827 LONG lInitialCount,
2828 LONG lMaximumCount,
2829 LPCTSTR lpName)
2830{
2831 int iIndex; /* index into the handle table */
2832 int iIndexNew; /* index into the handle table */
2833 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2834 PHMHANDLEDATA pHMHandleData;
2835 DWORD rc; /* API return code */
2836
2837 if(lpName) { //check if shared event semaphore already exists
2838 //TODO: No inheritance??
2839 dprintf(("Semaphore name %s", lpName));
2840
2841 HANDLE handle = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, lpName);
2842 if(handle) {
2843 dprintf(("CreateSemaphore: return handle of existing semaphore %x", handle));
2844 SetLastError(ERROR_ALREADY_EXISTS);
2845 return handle;
2846 }
2847 }
2848
2849 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2850
2851 iIndexNew = _HMHandleGetFree(); /* get free handle */
2852 if (-1 == iIndexNew) /* oops, no free handles ! */
2853 {
2854 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2855 return 0; /* signal error */
2856 }
2857
2858
2859 /* initialize the complete HMHANDLEDATA structure */
2860 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2861 pHMHandleData->dwAccess = 0;
2862 pHMHandleData->dwShare = 0;
2863 pHMHandleData->dwCreation = 0;
2864 pHMHandleData->dwFlags = 0;
2865 pHMHandleData->lpHandlerData = NULL;
2866 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2867
2868
2869 /* we've got to mark the handle as occupied here, since another device */
2870 /* could be created within the device handler -> deadlock */
2871
2872 /* write appropriate entry into the handle table if open succeeded */
2873 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2874 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2875
2876 /* call the device handler */
2877 rc = pDeviceHandler->CreateSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2878 lpsa,
2879 lInitialCount,
2880 lMaximumCount,
2881 lpName);
2882 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2883 {
2884 FREEHANDLE(iIndexNew);
2885// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2886 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2887 return 0; /* signal failure */
2888 }
2889 else
2890 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2891
2892 return iIndexNew; /* return valid handle */
2893}
2894
2895
2896/*****************************************************************************
2897 * Name : HANDLE HMOpenSemaphore
2898 * Purpose : Wrapper for the OpenSemaphore() API
2899 * Parameters:
2900 * Variables :
2901 * Result :
2902 * Remark :
2903 * Status :
2904 *
2905 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2906 *****************************************************************************/
2907
2908HANDLE WIN32API OpenSemaphoreA(DWORD fdwAccess,
2909 BOOL fInherit,
2910 LPCTSTR lpName)
2911{
2912 int iIndex; /* index into the handle table */
2913 int iIndexNew; /* index into the handle table */
2914 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2915 PHMHANDLEDATA pHMHandleData;
2916 DWORD rc; /* API return code */
2917
2918
2919 if(lpName) {
2920 dprintf(("Semaphore name %s", lpName));
2921 }
2922
2923 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2924
2925 iIndexNew = _HMHandleGetFree(); /* get free handle */
2926 if (-1 == iIndexNew) /* oops, no free handles ! */
2927 {
2928 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2929 return 0; /* signal error */
2930 }
2931
2932
2933 /* initialize the complete HMHANDLEDATA structure */
2934 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2935 pHMHandleData->dwAccess = fdwAccess;
2936 pHMHandleData->dwShare = 0;
2937 pHMHandleData->dwCreation = 0;
2938 pHMHandleData->dwFlags = 0;
2939 pHMHandleData->lpHandlerData = NULL;
2940 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2941
2942
2943 /* we've got to mark the handle as occupied here, since another device */
2944 /* could be created within the device handler -> deadlock */
2945
2946 /* write appropriate entry into the handle table if open succeeded */
2947 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2948 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2949
2950 /* call the device handler */
2951 rc = pDeviceHandler->OpenSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2952 fInherit,
2953 lpName);
2954 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2955 {
2956 FREEHANDLE(iIndexNew);
2957// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2958 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2959 return 0; /* signal failure */
2960 }
2961 else
2962 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2963
2964 return iIndexNew; /* return valid handle */
2965}
2966
2967
2968/*****************************************************************************
2969 * Name : HMReleaseSemaphore
2970 * Purpose : router function for ReleaseSemaphore
2971 * Parameters:
2972 * Variables :
2973 * Result :
2974 * Remark :
2975 * Status :
2976 *
2977 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2978 *****************************************************************************/
2979
2980BOOL WIN32API ReleaseSemaphore(HANDLE hEvent,
2981 LONG cReleaseCount,
2982 LPLONG lpPreviousCount)
2983{
2984 int iIndex; /* index into the handle table */
2985 DWORD dwResult; /* result from the device handler's API */
2986 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2987
2988 /* validate handle */
2989 iIndex = _HMHandleQuery(hEvent); /* get the index */
2990 if (-1 == iIndex) /* error ? */
2991 {
2992 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2993 return 0; /* signal failure */
2994 }
2995 else
2996 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2997
2998 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2999
3000 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3001 return ERROR_SYS_INTERNAL;
3002
3003 dwResult = pHMHandle->pDeviceHandler->ReleaseSemaphore(&pHMHandle->hmHandleData,
3004 cReleaseCount,
3005 lpPreviousCount);
3006
3007 return (dwResult); /* deliver return code */
3008}
3009
3010
3011/*****************************************************************************
3012 * Name : HANDLE HMCreateFileMapping
3013 * Purpose : Wrapper for the CreateFileMapping() API
3014 * Parameters:
3015 * Variables :
3016 * Result :
3017 * Remark :
3018 * Status :
3019 *
3020 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
3021 *****************************************************************************/
3022
3023HANDLE HMCreateFileMapping(HANDLE hFile,
3024 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
3025 DWORD flProtect,
3026 DWORD dwMaximumSizeHigh,
3027 DWORD dwMaximumSizeLow,
3028 LPCTSTR lpName)
3029{
3030 int iIndex; /* index into the handle table */
3031 int iIndexNew; /* index into the handle table */
3032 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3033 PHMHANDLEDATA pHMHandleData;
3034 DWORD rc; /* API return code */
3035
3036 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
3037
3038 iIndexNew = _HMHandleGetFree(); /* get free handle */
3039 if (-1 == iIndexNew) /* oops, no free handles ! */
3040 {
3041 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3042 return 0; /* signal error */
3043 }
3044
3045 /* initialize the complete HMHANDLEDATA structure */
3046 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3047 pHMHandleData->dwAccess = 0;
3048 pHMHandleData->dwShare = 0;
3049 pHMHandleData->dwCreation = 0;
3050 pHMHandleData->dwFlags = 0;
3051 pHMHandleData->lpHandlerData = NULL;
3052 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
3053
3054 /* we've got to mark the handle as occupied here, since another device */
3055 /* could be created within the device handler -> deadlock */
3056
3057 /* write appropriate entry into the handle table if open succeeded */
3058 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3059 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3060
3061 /* call the device handler */
3062
3063 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3064 // a valid HandleManager-internal handle!
3065 rc = pDeviceHandler->CreateFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
3066 hFile,
3067 lpFileMappingAttributes,
3068 flProtect,
3069 dwMaximumSizeHigh,
3070 dwMaximumSizeLow,
3071 lpName);
3072
3073 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
3074 {
3075 if(rc != ERROR_ALREADY_EXISTS) {
3076 FREEHANDLE(iIndexNew);
3077// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3078 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3079 return (NULL); /* signal error */
3080 }
3081 SetLastError(ERROR_ALREADY_EXISTS);
3082 return iIndexNew; /* return valid handle */
3083 }
3084 else
3085 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3086
3087 return iIndexNew; /* return valid handle */
3088}
3089
3090
3091/*****************************************************************************
3092 * Name : HANDLE HMOpenFileMapping
3093 * Purpose : Wrapper for the OpenFileMapping() API
3094 * Parameters:
3095 * Variables :
3096 * Result : HANDLE if succeeded,
3097 * NULL if failed.
3098 * Remark :
3099 * Status :
3100 *
3101 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
3102 *****************************************************************************/
3103
3104HANDLE HMOpenFileMapping(DWORD fdwAccess,
3105 BOOL fInherit,
3106 LPCTSTR lpName)
3107{
3108 int iIndex; /* index into the handle table */
3109 int iIndexNew; /* index into the handle table */
3110 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3111 PHMHANDLEDATA pHMHandleData;
3112 DWORD rc; /* API return code */
3113
3114
3115 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
3116
3117 iIndexNew = _HMHandleGetFree(); /* get free handle */
3118 if (-1 == iIndexNew) /* oops, no free handles ! */
3119 {
3120 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3121 return (NULL); /* signal error */
3122 }
3123
3124 /* initialize the complete HMHANDLEDATA structure */
3125 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3126 pHMHandleData->dwAccess = fdwAccess;
3127 pHMHandleData->dwShare = 0;
3128 pHMHandleData->dwCreation = 0;
3129 pHMHandleData->dwFlags = 0;
3130 pHMHandleData->lpHandlerData = NULL;
3131
3132
3133 /* we've got to mark the handle as occupied here, since another device */
3134 /* could be created within the device handler -> deadlock */
3135
3136 /* write appropriate entry into the handle table if open succeeded */
3137 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3138 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3139
3140 /* call the device handler */
3141 rc = pDeviceHandler->OpenFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
3142 fdwAccess,
3143 fInherit,
3144 lpName);
3145 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3146 {
3147 FREEHANDLE(iIndexNew);
3148// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3149 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3150 return (NULL); /* signal error */
3151 }
3152 else
3153 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3154
3155 return iIndexNew; /* return valid handle */
3156}
3157
3158
3159/*****************************************************************************
3160 * Name : HMMapViewOfFileEx
3161 * Purpose : router function for MapViewOfFileEx
3162 * Parameters:
3163 * Variables :
3164 * Result :
3165 * Remark :
3166 * Status :
3167 *
3168 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3169 *****************************************************************************/
3170
3171LPVOID HMMapViewOfFileEx(HANDLE hFileMappingObject,
3172 DWORD dwDesiredAccess,
3173 DWORD dwFileOffsetHigh,
3174 DWORD dwFileOffsetLow,
3175 DWORD dwNumberOfBytesToMap,
3176 LPVOID lpBaseAddress)
3177{
3178 int iIndex; /* index into the handle table */
3179 LPVOID lpResult; /* result from the device handler's API */
3180 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3181
3182 /* validate handle */
3183 iIndex = _HMHandleQuery(hFileMappingObject); /* get the index */
3184 if (-1 == iIndex) /* error ? */
3185 {
3186 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3187 return (NULL); /* signal failure */
3188 }
3189
3190 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3191
3192 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3193 return NULL;
3194
3195 lpResult = pHMHandle->pDeviceHandler->MapViewOfFileEx(&pHMHandle->hmHandleData,
3196 dwDesiredAccess,
3197 dwFileOffsetHigh,
3198 dwFileOffsetLow,
3199 dwNumberOfBytesToMap,
3200 lpBaseAddress);
3201
3202 return (lpResult); /* deliver return code */
3203}
3204
3205/*****************************************************************************
3206 * Name : HMWaitForMultipleObjects
3207 * Purpose : router function for WaitForMultipleObjects
3208 * Parameters:
3209 * Variables :
3210 * Result :
3211 * Remark :
3212 * Status :
3213 *
3214 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3215 *****************************************************************************/
3216
3217DWORD HMWaitForMultipleObjects (DWORD cObjects,
3218 PHANDLE lphObjects,
3219 BOOL fWaitAll,
3220 DWORD dwTimeout)
3221{
3222 ULONG ulIndex;
3223 PHANDLE pArrayOfHandles;
3224 PHANDLE pLoop1 = lphObjects;
3225 PHANDLE pLoop2;
3226 DWORD rc;
3227
3228 // allocate array for handle table
3229 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3230 if (pArrayOfHandles == NULL)
3231 {
3232 dprintf(("ERROR: HMWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3233 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3234 return WAIT_FAILED;
3235 }
3236 else
3237 pLoop2 = pArrayOfHandles;
3238
3239 // convert array to odin handles
3240 for (ulIndex = 0;
3241
3242 ulIndex < cObjects;
3243
3244 ulIndex++,
3245 pLoop1++,
3246 pLoop2++)
3247 {
3248 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3249 pLoop2);
3250
3251 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, Open32-%08xh\n",
3252 ulIndex,
3253 *pLoop1,
3254 *pLoop2));
3255
3256 // @@@PH to imlpement: check handle type!
3257 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3258 if (rc != NO_ERROR)
3259 {
3260 dprintf(("KERNEL32: HMWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3261 *pLoop1));
3262
3263 *pLoop2 = *pLoop1;
3264//// SetLastError(ERROR_INVALID_HANDLE);
3265//// return (WAIT_FAILED);
3266 }
3267 }
3268
3269 // OK, now forward to Open32.
3270 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3271 // but to i.e. the console subsystem!
3272 rc = O32_WaitForMultipleObjects(cObjects,
3273 pArrayOfHandles,
3274 fWaitAll,
3275 dwTimeout);
3276
3277 return (rc); // OK, done
3278}
3279
3280
3281/*****************************************************************************
3282 * Name : HMWaitForMultipleObjectsEx
3283 * Purpose : router function for WaitForMultipleObjectsEx
3284 * Parameters:
3285 * Variables :
3286 * Result :
3287 * Remark :
3288 * Status :
3289 *
3290 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3291 *****************************************************************************/
3292
3293DWORD HMWaitForMultipleObjectsEx (DWORD cObjects,
3294 PHANDLE lphObjects,
3295 BOOL fWaitAll,
3296 DWORD dwTimeout,
3297 BOOL fAlertable)
3298{
3299 // @@@PH: Note: fAlertable is ignored !
3300 return (HMWaitForMultipleObjects(cObjects,
3301 lphObjects,
3302 fWaitAll,
3303 dwTimeout));
3304}
3305
3306/*****************************************************************************
3307 * Name : HMMsgWaitForMultipleObjects
3308 * Purpose : router function for MsgWaitForMultipleObjects
3309 * Parameters:
3310 * Variables :
3311 * Result :
3312 * Remark : Open32 doesn't implement this properly! (doesn't check dwWakeMask)
3313 * Status :
3314 *
3315 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3316 *****************************************************************************/
3317
3318DWORD HMMsgWaitForMultipleObjects (DWORD cObjects,
3319 LPHANDLE lphObjects,
3320 BOOL fWaitAll,
3321 DWORD dwTimeout,
3322 DWORD dwWakeMask)
3323{
3324 ULONG ulIndex;
3325 PHANDLE pArrayOfHandles;
3326 PHANDLE pLoop1 = lphObjects;
3327 PHANDLE pLoop2;
3328 DWORD rc;
3329
3330 // allocate array for handle table
3331 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3332 if (pArrayOfHandles == NULL)
3333 {
3334 dprintf(("ERROR: HMMsgWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3335 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3336 return WAIT_FAILED;
3337 }
3338 else
3339 pLoop2 = pArrayOfHandles;
3340
3341 // convert array to odin handles
3342 for (ulIndex = 0;
3343
3344 ulIndex < cObjects;
3345
3346 ulIndex++,
3347 pLoop1++,
3348 pLoop2++)
3349 {
3350 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3351 pLoop2);
3352
3353 dprintf2(("MsgWaitForMultipleObjects handle %x->%x", *pLoop1, *pLoop2));
3354 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3355 if (rc != NO_ERROR)
3356 {
3357 dprintf(("KERNEL32: HMMsgWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3358 *pLoop1));
3359
3360 *pLoop2 = *pLoop1;
3361//// SetLastError(ERROR_INVALID_HANDLE);
3362//// return (WAIT_FAILED);
3363 }
3364 }
3365
3366 // OK, now forward to Open32.
3367 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3368 // but to i.e. the console subsystem!
3369 rc = O32_MsgWaitForMultipleObjects(cObjects,
3370 pArrayOfHandles,
3371 fWaitAll, dwTimeout,
3372 dwWakeMask);
3373
3374 dprintf2(("MsgWaitForMultipleObjects returned %d", rc));
3375 return (rc); // OK, done
3376}
3377/*****************************************************************************
3378 * Name : HMDeviceIoControl
3379 * Purpose : router function for DeviceIoControl
3380 * Parameters:
3381 * Variables :
3382 * Result :
3383 * Remark :
3384 * Status :
3385 *
3386 * Author : Sander van Leeuwen
3387 *****************************************************************************/
3388
3389BOOL WIN32API DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
3390 LPVOID lpInBuffer, DWORD nInBufferSize,
3391 LPVOID lpOutBuffer, DWORD nOutBufferSize,
3392 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
3393{
3394 int iIndex; /* index into the handle table */
3395 BOOL fResult; /* result from the device handler's CloseHandle() */
3396 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3397
3398 /* validate handle */
3399 iIndex = _HMHandleQuery(hDevice); /* get the index */
3400 if (-1 == iIndex) /* error ? */
3401 {
3402 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3403 return (FALSE); /* signal failure */
3404 }
3405
3406 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3407
3408 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3409 return ERROR_SYS_INTERNAL;
3410
3411 fResult = pHMHandle->pDeviceHandler->DeviceIoControl(&pHMHandle->hmHandleData,
3412 dwIoControlCode,
3413 lpInBuffer, nInBufferSize,
3414 lpOutBuffer, nOutBufferSize,
3415 lpBytesReturned, lpOverlapped);
3416
3417 return (fResult); /* deliver return code */
3418}
3419/*****************************************************************************
3420 * Name : BOOL WIN32API CancelIo
3421 * Purpose : The CancelIO function cancels all pending input and output
3422 * (I/O) operations that were issued by the calling thread for
3423 * the specified file handle. The function does not cancel
3424 * I/O operations issued for the file handle by other threads.
3425 * Parameters: HANDLE hFile file handle for which to cancel I/O
3426 * Variables :
3427 * Result : If the function succeeds, the return value is nonzero All pending
3428 * I/O operations issued by the calling thread for the file handle
3429 * were successfully canceled.
3430 * If the function fails, the return value is zero.
3431 * To get extended error information, call GetLastError.
3432 * Remark : If there are any I/O operations in progress for the specified
3433 * file HANDLE and they were issued by the calling thread, the
3434 * CancelIO function cancels them.
3435 * Note that the I/O operations must have been issued as
3436 * overlapped I/O. If they were not, the I/O operations would not
3437 * have returned to allow the thread to call the CancelIO function.
3438 * Calling the CancelIO function with a file handle that was not
3439 * opened with FILE_FLAG_OVERLAPPED does nothing.
3440 * All I/O operations that are canceled will complete with the
3441 * error ERROR_OPERATION_ABORTED. All completion notifications
3442 * for the I/O operations will occur normally.
3443 * Status :
3444 *
3445 * Author : Sander van Leeuwen
3446 *****************************************************************************/
3447BOOL WIN32API CancelIo(HANDLE hDevice)
3448{
3449 int iIndex; /* index into the handle table */
3450 BOOL fResult; /* result from the device handler's CloseHandle() */
3451 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3452
3453 /* validate handle */
3454 iIndex = _HMHandleQuery(hDevice); /* get the index */
3455 if (-1 == iIndex) /* error ? */
3456 {
3457 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3458 return (FALSE); /* signal failure */
3459 }
3460
3461 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3462
3463 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3464 return ERROR_SYS_INTERNAL;
3465
3466 fResult = pHMHandle->pDeviceHandler->CancelIo(&pHMHandle->hmHandleData);
3467
3468 return (fResult); /* deliver return code */
3469}
3470
3471/*****************************************************************************
3472 * Name : HMOpenThreadToken
3473 * Purpose : router function for NtOpenThreadToken
3474 * Parameters:
3475 * Variables :
3476 * Result :
3477 * Remark :
3478 * Status :
3479 *
3480 * Author : SvL
3481 *****************************************************************************/
3482
3483DWORD HMOpenThreadToken(HANDLE ThreadHandle,
3484 DWORD DesiredAccess,
3485 DWORD OpenAsSelf,
3486 HANDLE *TokenHandle)
3487{
3488 int iIndex; /* index into the handle table */
3489 int iIndexNew; /* index into the handle table */
3490 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3491 PHMHANDLEDATA pHMHandleData;
3492 DWORD rc; /* API return code */
3493
3494 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3495
3496 iIndexNew = _HMHandleGetFree(); /* get free handle */
3497 if (-1 == iIndexNew) /* oops, no free handles ! */
3498 {
3499 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3500 return ERROR_NOT_ENOUGH_MEMORY;
3501 }
3502
3503 /* initialize the complete HMHANDLEDATA structure */
3504 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3505 pHMHandleData->dwAccess = DesiredAccess;
3506 pHMHandleData->dwShare = 0;
3507 pHMHandleData->dwCreation = 0;
3508 pHMHandleData->dwFlags = 0;
3509 pHMHandleData->lpHandlerData = NULL;
3510 pHMHandleData->dwInternalType = HMTYPE_THREADTOKEN;
3511
3512
3513 /* we've got to mark the handle as occupied here, since another device */
3514 /* could be created within the device handler -> deadlock */
3515
3516 /* write appropriate entry into the handle table if open succeeded */
3517 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3518 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3519
3520 /* call the device handler */
3521
3522 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3523 // a valid HandleManager-internal handle!
3524 rc = pDeviceHandler->OpenThreadToken(&TabWin32Handles[iIndexNew].hmHandleData,
3525 ThreadHandle,
3526 OpenAsSelf);
3527
3528 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3529 {
3530 FREEHANDLE(iIndexNew);
3531// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3532 return (rc); /* signal error */
3533 }
3534 else
3535 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3536
3537 *TokenHandle = iIndexNew; /* return valid handle */
3538 return STATUS_SUCCESS;
3539}
3540
3541/*****************************************************************************
3542 * Name : HMOpenProcessToken
3543 * Purpose : router function for NtOpenProcessToken
3544 * Parameters:
3545 * Variables :
3546 * Result :
3547 * Remark :
3548 * Status :
3549 *
3550 * Author : SvL
3551 *****************************************************************************/
3552DWORD HMOpenProcessToken(HANDLE ProcessHandle,
3553 DWORD DesiredAccess,
3554 DWORD dwUserData,
3555 HANDLE *TokenHandle)
3556{
3557 int iIndex; /* index into the handle table */
3558 int iIndexNew; /* index into the handle table */
3559 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3560 PHMHANDLEDATA pHMHandleData;
3561 DWORD rc; /* API return code */
3562
3563 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3564
3565 iIndexNew = _HMHandleGetFree(); /* get free handle */
3566 if (-1 == iIndexNew) /* oops, no free handles ! */
3567 {
3568 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3569 return ERROR_NOT_ENOUGH_MEMORY;
3570 }
3571
3572 /* initialize the complete HMHANDLEDATA structure */
3573 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3574 pHMHandleData->dwAccess = DesiredAccess;
3575 pHMHandleData->dwShare = 0;
3576 pHMHandleData->dwCreation = 0;
3577 pHMHandleData->dwFlags = 0;
3578 pHMHandleData->lpHandlerData = NULL;
3579 pHMHandleData->dwInternalType = HMTYPE_PROCESSTOKEN;
3580
3581
3582 /* we've got to mark the handle as occupied here, since another device */
3583 /* could be created within the device handler -> deadlock */
3584
3585 /* write appropriate entry into the handle table if open succeeded */
3586 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3587 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3588
3589 /* call the device handler */
3590
3591 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3592 // a valid HandleManager-internal handle!
3593 rc = pDeviceHandler->OpenProcessToken(&TabWin32Handles[iIndexNew].hmHandleData,
3594 dwUserData,
3595 ProcessHandle);
3596
3597 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3598 {
3599 FREEHANDLE(iIndexNew);
3600// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3601 return (rc); /* signal error */
3602 }
3603 else
3604 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3605
3606 *TokenHandle = iIndexNew; /* return valid handle */
3607 return STATUS_SUCCESS;
3608}
3609
3610
3611/**
3612 * Gets the type of an object.
3613 *
3614 * @returns the value of one of the HMMTYPE_ defines.
3615 * @returns HMTYPE_BAD_HANDLE if hObject isn't a valid handle.
3616 * @param hObject Handle to object.
3617 */
3618unsigned WIN32API HMQueryObjectType(HANDLE hObject)
3619{
3620 PHMHANDLEDATA pData = HMQueryHandleData(hObject);
3621 if (pData)
3622 return (unsigned)pData->dwInternalType;
3623 return HMTYPE_BAD_HANDLE;
3624}
3625
Note: See TracBrowser for help on using the repository browser.