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

Last change on this file since 9610 was 9235, checked in by sandervl, 23 years ago

WaitForSingleObject, (Msg)WaitForMultipleObjects: If dwTimeout is not 0 and smaller than 20 ms, then temporarily change thread priority to time critical to make sure we don't get a late timeout

File size: 191.5 KB
Line 
1/* $Id: HandleManager.cpp,v 1.91 2002-09-14 13:49:39 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 "misc.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 <vmutex.h>
70#include <win\thread.h>
71
72#define DBG_LOCALLOG DBG_handlemanager
73#include "dbglocal.h"
74
75/*****************************************************************************
76 * Defines *
77 *****************************************************************************/
78
79 /* this is the size of our currently static handle table */
80#define MAX_OS2_HMHANDLES 4096
81
82
83/*****************************************************************************
84 * Structures *
85 *****************************************************************************/
86
87typedef struct _HMHANDLE
88{
89 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
90 HMHANDLEDATA hmHandleData; /* attributes of the handle */
91} HMHANDLE, *PHMHANDLE;
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;
122
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 *pHMDisk;
140 HMDeviceHandler *pHMMutex;
141 HMDeviceHandler *pHMSemaphore;
142 HMDeviceHandler *pHMFileMapping; /* static instances of subsystems */
143 HMDeviceHandler *pHMComm; /* serial communication */
144 HMDeviceHandler *pHMToken; /* security tokens */
145 HMDeviceHandler *pHMThread;
146 HMDeviceHandler *pHMNamedPipe;
147 HMDeviceHandler *pHMMailslot;
148 HMDeviceHandler *pHMParPort; /* parallel communication */
149 HMDeviceHandler *pHMNul; /* nul device */
150
151 ULONG ulHandleLast; /* index of last used handle */
152} HMGlobals;
153
154
155/*****************************************************************************
156 * Local Prototypes *
157 *****************************************************************************/
158
159 /* get appropriate device handler by the device name */
160static HMDeviceHandler* _Optlink _HMDeviceFind(LPSTR pszDeviceName);
161
162 /* get next free handle from the handle table */
163static ULONG _Optlink _HMHandleGetFree(void);
164
165 /* get handle table entry from handle */
166static ULONG _Optlink _HMHandleQuery(HANDLE hHandle);
167
168// Get GlobalDeviceData
169static VOID *_HMDeviceGetData (LPSTR pszDeviceName);
170
171
172/*****************************************************************************
173 * Name : static HMDeviceHandler * _HMDeviceFind
174 * Purpose : obtain appropriate device handler from the table by searching
175 * for a device name or alias
176 * Parameters: PSZ pszDeviceName
177 * Variables :
178 * Result : HMDeviceHandler * - pointer to the handler object
179 * Remark :
180 * Status :
181 *
182 * Author : Patrick Haller [Wed, 1998/02/11 20:42]
183 *****************************************************************************/
184
185static HMDeviceHandler *_HMDeviceFind (LPSTR pszDeviceName)
186{
187 PHMDEVICE pHMDevice; /* iterator over the device table */
188 int namelength = strlen(pszDeviceName);
189
190 if (pszDeviceName != NULL)
191 {
192 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
193 pHMDevice != NULL;
194 pHMDevice = pHMDevice->pNext)
195 {
196 if(pHMDevice->pDeviceHandler->FindDevice(pHMDevice->pszDeviceName, pszDeviceName, namelength) == TRUE)
197 {
198 return pHMDevice->pDeviceHandler;
199 }
200 }
201 }
202 return (HMGlobals.pHMOpen32); /* haven't found anything, return default */
203}
204/*****************************************************************************
205 * Name : static VOID *_HMDeviceGetData
206 * Purpose : obtain pointer to device data from the table by searching
207 * for a device name or alias
208 * Parameters: PSZ pszDeviceName
209 * Variables :
210 * Result : VOID * - pointer to the handlers device data
211 * Remark :
212 * Status :
213 *
214 * Author : Markus Montkowski
215 *****************************************************************************/
216
217static VOID *_HMDeviceGetData (LPSTR pszDeviceName)
218{
219 PHMDEVICE pHMDevice; /* iterator over the device table */
220 int namelength = strlen(pszDeviceName);
221
222 if (pszDeviceName != NULL)
223 {
224 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
225 pHMDevice != NULL;
226 pHMDevice = pHMDevice->pNext)
227 {
228 if(pHMDevice->pDeviceHandler->FindDevice(pHMDevice->pszDeviceName, pszDeviceName, namelength) == TRUE)
229 {
230 return (pHMDevice->pDevData); /* OK, we've found our device */
231 }
232 }
233 }
234 return (NULL); /* haven't found anything, return NULL */
235}
236
237/*****************************************************************************
238 * Name : static int _HMHandleGetFree
239 * Purpose : get index to first free handle in the handle table
240 * Parameters:
241 * Variables :
242 * Result : int iIndex - index to the table or -1 in case of error
243 * Remark :
244 * Status :
245 *
246 * Author : Patrick Haller [Wed, 1998/02/11 20:43]
247 *****************************************************************************/
248
249static ULONG _HMHandleGetFree(void)
250{
251 register ULONG ulLoop;
252
253 handleMutex.enter();
254
255 for (ulLoop = 1; // @@@PH Note, this is an experimental change
256 // 0L as hHandle is sometimes considered invalid!
257 // this will never return 0l as free handle now.
258 ulLoop < MAX_OS2_HMHANDLES;
259 ulLoop++)
260 {
261 /* free handle found ? */
262 if (INVALID_HANDLE_VALUE == TabWin32Handles[ulLoop].hmHandleData.hHMHandle) {
263 //SvL: Mark handle as allocated here. Doing it outside of this function
264 // isn't thread safe. (and not very smart)
265 TabWin32Handles[ulLoop].hmHandleData.hHMHandle = ulLoop;
266 TabWin32Handles[ulLoop].hmHandleData.dwUserData = 0;
267 TabWin32Handles[ulLoop].hmHandleData.dwInternalType = HMTYPE_UNKNOWN;
268 TabWin32Handles[ulLoop].hmHandleData.hWin32Handle = (HANDLE)ulLoop;
269 TabWin32Handles[ulLoop].hmHandleData.lpDeviceData = NULL;
270 handleMutex.leave();
271 return (ulLoop); /* OK, then return it to the caller */
272 }
273 }
274
275 handleMutex.leave();
276 return (INVALID_HANDLE_VALUE); /* haven't found any free handle */
277}
278
279
280/*****************************************************************************
281 * Name : HMHandleGetUserData
282 * Purpose : Get the dwUserData dword for a specific handle
283 * Parameters: HANDLE hHandle
284 * Variables :
285 * Result : -1 or dwUserData
286 * Remark :
287 * Status :
288 *
289 * Author : SvL
290 *****************************************************************************/
291DWORD HMHandleGetUserData(ULONG hHandle)
292{
293 if (hHandle > MAX_OS2_HMHANDLES) /* check the table range */
294 return (-1);
295 /* Oops, invalid handle ! */
296 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
297 return (-1); /* nope, ERROR_INVALID_HANDLE */
298
299 return TabWin32Handles[hHandle].hmHandleData.dwUserData;
300}
301
302/*****************************************************************************
303 * Name : HMHandleGetUserData
304 * Purpose : Get the dwUserData dword for a specific handle
305 * Parameters: HANDLE hHandle
306 * Variables :
307 * Result : -1 or dwUserData
308 * Remark :
309 * Status :
310 *
311 * Author : SvL
312 *****************************************************************************/
313DWORD HMHandleSetUserData(ULONG hHandle, ULONG dwUserData)
314{
315 if (hHandle > MAX_OS2_HMHANDLES) /* check the table range */
316 return (-1);
317 /* Oops, invalid handle ! */
318 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
319 return (-1); /* nope, ERROR_INVALID_HANDLE */
320
321 TabWin32Handles[hHandle].hmHandleData.dwUserData = dwUserData;
322 return NO_ERROR;
323}
324
325/*****************************************************************************
326 * Name : static int _HMHandleQuery
327 * Purpose : gets the index of handle table entry as fast as possible from
328 * the specified handle
329 * Parameters: HANDLE hHandle
330 * Variables :
331 * Result : index or -1 in case of error
332 * Remark : Should fail for standard handles (in/out/err)!!!!!!!!!!
333 * HMGetFileType depends on this!!!
334 * Status :
335 *
336 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
337 *****************************************************************************/
338
339static ULONG INLINE _HMHandleQuery(HANDLE hHandle)
340{
341 if (hHandle > MAX_OS2_HMHANDLES) /* check the table range */
342 return (INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
343
344 /* Oops, invalid handle ! */
345 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
346 return (INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
347
348 return ( hHandle); /* OK, we've got our handle index */
349}
350
351
352/*****************************************************************************
353 * Name : DWORD HMDeviceRegister
354 * Purpose : register a device with the handle manager
355 * Parameters: PSZ pszDeviceName
356 * HMDeviceHandler *pDeviceHandler
357 * Variables :
358 * Result : API returncode
359 * Remark :
360 * Status :
361 *
362 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
363 *****************************************************************************/
364
365DWORD HMDeviceRegisterEx(LPSTR pszDeviceName,
366 HMDeviceHandler *pDeviceHandler,
367 VOID *pDevData)
368{
369 PHMDEVICE pHMDevice; /* our new device to be allocated */
370
371 if ( (pszDeviceName == NULL) || /* check parameters */
372 (pDeviceHandler == NULL) )
373 return (ERROR_INVALID_PARAMETER); /* raise error conditon */
374
375
376 pHMDevice = (PHMDEVICE) malloc (sizeof (HMDEVICE) ); /* allocate memory */
377 if (pHMDevice == NULL) /* check proper allocation */
378 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
379
380 pHMDevice->pszDeviceName = strdup(pszDeviceName); /* copy name */
381 if (pHMDevice->pszDeviceName == NULL) /* check proper allocation */
382 {
383 free (pHMDevice); /* free previously allocated memory */
384 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
385 }
386
387 pHMDevice->pDeviceHandler = pDeviceHandler; /* store pointer to device */
388 pHMDevice->pNext = TabWin32Devices; /* establish linkage */
389 pHMDevice->pDevData = pDevData;
390
391 TabWin32Devices = pHMDevice; /* insert new node as root in the list */
392
393 return (NO_ERROR);
394}
395
396DWORD HMDeviceRegister(LPSTR pszDeviceName,
397 HMDeviceHandler *pDeviceHandler)
398{
399 return HMDeviceRegisterEx(pszDeviceName, pDeviceHandler, NULL);
400}
401
402/*****************************************************************************
403 * Name : DWORD HMInitialize
404 * Purpose : Initialize the handlemanager
405 * Parameters: -
406 * Variables : -
407 * Result : always NO_ERROR
408 * Remark : this routine just stores the standard handles in the
409 * internal table within the HandleManager
410 * Status :
411 *
412 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
413 *****************************************************************************/
414
415DWORD HMInitialize(void)
416{
417 ULONG ulIndex;
418
419 if (HMGlobals.fIsInitialized != TRUE)
420 {
421 handleMutex.enter();
422
423 TabWin32Handles = (HMHANDLE *)malloc(MAX_OS2_HMHANDLES*sizeof(HMHANDLE));
424 if(TabWin32Handles == NULL) {
425 DebugInt3();
426 return ERROR_NOT_ENOUGH_MEMORY;
427 }
428 memset(TabWin32Handles, 0, MAX_OS2_HMHANDLES*sizeof(HMHANDLE));
429
430 // fill handle table
431 for(ulIndex = 0; ulIndex < MAX_OS2_HMHANDLES; ulIndex++) {
432 TabWin32Handles[ulIndex].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
433 }
434 handleMutex.leave();
435
436 dprintf(("KERNEL32:HandleManager:HMInitialize() storing handles.\n"));
437
438 memset(&HMGlobals, /* zero out the structure first */
439 0,
440 sizeof(HMGlobals));
441
442 HMGlobals.fIsInitialized = TRUE; /* OK, done */
443
444#if 1
445 //This is a very bad idea. \\\\.\\NTICE -> NTICE, if the file exits, then
446 //it will open the file instead of the device driver
447 /* add standard symbolic links first, so local symbolic links in the
448 * device handlers get precedence over the default here.
449 *
450 * Device handlers are supposed to place the appropriate
451 * symbolic links such as "\\.\\COM1", "COM1"
452 *
453 * - "\\.\f:\temp\readme.txt" is a valid file
454 * - "com1" is a valid device in case serial port 1 exists,
455 * otherwise it'd be a valid file.
456 * - "\\.\filename" is the only misleading case (to be verified)
457 *
458 * Note:
459 * the Open32 "device" definately MUST be the last device to be
460 * asked to accept the specified name.
461 */
462 {
463 // strings are placed in read-only segment
464 PSZ pszDrive = strdup("\\\\.\\x:");
465 PSZ pszDrive2 = strdup("\\\\.\\x:");
466 for (char ch = 'A'; ch <= 'Z'; ch++)
467 {
468 pszDrive[4] = ch;
469 pszDrive2[4] = ch;
470 HandleNamesAddSymbolicLink(pszDrive, pszDrive+4);
471 HandleNamesAddSymbolicLink(pszDrive2, pszDrive2+4);
472 }
473 free(pszDrive);
474 free(pszDrive2);
475 HandleNamesAddSymbolicLink("\\\\?\\UNC\\", "\\\\");
476 //SvL: Can be used in Windows 2000 to open device drivers
477 HandleNamesAddSymbolicLink("\\\\.\\Global", "\\\\.");
478 }
479#endif
480
481 /* copy standard handles from OS/2's Open32 Subsystem */
482 HMGlobals.pHMStandard = new HMDeviceStandardClass("\\\\STANDARD_HANDLE\\");
483 HMSetStdHandle(STD_INPUT_HANDLE, O32_GetStdHandle(STD_INPUT_HANDLE));
484 HMSetStdHandle(STD_OUTPUT_HANDLE, O32_GetStdHandle(STD_OUTPUT_HANDLE));
485 HMSetStdHandle(STD_ERROR_HANDLE, O32_GetStdHandle(STD_ERROR_HANDLE));
486
487 /* create handle manager instance for Open32 handles */
488 HMGlobals.pHMOpen32 = new HMDeviceOpen32Class("\\\\.\\");
489 HMGlobals.pHMEvent = new HMDeviceEventClass("\\\\EVENT\\");
490 HMGlobals.pHMFile = new HMDeviceFileClass("\\\\FILE\\");
491 HMGlobals.pHMDisk = new HMDeviceDiskClass("\\\\DISK\\");
492 HMGlobals.pHMMutex = new HMDeviceMutexClass("\\\\MUTEX\\");
493 HMGlobals.pHMSemaphore = new HMDeviceSemaphoreClass("\\\\SEM\\");
494 HMGlobals.pHMFileMapping= new HMDeviceMemMapClass("\\\\MEMMAP\\");
495 HMGlobals.pHMComm = new HMDeviceCommClass("\\\\COM\\");
496 HMGlobals.pHMToken = new HMDeviceTokenClass("\\\\TOKEN\\");
497 HMGlobals.pHMThread = new HMDeviceThreadClass("\\\\THREAD\\");
498 HMGlobals.pHMNamedPipe = new HMDeviceNamedPipeClass("\\\\PIPE\\");
499 HMGlobals.pHMMailslot = new HMMailslotClass("\\MAILSLOT\\");
500 HMGlobals.pHMParPort = new HMDeviceParPortClass("\\\\LPT\\");
501 HMGlobals.pHMNul = new HMDeviceNulClass("\\\\NUL\\");
502 }
503 return (NO_ERROR);
504}
505
506
507/*****************************************************************************
508 * Name : DWORD HMTerminate
509 * Purpose : Terminate the handlemanager
510 * Parameters:
511 * Variables :
512 * Result :
513 * Remark :
514 * Status :
515 *
516 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
517 *****************************************************************************/
518
519DWORD HMTerminate(void)
520{
521 /* @@@PH we could deallocate the device list here */
522
523 if(HMGlobals.pHMOpen32)
524 delete HMGlobals.pHMOpen32;
525 if(HMGlobals.pHMEvent)
526 delete HMGlobals.pHMEvent;
527 if(HMGlobals.pHMFile)
528 delete HMGlobals.pHMFile;
529 if(HMGlobals.pHMMutex)
530 delete HMGlobals.pHMMutex;
531 if(HMGlobals.pHMSemaphore)
532 delete HMGlobals.pHMSemaphore;
533 if(HMGlobals.pHMFileMapping)
534 delete HMGlobals.pHMFileMapping;
535 if(HMGlobals.pHMComm)
536 delete HMGlobals.pHMComm;
537 if(HMGlobals.pHMToken)
538 delete HMGlobals.pHMToken;
539 if(HMGlobals.pHMThread)
540 delete HMGlobals.pHMThread;
541 if(HMGlobals.pHMNamedPipe)
542 delete HMGlobals.pHMNamedPipe;
543 if(HMGlobals.pHMMailslot)
544 delete HMGlobals.pHMMailslot;
545 if(HMGlobals.pHMDisk)
546 delete HMGlobals.pHMDisk;
547 if(HMGlobals.pHMStandard);
548 delete HMGlobals.pHMStandard;
549 if(HMGlobals.pHMParPort)
550 delete HMGlobals.pHMParPort;
551 if(HMGlobals.pHMNul)
552 delete HMGlobals.pHMNul;
553
554 return (NO_ERROR);
555}
556
557
558/*****************************************************************************/
559/* handle translation buffer management */
560/* */
561/* Since some Win32 applications rely (!) on 16-bit handles, we've got to do */
562/* 32-bit to 16-bit and vs vsa translation here. */
563/* Filehandle-based functions should be routed via the handlemanager instead */
564/* of going to Open32 directly. */
565/*****************************************************************************/
566
567
568/*****************************************************************************
569 * Name : DWORD HMHandleAllocate
570 * Purpose : allocate a handle in the translation table
571 * Parameters: PULONG pHandle16 - to return the allocated handle
572 * ULONG hHandle32 - the associated OS/2 handle
573 * Variables :
574 * Result : API returncode
575 * Remark : no parameter checking is done, phHandle may not be invalid
576 * hHandle32 shouldn't be 0
577 * Should be protected with a HM-Mutex !
578 * Status :
579 *
580 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
581 *****************************************************************************/
582
583DWORD HMHandleAllocate (PULONG phHandle16,
584 ULONG hHandleOS2)
585{
586 register ULONG ulHandle;
587
588#ifdef DEBUG_LOCAL
589 dprintf(("KERNEL32: HMHandleAllocate (%08xh,%08xh)\n",
590 phHandle16,
591 hHandleOS2));
592#endif
593
594 // @@@PH 2001-09-27
595 // prevent too quick re-use of last handle
596 ulHandle = HMGlobals.ulHandleLast + 1; /* get free handle */
597
598 handleMutex.enter();
599
600 if(ulHandle == 0) {
601 ulHandle = 1; //SvL: Start searching from index 1
602 }
603 do
604 {
605 /* check if handle is free */
606 if (TabWin32Handles[ulHandle].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
607 {
608 *phHandle16 = ulHandle;
609 TabWin32Handles[ulHandle].hmHandleData.hHMHandle = hHandleOS2;
610 TabWin32Handles[ulHandle].hmHandleData.lpDeviceData = NULL;
611 HMGlobals.ulHandleLast = ulHandle; /* to shorten search times */
612
613 handleMutex.leave();
614 return (NO_ERROR); /* OK */
615 }
616
617 ulHandle++; /* skip to next entry */
618
619 if (ulHandle >= MAX_OS2_HMHANDLES) /* check boundary */
620 ulHandle = 1;
621 }
622 while (ulHandle != HMGlobals.ulHandleLast);
623
624 handleMutex.leave();
625
626 return (ERROR_TOO_MANY_OPEN_FILES); /* OK, we're done */
627}
628
629
630/*****************************************************************************
631 * Name : DWORD HMHandleFree
632 * Purpose : free a handle from the translation table
633 * Parameters: ULONG hHandle16 - the handle to be freed
634 * Variables :
635 * Result : API returncode
636 * Remark : no parameter checking is done, hHandle16 MAY NEVER exceed
637 * the MAX_TRANSLATION_HANDLES boundary
638 * Status :
639 *
640 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
641 *****************************************************************************/
642
643DWORD HMHandleFree (ULONG hHandle16)
644{
645 ULONG rc; /* API returncode */
646
647#ifdef DEBUG_LOCAL
648 dprintf(("KERNEL32: HMHandleFree (%08xh)\n",
649 hHandle16));
650#endif
651
652 rc = HMHandleValidate(hHandle16); /* verify handle */
653 if (rc != NO_ERROR) /* check errors */
654 return (rc); /* raise error condition */
655
656 TabWin32Handles[hHandle16].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
657 /* OK, done */
658
659 return (NO_ERROR);
660}
661
662
663/*****************************************************************************
664 * Name : DWORD HMHandleValidate
665 * Purpose : validate a handle through the translation table
666 * Parameters: ULONG hHandle16 - the handle to be verified
667 * Variables :
668 * Result : API returncode
669 * Remark :
670 * Status :
671 *
672 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
673 *****************************************************************************/
674
675DWORD HMHandleValidate (ULONG hHandle16)
676{
677#ifdef DEBUG_LOCAL
678 dprintf(("KERNEL32: HMHandleValidate (%08xh)\n",
679 hHandle16));
680#endif
681
682 if (hHandle16 >= MAX_OS2_HMHANDLES) /* check boundary */
683 return (ERROR_INVALID_HANDLE); /* raise error condition */
684
685 if (TabWin32Handles[hHandle16].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
686 /* valid ? */
687 return (ERROR_INVALID_HANDLE); /* raise error condition */
688
689 return (NO_ERROR);
690}
691//*****************************************************************************
692//*****************************************************************************
693PHMHANDLEDATA HMQueryHandleData(HANDLE handle)
694{
695 int iIndex;
696
697 iIndex = _HMHandleQuery(handle); /* get the index */
698 if (-1 == iIndex) /* error ? */
699 {
700 return NULL;
701 }
702 return &TabWin32Handles[iIndex].hmHandleData; /* call device handler */
703}
704
705/*****************************************************************************
706 * Name : DWORD HMHandleTranslateToWin
707 * Purpose : translate a 32-bit OS/2 handle to the associated windows handle
708 * Parameters: ULONG hHandle32 - the OS/2 handle
709 * PULONG phHandle16 - the associated windows handle
710 * Variables :
711 * Result : API returncode
712 * Remark :
713 * Status :
714 *
715 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
716 *****************************************************************************/
717
718DWORD HMHandleTranslateToWin (ULONG hHandleOS2,
719 PULONG phHandle16)
720{
721 ULONG rc; /* API returncode */
722 register ULONG ulIndex; /* index counter over the table */
723
724#ifdef DEBUG_LOCAL
725 dprintf(("KERNEL32: HMHandleTranslateToWin (%08xh, %08xh)\n",
726 hHandleOS2,
727 phHandle16));
728#endif
729
730 for (ulIndex = 1;
731 ulIndex < MAX_OS2_HMHANDLES;
732 ulIndex++)
733 {
734 /* look for the handle */
735 if (TabWin32Handles[ulIndex].hmHandleData.hHMHandle == hHandleOS2)
736 {
737 *phHandle16 = ulIndex; /* deliver result */
738 return (NO_ERROR); /* OK */
739 }
740 }
741
742 return (ERROR_INVALID_HANDLE); /* raise error condition */
743}
744
745
746/*****************************************************************************
747 * Name : DWORD HMHandleTranslateToOS2
748 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
749 * Parameters: ULONG hHandle16 - the windows handle
750 * PULONG phHandle32 - the associated OS/2 handle
751 * Variables :
752 * Result : API returncode
753 * Remark :
754 * Status :
755 *
756 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
757 *****************************************************************************/
758
759DWORD HMHandleTranslateToOS2 (ULONG hHandle16,
760 PULONG phHandleOS2)
761{
762#ifdef DEBUG_LOCAL
763 dprintf(("KERNEL32: HMHandleTranslateToOS2 (%08xh, %08xh)\n",
764 hHandle16,
765 phHandleOS2));
766#endif
767
768 if (HMHandleValidate(hHandle16) == NO_ERROR) /* verify handle */
769 {
770 *phHandleOS2 = TabWin32Handles[hHandle16].hmHandleData.hHMHandle;
771 return (NO_ERROR);
772 }
773
774 return (ERROR_INVALID_HANDLE); /* raise error condition */
775}
776
777
778/*****************************************************************************
779 * Name : DWORD HMHandleTranslateToOS2i
780 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
781 * Parameters: ULONG hHandle16 - the windows handle
782 * Variables :
783 * Result : OS/2 handle
784 * Remark : no checkinf
785 * Status :
786 *
787 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
788 *****************************************************************************/
789
790DWORD HMHandleTranslateToOS2i (ULONG hHandle16)
791{
792#ifdef DEBUG_LOCAL
793 dprintf(("KERNEL32: HMHandleTranslateToOS2i (%08xh)\n",
794 hHandle16));
795#endif
796
797 return(TabWin32Handles[hHandle16].hmHandleData.hHMHandle);
798}
799
800/*****************************************************************************
801 * Name : HANDLE _HMGetStdHandle
802 * Purpose : replacement for Open32's GetStdHandle function
803 * Parameters: DWORD nStdHandle
804 * Variables :
805 * Result : HANDLE to standard device
806 * Remark :
807 * Status :
808 *
809 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
810 *****************************************************************************/
811
812HANDLE HMGetStdHandle(DWORD nStdHandle)
813{
814 switch (nStdHandle)
815 {
816 case STD_INPUT_HANDLE: return (HMGlobals.hStandardIn);
817 case STD_OUTPUT_HANDLE: return (HMGlobals.hStandardOut);
818 case STD_ERROR_HANDLE: return (HMGlobals.hStandardError);
819
820 default:
821 {
822 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
823 return (INVALID_HANDLE_VALUE); /* raise error condition */
824 }
825 }
826}
827
828
829/*****************************************************************************
830 * Name : HANDLE _HMSetStdHandle
831 * Purpose : replacement for Open32's SetStdHandle function
832 * Parameters: DWORD nStdHandle
833 * HANDLE hHandle
834 * Variables :
835 * Result : BOOL fSuccess
836 * Remark :
837 * Status :
838 *
839 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
840 *****************************************************************************/
841
842BOOL HMSetStdHandle(DWORD nStdHandle, HANDLE hHandleOpen32)
843{
844 PHMHANDLEDATA pHMHandleData;
845 HANDLE hHandle;
846
847 hHandle = _HMHandleGetFree(); /* get free handle */
848 if (hHandle == -1) /* oops, no free handles ! */
849 {
850 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
851 return 0;
852 }
853
854 /* initialize the complete HMHANDLEDATA structure */
855 pHMHandleData = &TabWin32Handles[hHandle].hmHandleData;
856 pHMHandleData->dwAccess = 0;
857 pHMHandleData->dwShare = 0;
858 pHMHandleData->dwCreation = 0;
859 pHMHandleData->dwFlags = 0;
860 pHMHandleData->dwUserData = nStdHandle;
861 pHMHandleData->hHMHandle = hHandleOpen32;
862 pHMHandleData->lpHandlerData = NULL;
863
864 TabWin32Handles[hHandle].pDeviceHandler = HMGlobals.pHMStandard;
865
866 switch (nStdHandle)
867 {
868 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
869 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
870 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
871
872 default:
873 {
874 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
875 return (FALSE); /* raise error condition */
876 }
877 }
878}
879
880
881/*****************************************************************************
882 * Name : HANDLE HMDuplicateHandle
883 * Purpose : replacement for Open32's HMDuplicateHandle function
884 * Parameters:
885 *
886 * Variables :
887 * Result : BOOL fSuccess
888 * Remark :
889 * Status :
890 *
891 * Author : Sander van Leeuwen [Wed, 1999/08/25 15:44]
892 *****************************************************************************/
893
894BOOL HMDuplicateHandle(HANDLE srcprocess,
895 HANDLE srchandle,
896 HANDLE destprocess,
897 PHANDLE desthandle,
898 DWORD fdwAccess,
899 BOOL fInherit,
900 DWORD fdwOptions,
901 DWORD fdwOdinOptions)
902{
903 int iIndex; /* index into the handle table */
904 int iIndexNew; /* index into the handle table */
905 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
906 PHMHANDLEDATA pHMHandleData;
907 BOOL rc; /* API return code */
908
909 if(HMHandleValidate(srchandle) != NO_ERROR)
910 {
911 dprintf(("KERNEL32: HMDuplicateHandle: invalid handle %x", srchandle));
912 SetLastError(ERROR_INVALID_HANDLE); /* use this as error message */
913 return FALSE;
914 }
915
916 pDeviceHandler = TabWin32Handles[srchandle].pDeviceHandler; /* device is predefined */
917 iIndexNew = _HMHandleGetFree(); /* get free handle */
918 if (-1 == iIndexNew) /* oops, no free handles ! */
919 {
920 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
921 return FALSE; /* signal error */
922 }
923
924 /* initialize the complete HMHANDLEDATA structure */
925 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
926 if (fdwOptions & DUPLICATE_SAME_ACCESS)
927 pHMHandleData->dwAccess = TabWin32Handles[srchandle].hmHandleData.dwAccess;
928 else
929 pHMHandleData->dwAccess = fdwAccess;
930
931 if((fdwOdinOptions & DUPLICATE_ACCESS_READWRITE) == DUPLICATE_ACCESS_READWRITE) {
932 pHMHandleData->dwAccess = GENERIC_READ | GENERIC_WRITE;
933 }
934 else
935 if(fdwOdinOptions & DUPLICATE_ACCESS_READ) {
936 pHMHandleData->dwAccess = GENERIC_READ;
937 }
938
939 if(fdwOdinOptions & DUPLICATE_SHARE_READ) {
940 pHMHandleData->dwShare = FILE_SHARE_READ;
941 }
942 else
943 if(fdwOdinOptions & DUPLICATE_SHARE_DENYNONE) {
944 pHMHandleData->dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
945 }
946 else pHMHandleData->dwShare = TabWin32Handles[srchandle].hmHandleData.dwShare;
947
948 pHMHandleData->dwCreation = TabWin32Handles[srchandle].hmHandleData.dwCreation;
949 pHMHandleData->dwFlags = TabWin32Handles[srchandle].hmHandleData.dwFlags;
950 pHMHandleData->lpHandlerData = TabWin32Handles[srchandle].hmHandleData.lpHandlerData;
951
952
953 /* we've got to mark the handle as occupied here, since another device */
954 /* could be created within the device handler -> deadlock */
955
956 /* write appropriate entry into the handle table if open succeeded */
957 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
958 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
959 /* call the device handler */
960 rc = pDeviceHandler->DuplicateHandle(&TabWin32Handles[iIndexNew].hmHandleData,
961 srcprocess,
962 &TabWin32Handles[srchandle].hmHandleData,
963 destprocess,
964 desthandle,
965 fdwAccess,
966 fInherit,
967 fdwOptions & ~DUPLICATE_CLOSE_SOURCE,
968 fdwOdinOptions);
969
970 //Don't let Open32 close it for us, but do it manually (regardless of error; see SDK docs))
971 if (fdwOptions & DUPLICATE_CLOSE_SOURCE)
972 HMCloseHandle(srchandle);
973
974 if(rc == FALSE) /* oops, creation failed within the device handler */
975 {
976 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
977 return FALSE; /* signal error */
978 }
979 else
980 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
981
982 *desthandle = iIndexNew;
983 return TRUE; /* return valid handle */
984}
985
986/*****************************************************************************
987 * Name : HANDLE HMCreateFile
988 * Purpose : Wrapper for the CreateFile() API
989 * Parameters:
990 * Variables :
991 * Result :
992 * Remark : Fix parameters passed to the HMDeviceManager::CreateFile
993 * Supply access mode and share mode validation routines
994 * Status :
995 *
996 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
997 *****************************************************************************/
998
999HFILE HMCreateFile(LPCSTR lpFileName,
1000 DWORD dwDesiredAccess,
1001 DWORD dwShareMode,
1002 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1003 DWORD dwCreationDisposition,
1004 DWORD dwFlagsAndAttributes,
1005 HANDLE hTemplateFile)
1006{
1007 int iIndex; /* index into the handle table */
1008 int iIndexNew; /* index into the handle table */
1009 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1010 HANDLE hResult;
1011 DWORD rc; /* API return code */
1012 PHMHANDLEDATA pHMHandleData;
1013 HMHANDLEDATA HMHandleTemp; /* temporary buffer for handle data */
1014 VOID *pDevData;
1015
1016 /* create new handle by either lpFileName or hTemplateFile */
1017 if (lpFileName == NULL) /* this indicates creation from template */
1018 {
1019 iIndex = _HMHandleQuery(hTemplateFile); /* query table for template */
1020 if (-1 == iIndex) /* this device is unknown to us */
1021 {
1022 SetLastError (ERROR_INVALID_HANDLE);
1023 return INVALID_HANDLE_VALUE;
1024 }
1025 else
1026 {
1027 /* to pass to handler */
1028 pHMHandleData = &TabWin32Handles[iIndex].hmHandleData;
1029 pDeviceHandler = TabWin32Handles[iIndex].pDeviceHandler;
1030 }
1031 }
1032 else
1033 {
1034 // name resolving
1035 CHAR szFilename[260];
1036 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1037 szFilename,
1038 sizeof(szFilename),
1039 TRUE))
1040 {
1041 // use the resolved name
1042 lpFileName = szFilename;
1043 }
1044
1045
1046 pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1047 if (NULL == pDeviceHandler) /* this name is unknown to us */
1048 {
1049 SetLastError(ERROR_FILE_NOT_FOUND);
1050 return (INVALID_HANDLE_VALUE); /* signal error */
1051 }
1052 else
1053 pHMHandleData = NULL;
1054
1055 pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1056
1057 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1058 pDeviceHandler = HMGlobals.pHMFile;
1059 }
1060 }
1061
1062
1063 iIndexNew = _HMHandleGetFree(); /* get free handle */
1064 if (-1 == iIndexNew) /* oops, no free handles ! */
1065 {
1066 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1067 return (INVALID_HANDLE_VALUE); /* signal error */
1068 }
1069
1070
1071 /* initialize the complete HMHANDLEDATA structure */
1072 if (lpFileName == NULL) /* create from template */
1073 memcpy (&HMHandleTemp,
1074 &TabWin32Handles[iIndex].hmHandleData,
1075 sizeof(HMHANDLEDATA));
1076 else
1077 {
1078 HMHandleTemp.dwAccess = dwDesiredAccess;
1079 HMHandleTemp.dwShare = dwShareMode;
1080 HMHandleTemp.dwCreation = dwCreationDisposition;
1081 HMHandleTemp.dwFlags = dwFlagsAndAttributes;
1082 HMHandleTemp.lpHandlerData = NULL;
1083 HMHandleTemp.hWin32Handle = iIndexNew;
1084 HMHandleTemp.lpDeviceData = pDevData;
1085 }
1086
1087 /* we've got to mark the handle as occupied here, since another device */
1088 /* could be created within the device handler -> deadlock */
1089
1090 /* write appropriate entry into the handle table if open succeeded */
1091 HMHandleTemp.hHMHandle = iIndexNew;
1092 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1093 /* now copy back our temporary handle data */
1094 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1095 &HMHandleTemp,
1096 sizeof(HMHANDLEDATA));
1097
1098 rc = pDeviceHandler->CreateFile(lpFileName, /* call the device handler */
1099 &HMHandleTemp,
1100 lpSecurityAttributes,
1101 pHMHandleData);
1102
1103#ifdef DEBUG_LOCAL
1104 dprintf(("KERNEL32/HandleManager:CheckPoint2: %s lpHandlerData=%08xh\n",
1105 lpFileName,
1106 HMHandleTemp.lpHandlerData));
1107#endif
1108
1109 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
1110 {
1111 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1112
1113 // Note:
1114 // device handlers have to return an Win32-style error code
1115 // from CreateFile() !
1116 SetLastError(rc);
1117 return (INVALID_HANDLE_VALUE); /* signal error */
1118 }
1119 else
1120 {
1121 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1122
1123 /* copy data fields that might have been modified by CreateFile */
1124 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1125 &HMHandleTemp,
1126 sizeof(HMHANDLEDATA));
1127 }
1128
1129 return (HFILE)iIndexNew; /* return valid handle */
1130}
1131
1132
1133/*****************************************************************************
1134 * Name : HANDLE HMOpenFile
1135 * Purpose : Wrapper for the OpenFile() API
1136 * Parameters:
1137 * Variables :
1138 * Result :
1139 * Remark : Fix parameters passed to the HMDeviceManager::OpenFile
1140 * Supply access mode and share mode validation routines
1141 * Status :
1142 *
1143 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1144 *****************************************************************************/
1145
1146
1147/***********************************************************************
1148 * FILE_ConvertOFMode
1149 *
1150 * Convert OF_* mode into flags for CreateFile.
1151 */
1152static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
1153{
1154 switch(mode & 0x03)
1155 {
1156 case OF_READ: *access = GENERIC_READ; break;
1157 case OF_WRITE: *access = GENERIC_WRITE; break;
1158 case OF_READWRITE: *access = GENERIC_READ | GENERIC_WRITE; break;
1159 default: *access = 0; break;
1160 }
1161 switch(mode & 0x70)
1162 {
1163 case OF_SHARE_EXCLUSIVE: *sharing = 0; break;
1164 case OF_SHARE_DENY_WRITE: *sharing = FILE_SHARE_READ; break;
1165 case OF_SHARE_DENY_READ: *sharing = FILE_SHARE_WRITE; break;
1166 case OF_SHARE_DENY_NONE:
1167 case OF_SHARE_COMPAT:
1168 default: *sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; break;
1169 }
1170}
1171
1172HANDLE HMOpenFile(LPCSTR lpFileName,
1173 OFSTRUCT* pOFStruct,
1174 UINT fuMode)
1175{
1176 int iIndex; /* index into the handle table */
1177 int iIndexNew; /* index into the handle table */
1178 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1179 VOID *pDevData;
1180 PHMHANDLEDATA pHMHandleData;
1181 DWORD rc; /* API return code */
1182
1183 // name resolving
1184 CHAR szFilename[260];
1185 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1186 szFilename,
1187 sizeof(szFilename),
1188 TRUE))
1189 {
1190 // use the resolved name
1191 lpFileName = szFilename;
1192 }
1193
1194
1195 if(fuMode & OF_REOPEN) {
1196 pDeviceHandler = _HMDeviceFind((LPSTR)pOFStruct->szPathName); /* find device */
1197 }
1198 else pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1199 if (NULL == pDeviceHandler) /* this name is unknown to us */
1200 {
1201 SetLastError(ERROR_FILE_NOT_FOUND);
1202 return (INVALID_HANDLE_VALUE); /* signal error */
1203 }
1204 else
1205 pHMHandleData = NULL;
1206
1207 if(fuMode & OF_REOPEN) {
1208 pDevData = _HMDeviceGetData((LPSTR)pOFStruct->szPathName);
1209 }
1210 else pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1211
1212
1213 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1214 pDeviceHandler = HMGlobals.pHMFile;
1215 }
1216
1217 iIndexNew = _HMHandleGetFree(); /* get free handle */
1218 if (-1 == iIndexNew) /* oops, no free handles ! */
1219 {
1220 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1221 return (INVALID_HANDLE_VALUE); /* signal error */
1222 }
1223
1224 /* initialize the complete HMHANDLEDATA structure */
1225 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
1226
1227 FILE_ConvertOFMode(fuMode, /* map OF_flags */
1228 &pHMHandleData->dwAccess,
1229 &pHMHandleData->dwShare);
1230
1231 //SvL; Must be OPEN_EXISTING because mmaps depend on it (to duplicate
1232 // the file handle when this handle is a parameter for CreateFileMappingA/W
1233 pHMHandleData->dwCreation = OPEN_EXISTING;
1234 pHMHandleData->dwFlags = 0;
1235 pHMHandleData->lpHandlerData = NULL;
1236 pHMHandleData->lpDeviceData = pDevData;
1237
1238 /* we've got to mark the handle as occupied here, since another device */
1239 /* could be created within the device handler -> deadlock */
1240
1241 /* write appropriate entry into the handle table if open succeeded */
1242 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
1243 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1244
1245 rc = pDeviceHandler->OpenFile(lpFileName, /* call the device handler */
1246 &TabWin32Handles[iIndexNew].hmHandleData,
1247 pOFStruct,
1248 fuMode);
1249
1250#ifdef DEBUG_LOCAL
1251 dprintf(("KERNEL32/HandleManager:CheckPoint3: %s lpHandlerData=%08xh rc=%08xh\n",
1252 lpFileName,
1253 &TabWin32Handles[iIndexNew].hmHandleData.lpHandlerData,
1254 rc));
1255#endif
1256
1257 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
1258 {
1259 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1260 SetLastError(pOFStruct->nErrCode);
1261 return (INVALID_HANDLE_VALUE); /* signal error */
1262 }
1263 else {
1264 if(fuMode & (OF_DELETE|OF_EXIST)) {
1265 //file handle already closed
1266 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1267 return TRUE; //TODO: correct?
1268 }
1269 if(fuMode & OF_PARSE) {
1270 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1271 return 0;
1272 }
1273 if(fuMode & OF_VERIFY) {
1274 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1275 return 1; //TODO: correct?
1276 }
1277 }
1278
1279#ifdef DEBUG_LOCAL
1280 dprintf(("KERNEL32/HandleManager: OpenFile(%s)=%08xh\n",
1281 lpFileName,
1282 iIndexNew));
1283#endif
1284
1285 return iIndexNew; /* return valid handle */
1286}
1287
1288
1289
1290/*****************************************************************************
1291 * Name : HANDLE HMCloseFile
1292 * Purpose : Wrapper for the CloseHandle() API
1293 * Parameters:
1294 * Variables :
1295 * Result :
1296 * Remark :
1297 * Status :
1298 *
1299 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1300 *****************************************************************************/
1301
1302BOOL HMCloseHandle(HANDLE hObject)
1303{
1304 int iIndex; /* index into the handle table */
1305 BOOL fResult; /* result from the device handler's CloseHandle() */
1306 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1307
1308 /* validate handle */
1309 iIndex = _HMHandleQuery(hObject); /* get the index */
1310 if (-1 == iIndex) /* error ? */
1311 {
1312 //@@@PH it may occur someone closes e.g. a semaphore handle
1313 // which is not registered through the HandleManager yet.
1314 // so we try to pass on to Open32 instead.
1315 dprintf(("KERNEL32: HandleManager:HMCloseHandle(%08xh) passed on to Open32.\n",
1316 hObject));
1317
1318 fResult = O32_CloseHandle(hObject);
1319 return (fResult);
1320
1321 //SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1322 //return (FALSE); /* signal failure */
1323 }
1324
1325 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1326 //SvL: Check if pDeviceHandler is set
1327 if (pHMHandle->pDeviceHandler)
1328 {
1329 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
1330 }
1331 else
1332 {
1333 dprintf(("HMCloseHAndle(%08xh): pDeviceHandler not set", hObject));
1334 fResult = TRUE;
1335 }
1336
1337 if (fResult == TRUE) /* remove handle if close succeeded */
1338 {
1339 pHMHandle->hmHandleData.hHMHandle = INVALID_HANDLE_VALUE; /* mark handle as free */
1340 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1341 }
1342
1343 return (fResult); /* deliver return code */
1344}
1345
1346
1347/*****************************************************************************
1348 * Name : HANDLE HMReadFile
1349 * Purpose : Wrapper for the ReadHandle() API
1350 * Parameters:
1351 * Variables :
1352 * Result :
1353 * Remark :
1354 * Status :
1355 *
1356 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1357 *****************************************************************************/
1358
1359BOOL HMReadFile(HANDLE hFile,
1360 LPVOID lpBuffer,
1361 DWORD nNumberOfBytesToRead,
1362 LPDWORD lpNumberOfBytesRead,
1363 LPOVERLAPPED lpOverlapped,
1364 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1365{
1366 int iIndex; /* index into the handle table */
1367 BOOL fResult; /* result from the device handler's CloseHandle() */
1368 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1369
1370 /* validate handle */
1371 iIndex = _HMHandleQuery(hFile); /* get the index */
1372 if (-1 == iIndex) /* error ? */
1373 {
1374 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1375 return (FALSE); /* signal failure */
1376 }
1377
1378 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1379 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
1380 lpBuffer,
1381 nNumberOfBytesToRead,
1382 lpNumberOfBytesRead,
1383 lpOverlapped, lpCompletionRoutine);
1384
1385 return (fResult); /* deliver return code */
1386}
1387
1388/*****************************************************************************
1389 * Name : HANDLE HMWriteFile
1390 * Purpose : Wrapper for the WriteHandle() API
1391 * Parameters:
1392 * Variables :
1393 * Result :
1394 * Remark :
1395 * Status :
1396 *
1397 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1398 *****************************************************************************/
1399
1400BOOL HMWriteFile(HANDLE hFile,
1401 LPCVOID lpBuffer,
1402 DWORD nNumberOfBytesToWrite,
1403 LPDWORD lpNumberOfBytesWritten,
1404 LPOVERLAPPED lpOverlapped,
1405 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1406{
1407 int iIndex; /* index into the handle table */
1408 BOOL fResult; /* result from the device handler's CloseHandle() */
1409 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1410
1411 /* validate handle */
1412 iIndex = _HMHandleQuery(hFile); /* get the index */
1413 if (-1 == iIndex) /* error ? */
1414 {
1415 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1416 return (FALSE); /* signal failure */
1417 }
1418
1419 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1420 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
1421 lpBuffer,
1422 nNumberOfBytesToWrite,
1423 lpNumberOfBytesWritten,
1424 lpOverlapped, lpCompletionRoutine);
1425
1426 return (fResult); /* deliver return code */
1427}
1428
1429
1430/*****************************************************************************
1431 * Name : HANDLE HMGetFileType
1432 * Purpose : Wrapper for the GetFileType() API
1433 * Parameters:
1434 * Variables :
1435 * Result :
1436 * Remark :
1437 * Status :
1438 *
1439 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1440 *****************************************************************************/
1441
1442DWORD HMGetFileType(HANDLE hFile)
1443{
1444 int iIndex; /* index into the handle table */
1445 DWORD dwResult; /* result from the device handler's API */
1446 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1447
1448 /* validate handle */
1449 iIndex = _HMHandleQuery(hFile); /* get the index */
1450 if (-1 == iIndex) /* error ? */
1451 {
1452 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1453 return FILE_TYPE_UNKNOWN; /* signal failure */
1454 }
1455
1456 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1457 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1458
1459 return (dwResult); /* deliver return code */
1460}
1461
1462
1463/*****************************************************************************
1464 * Name : HMDeviceHandler::_DeviceReuqest
1465 * Purpose : entry method for special request functions
1466 * Parameters: ULONG ulRequestCode
1467 * various parameters as required
1468 * Variables :
1469 * Result :
1470 * Remark : the standard behaviour is to return an error code for non-
1471 * existant request codes
1472 * Status :
1473 *
1474 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1475 *****************************************************************************/
1476
1477DWORD HMDeviceRequest (HANDLE hFile,
1478 ULONG ulRequestCode,
1479 ULONG arg1,
1480 ULONG arg2,
1481 ULONG arg3,
1482 ULONG arg4)
1483{
1484 int iIndex; /* index into the handle table */
1485 DWORD dwResult; /* result from the device handler's API */
1486 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1487
1488 /* validate handle */
1489 iIndex = _HMHandleQuery(hFile); /* get the index */
1490 if (-1 == iIndex) /* error ? */
1491 {
1492 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1493 return (INVALID_HANDLE_ERROR); /* signal failure */
1494 }
1495
1496 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1497 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1498 ulRequestCode,
1499 arg1,
1500 arg2,
1501 arg3,
1502 arg4);
1503
1504 return (dwResult); /* deliver return code */
1505}
1506
1507
1508/*****************************************************************************
1509 * Name : HMDeviceHandler::GetFileInformationByHandle
1510 * Purpose : router function for GetFileInformationByHandle
1511 * Parameters:
1512 * Variables :
1513 * Result :
1514 * Remark :
1515 * Status :
1516 *
1517 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1518 *****************************************************************************/
1519
1520BOOL HMGetFileInformationByHandle (HANDLE hFile,
1521 BY_HANDLE_FILE_INFORMATION *pHFI)
1522{
1523 int iIndex; /* index into the handle table */
1524 DWORD dwResult; /* result from the device handler's API */
1525 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1526
1527 /* validate handle */
1528 iIndex = _HMHandleQuery(hFile); /* get the index */
1529 if (-1 == iIndex) /* error ? */
1530 {
1531 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1532 return FALSE; /* signal failure */
1533 }
1534
1535 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1536 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
1537 pHFI);
1538
1539 return (dwResult); /* deliver return code */
1540}
1541
1542
1543/*****************************************************************************
1544 * Name : HMDeviceHandler::SetEndOfFile
1545 * Purpose : router function for SetEndOfFile
1546 * Parameters:
1547 * Variables :
1548 * Result :
1549 * Remark :
1550 * Status :
1551 *
1552 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1553 *****************************************************************************/
1554
1555BOOL HMSetEndOfFile (HANDLE hFile)
1556{
1557 int iIndex; /* index into the handle table */
1558 BOOL bResult; /* result from the device handler's API */
1559 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1560
1561 /* validate handle */
1562 iIndex = _HMHandleQuery(hFile); /* get the index */
1563 if (-1 == iIndex) /* error ? */
1564 {
1565 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1566 return FALSE; /* signal failure */
1567 }
1568
1569 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1570 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
1571
1572 return (bResult); /* deliver return code */
1573}
1574
1575
1576/*****************************************************************************
1577 * Name : HMDeviceHandler::SetFileTime
1578 * Purpose : router function for SetFileTime
1579 * Parameters:
1580 * Variables :
1581 * Result :
1582 * Remark :
1583 * Status :
1584 *
1585 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1586 *****************************************************************************/
1587
1588BOOL HMSetFileTime (HANDLE hFile,
1589 const FILETIME *pFT1,
1590 const FILETIME *pFT2,
1591 const FILETIME *pFT3)
1592{
1593 int iIndex; /* index into the handle table */
1594 BOOL bResult; /* result from the device handler's API */
1595 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1596
1597 /* validate handle */
1598 iIndex = _HMHandleQuery(hFile); /* get the index */
1599 if (-1 == iIndex) /* error ? */
1600 {
1601 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1602 return FALSE; /* signal failure */
1603 }
1604
1605 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1606 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
1607 (LPFILETIME)pFT1,
1608 (LPFILETIME)pFT2,
1609 (LPFILETIME)pFT3);
1610
1611 return (bResult); /* deliver return code */
1612}
1613
1614/*****************************************************************************
1615 * Name : HMDeviceHandler::GetFileTime
1616 * Purpose : router function for SetFileTime
1617 * Parameters:
1618 * Variables :
1619 * Result :
1620 * Remark :
1621 * Status :
1622 *
1623 * Author : SvL
1624 *****************************************************************************/
1625
1626BOOL HMGetFileTime (HANDLE hFile,
1627 const FILETIME *pFT1,
1628 const FILETIME *pFT2,
1629 const FILETIME *pFT3)
1630{
1631 int iIndex; /* index into the handle table */
1632 BOOL bResult; /* result from the device handler's API */
1633 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1634
1635 /* validate handle */
1636 iIndex = _HMHandleQuery(hFile); /* get the index */
1637 if (-1 == iIndex) /* error ? */
1638 {
1639 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1640 return FALSE; /* signal failure */
1641 }
1642
1643 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1644 bResult = pHMHandle->pDeviceHandler->GetFileTime(&pHMHandle->hmHandleData,
1645 (LPFILETIME)pFT1,
1646 (LPFILETIME)pFT2,
1647 (LPFILETIME)pFT3);
1648
1649 return (bResult); /* deliver return code */
1650}
1651
1652
1653/*****************************************************************************
1654 * Name : HMDeviceHandler::GetFileSize
1655 * Purpose : router function for GetFileSize
1656 * Parameters:
1657 * Variables :
1658 * Result :
1659 * Remark :
1660 * Status :
1661 *
1662 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1663 *****************************************************************************/
1664
1665DWORD HMGetFileSize (HANDLE hFile,
1666 PDWORD pSize)
1667{
1668 int iIndex; /* index into the handle table */
1669 DWORD dwResult; /* result from the device handler's API */
1670 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1671
1672 /* validate handle */
1673 iIndex = _HMHandleQuery(hFile); /* get the index */
1674 if (-1 == iIndex) /* error ? */
1675 {
1676 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1677 return -1; //INVALID_SET_FILE_POINTER
1678 }
1679
1680 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1681 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
1682 pSize);
1683
1684 return (dwResult); /* deliver return code */
1685}
1686
1687
1688/*****************************************************************************
1689 * Name : HMDeviceHandler::SetFilePointer
1690 * Purpose : router function for SetFilePointer
1691 * Parameters:
1692 * Variables :
1693 * Result :
1694 * Remark :
1695 * Status :
1696 *
1697 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1698 *****************************************************************************/
1699
1700DWORD HMSetFilePointer (HANDLE hFile,
1701 LONG lDistanceToMove,
1702 PLONG lpDistanceToMoveHigh,
1703 DWORD dwMoveMethod)
1704{
1705 int iIndex; /* index into the handle table */
1706 DWORD dwResult; /* result from the device handler's API */
1707 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1708
1709 /* validate handle */
1710 iIndex = _HMHandleQuery(hFile); /* get the index */
1711 if (-1 == iIndex) /* error ? */
1712 {
1713 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1714 return (INVALID_HANDLE_ERROR); /* signal failure */
1715 }
1716
1717 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1718 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
1719 lDistanceToMove,
1720 lpDistanceToMoveHigh,
1721 dwMoveMethod);
1722
1723 return (dwResult); /* deliver return code */
1724}
1725
1726
1727/*****************************************************************************
1728 * Name : HMDeviceHandler::LockFile
1729 * Purpose : router function for LockFile
1730 * Parameters:
1731 * Variables :
1732 * Result :
1733 * Remark :
1734 * Status :
1735 *
1736 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1737 *****************************************************************************/
1738
1739BOOL HMLockFile (HFILE hFile,
1740 DWORD arg2,
1741 DWORD arg3,
1742 DWORD arg4,
1743 DWORD arg5)
1744{
1745 int iIndex; /* index into the handle table */
1746 DWORD dwResult; /* result from the device handler's API */
1747 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1748
1749 /* validate handle */
1750 iIndex = _HMHandleQuery(hFile); /* get the index */
1751 if (-1 == iIndex) /* error ? */
1752 {
1753 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1754 return FALSE; /* signal failure */
1755 }
1756
1757 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1758 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
1759 arg2,
1760 arg3,
1761 arg4,
1762 arg5);
1763
1764 return (dwResult); /* deliver return code */
1765}
1766
1767
1768/*****************************************************************************
1769 * Name : HMDeviceHandler::LockFileEx
1770 * Purpose : router function for LockFileEx
1771 * Parameters:
1772 * Variables :
1773 * Result :
1774 * Remark :
1775 * Status :
1776 *
1777 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1778 *****************************************************************************/
1779
1780BOOL HMLockFileEx(HANDLE hFile,
1781 DWORD dwFlags,
1782 DWORD dwReserved,
1783 DWORD nNumberOfBytesToLockLow,
1784 DWORD nNumberOfBytesToLockHigh,
1785 LPOVERLAPPED lpOverlapped)
1786{
1787 int iIndex; /* index into the handle table */
1788 DWORD dwResult; /* result from the device handler's API */
1789 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1790
1791 /* validate handle */
1792 iIndex = _HMHandleQuery(hFile); /* get the index */
1793 if (-1 == iIndex) /* error ? */
1794 {
1795 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1796 return FALSE; /* signal failure */
1797 }
1798
1799 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1800 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
1801 dwFlags,
1802 dwReserved,
1803 nNumberOfBytesToLockLow,
1804 nNumberOfBytesToLockHigh,
1805 lpOverlapped);
1806
1807 return (dwResult); /* deliver return code */
1808}
1809
1810
1811
1812/*****************************************************************************
1813 * Name : HMDeviceHandler::UnlockFile
1814 * Purpose : router function for UnlockFile
1815 * Parameters:
1816 * Variables :
1817 * Result :
1818 * Remark :
1819 * Status :
1820 *
1821 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1822 *****************************************************************************/
1823
1824BOOL HMUnlockFile (HFILE hFile,
1825 DWORD arg2,
1826 DWORD arg3,
1827 DWORD arg4,
1828 DWORD arg5)
1829{
1830 int iIndex; /* index into the handle table */
1831 DWORD dwResult; /* result from the device handler's API */
1832 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1833
1834 /* validate handle */
1835 iIndex = _HMHandleQuery(hFile); /* get the index */
1836 if (-1 == iIndex) /* error ? */
1837 {
1838 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1839 return FALSE; /* signal failure */
1840 }
1841
1842 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1843 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
1844 arg2,
1845 arg3,
1846 arg4,
1847 arg5);
1848
1849 return (dwResult); /* deliver return code */
1850}
1851
1852
1853/*****************************************************************************
1854 * Name : HMDeviceHandler::UnlockFileEx
1855 * Purpose : router function for UnlockFileEx
1856 * Parameters:
1857 * Variables :
1858 * Result :
1859 * Remark :
1860 * Status :
1861 *
1862 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1863 *****************************************************************************/
1864
1865BOOL HMUnlockFileEx(HANDLE hFile,
1866 DWORD dwReserved,
1867 DWORD nNumberOfBytesToLockLow,
1868 DWORD nNumberOfBytesToLockHigh,
1869 LPOVERLAPPED lpOverlapped)
1870{
1871 int iIndex; /* index into the handle table */
1872 DWORD dwResult; /* result from the device handler's API */
1873 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1874
1875 /* validate handle */
1876 iIndex = _HMHandleQuery(hFile); /* get the index */
1877 if (-1 == iIndex) /* error ? */
1878 {
1879 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1880 return FALSE; /* signal failure */
1881 }
1882
1883 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1884 dwResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
1885 dwReserved,
1886 nNumberOfBytesToLockLow,
1887 nNumberOfBytesToLockHigh,
1888 lpOverlapped);
1889
1890 return (dwResult); /* deliver return code */
1891}
1892
1893
1894/*****************************************************************************
1895 * Name : HMDeviceHandler::WaitForSingleObject
1896 * Purpose : router function for WaitForSingleObject
1897 * Parameters:
1898 * Variables :
1899 * Result :
1900 * Remark :
1901 * Status :
1902 *
1903 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1904 *****************************************************************************/
1905
1906DWORD HMWaitForSingleObject(HANDLE hObject,
1907 DWORD dwTimeout)
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(hObject); /* get the index */
1915 if (-1 == iIndex) /* error ? */
1916 {
1917 dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n",
1918 hObject));
1919
1920 if(dwTimeout == INFINITE) {
1921 //Workaround for applications that block the PM input queue
1922 //while waiting for a child process to terminate.
1923 //(WaitSingleObject now calls MsgWaitMultipleObjects and
1924 // processes messages while waiting for the process to die)
1925 //(Napster install now doesn't block PM anymore (forcing a reboot))
1926
1927 HMODULE hUser32 = LoadLibraryA("USER32.DLL");
1928
1929 BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
1930 LONG (* WINAPI pfnDispatchMessageA)(const MSG*);
1931
1932 *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
1933 *(FARPROC *)&pfnDispatchMessageA = GetProcAddress(hUser32,"DispatchMessageA");
1934
1935 TEB *teb = GetThreadTEB();
1936
1937 if(!teb || !pfnPeekMessageA || !pfnDispatchMessageA) {
1938 dprintf(("ERROR: !teb || !pfnPeekMessageA || !pfnDispatchMessageA"));
1939 DebugInt3();
1940 return WAIT_FAILED;
1941 }
1942
1943 //TODO: Ignoring all messages could be dangerous. But processing them,
1944 //while the app doesn't expect any, isn't safe either.
1945//-> must active check in pmwindow.cpp if this is enabled again!
1946// teb->o.odin.fIgnoreMsgs = TRUE;
1947
1948 while(TRUE) {
1949 dwResult = HMMsgWaitForMultipleObjects(1, &hObject, FALSE,
1950 INFINITE, QS_ALLINPUT);
1951 if(dwResult == WAIT_OBJECT_0 + 1) {
1952 MSG msg ;
1953
1954 while (pfnPeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1955 {
1956 if (msg.message == WM_QUIT) {
1957 dprintf(("ERROR: WaitForSingleObject call abandoned because WM_QUIT msg was received!!"));
1958// teb->o.odin.fIgnoreMsgs = FALSE;
1959 FreeLibrary(hUser32);
1960 return WAIT_ABANDONED;
1961 }
1962
1963 /* otherwise dispatch it */
1964 pfnDispatchMessageA(&msg);
1965
1966 } // end of PeekMessage while loop
1967 }
1968 else {
1969 dprintf(("WaitForSingleObject: Process %x terminated", hObject));
1970 break;
1971 }
1972 }
1973// teb->o.odin.fIgnoreMsgs = FALSE;
1974 FreeLibrary(hUser32);
1975 return dwResult;
1976 }
1977 else {
1978 // maybe handles from CreateProcess() ...
1979 dwResult = O32_WaitForSingleObject(hObject, dwTimeout);
1980 return (dwResult);
1981 }
1982 }
1983
1984 //If the timeout is less than 20 milliseconds (and not zero), then we are likely to
1985 //return too late if the thread priority isn't time critical (time slices
1986 //of 32 ms)
1987 //To avoid this problem, we temporarily switch to time critical priority.
1988 HANDLE hThread = GetCurrentThread();
1989 DWORD dwThreadPriority = GetThreadPriority(hThread);
1990
1991 if(dwTimeout && dwTimeout < 20 && dwThreadPriority != THREAD_PRIORITY_TIME_CRITICAL) {
1992 dprintf(("Temporarily change priority to THREAD_PRIORITY_TIME_CRITICAL for better timing"));
1993 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
1994 //round to 8 ms units to get more precise timeouts
1995 if(dwTimeout > 8)
1996 dwTimeout = (dwTimeout/8)*8;
1997 }
1998 else dwThreadPriority = -1;
1999
2000 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2001 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObject(&pHMHandle->hmHandleData,
2002 dwTimeout);
2003
2004 //Restore thread priority if we previously changed it
2005 if(dwThreadPriority != -1) {
2006 SetThreadPriority(hThread, dwThreadPriority);
2007 }
2008 return (dwResult); /* deliver return code */
2009}
2010
2011
2012/*****************************************************************************
2013 * Name : HMDeviceHandler::WaitForSingleObjectEx
2014 * Purpose : router function for WaitForSingleObjectEx
2015 * Parameters:
2016 * Variables :
2017 * Result :
2018 * Remark :
2019 * Status :
2020 *
2021 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2022 *****************************************************************************/
2023
2024DWORD HMWaitForSingleObjectEx(HANDLE hObject,
2025 DWORD dwTimeout,
2026 BOOL fAlertable)
2027{
2028 int iIndex; /* index into the handle table */
2029 DWORD dwResult; /* result from the device handler's API */
2030 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2031
2032 /* validate handle */
2033 iIndex = _HMHandleQuery(hObject); /* get the index */
2034 if (-1 == iIndex) /* error ? */
2035 {
2036 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2037 return WAIT_FAILED; /* signal failure */
2038 }
2039
2040 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2041 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObjectEx(&pHMHandle->hmHandleData,
2042 dwTimeout,
2043 fAlertable);
2044
2045 return (dwResult); /* deliver return code */
2046}
2047
2048
2049/*****************************************************************************
2050 * Name : HMDeviceHandler::FlushFileBuffers
2051 * Purpose : router function for FlushFileBuffers
2052 * Parameters:
2053 * Variables :
2054 * Result :
2055 * Remark :
2056 * Status :
2057 *
2058 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2059 *****************************************************************************/
2060
2061BOOL HMFlushFileBuffers(HANDLE hFile)
2062{
2063 int iIndex; /* index into the handle table */
2064 DWORD dwResult; /* result from the device handler's API */
2065 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2066
2067 /* validate handle */
2068 iIndex = _HMHandleQuery(hFile); /* get the index */
2069 if (-1 == iIndex) /* error ? */
2070 {
2071 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2072 return FALSE; /* signal failure */
2073 }
2074
2075 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2076 dwResult = pHMHandle->pDeviceHandler->FlushFileBuffers(&pHMHandle->hmHandleData);
2077
2078 return (dwResult); /* deliver return code */
2079}
2080
2081
2082/*****************************************************************************
2083 * Name : HMDeviceHandler::GetOverlappedResult
2084 * Purpose : router function for GetOverlappedResult
2085 * Parameters:
2086 * Variables :
2087 * Result :
2088 * Remark :
2089 * Status :
2090 *
2091 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2092 *****************************************************************************/
2093
2094BOOL HMGetOverlappedResult(HANDLE hObject,
2095 LPOVERLAPPED lpOverlapped,
2096 LPDWORD arg3,
2097 BOOL arg4)
2098{
2099 int iIndex; /* index into the handle table */
2100 DWORD dwResult; /* result from the device handler's API */
2101 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2102
2103 /* validate handle */
2104 iIndex = _HMHandleQuery(hObject); /* get the index */
2105 if (-1 == iIndex) /* error ? */
2106 {
2107 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2108 return FALSE; /* signal failure */
2109 }
2110
2111 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2112 dwResult = pHMHandle->pDeviceHandler->GetOverlappedResult(&pHMHandle->hmHandleData,
2113 lpOverlapped,
2114 arg3,
2115 arg4);
2116
2117 return (dwResult); /* deliver return code */
2118}
2119
2120
2121/*****************************************************************************
2122 * Name : HMReleaseMutex
2123 * Purpose : router function for ReleaseMutex
2124 * Parameters:
2125 * Variables :
2126 * Result :
2127 * Remark :
2128 * Status :
2129 *
2130 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2131 *****************************************************************************/
2132
2133BOOL HMReleaseMutex(HANDLE hObject)
2134{
2135 int iIndex; /* index into the handle table */
2136 DWORD dwResult; /* result from the device handler's API */
2137 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2138
2139 /* validate handle */
2140 iIndex = _HMHandleQuery(hObject); /* get the index */
2141 if (-1 == iIndex) /* error ? */
2142 {
2143 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2144 return FALSE; /* signal failure */
2145 }
2146
2147 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2148 dwResult = pHMHandle->pDeviceHandler->ReleaseMutex(&pHMHandle->hmHandleData);
2149
2150 return (dwResult); /* deliver return code */
2151}
2152
2153
2154/*****************************************************************************
2155 * Name : HMSetEvent
2156 * Purpose : router function for SetEvent
2157 * Parameters:
2158 * Variables :
2159 * Result :
2160 * Remark :
2161 * Status :
2162 *
2163 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2164 *****************************************************************************/
2165
2166BOOL HMSetEvent(HANDLE hEvent)
2167{
2168 int iIndex; /* index into the handle table */
2169 DWORD dwResult; /* result from the device handler's API */
2170 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2171
2172 /* validate handle */
2173 iIndex = _HMHandleQuery(hEvent); /* get the index */
2174 if (-1 == iIndex) /* error ? */
2175 {
2176 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2177 return FALSE; /* signal failure */
2178 }
2179
2180 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2181 dwResult = pHMHandle->pDeviceHandler->SetEvent(&pHMHandle->hmHandleData);
2182
2183 return (dwResult); /* deliver return code */
2184}
2185
2186
2187/*****************************************************************************
2188 * Name : HMPulseEvent
2189 * Purpose : router function for PulseEvent
2190 * Parameters:
2191 * Variables :
2192 * Result :
2193 * Remark :
2194 * Status :
2195 *
2196 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2197 *****************************************************************************/
2198
2199BOOL HMPulseEvent(HANDLE hEvent)
2200{
2201 int iIndex; /* index into the handle table */
2202 DWORD dwResult; /* result from the device handler's API */
2203 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2204
2205 /* validate handle */
2206 iIndex = _HMHandleQuery(hEvent); /* get the index */
2207 if (-1 == iIndex) /* error ? */
2208 {
2209 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2210 return FALSE; /* signal failure */
2211 }
2212
2213 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2214 dwResult = pHMHandle->pDeviceHandler->PulseEvent(&pHMHandle->hmHandleData);
2215
2216 return (dwResult); /* deliver return code */
2217}
2218
2219
2220/*****************************************************************************
2221 * Name : HMResetEvent
2222 * Purpose : router function for ResetEvent
2223 * Parameters:
2224 * Variables :
2225 * Result :
2226 * Remark :
2227 * Status :
2228 *
2229 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2230 *****************************************************************************/
2231
2232BOOL HMResetEvent(HANDLE hEvent)
2233{
2234 int iIndex; /* index into the handle table */
2235 DWORD dwResult; /* result from the device handler's API */
2236 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2237
2238 /* validate handle */
2239 iIndex = _HMHandleQuery(hEvent); /* get the index */
2240 if (-1 == iIndex) /* error ? */
2241 {
2242 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2243 return FALSE; /* signal failure */
2244 }
2245
2246 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2247 dwResult = pHMHandle->pDeviceHandler->ResetEvent(&pHMHandle->hmHandleData);
2248
2249 return (dwResult); /* deliver return code */
2250}
2251
2252
2253/*****************************************************************************
2254 * Name : HANDLE HMCreateEvent
2255 * Purpose : Wrapper for the CreateEvent() API
2256 * Parameters:
2257 * Variables :
2258 * Result :
2259 * Remark :
2260 * Status :
2261 *
2262 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2263 *****************************************************************************/
2264
2265HANDLE HMCreateEvent(LPSECURITY_ATTRIBUTES lpsa,
2266 BOOL bManualReset,
2267 BOOL bInitialState,
2268 LPCTSTR lpName)
2269{
2270 int iIndex; /* index into the handle table */
2271 int iIndexNew; /* index into the handle table */
2272 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2273 PHMHANDLEDATA pHMHandleData;
2274 DWORD rc; /* API return code */
2275
2276
2277 if(lpName) { //check if shared event semaphore already exists
2278 //TODO: No inheritance??
2279 HANDLE handle = HMOpenEvent(EVENT_ALL_ACCESS, FALSE, lpName);
2280 if(handle) {
2281 dprintf(("CreateEvent: return handle of existing event semaphore %x", handle));
2282 SetLastError(ERROR_ALREADY_EXISTS);
2283 return handle;
2284 }
2285 }
2286
2287 pDeviceHandler = HMGlobals.pHMEvent; /* device is predefined */
2288
2289 iIndexNew = _HMHandleGetFree(); /* get free handle */
2290 if (-1 == iIndexNew) /* oops, no free handles ! */
2291 {
2292 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2293 return 0; /* signal error */
2294 }
2295
2296 /* Initialize the complete HMHANDLEDATA structure */
2297 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2298 pHMHandleData->dwAccess = 0;
2299 pHMHandleData->dwShare = 0;
2300 pHMHandleData->dwCreation = 0;
2301 pHMHandleData->dwFlags = 0;
2302 pHMHandleData->lpHandlerData = NULL;
2303
2304 /* we've got to mark the handle as occupied here, since another device */
2305 /* could be created within the device handler -> deadlock */
2306
2307 /* write appropriate entry into the handle table if open succeeded */
2308 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2309 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2310
2311 /* call the device handler */
2312 rc = pDeviceHandler->CreateEvent(&TabWin32Handles[iIndexNew].hmHandleData,
2313 lpsa,
2314 bManualReset,
2315 bInitialState,
2316 lpName);
2317 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2318 {
2319 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2320 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2321 return 0; /* signal error */
2322 }
2323 else
2324 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2325
2326 return iIndexNew; /* return valid handle */
2327}
2328
2329
2330/*****************************************************************************
2331 * Name : HANDLE HMCreateMutex
2332 * Purpose : Wrapper for the CreateMutex() API
2333 * Parameters:
2334 * Variables :
2335 * Result :
2336 * Remark :
2337 * Status :
2338 *
2339 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2340 *****************************************************************************/
2341
2342HANDLE HMCreateMutex(LPSECURITY_ATTRIBUTES lpsa,
2343 BOOL bInitialOwner,
2344 LPCTSTR lpName)
2345{
2346 int iIndex; /* index into the handle table */
2347 int iIndexNew; /* index into the handle table */
2348 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2349 PHMHANDLEDATA pHMHandleData;
2350 DWORD rc; /* API return code */
2351
2352
2353 if(lpName) { //check if shared mutex semaphore already exists
2354 //TODO: No inheritance??
2355 HANDLE handle = HMOpenMutex(MUTEX_ALL_ACCESS, FALSE, lpName);
2356 if(handle) {
2357 dprintf(("CreateMutex: return handle of existing mutex semaphore %x", handle));
2358 SetLastError(ERROR_ALREADY_EXISTS);
2359 return handle;
2360 }
2361 }
2362
2363 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2364
2365 iIndexNew = _HMHandleGetFree(); /* get free handle */
2366 if (-1 == iIndexNew) /* oops, no free handles ! */
2367 {
2368 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2369 return 0; /* signal error */
2370 }
2371
2372
2373 /* initialize the complete HMHANDLEDATA structure */
2374 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2375 pHMHandleData->dwAccess = 0;
2376 pHMHandleData->dwShare = 0;
2377 pHMHandleData->dwCreation = 0;
2378 pHMHandleData->dwFlags = 0;
2379 pHMHandleData->lpHandlerData = NULL;
2380
2381
2382 /* we've got to mark the handle as occupied here, since another device */
2383 /* could be created within the device handler -> deadlock */
2384
2385 /* write appropriate entry into the handle table if open succeeded */
2386 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2387 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2388
2389 /* call the device handler */
2390 rc = pDeviceHandler->CreateMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2391 lpsa,
2392 bInitialOwner,
2393 lpName);
2394 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2395 {
2396 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2397 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2398 return 0; /* signal error */
2399 }
2400 else
2401 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2402
2403 return iIndexNew; /* return valid handle */
2404}
2405
2406
2407/*****************************************************************************
2408 * Name : HANDLE HMOpenEvent
2409 * Purpose : Wrapper for the OpenEvent() API
2410 * Parameters:
2411 * Variables :
2412 * Result :
2413 * Remark :
2414 * Status :
2415 *
2416 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2417 *****************************************************************************/
2418
2419HANDLE HMOpenEvent(DWORD fdwAccess,
2420 BOOL fInherit,
2421 LPCTSTR lpName)
2422{
2423 int iIndex; /* index into the handle table */
2424 int iIndexNew; /* index into the handle table */
2425 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2426 PHMHANDLEDATA pHMHandleData;
2427 DWORD rc; /* API return code */
2428
2429
2430 pDeviceHandler = HMGlobals.pHMEvent; /* device is predefined */
2431
2432 iIndexNew = _HMHandleGetFree(); /* get free handle */
2433 if (-1 == iIndexNew) /* oops, no free handles ! */
2434 {
2435 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2436 return 0; /* signal error */
2437 }
2438
2439
2440 /* initialize the complete HMHANDLEDATA structure */
2441 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2442 pHMHandleData->dwAccess = fdwAccess;
2443 pHMHandleData->dwShare = 0;
2444 pHMHandleData->dwCreation = 0;
2445 pHMHandleData->dwFlags = 0;
2446 pHMHandleData->lpHandlerData = NULL;
2447
2448
2449 /* we've got to mark the handle as occupied here, since another device */
2450 /* could be created within the device handler -> deadlock */
2451
2452 /* write appropriate entry into the handle table if open succeeded */
2453 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2454 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2455
2456 /* call the device handler */
2457 rc = pDeviceHandler->OpenEvent(&TabWin32Handles[iIndexNew].hmHandleData,
2458 fInherit,
2459 lpName);
2460 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2461 {
2462 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2463 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2464 return 0; /* signal error */
2465 }
2466 else
2467 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2468
2469 return iIndexNew; /* return valid handle */
2470}
2471
2472
2473/*****************************************************************************
2474 * Name : HANDLE HMOpenMutex
2475 * Purpose : Wrapper for the OpenMutex() API
2476 * Parameters:
2477 * Variables :
2478 * Result :
2479 * Remark :
2480 * Status :
2481 *
2482 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2483 *****************************************************************************/
2484
2485HANDLE HMOpenMutex(DWORD fdwAccess,
2486 BOOL fInherit,
2487 LPCTSTR lpName)
2488{
2489 int iIndex; /* index into the handle table */
2490 int iIndexNew; /* index into the handle table */
2491 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2492 PHMHANDLEDATA pHMHandleData;
2493 DWORD rc; /* API return code */
2494
2495
2496 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2497
2498 iIndexNew = _HMHandleGetFree(); /* get free handle */
2499 if (-1 == iIndexNew) /* oops, no free handles ! */
2500 {
2501 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2502 return 0; /* signal error */
2503 }
2504
2505
2506 /* initialize the complete HMHANDLEDATA structure */
2507 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2508 pHMHandleData->dwAccess = fdwAccess;
2509 pHMHandleData->dwShare = 0;
2510 pHMHandleData->dwCreation = 0;
2511 pHMHandleData->dwFlags = 0;
2512 pHMHandleData->lpHandlerData = NULL;
2513
2514
2515 /* we've got to mark the handle as occupied here, since another device */
2516 /* could be created within the device handler -> deadlock */
2517
2518 /* write appropriate entry into the handle table if open succeeded */
2519 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2520 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2521
2522 /* call the device handler */
2523 rc = pDeviceHandler->OpenMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2524 fInherit,
2525 lpName);
2526 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2527 {
2528 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2529 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2530 return 0; /* signal error */
2531 }
2532 else
2533 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2534
2535 return iIndexNew; /* return valid handle */
2536}
2537
2538
2539/*****************************************************************************
2540 * Name : HANDLE HMCreateSemaphore
2541 * Purpose : Wrapper for the CreateSemaphore() API
2542 * Parameters:
2543 * Variables :
2544 * Result :
2545 * Remark :
2546 * Status :
2547 *
2548 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2549 *****************************************************************************/
2550
2551HANDLE HMCreateSemaphore(LPSECURITY_ATTRIBUTES lpsa,
2552 LONG lInitialCount,
2553 LONG lMaximumCount,
2554 LPCTSTR lpName)
2555{
2556 int iIndex; /* index into the handle table */
2557 int iIndexNew; /* index into the handle table */
2558 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2559 PHMHANDLEDATA pHMHandleData;
2560 DWORD rc; /* API return code */
2561
2562 if(lpName) { //check if shared event semaphore already exists
2563 //TODO: No inheritance??
2564 HANDLE handle = HMOpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, lpName);
2565 if(handle) {
2566 dprintf(("CreateSemaphore: return handle of existing semaphore %x", handle));
2567 SetLastError(ERROR_ALREADY_EXISTS);
2568 return handle;
2569 }
2570 }
2571
2572 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2573
2574 iIndexNew = _HMHandleGetFree(); /* get free handle */
2575 if (-1 == iIndexNew) /* oops, no free handles ! */
2576 {
2577 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2578 return 0; /* signal error */
2579 }
2580
2581
2582 /* initialize the complete HMHANDLEDATA structure */
2583 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2584 pHMHandleData->dwAccess = 0;
2585 pHMHandleData->dwShare = 0;
2586 pHMHandleData->dwCreation = 0;
2587 pHMHandleData->dwFlags = 0;
2588 pHMHandleData->lpHandlerData = NULL;
2589
2590
2591 /* we've got to mark the handle as occupied here, since another device */
2592 /* could be created within the device handler -> deadlock */
2593
2594 /* write appropriate entry into the handle table if open succeeded */
2595 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2596 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2597
2598 /* call the device handler */
2599 rc = pDeviceHandler->CreateSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2600 lpsa,
2601 lInitialCount,
2602 lMaximumCount,
2603 lpName);
2604 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2605 {
2606 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2607 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2608 return 0; /* signal failure */
2609 }
2610 else
2611 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2612
2613 return iIndexNew; /* return valid handle */
2614}
2615
2616
2617/*****************************************************************************
2618 * Name : HANDLE HMOpenSemaphore
2619 * Purpose : Wrapper for the OpenSemaphore() API
2620 * Parameters:
2621 * Variables :
2622 * Result :
2623 * Remark :
2624 * Status :
2625 *
2626 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2627 *****************************************************************************/
2628
2629HANDLE HMOpenSemaphore(DWORD fdwAccess,
2630 BOOL fInherit,
2631 LPCTSTR lpName)
2632{
2633 int iIndex; /* index into the handle table */
2634 int iIndexNew; /* index into the handle table */
2635 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2636 PHMHANDLEDATA pHMHandleData;
2637 DWORD rc; /* API return code */
2638
2639
2640 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2641
2642 iIndexNew = _HMHandleGetFree(); /* get free handle */
2643 if (-1 == iIndexNew) /* oops, no free handles ! */
2644 {
2645 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2646 return 0; /* signal error */
2647 }
2648
2649
2650 /* initialize the complete HMHANDLEDATA structure */
2651 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2652 pHMHandleData->dwAccess = fdwAccess;
2653 pHMHandleData->dwShare = 0;
2654 pHMHandleData->dwCreation = 0;
2655 pHMHandleData->dwFlags = 0;
2656 pHMHandleData->lpHandlerData = NULL;
2657
2658
2659 /* we've got to mark the handle as occupied here, since another device */
2660 /* could be created within the device handler -> deadlock */
2661
2662 /* write appropriate entry into the handle table if open succeeded */
2663 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2664 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2665
2666 /* call the device handler */
2667 rc = pDeviceHandler->OpenSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2668 fInherit,
2669 lpName);
2670 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2671 {
2672 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2673 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2674 return 0; /* signal failure */
2675 }
2676 else
2677 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2678
2679 return iIndexNew; /* return valid handle */
2680}
2681
2682
2683/*****************************************************************************
2684 * Name : HMReleaseSemaphore
2685 * Purpose : router function for ReleaseSemaphore
2686 * Parameters:
2687 * Variables :
2688 * Result :
2689 * Remark :
2690 * Status :
2691 *
2692 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2693 *****************************************************************************/
2694
2695BOOL HMReleaseSemaphore(HANDLE hEvent,
2696 LONG cReleaseCount,
2697 LPLONG lpPreviousCount)
2698{
2699 int iIndex; /* index into the handle table */
2700 DWORD dwResult; /* result from the device handler's API */
2701 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2702
2703 /* validate handle */
2704 iIndex = _HMHandleQuery(hEvent); /* get the index */
2705 if (-1 == iIndex) /* error ? */
2706 {
2707 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2708 return 0; /* signal failure */
2709 }
2710 else
2711 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2712
2713 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2714 dwResult = pHMHandle->pDeviceHandler->ReleaseSemaphore(&pHMHandle->hmHandleData,
2715 cReleaseCount,
2716 lpPreviousCount);
2717
2718 return (dwResult); /* deliver return code */
2719}
2720
2721
2722/*****************************************************************************
2723 * Name : HANDLE HMCreateFileMapping
2724 * Purpose : Wrapper for the CreateFileMapping() API
2725 * Parameters:
2726 * Variables :
2727 * Result :
2728 * Remark :
2729 * Status :
2730 *
2731 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2732 *****************************************************************************/
2733
2734HANDLE HMCreateFileMapping(HANDLE hFile,
2735 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
2736 DWORD flProtect,
2737 DWORD dwMaximumSizeHigh,
2738 DWORD dwMaximumSizeLow,
2739 LPCTSTR lpName)
2740{
2741 int iIndex; /* index into the handle table */
2742 int iIndexNew; /* index into the handle table */
2743 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2744 PHMHANDLEDATA pHMHandleData;
2745 DWORD rc; /* API return code */
2746
2747 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
2748
2749 iIndexNew = _HMHandleGetFree(); /* get free handle */
2750 if (-1 == iIndexNew) /* oops, no free handles ! */
2751 {
2752 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2753 return 0; /* signal error */
2754 }
2755
2756 /* initialize the complete HMHANDLEDATA structure */
2757 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2758 pHMHandleData->dwAccess = 0;
2759 pHMHandleData->dwShare = 0;
2760 pHMHandleData->dwCreation = 0;
2761 pHMHandleData->dwFlags = 0;
2762 pHMHandleData->lpHandlerData = NULL;
2763
2764 /* we've got to mark the handle as occupied here, since another device */
2765 /* could be created within the device handler -> deadlock */
2766
2767 /* write appropriate entry into the handle table if open succeeded */
2768 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2769 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2770
2771 /* call the device handler */
2772
2773 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
2774 // a valid HandleManager-internal handle!
2775 rc = pDeviceHandler->CreateFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
2776 hFile,
2777 lpFileMappingAttributes,
2778 flProtect,
2779 dwMaximumSizeHigh,
2780 dwMaximumSizeLow,
2781 lpName);
2782
2783 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
2784 {
2785 if(rc != ERROR_ALREADY_EXISTS) {
2786 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2787 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2788 return (NULL); /* signal error */
2789 }
2790 SetLastError(ERROR_ALREADY_EXISTS);
2791 return iIndexNew; /* return valid handle */
2792 }
2793 else
2794 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2795
2796 return iIndexNew; /* return valid handle */
2797}
2798
2799
2800/*****************************************************************************
2801 * Name : HANDLE HMOpenFileMapping
2802 * Purpose : Wrapper for the OpenFileMapping() API
2803 * Parameters:
2804 * Variables :
2805 * Result : HANDLE if succeeded,
2806 * NULL if failed.
2807 * Remark :
2808 * Status :
2809 *
2810 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2811 *****************************************************************************/
2812
2813HANDLE HMOpenFileMapping(DWORD fdwAccess,
2814 BOOL fInherit,
2815 LPCTSTR lpName)
2816{
2817 int iIndex; /* index into the handle table */
2818 int iIndexNew; /* index into the handle table */
2819 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2820 PHMHANDLEDATA pHMHandleData;
2821 DWORD rc; /* API return code */
2822
2823
2824 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
2825
2826 iIndexNew = _HMHandleGetFree(); /* get free handle */
2827 if (-1 == iIndexNew) /* oops, no free handles ! */
2828 {
2829 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2830 return (NULL); /* signal error */
2831 }
2832
2833 /* initialize the complete HMHANDLEDATA structure */
2834 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2835 pHMHandleData->dwAccess = fdwAccess;
2836 pHMHandleData->dwShare = 0;
2837 pHMHandleData->dwCreation = 0;
2838 pHMHandleData->dwFlags = 0;
2839 pHMHandleData->lpHandlerData = NULL;
2840
2841
2842 /* we've got to mark the handle as occupied here, since another device */
2843 /* could be created within the device handler -> deadlock */
2844
2845 /* write appropriate entry into the handle table if open succeeded */
2846 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2847 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2848
2849 /* call the device handler */
2850 rc = pDeviceHandler->OpenFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
2851 fdwAccess,
2852 fInherit,
2853 lpName);
2854 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2855 {
2856 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2857 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2858 return (NULL); /* signal error */
2859 }
2860 else
2861 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2862
2863 return iIndexNew; /* return valid handle */
2864}
2865
2866
2867/*****************************************************************************
2868 * Name : HMMapViewOfFileEx
2869 * Purpose : router function for MapViewOfFileEx
2870 * Parameters:
2871 * Variables :
2872 * Result :
2873 * Remark :
2874 * Status :
2875 *
2876 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2877 *****************************************************************************/
2878
2879LPVOID HMMapViewOfFileEx(HANDLE hFileMappingObject,
2880 DWORD dwDesiredAccess,
2881 DWORD dwFileOffsetHigh,
2882 DWORD dwFileOffsetLow,
2883 DWORD dwNumberOfBytesToMap,
2884 LPVOID lpBaseAddress)
2885{
2886 int iIndex; /* index into the handle table */
2887 LPVOID lpResult; /* result from the device handler's API */
2888 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2889
2890 /* validate handle */
2891 iIndex = _HMHandleQuery(hFileMappingObject); /* get the index */
2892 if (-1 == iIndex) /* error ? */
2893 {
2894 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2895 return (NULL); /* signal failure */
2896 }
2897
2898 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2899 lpResult = pHMHandle->pDeviceHandler->MapViewOfFileEx(&pHMHandle->hmHandleData,
2900 dwDesiredAccess,
2901 dwFileOffsetHigh,
2902 dwFileOffsetLow,
2903 dwNumberOfBytesToMap,
2904 lpBaseAddress);
2905
2906 return (lpResult); /* deliver return code */
2907}
2908
2909/*****************************************************************************
2910 * Name : HMWaitForMultipleObjects
2911 * Purpose : router function for WaitForMultipleObjects
2912 * Parameters:
2913 * Variables :
2914 * Result :
2915 * Remark :
2916 * Status :
2917 *
2918 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2919 *****************************************************************************/
2920
2921DWORD HMWaitForMultipleObjects (DWORD cObjects,
2922 PHANDLE lphObjects,
2923 BOOL fWaitAll,
2924 DWORD dwTimeout)
2925{
2926#ifdef USE_OS2SEMAPHORES
2927 int iIndex; /* index into the handle table */
2928 DWORD dwResult; /* result from the device handler's API */
2929 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2930
2931 if(cObjects == 1) {
2932 return HMWaitForSingleObject(*lphObjects, dwTimeout);
2933 }
2934
2935 if(cObjects > MAXIMUM_WAIT_OBJECTS) {
2936 dprintf(("KERNEL32: HMWaitForMultipleObjects: Too many objects (%d)", cObjects));
2937 SetLastError(ERROR_INVALID_PARAMETER);
2938 return WAIT_FAILED;
2939 }
2940
2941 /* validate handle */
2942 iIndex = _HMHandleQuery(*lphObjects); /* get the index */
2943 if (-1 == iIndex) /* error ? */
2944 {//oh, oh. possible problem here
2945 //TODO: rewrite handling of other handles; don't forward to open32
2946 dprintf(("WANRING: HMWaitForMultipleObjects: unknown handle passed on to Open32 -> will not work if other handles are semaphores"));
2947 return O32_WaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
2948 }
2949
2950 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2951 dwResult = pHMHandle->pDeviceHandler->WaitForMultipleObjects(&pHMHandle->hmHandleData,
2952 cObjects, lphObjects, fWaitAll,
2953 dwTimeout);
2954
2955 return (dwResult); /* deliver return code */
2956#else
2957 ULONG ulIndex;
2958 PHANDLE pArrayOfHandles;
2959 PHANDLE pLoop1 = lphObjects;
2960 PHANDLE pLoop2;
2961 DWORD rc;
2962
2963 // allocate array for handle table
2964 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
2965 if (pArrayOfHandles == NULL)
2966 {
2967 dprintf(("ERROR: HMWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
2968 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2969 return WAIT_FAILED;
2970 }
2971 else
2972 pLoop2 = pArrayOfHandles;
2973
2974 // convert array to odin handles
2975 for (ulIndex = 0;
2976
2977 ulIndex < cObjects;
2978
2979 ulIndex++,
2980 pLoop1++,
2981 pLoop2++)
2982 {
2983 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
2984 pLoop2);
2985
2986 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, Open32-%08xh\n",
2987 ulIndex,
2988 *pLoop1,
2989 *pLoop2));
2990
2991 // @@@PH to imlpement: check handle type!
2992 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
2993 if (rc != NO_ERROR)
2994 {
2995 dprintf(("KERNEL32: HMWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
2996 *pLoop1));
2997
2998 *pLoop2 = *pLoop1;
2999//// SetLastError(ERROR_INVALID_HANDLE);
3000//// return (WAIT_FAILED);
3001 }
3002 }
3003
3004 //If the timeout is less than 20 milliseconds (and not zero), then we are likely to
3005 //return too late if the thread priority isn't time critical (time slices
3006 //of 32 ms)
3007 //To avoid this problem, we temporarily switch to time critical priority.
3008 HANDLE hThread = GetCurrentThread();
3009 DWORD dwThreadPriority = GetThreadPriority(hThread);
3010
3011 if(dwTimeout && dwTimeout < 20 && dwThreadPriority != THREAD_PRIORITY_TIME_CRITICAL) {
3012 dprintf(("Temporarily change priority to THREAD_PRIORITY_TIME_CRITICAL for better timing"));
3013 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
3014 //round to 8 ms units to get more precise timeouts
3015 if(dwTimeout > 8)
3016 dwTimeout = (dwTimeout/8)*8;
3017 }
3018 else dwThreadPriority = -1;
3019
3020 // OK, now forward to Open32.
3021 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3022 // but to i.e. the console subsystem!
3023 rc = O32_WaitForMultipleObjects(cObjects,
3024 pArrayOfHandles,
3025 fWaitAll,
3026 dwTimeout);
3027
3028 //Restore old thread priority if we changed it before
3029 if(dwThreadPriority != -1) {
3030 SetThreadPriority(hThread, dwThreadPriority);
3031 }
3032
3033 return (rc); // OK, done
3034#endif
3035}
3036
3037
3038/*****************************************************************************
3039 * Name : HMWaitForMultipleObjectsEx
3040 * Purpose : router function for WaitForMultipleObjectsEx
3041 * Parameters:
3042 * Variables :
3043 * Result :
3044 * Remark :
3045 * Status :
3046 *
3047 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3048 *****************************************************************************/
3049
3050DWORD HMWaitForMultipleObjectsEx (DWORD cObjects,
3051 PHANDLE lphObjects,
3052 BOOL fWaitAll,
3053 DWORD dwTimeout,
3054 BOOL fAlertable)
3055{
3056 // @@@PH: Note: fAlertable is ignored !
3057 return (HMWaitForMultipleObjects(cObjects,
3058 lphObjects,
3059 fWaitAll,
3060 dwTimeout));
3061}
3062
3063/*****************************************************************************
3064 * Name : HMMsgWaitForMultipleObjects
3065 * Purpose : router function for MsgWaitForMultipleObjects
3066 * Parameters:
3067 * Variables :
3068 * Result :
3069 * Remark : Open32 doesn't implement this properly! (doesn't check dwWakeMask)
3070 * Status :
3071 *
3072 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3073 *****************************************************************************/
3074
3075DWORD HMMsgWaitForMultipleObjects (DWORD cObjects,
3076 LPHANDLE lphObjects,
3077 BOOL fWaitAll,
3078 DWORD dwTimeout,
3079 DWORD dwWakeMask)
3080{
3081#ifdef USE_OS2SEMAPHORES
3082 int iIndex; /* index into the handle table */
3083 DWORD dwResult; /* result from the device handler's API */
3084 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3085
3086
3087 if(dwWakeMask == 0) {
3088 dprintf(("WARNING: wakemask == 0 -> calling WaitForMultipleObjects"));
3089 return HMWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout);
3090 }
3091 /* validate handle */
3092 iIndex = _HMHandleQuery(*lphObjects); /* get the index */
3093 if (-1 == iIndex) /* error ? */
3094 {//oh, oh. possible problem here
3095 //TODO: rewrite handling of other handles; don't forward to open32
3096 dprintf(("WANRING: HMWaitForMultipleObjects: unknown handle passed on to Open32 -> will not work if other handles are semaphores"));
3097 return O32_MsgWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout, dwWakeMask);
3098 }
3099
3100 if(cObjects > MAXIMUM_WAIT_OBJECTS) {
3101 dprintf(("KERNEL32: HMMsgWaitForMultipleObjects: Too many objects (%d)", cObjects));
3102 SetLastError(ERROR_INVALID_PARAMETER);
3103 return WAIT_FAILED;
3104 }
3105
3106 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3107 dwResult = pHMHandle->pDeviceHandler->MsgWaitForMultipleObjects(&pHMHandle->hmHandleData,
3108 cObjects, lphObjects, fWaitAll,
3109 dwTimeout, dwWakeMask);
3110
3111 return (dwResult); /* deliver return code */
3112#else
3113 ULONG ulIndex;
3114 PHANDLE pArrayOfHandles;
3115 PHANDLE pLoop1 = lphObjects;
3116 PHANDLE pLoop2;
3117 DWORD rc;
3118
3119 // allocate array for handle table
3120 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3121 if (pArrayOfHandles == NULL)
3122 {
3123 dprintf(("ERROR: HMMsgWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3124 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3125 return WAIT_FAILED;
3126 }
3127 else
3128 pLoop2 = pArrayOfHandles;
3129
3130 // convert array to odin handles
3131 for (ulIndex = 0;
3132
3133 ulIndex < cObjects;
3134
3135 ulIndex++,
3136 pLoop1++,
3137 pLoop2++)
3138 {
3139 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3140 pLoop2);
3141
3142 dprintf2(("MsgWaitForMultipleObjects handle %x->%x", *pLoop1, *pLoop2));
3143 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3144 if (rc != NO_ERROR)
3145 {
3146 dprintf(("KERNEL32: HMMsgWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3147 *pLoop1));
3148
3149 *pLoop2 = *pLoop1;
3150//// SetLastError(ERROR_INVALID_HANDLE);
3151//// return (WAIT_FAILED);
3152 }
3153 }
3154
3155 //If the timeout is less than 20 milliseconds (and not zero), then we are likely to
3156 //return too late if the thread priority isn't time critical (time slices
3157 //of 32 ms)
3158 //To avoid this problem, we temporarily switch to time critical priority.
3159 HANDLE hThread = GetCurrentThread();
3160 DWORD dwThreadPriority = GetThreadPriority(hThread);
3161
3162 if(dwTimeout && dwTimeout < 20 && dwThreadPriority != THREAD_PRIORITY_TIME_CRITICAL) {
3163 dprintf(("Temporarily change priority to THREAD_PRIORITY_TIME_CRITICAL for better timing"));
3164 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
3165 //round to 8 ms units to get more precise timeouts
3166 if(dwTimeout > 8)
3167 dwTimeout = (dwTimeout/8)*8;
3168 }
3169 else dwThreadPriority = -1;
3170
3171 // OK, now forward to Open32.
3172 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3173 // but to i.e. the console subsystem!
3174 rc = O32_MsgWaitForMultipleObjects(cObjects,
3175 pArrayOfHandles,
3176 fWaitAll, dwTimeout,
3177 dwWakeMask);
3178
3179 //Restore old thread priority if we changed it before
3180 if(dwThreadPriority != -1) {
3181 SetThreadPriority(hThread, dwThreadPriority);
3182 }
3183
3184 dprintf2(("MsgWaitForMultipleObjects returned %d", rc));
3185 return (rc); // OK, done
3186#endif
3187}
3188/*****************************************************************************
3189 * Name : HMDeviceIoControl
3190 * Purpose : router function for DeviceIoControl
3191 * Parameters:
3192 * Variables :
3193 * Result :
3194 * Remark :
3195 * Status :
3196 *
3197 * Author : Sander van Leeuwen
3198 *****************************************************************************/
3199
3200BOOL HMDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
3201 LPVOID lpInBuffer, DWORD nInBufferSize,
3202 LPVOID lpOutBuffer, DWORD nOutBufferSize,
3203 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
3204{
3205 int iIndex; /* index into the handle table */
3206 BOOL fResult; /* result from the device handler's CloseHandle() */
3207 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3208
3209 /* validate handle */
3210 iIndex = _HMHandleQuery(hDevice); /* get the index */
3211 if (-1 == iIndex) /* error ? */
3212 {
3213 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3214 return (FALSE); /* signal failure */
3215 }
3216
3217 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3218 fResult = pHMHandle->pDeviceHandler->DeviceIoControl(&pHMHandle->hmHandleData,
3219 dwIoControlCode,
3220 lpInBuffer, nInBufferSize,
3221 lpOutBuffer, nOutBufferSize,
3222 lpBytesReturned, lpOverlapped);
3223
3224 return (fResult); /* deliver return code */
3225}
3226/*****************************************************************************
3227 * Name : HMCancelIo
3228 * Purpose : router function for CancelIo
3229 * Parameters:
3230 * Variables :
3231 * Result :
3232 * Remark :
3233 * Status :
3234 *
3235 * Author : Sander van Leeuwen
3236 *****************************************************************************/
3237BOOL HMCancelIo(HANDLE hDevice)
3238{
3239 int iIndex; /* index into the handle table */
3240 BOOL fResult; /* result from the device handler's CloseHandle() */
3241 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3242
3243 /* validate handle */
3244 iIndex = _HMHandleQuery(hDevice); /* get the index */
3245 if (-1 == iIndex) /* error ? */
3246 {
3247 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3248 return (FALSE); /* signal failure */
3249 }
3250
3251 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3252 fResult = pHMHandle->pDeviceHandler->CancelIo(&pHMHandle->hmHandleData);
3253
3254 return (fResult); /* deliver return code */
3255}
3256/*****************************************************************************
3257 * Name : HMCOMGetCommState
3258 * Purpose : router function for GetCommState
3259 * Parameters:
3260 * Variables :
3261 * Result :
3262 * Remark :
3263 * Status :
3264 *
3265 * Author : Achim Hasenmueller [Sat, 1999/11/27 13:40]
3266 *****************************************************************************/
3267
3268BOOL HMCommGetCommState(HANDLE hCommDev, LPDCB lpdcb)
3269{
3270 int iIndex; /* index into the handle table */
3271 BOOL bResult; /* result from the device handler's API */
3272 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3273
3274 /* validate handle */
3275 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3276 if (-1 == iIndex) /* error ? */
3277 {
3278 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3279 return (NULL); /* signal failure */
3280 }
3281
3282 if(IsBadWritePtr(lpdcb,sizeof(DCB)))
3283 {
3284 SetLastError(ERROR_INVALID_PARAMETER);
3285 return FALSE;
3286 }
3287
3288 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3289 bResult = pHMHandle->pDeviceHandler->GetCommState(&pHMHandle->hmHandleData,
3290 lpdcb);
3291
3292 return (bResult); /* deliver return code */
3293}
3294
3295BOOL HMCommWaitCommEvent( HANDLE hCommDev,
3296 LPDWORD lpfdwEvtMask,
3297 LPOVERLAPPED lpo)
3298{
3299 int iIndex; /* index into the handle table */
3300 BOOL bResult; /* result from the device handler's API */
3301 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3302
3303 /* validate handle */
3304 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3305 if (-1 == iIndex) /* error ? */
3306 {
3307 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3308 return FALSE; /* signal failure */
3309 }
3310
3311 if(NULL!=lpo && IsBadReadPtr(lpo,sizeof(OVERLAPPED)) )
3312 {
3313 SetLastError(ERROR_INVALID_PARAMETER);
3314 return FALSE;
3315 }
3316
3317 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3318 bResult = pHMHandle->pDeviceHandler->WaitCommEvent( &pHMHandle->hmHandleData,
3319 lpfdwEvtMask,
3320 lpo);
3321
3322 return (bResult); /* deliver return code */
3323}
3324
3325BOOL HMCommGetCommProperties( HANDLE hCommDev,
3326 LPCOMMPROP lpcmmp)
3327{
3328 int iIndex; /* index into the handle table */
3329 BOOL bResult; /* result from the device handler's API */
3330 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3331
3332 /* validate handle */
3333 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3334 if (-1 == iIndex) /* error ? */
3335 {
3336 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3337 return (NULL); /* signal failure */
3338 }
3339
3340 if(IsBadWritePtr(lpcmmp,sizeof(COMMPROP)) )
3341 {
3342 SetLastError(ERROR_INVALID_PARAMETER);
3343 return FALSE;
3344 }
3345
3346 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3347 bResult = pHMHandle->pDeviceHandler->GetCommProperties( &pHMHandle->hmHandleData,
3348 lpcmmp);
3349
3350 return (bResult); /* deliver return code */
3351}
3352
3353BOOL HMCommGetCommMask( HANDLE hCommDev,
3354 LPDWORD lpfdwEvtMask)
3355{
3356 int iIndex; /* index into the handle table */
3357 BOOL bResult; /* result from the device handler's API */
3358 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3359
3360 /* validate handle */
3361 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3362 if (-1 == iIndex) /* error ? */
3363 {
3364 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3365 return (NULL); /* signal failure */
3366 }
3367
3368 if(IsBadWritePtr(lpfdwEvtMask,sizeof(DWORD)) )
3369 {
3370 SetLastError(ERROR_INVALID_PARAMETER);
3371 return FALSE;
3372 }
3373
3374 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3375 bResult = pHMHandle->pDeviceHandler->GetCommMask( &pHMHandle->hmHandleData,
3376 lpfdwEvtMask);
3377
3378 return (bResult); /* deliver return code */
3379}
3380
3381BOOL HMCommSetCommMask( HANDLE hCommDev,
3382 DWORD fdwEvtMask)
3383{
3384 int iIndex; /* index into the handle table */
3385 BOOL bResult; /* result from the device handler's API */
3386 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3387
3388 /* validate handle */
3389 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3390 if (-1 == iIndex) /* error ? */
3391 {
3392 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3393 return (NULL); /* signal failure */
3394 }
3395
3396 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3397 bResult = pHMHandle->pDeviceHandler->SetCommMask( &pHMHandle->hmHandleData,
3398 fdwEvtMask);
3399
3400 return (bResult); /* deliver return code */
3401}
3402
3403BOOL HMCommPurgeComm( HANDLE hCommDev,
3404 DWORD fdwAction)
3405{
3406 int iIndex; /* index into the handle table */
3407 BOOL bResult; /* result from the device handler's API */
3408 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3409
3410 /* validate handle */
3411 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3412 if (-1 == iIndex) /* error ? */
3413 {
3414 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3415 return (NULL); /* signal failure */
3416 }
3417
3418
3419 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3420 bResult = pHMHandle->pDeviceHandler->PurgeComm( &pHMHandle->hmHandleData,
3421 fdwAction);
3422
3423 return (bResult); /* deliver return code */
3424}
3425
3426BOOL HMCommClearCommError( HANDLE hCommDev,
3427 LPDWORD lpdwErrors,
3428 LPCOMSTAT lpcst)
3429{
3430 int iIndex; /* index into the handle table */
3431 BOOL bResult; /* result from the device handler's API */
3432 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3433
3434 /* validate handle */
3435 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3436 if (-1 == iIndex) /* error ? */
3437 {
3438 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3439 return (NULL); /* signal failure */
3440 }
3441
3442 if(IsBadWritePtr(lpdwErrors,sizeof(DWORD)) ||
3443 (NULL!=lpcst && IsBadWritePtr(lpcst,sizeof(COMSTAT)) ) )
3444 {
3445 SetLastError(ERROR_INVALID_PARAMETER);
3446 return FALSE;
3447 }
3448
3449 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3450 bResult = pHMHandle->pDeviceHandler->ClearCommError(&pHMHandle->hmHandleData,
3451 lpdwErrors,
3452 lpcst);
3453
3454 return (bResult); /* deliver return code */
3455}
3456
3457BOOL HMCommSetCommState( HANDLE hCommDev,
3458 LPDCB lpdcb)
3459{
3460 int iIndex; /* index into the handle table */
3461 BOOL bResult; /* result from the device handler's API */
3462 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3463
3464 /* validate handle */
3465 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3466 if (-1 == iIndex) /* error ? */
3467 {
3468 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3469 return (NULL); /* signal failure */
3470 }
3471
3472 if(IsBadReadPtr(lpdcb,sizeof(DCB)) )
3473 {
3474 SetLastError(ERROR_INVALID_PARAMETER);
3475 return FALSE;
3476 }
3477
3478
3479 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3480 bResult = pHMHandle->pDeviceHandler->SetCommState(&pHMHandle->hmHandleData,
3481 lpdcb);
3482
3483 return (bResult); /* deliver return code */
3484}
3485
3486
3487BOOL HMCommGetCommTimeouts( HANDLE hCommDev,
3488 LPCOMMTIMEOUTS lpctmo)
3489{
3490 int iIndex; /* index into the handle table */
3491 BOOL bResult; /* result from the device handler's API */
3492 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3493
3494 /* validate handle */
3495 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3496 if (-1 == iIndex) /* error ? */
3497 {
3498 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3499 return (NULL); /* signal failure */
3500 }
3501
3502 if(IsBadWritePtr(lpctmo,sizeof(COMMTIMEOUTS)) )
3503 {
3504 SetLastError(ERROR_INVALID_PARAMETER);
3505 return FALSE;
3506 }
3507
3508 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3509 bResult = pHMHandle->pDeviceHandler->GetCommTimeouts( &pHMHandle->hmHandleData,
3510 lpctmo);
3511
3512 return (bResult); /* deliver return code */
3513}
3514BOOL HMCommGetCommModemStatus( HANDLE hCommDev,
3515 LPDWORD lpModemStat )
3516{
3517 int iIndex; /* index into the handle table */
3518 BOOL bResult; /* result from the device handler's API */
3519 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3520
3521 /* validate handle */
3522 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3523 if (-1 == iIndex) /* error ? */
3524 {
3525 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3526 return (NULL); /* signal failure */
3527 }
3528
3529 if(IsBadWritePtr(lpModemStat,sizeof(DWORD)) )
3530 {
3531 SetLastError(ERROR_INVALID_PARAMETER);
3532 return FALSE;
3533 }
3534
3535 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3536 bResult = pHMHandle->pDeviceHandler->GetCommModemStatus( &pHMHandle->hmHandleData,
3537 lpModemStat);
3538
3539 return (bResult); /* deliver return code */
3540}
3541
3542BOOL HMCommSetCommTimeouts( HANDLE hCommDev,
3543 LPCOMMTIMEOUTS lpctmo)
3544{
3545 int iIndex; /* index into the handle table */
3546 BOOL bResult; /* result from the device handler's API */
3547 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3548
3549 /* validate handle */
3550 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3551 if (-1 == iIndex) /* error ? */
3552 {
3553 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3554 return (NULL); /* signal failure */
3555 }
3556
3557 if(IsBadReadPtr(lpctmo,sizeof(COMMTIMEOUTS)) )
3558 {
3559 SetLastError(ERROR_INVALID_PARAMETER);
3560 return FALSE;
3561 }
3562
3563 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3564 bResult = pHMHandle->pDeviceHandler->SetCommTimeouts( &pHMHandle->hmHandleData,
3565 lpctmo);
3566
3567 return (bResult); /* deliver return code */
3568}
3569
3570BOOL HMCommTransmitCommChar( HANDLE hCommDev,
3571 CHAR cChar )
3572{
3573 int iIndex; /* index into the handle table */
3574 BOOL bResult; /* result from the device handler's API */
3575 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3576
3577 /* validate handle */
3578 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3579 if (-1 == iIndex) /* error ? */
3580 {
3581 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3582 return (NULL); /* signal failure */
3583 }
3584
3585 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3586 bResult = pHMHandle->pDeviceHandler->TransmitCommChar( &pHMHandle->hmHandleData,
3587 cChar);
3588
3589 return (bResult); /* deliver return code */
3590}
3591
3592BOOL HMCommSetCommConfig( HANDLE hCommDev,
3593 LPCOMMCONFIG lpCC,
3594 DWORD dwSize )
3595{
3596 int iIndex; /* index into the handle table */
3597 BOOL bResult; /* result from the device handler's API */
3598 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3599
3600 /* validate handle */
3601 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3602 if (-1 == iIndex) /* error ? */
3603 {
3604 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3605 return (NULL); /* signal failure */
3606 }
3607
3608 if( IsBadReadPtr(lpCC,sizeof(COMMCONFIG)) ||
3609 dwSize < sizeof(COMMCONFIG) )
3610 {
3611 SetLastError(ERROR_INVALID_PARAMETER);
3612 return FALSE;
3613 }
3614
3615 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3616 bResult = pHMHandle->pDeviceHandler->SetCommConfig( &pHMHandle->hmHandleData,
3617 lpCC,
3618 dwSize);
3619
3620 return (bResult); /* deliver return code */
3621}
3622
3623BOOL HMCommSetCommBreak( HANDLE hCommDev )
3624{
3625 int iIndex; /* index into the handle table */
3626 BOOL bResult; /* result from the device handler's API */
3627 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3628
3629 /* validate handle */
3630 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3631 if (-1 == iIndex) /* error ? */
3632 {
3633 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3634 return (NULL); /* signal failure */
3635 }
3636
3637 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3638 bResult = pHMHandle->pDeviceHandler->SetCommBreak( &pHMHandle->hmHandleData);
3639
3640 return (bResult); /* deliver return code */
3641}
3642
3643BOOL HMCommGetCommConfig( HANDLE hCommDev,
3644 LPCOMMCONFIG lpCC,
3645 LPDWORD lpdwSize )
3646{
3647 int iIndex; /* index into the handle table */
3648 BOOL bResult; /* result from the device handler's API */
3649 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3650
3651 /* validate handle */
3652 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3653 if (-1 == iIndex) /* error ? */
3654 {
3655 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3656 return (NULL); /* signal failure */
3657 }
3658
3659 if(IsBadWritePtr(lpdwSize,sizeof(DWORD)) )
3660 {
3661 SetLastError(ERROR_INVALID_PARAMETER);
3662 return FALSE;
3663 }
3664
3665 if( IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
3666 *lpdwSize< sizeof(COMMCONFIG) )
3667 {
3668 SetLastError(ERROR_INSUFFICIENT_BUFFER);
3669 *lpdwSize= sizeof(COMMCONFIG);
3670 return FALSE;
3671 }
3672
3673 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3674 bResult = pHMHandle->pDeviceHandler->GetCommConfig( &pHMHandle->hmHandleData,
3675 lpCC,
3676 lpdwSize);
3677
3678 return (bResult); /* deliver return code */
3679}
3680
3681BOOL HMCommEscapeCommFunction( HANDLE hCommDev,
3682 UINT dwFunc )
3683{
3684 int iIndex; /* index into the handle table */
3685 BOOL bResult; /* result from the device handler's API */
3686 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3687
3688 /* validate handle */
3689 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3690 if (-1 == iIndex) /* error ? */
3691 {
3692 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3693 return (NULL); /* signal failure */
3694 }
3695
3696 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3697
3698 switch(dwFunc)
3699 {
3700 case CLRDTR:
3701 case CLRRTS:
3702 case SETDTR:
3703 case SETRTS:
3704 case SETXOFF:
3705 case SETXON:
3706 bResult = pHMHandle->pDeviceHandler->EscapeCommFunction( &pHMHandle->hmHandleData,
3707 dwFunc);
3708 break;
3709 case SETBREAK:
3710 bResult = pHMHandle->pDeviceHandler->SetCommBreak(&pHMHandle->hmHandleData);
3711 break;
3712 case CLRBREAK:
3713 bResult = pHMHandle->pDeviceHandler->ClearCommBreak(&pHMHandle->hmHandleData);
3714 break;
3715 default:
3716 SetLastError(ERROR_INVALID_PARAMETER);
3717 bResult = FALSE;
3718 }
3719
3720
3721 return (bResult); /* deliver return code */
3722}
3723
3724BOOL HMCommSetupComm( HANDLE hCommDev,
3725 DWORD dwInQueue,
3726 DWORD dwOutQueue)
3727{
3728 int iIndex; /* index into the handle table */
3729 BOOL bResult; /* result from the device handler's API */
3730 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3731
3732 /* validate handle */
3733 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3734 if (-1 == iIndex) /* error ? */
3735 {
3736 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3737 return (NULL); /* signal failure */
3738 }
3739
3740 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3741 bResult = pHMHandle->pDeviceHandler->SetupComm(&pHMHandle->hmHandleData,
3742 dwInQueue,
3743 dwOutQueue);
3744
3745 return (bResult); /* deliver return code */
3746}
3747
3748BOOL HMCommClearCommBreak(HANDLE hCommDev)
3749{
3750 int iIndex; /* index into the handle table */
3751 BOOL bResult; /* result from the device handler's API */
3752 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3753
3754 /* validate handle */
3755 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3756 if (-1 == iIndex) /* error ? */
3757 {
3758 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3759 return (NULL); /* signal failure */
3760 }
3761
3762 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3763 bResult = pHMHandle->pDeviceHandler->ClearCommBreak(&pHMHandle->hmHandleData);
3764
3765 return (bResult); /* deliver return code */
3766}
3767
3768BOOL HMCommSetDefaultCommConfig( HANDLE hCommDev,
3769 LPCOMMCONFIG lpCC,
3770 DWORD dwSize)
3771{
3772 int iIndex; /* index into the handle table */
3773 BOOL bResult; /* result from the device handler's API */
3774 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3775
3776 /* validate handle */
3777 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3778 if (-1 == iIndex) /* error ? */
3779 {
3780 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3781 return (NULL); /* signal failure */
3782 }
3783
3784 if( (lpCC!=NULL) &&
3785 ( IsBadReadPtr(lpCC,sizeof(COMMCONFIG)) ||
3786 dwSize != sizeof(COMMCONFIG) ) )
3787 {
3788 SetLastError(ERROR_INVALID_PARAMETER);
3789 return FALSE;
3790 }
3791
3792 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3793 bResult = pHMHandle->pDeviceHandler->SetDefaultCommConfig(&pHMHandle->hmHandleData,
3794 lpCC,
3795 dwSize);
3796
3797 return (bResult); /* deliver return code */
3798}
3799
3800BOOL HMCommGetDefaultCommConfig( HANDLE hCommDev,
3801 LPCOMMCONFIG lpCC,
3802 LPDWORD lpdwSize)
3803{
3804 int iIndex; /* index into the handle table */
3805 BOOL bResult; /* result from the device handler's API */
3806 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3807
3808 /* validate handle */
3809 iIndex = _HMHandleQuery(hCommDev); /* get the index */
3810 if (-1 == iIndex) /* error ? */
3811 {
3812 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3813 return (NULL); /* signal failure */
3814 }
3815
3816 if(IsBadWritePtr(lpdwSize,sizeof(DWORD)))
3817 {
3818 SetLastError(ERROR_INVALID_PARAMETER);
3819 return FALSE;
3820 }
3821
3822 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3823 bResult = pHMHandle->pDeviceHandler->GetDefaultCommConfig( &pHMHandle->hmHandleData,
3824 lpCC,
3825 lpdwSize);
3826
3827 return (bResult); /* deliver return code */
3828}
3829
3830/*****************************************************************************
3831 * Name : HMOpenThreadToken
3832 * Purpose : router function for NtOpenThreadToken
3833 * Parameters:
3834 * Variables :
3835 * Result :
3836 * Remark :
3837 * Status :
3838 *
3839 * Author : SvL
3840 *****************************************************************************/
3841
3842DWORD HMOpenThreadToken(HANDLE ThreadHandle,
3843 DWORD DesiredAccess,
3844 DWORD OpenAsSelf,
3845 HANDLE *TokenHandle)
3846{
3847 int iIndex; /* index into the handle table */
3848 int iIndexNew; /* index into the handle table */
3849 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3850 PHMHANDLEDATA pHMHandleData;
3851 DWORD rc; /* API return code */
3852
3853 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3854
3855 iIndexNew = _HMHandleGetFree(); /* get free handle */
3856 if (-1 == iIndexNew) /* oops, no free handles ! */
3857 {
3858 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3859 return ERROR_NOT_ENOUGH_MEMORY;
3860 }
3861
3862 /* initialize the complete HMHANDLEDATA structure */
3863 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3864 pHMHandleData->dwAccess = DesiredAccess;
3865 pHMHandleData->dwShare = 0;
3866 pHMHandleData->dwCreation = 0;
3867 pHMHandleData->dwFlags = 0;
3868 pHMHandleData->lpHandlerData = NULL;
3869
3870
3871 /* we've got to mark the handle as occupied here, since another device */
3872 /* could be created within the device handler -> deadlock */
3873
3874 /* write appropriate entry into the handle table if open succeeded */
3875 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3876 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3877
3878 /* call the device handler */
3879
3880 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3881 // a valid HandleManager-internal handle!
3882 rc = pDeviceHandler->OpenThreadToken(&TabWin32Handles[iIndexNew].hmHandleData,
3883 ThreadHandle,
3884 OpenAsSelf);
3885
3886 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3887 {
3888 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3889 return (rc); /* signal error */
3890 }
3891 else
3892 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3893
3894 *TokenHandle = iIndexNew; /* return valid handle */
3895 return STATUS_SUCCESS;
3896}
3897
3898/*****************************************************************************
3899 * Name : HMOpenProcessToken
3900 * Purpose : router function for NtOpenProcessToken
3901 * Parameters:
3902 * Variables :
3903 * Result :
3904 * Remark :
3905 * Status :
3906 *
3907 * Author : SvL
3908 *****************************************************************************/
3909DWORD HMOpenProcessToken(HANDLE ProcessHandle,
3910 DWORD DesiredAccess,
3911 DWORD dwUserData,
3912 HANDLE *TokenHandle)
3913{
3914 int iIndex; /* index into the handle table */
3915 int iIndexNew; /* index into the handle table */
3916 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3917 PHMHANDLEDATA pHMHandleData;
3918 DWORD rc; /* API return code */
3919
3920 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3921
3922 iIndexNew = _HMHandleGetFree(); /* get free handle */
3923 if (-1 == iIndexNew) /* oops, no free handles ! */
3924 {
3925 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3926 return ERROR_NOT_ENOUGH_MEMORY;
3927 }
3928
3929 /* initialize the complete HMHANDLEDATA structure */
3930 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3931 pHMHandleData->dwAccess = DesiredAccess;
3932 pHMHandleData->dwShare = 0;
3933 pHMHandleData->dwCreation = 0;
3934 pHMHandleData->dwFlags = 0;
3935 pHMHandleData->lpHandlerData = NULL;
3936
3937
3938 /* we've got to mark the handle as occupied here, since another device */
3939 /* could be created within the device handler -> deadlock */
3940
3941 /* write appropriate entry into the handle table if open succeeded */
3942 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3943 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3944
3945 /* call the device handler */
3946
3947 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3948 // a valid HandleManager-internal handle!
3949 rc = pDeviceHandler->OpenProcessToken(&TabWin32Handles[iIndexNew].hmHandleData,
3950 dwUserData,
3951 ProcessHandle);
3952
3953 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3954 {
3955 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3956 return (rc); /* signal error */
3957 }
3958 else
3959 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3960
3961 *TokenHandle = iIndexNew; /* return valid handle */
3962 return STATUS_SUCCESS;
3963}
3964/*****************************************************************************
3965 * Name : HMCreateThread
3966 * Purpose : router function for CreateThread
3967 * Parameters:
3968 * Variables :
3969 * Result :
3970 * Remark :
3971 * Status :
3972 *
3973 * Author : SvL
3974 *****************************************************************************/
3975HANDLE HMCreateThread(LPSECURITY_ATTRIBUTES lpsa,
3976 DWORD cbStack,
3977 LPTHREAD_START_ROUTINE lpStartAddr,
3978 LPVOID lpvThreadParm,
3979 DWORD fdwCreate,
3980 LPDWORD lpIDThread,
3981 BOOL fFirstThread)
3982{
3983 int iIndex; /* index into the handle table */
3984 int iIndexNew; /* index into the handle table */
3985 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3986 PHMHANDLEDATA pHMHandleData;
3987 HANDLE rc; /* API return code */
3988
3989 SetLastError(ERROR_SUCCESS);
3990
3991 pDeviceHandler = HMGlobals.pHMThread; /* device is predefined */
3992
3993 iIndexNew = _HMHandleGetFree(); /* get free handle */
3994 if (-1 == iIndexNew) /* oops, no free handles ! */
3995 {
3996 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3997 return 0;
3998 }
3999
4000 /* initialize the complete HMHANDLEDATA structure */
4001 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
4002 pHMHandleData->dwAccess = 0;
4003 pHMHandleData->dwShare = 0;
4004 pHMHandleData->dwCreation = 0;
4005 pHMHandleData->dwFlags = 0;
4006 pHMHandleData->lpHandlerData = NULL;
4007
4008
4009 /* we've got to mark the handle as occupied here, since another device */
4010 /* could be created within the device handler -> deadlock */
4011
4012 /* write appropriate entry into the handle table if open succeeded */
4013 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
4014 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
4015
4016 /* call the device handler */
4017
4018 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
4019 // a valid HandleManager-internal handle!
4020 rc = pDeviceHandler->CreateThread(&TabWin32Handles[iIndexNew].hmHandleData,
4021 lpsa, cbStack, lpStartAddr,
4022 lpvThreadParm, fdwCreate, lpIDThread, fFirstThread);
4023
4024 if (rc == 0) /* oops, creation failed within the device handler */
4025 {
4026 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
4027 return 0; /* signal error */
4028 }
4029
4030 return iIndexNew;
4031}
4032/*****************************************************************************
4033 * Name : HMGetThreadPriority
4034 * Purpose : router function for GetThreadPriority
4035 * Parameters:
4036 * Variables :
4037 * Result :
4038 * Remark :
4039 * Status :
4040 *
4041 * Author : SvL
4042 *****************************************************************************/
4043INT HMGetThreadPriority(HANDLE hThread)
4044{
4045 int iIndex; /* index into the handle table */
4046 INT lpResult; /* result from the device handler's API */
4047 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4048
4049 SetLastError(ERROR_SUCCESS);
4050 /* validate handle */
4051 iIndex = _HMHandleQuery(hThread); /* get the index */
4052 if (-1 == iIndex) /* error ? */
4053 {
4054 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4055 return (-1); /* signal failure */
4056 }
4057
4058 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4059 lpResult = pHMHandle->pDeviceHandler->GetThreadPriority(hThread, &TabWin32Handles[iIndex].hmHandleData);
4060
4061 return (lpResult); /* deliver return code */
4062}
4063/*****************************************************************************
4064 * Name : HMSuspendThread
4065 * Purpose : router function for SuspendThread
4066 * Parameters:
4067 * Variables :
4068 * Result :
4069 * Remark :
4070 * Status :
4071 *
4072 * Author : SvL
4073 *****************************************************************************/
4074DWORD HMSuspendThread(HANDLE hThread)
4075{
4076 int iIndex; /* index into the handle table */
4077 HANDLE lpResult; /* result from the device handler's API */
4078 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4079
4080 SetLastError(ERROR_SUCCESS);
4081 /* validate handle */
4082 iIndex = _HMHandleQuery(hThread); /* get the index */
4083 if (-1 == iIndex) /* error ? */
4084 {
4085 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4086 return -1; /* signal failure */
4087 }
4088
4089 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4090 lpResult = pHMHandle->pDeviceHandler->SuspendThread(hThread, &TabWin32Handles[iIndex].hmHandleData);
4091
4092 return (lpResult); /* deliver return code */
4093}
4094/*****************************************************************************
4095 * Name : HMSetThreadPriority
4096 * Purpose : router function for SetThreadPriority
4097 * Parameters:
4098 * Variables :
4099 * Result :
4100 * Remark :
4101 * Status :
4102 *
4103 * Author : SvL
4104 *****************************************************************************/
4105BOOL HMSetThreadPriority(HANDLE hThread, int priority)
4106{
4107 int iIndex; /* index into the handle table */
4108 BOOL lpResult; /* result from the device handler's API */
4109 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4110
4111 SetLastError(ERROR_SUCCESS);
4112 /* validate handle */
4113 iIndex = _HMHandleQuery(hThread); /* get the index */
4114 if (-1 == iIndex) /* error ? */
4115 {
4116 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4117 return FALSE; /* signal failure */
4118 }
4119
4120 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4121 lpResult = pHMHandle->pDeviceHandler->SetThreadPriority(hThread, &TabWin32Handles[iIndex].hmHandleData, priority);
4122
4123 return (lpResult); /* deliver return code */
4124}
4125/*****************************************************************************
4126 * Name : HMGetThreadContext
4127 * Purpose : router function for GetThreadContext
4128 * Parameters:
4129 * Variables :
4130 * Result :
4131 * Remark :
4132 * Status :
4133 *
4134 * Author : SvL
4135 *****************************************************************************/
4136BOOL HMGetThreadContext(HANDLE hThread, CONTEXT *lpContext)
4137{
4138 int iIndex; /* index into the handle table */
4139 BOOL lpResult; /* result from the device handler's API */
4140 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4141
4142 SetLastError(ERROR_SUCCESS);
4143 /* validate handle */
4144 iIndex = _HMHandleQuery(hThread); /* get the index */
4145 if (-1 == iIndex) /* error ? */
4146 {
4147 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4148 return FALSE; /* signal failure */
4149 }
4150
4151 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4152 lpResult = pHMHandle->pDeviceHandler->GetThreadContext(hThread, &TabWin32Handles[iIndex].hmHandleData, lpContext);
4153
4154 return (lpResult); /* deliver return code */
4155}
4156/*****************************************************************************
4157 * Name : HMSetThreadContext
4158 * Purpose : router function for SetThreadContext
4159 * Parameters:
4160 * Variables :
4161 * Result :
4162 * Remark :
4163 * Status :
4164 *
4165 * Author : SvL
4166 *****************************************************************************/
4167BOOL HMSetThreadContext(HANDLE hThread, const CONTEXT *lpContext)
4168{
4169 int iIndex; /* index into the handle table */
4170 BOOL lpResult; /* result from the device handler's API */
4171 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4172
4173 SetLastError(ERROR_SUCCESS);
4174 /* validate handle */
4175 iIndex = _HMHandleQuery(hThread); /* get the index */
4176 if (-1 == iIndex) /* error ? */
4177 {
4178 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4179 return FALSE; /* signal failure */
4180 }
4181
4182 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4183 lpResult = pHMHandle->pDeviceHandler->SetThreadContext(hThread, &TabWin32Handles[iIndex].hmHandleData, lpContext);
4184
4185 return (lpResult); /* deliver return code */
4186}
4187/*****************************************************************************
4188 * Name : HMTerminateThread
4189 * Purpose : router function for TerminateThread
4190 * Parameters:
4191 * Variables :
4192 * Result :
4193 * Remark :
4194 * Status :
4195 *
4196 * Author : SvL
4197 *****************************************************************************/
4198BOOL HMTerminateThread(HANDLE hThread, DWORD exitcode)
4199{
4200 int iIndex; /* index into the handle table */
4201 BOOL lpResult; /* result from the device handler's API */
4202 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4203
4204 SetLastError(ERROR_SUCCESS);
4205 /* validate handle */
4206 iIndex = _HMHandleQuery(hThread); /* get the index */
4207 if (-1 == iIndex) /* error ? */
4208 {
4209 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4210 return FALSE; /* signal failure */
4211 }
4212
4213 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4214 lpResult = pHMHandle->pDeviceHandler->TerminateThread(hThread, &TabWin32Handles[iIndex].hmHandleData, exitcode);
4215
4216 return (lpResult); /* deliver return code */
4217}
4218/*****************************************************************************
4219 * Name : HMResumeThread
4220 * Purpose : router function for ResumeThread
4221 * Parameters:
4222 * Variables :
4223 * Result :
4224 * Remark :
4225 * Status :
4226 *
4227 * Author : SvL
4228 *****************************************************************************/
4229DWORD HMResumeThread(HANDLE hThread)
4230{
4231 int iIndex; /* index into the handle table */
4232 DWORD lpResult; /* result from the device handler's API */
4233 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4234
4235 SetLastError(ERROR_SUCCESS);
4236 /* validate handle */
4237 iIndex = _HMHandleQuery(hThread); /* get the index */
4238 if (-1 == iIndex) /* error ? */
4239 {
4240 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4241 return -1; /* signal failure */
4242 }
4243
4244 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4245 lpResult = pHMHandle->pDeviceHandler->ResumeThread(hThread, &TabWin32Handles[iIndex].hmHandleData);
4246
4247 return (lpResult); /* deliver return code */
4248}
4249
4250/*****************************************************************************
4251 * Name : HMGetExitCodeThread
4252 * Purpose : router function for GetExitCodeThread
4253 * Parameters:
4254 * Variables :
4255 * Result :
4256 * Remark :
4257 * Status :
4258 *
4259 * Author : SvL
4260 *****************************************************************************/
4261BOOL HMGetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)
4262{
4263 int iIndex; /* index into the handle table */
4264 BOOL lpResult; /* result from the device handler's API */
4265 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4266
4267 SetLastError(ERROR_SUCCESS);
4268 /* validate handle */
4269 iIndex = _HMHandleQuery(hThread); /* get the index */
4270 if (-1 == iIndex) /* error ? */
4271 {
4272 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4273 return FALSE; /* signal failure */
4274 }
4275
4276 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4277 lpResult = pHMHandle->pDeviceHandler->GetExitCodeThread(hThread, &TabWin32Handles[iIndex].hmHandleData, lpExitCode);
4278
4279 return (lpResult); /* deliver return code */
4280}
4281/*****************************************************************************
4282 * Name : HMSetThreadTerminated
4283 * Purpose :
4284 * Parameters:
4285 * Variables :
4286 * Result :
4287 * Remark :
4288 * Status :
4289 *
4290 * Author : SvL
4291 *****************************************************************************/
4292BOOL HMSetThreadTerminated(HANDLE hThread)
4293{
4294 int iIndex; /* index into the handle table */
4295 BOOL lpResult; /* result from the device handler's API */
4296 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4297
4298 SetLastError(ERROR_SUCCESS);
4299 /* validate handle */
4300 iIndex = _HMHandleQuery(hThread); /* get the index */
4301 if (-1 == iIndex) /* error ? */
4302 {
4303 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4304 return FALSE; /* signal failure */
4305 }
4306
4307 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4308 lpResult = pHMHandle->pDeviceHandler->SetThreadTerminated(hThread, &TabWin32Handles[iIndex].hmHandleData);
4309
4310 return (lpResult); /* deliver return code */
4311}
4312
4313/*****************************************************************************
4314 * Name : HMPeekNamedPipe
4315 * Purpose :
4316 * Parameters:
4317 * Variables :
4318 * Result :
4319 * Remark :
4320 * Status :
4321 *
4322 * Author : Przemyslaw Dobrowolski
4323 *****************************************************************************/
4324BOOL HMPeekNamedPipe(HANDLE hPipe,
4325 LPVOID lpvBuffer,
4326 DWORD cbBuffer,
4327 LPDWORD lpcbRead,
4328 LPDWORD lpcbAvail,
4329 LPDWORD lpcbMessage)
4330{
4331 int iIndex; /* index into the handle table */
4332 BOOL lpResult; /* result from the device handler's API */
4333 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4334
4335 SetLastError(ERROR_SUCCESS);
4336 /* validate handle */
4337 iIndex = _HMHandleQuery(hPipe); /* get the index */
4338 if (-1 == iIndex) /* error ? */
4339 {
4340 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4341 return FALSE; /* signal failure */
4342 }
4343
4344 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4345 lpResult = pHMHandle->pDeviceHandler->PeekNamedPipe(&TabWin32Handles[iIndex].hmHandleData,
4346 lpvBuffer,
4347 cbBuffer,
4348 lpcbRead,
4349 lpcbAvail,
4350 lpcbMessage);
4351
4352 return (lpResult); /* deliver return code */
4353}
4354
4355/*****************************************************************************
4356 * Name : HMCreateNamedPipe
4357 * Purpose :
4358 * Parameters:
4359 * Variables :
4360 * Result :
4361 * Remark :
4362 * Status :
4363 *
4364 * Author : Przemyslaw Dobrowolski
4365 *****************************************************************************/
4366DWORD HMCreateNamedPipe(LPCTSTR lpName,
4367 DWORD dwOpenMode,
4368 DWORD dwPipeMode,
4369 DWORD nMaxInstances,
4370 DWORD nOutBufferSize,
4371 DWORD nInBufferSize,
4372 DWORD nDefaultTimeOut,
4373 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
4374{
4375 int iIndex; /* index into the handle table */
4376 int iIndexNew; /* index into the handle table */
4377 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
4378 PHMHANDLEDATA pHMHandleData;
4379 HANDLE rc; /* API return code */
4380
4381 SetLastError(ERROR_SUCCESS);
4382
4383 pDeviceHandler = HMGlobals.pHMNamedPipe; /* device is predefined */
4384
4385 iIndexNew = _HMHandleGetFree(); /* get free handle */
4386 if (-1 == iIndexNew) /* oops, no free handles ! */
4387 {
4388 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
4389 return 0;
4390 }
4391
4392 /* initialize the complete HMHANDLEDATA structure */
4393 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
4394 pHMHandleData->dwAccess = 0;
4395 pHMHandleData->dwShare = 0;
4396 pHMHandleData->dwCreation = 0;
4397 pHMHandleData->dwFlags = 0;
4398 pHMHandleData->lpHandlerData = NULL;
4399
4400 /* we've got to mark the handle as occupied here, since another device */
4401 /* could be created within the device handler -> deadlock */
4402
4403 /* write appropriate entry into the handle table if open succeeded */
4404 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
4405 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
4406
4407 /* call the device handler */
4408
4409 rc = pDeviceHandler->CreateNamedPipe(&TabWin32Handles[iIndexNew].hmHandleData,
4410 lpName,dwOpenMode,
4411 dwPipeMode,nMaxInstances,
4412 nOutBufferSize,nInBufferSize,
4413 nDefaultTimeOut,lpSecurityAttributes);
4414
4415 if (rc == -1) /* oops, creation failed within the device handler */
4416 {
4417 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
4418 return 0; /* signal error */
4419 }
4420
4421 return iIndexNew;
4422}
4423
4424/*****************************************************************************
4425 * Name : HMConnectNamedPipe
4426 * Purpose :
4427 * Parameters:
4428 * Variables :
4429 * Result :
4430 * Remark :
4431 * Status :
4432 *
4433 * Author : Przemyslaw Dobrowolski
4434 *****************************************************************************/
4435BOOL HMConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED lpOverlapped)
4436{
4437 int iIndex; /* index into the handle table */
4438 BOOL lpResult; /* result from the device handler's API */
4439 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4440
4441 SetLastError(ERROR_SUCCESS);
4442 /* validate handle */
4443 iIndex = _HMHandleQuery(hPipe); /* get the index */
4444 if (-1 == iIndex) /* error ? */
4445 {
4446 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4447 return FALSE; /* signal failure */
4448 }
4449
4450 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4451 lpResult = pHMHandle->pDeviceHandler->ConnectNamedPipe(&TabWin32Handles[iIndex].hmHandleData,
4452 lpOverlapped);
4453
4454 return (lpResult); /* deliver return code */
4455}
4456
4457/*****************************************************************************
4458 * Name : HMDisconnectNamedPipe
4459 * Purpose :
4460 * Parameters:
4461 * Variables :
4462 * Result :
4463 * Remark :
4464 * Status :
4465 *
4466 * Author : Przemyslaw Dobrowolski
4467 *****************************************************************************/
4468BOOL HMDisconnectNamedPipe(HANDLE hPipe)
4469{
4470 int iIndex; /* index into the handle table */
4471 BOOL lpResult; /* result from the device handler's API */
4472 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4473
4474 SetLastError(ERROR_SUCCESS);
4475 /* validate handle */
4476 iIndex = _HMHandleQuery(hPipe); /* get the index */
4477 if (-1 == iIndex) /* error ? */
4478 {
4479 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4480 return FALSE; /* signal failure */
4481 }
4482
4483 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4484 lpResult = pHMHandle->pDeviceHandler->DisconnectNamedPipe(&TabWin32Handles[iIndex].hmHandleData);
4485
4486 return (lpResult); /* deliver return code */
4487}
4488
4489/*****************************************************************************
4490 * Name : HMGetNamedPipeHandleState
4491 * Purpose :
4492 * Parameters:
4493 * Variables :
4494 * Result :
4495 * Remark :
4496 * Status :
4497 *
4498 * Author : Przemyslaw Dobrowolski
4499 *****************************************************************************/
4500BOOL HMGetNamedPipeHandleState(HANDLE hPipe,
4501 LPDWORD lpState,
4502 LPDWORD lpCurInstances,
4503 LPDWORD lpMaxCollectionCount,
4504 LPDWORD lpCollectDataTimeout,
4505 LPTSTR lpUserName,
4506 DWORD nMaxUserNameSize)
4507{
4508 int iIndex; /* index into the handle table */
4509 BOOL lpResult; /* result from the device handler's API */
4510 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4511
4512 SetLastError(ERROR_SUCCESS);
4513 /* validate handle */
4514 iIndex = _HMHandleQuery(hPipe); /* get the index */
4515 if (-1 == iIndex) /* error ? */
4516 {
4517 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4518 return FALSE; /* signal failure */
4519 }
4520
4521 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4522 lpResult = pHMHandle->pDeviceHandler->GetNamedPipeHandleState(&TabWin32Handles[iIndex].hmHandleData,
4523 lpState,
4524 lpCurInstances,
4525 lpMaxCollectionCount,
4526 lpCollectDataTimeout,
4527 lpUserName,
4528 nMaxUserNameSize);
4529
4530
4531 return (lpResult); /* deliver return code */
4532}
4533
4534/*****************************************************************************
4535 * Name : HMGetNamedPipeInfo
4536 * Purpose :
4537 * Parameters:
4538 * Variables :
4539 * Result :
4540 * Remark :
4541 * Status :
4542 *
4543 * Author : Przemyslaw Dobrowolski
4544 *****************************************************************************/
4545BOOL HMGetNamedPipeInfo(HANDLE hPipe,
4546 LPDWORD lpFlags,
4547 LPDWORD lpOutBufferSize,
4548 LPDWORD lpInBufferSize,
4549 LPDWORD lpMaxInstances)
4550{
4551 int iIndex; /* index into the handle table */
4552 BOOL lpResult; /* result from the device handler's API */
4553 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4554
4555 SetLastError(ERROR_SUCCESS);
4556 /* validate handle */
4557 iIndex = _HMHandleQuery(hPipe); /* get the index */
4558 if (-1 == iIndex) /* error ? */
4559 {
4560 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4561 return FALSE; /* signal failure */
4562 }
4563
4564 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4565 lpResult = pHMHandle->pDeviceHandler->GetNamedPipeInfo(&TabWin32Handles[iIndex].hmHandleData,
4566 lpFlags,
4567 lpOutBufferSize,
4568 lpInBufferSize,
4569 lpMaxInstances);
4570
4571 return (lpResult); /* deliver return code */
4572}
4573
4574/*****************************************************************************
4575 * Name : HMTransactNamedPipe
4576 * Purpose :
4577 * Parameters:
4578 * Variables :
4579 * Result :
4580 * Remark :
4581 * Status :
4582 *
4583 * Author : Przemyslaw Dobrowolski
4584 *****************************************************************************/
4585DWORD HMTransactNamedPipe(HANDLE hPipe,
4586 LPVOID lpvWriteBuf,
4587 DWORD cbWriteBuf,
4588 LPVOID lpvReadBuf,
4589 DWORD cbReadBuf,
4590 LPDWORD lpcbRead,
4591 LPOVERLAPPED lpo)
4592{
4593 int iIndex; /* index into the handle table */
4594 DWORD lpResult; /* result from the device handler's API */
4595 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4596
4597 SetLastError(ERROR_SUCCESS);
4598 /* validate handle */
4599 iIndex = _HMHandleQuery(hPipe); /* get the index */
4600 if (-1 == iIndex) /* error ? */
4601 {
4602 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4603 return FALSE; /* signal failure */
4604 }
4605
4606 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4607 lpResult = pHMHandle->pDeviceHandler->TransactNamedPipe(&TabWin32Handles[iIndex].hmHandleData,
4608 lpvWriteBuf,
4609 cbWriteBuf,
4610 lpvReadBuf,
4611 cbReadBuf,
4612 lpcbRead,
4613 lpo);
4614
4615 return (lpResult); /* deliver return code */
4616}
4617
4618/*****************************************************************************
4619 * Name : HMSetNamedPipeHandleState
4620 * Purpose :
4621 * Parameters:
4622 * Variables :
4623 * Result :
4624 * Remark :
4625 * Status :
4626 *
4627 * Author : Przemyslaw Dobrowolski
4628 *****************************************************************************/
4629BOOL HMSetNamedPipeHandleState(HANDLE hPipe,
4630 LPDWORD lpdwMode,
4631 LPDWORD lpcbMaxCollect,
4632 LPDWORD lpdwCollectDataTimeout)
4633{
4634 int iIndex; /* index into the handle table */
4635 BOOL lpResult; /* result from the device handler's API */
4636 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4637
4638 SetLastError(ERROR_SUCCESS);
4639 /* validate handle */
4640 iIndex = _HMHandleQuery(hPipe); /* get the index */
4641 if (-1 == iIndex) /* error ? */
4642 {
4643 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4644 return FALSE; /* signal failure */
4645 }
4646
4647 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4648 lpResult = pHMHandle->pDeviceHandler->SetNamedPipeHandleState(&TabWin32Handles[iIndex].hmHandleData,
4649 lpdwMode,
4650 lpcbMaxCollect,
4651 lpdwCollectDataTimeout);
4652
4653 return (lpResult); /* deliver return code */
4654}
4655
4656/*****************************************************************************
4657 * Name : HMCreatePipe
4658 * Purpose :
4659 * Parameters:
4660 * Variables :
4661 * Result :
4662 * Remark :
4663 * Status : NOT TESTED!
4664 *
4665 * Author : Przemyslaw Dobrowolski
4666 *****************************************************************************/
4667BOOL HMCreatePipe(PHANDLE phRead,
4668 PHANDLE phWrite,
4669 LPSECURITY_ATTRIBUTES lpsa,
4670 DWORD cbPipe)
4671{
4672 int iIndex; /* index into the handle table */
4673 int iIndexNewRead; /* index into the handle table */
4674 int iIndexNewWrite; /* index into the handle table */
4675 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
4676 PHMHANDLEDATA pHMHandleData;
4677 HANDLE rc; /* API return code */
4678
4679 SetLastError(ERROR_SUCCESS);
4680
4681 pDeviceHandler = HMGlobals.pHMNamedPipe; /* device is predefined */
4682
4683 iIndexNewRead = _HMHandleGetFree(); /* get free handle */
4684 if (-1 == iIndexNewRead) /* oops, no free handles ! */
4685 {
4686 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
4687 return 0;
4688 }
4689
4690 iIndexNewWrite = _HMHandleGetFree(); /* get free handle */
4691 if (-1 == iIndexNewWrite) /* oops, no free handles ! */
4692 {
4693 HMHandleFree(iIndexNewRead);
4694 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
4695 return 0;
4696 }
4697
4698
4699 /* initialize the complete HMHANDLEDATA structure */
4700 pHMHandleData = &TabWin32Handles[iIndexNewRead].hmHandleData;
4701 pHMHandleData->dwAccess = 0;
4702 pHMHandleData->dwShare = 0;
4703 pHMHandleData->dwCreation = 0;
4704 pHMHandleData->dwFlags = 0;
4705 pHMHandleData->lpHandlerData = NULL;
4706
4707 /* we've got to mark the handle as occupied here, since another device */
4708 /* could be created within the device handler -> deadlock */
4709
4710 /* write appropriate entry into the handle table if open succeeded */
4711 TabWin32Handles[iIndexNewRead].hmHandleData.hHMHandle = iIndexNewRead;
4712 TabWin32Handles[iIndexNewRead].pDeviceHandler = pDeviceHandler;
4713
4714 /* initialize the complete HMHANDLEDATA structure */
4715 pHMHandleData = &TabWin32Handles[iIndexNewWrite].hmHandleData;
4716 pHMHandleData->dwAccess = 0;
4717 pHMHandleData->dwShare = 0;
4718 pHMHandleData->dwCreation = 0;
4719 pHMHandleData->dwFlags = 0;
4720 pHMHandleData->lpHandlerData = NULL;
4721
4722 /* we've got to mark the handle as occupied here, since another device */
4723 /* could be created within the device handler -> deadlock */
4724
4725 /* write appropriate entry into the handle table if open succeeded */
4726 TabWin32Handles[iIndexNewWrite].hmHandleData.hHMHandle = iIndexNewWrite;
4727 TabWin32Handles[iIndexNewWrite].pDeviceHandler = pDeviceHandler;
4728 /* call the device handler */
4729
4730 rc = pDeviceHandler->CreatePipe(&TabWin32Handles[iIndexNewRead].hmHandleData,
4731 &TabWin32Handles[iIndexNewWrite].hmHandleData,
4732 lpsa,
4733 cbPipe);
4734
4735 if (rc == 0) /* oops, creation failed within the device handler */
4736 {
4737 HMHandleFree(iIndexNewRead);
4738 HMHandleFree(iIndexNewWrite);
4739 return FALSE; /* signal error */
4740 }
4741
4742 *phRead = iIndexNewRead;
4743 *phWrite = iIndexNewWrite;
4744
4745 return TRUE;
4746}
4747
4748/*****************************************************************************
4749 * Name : HMCreateMailslotA
4750 * Purpose :
4751 * Parameters:
4752 * Variables :
4753 * Result :
4754 * Remark :
4755 * Status :
4756 *
4757 * Author : SvL
4758 *****************************************************************************/
4759HANDLE HMCreateMailslotA(LPCSTR lpName, DWORD nMaxMessageSize,
4760 DWORD lReadTimeout,
4761 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
4762{
4763 int iIndex; /* index into the handle table */
4764 int iIndexNew; /* index into the handle table */
4765 HMMailslotClass *pDeviceHandler; /* device handler for this handle */
4766 PHMHANDLEDATA pHMHandleData;
4767 BOOL rc; /* API return code */
4768
4769 SetLastError(ERROR_SUCCESS);
4770
4771 pDeviceHandler = (HMMailslotClass *)HMGlobals.pHMMailslot; /* device is predefined */
4772
4773 iIndexNew = _HMHandleGetFree(); /* get free handle */
4774 if (-1 == iIndexNew) /* oops, no free handles ! */
4775 {
4776 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
4777 return 0;
4778 }
4779
4780 /* initialize the complete HMHANDLEDATA structure */
4781 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
4782 pHMHandleData->dwAccess = 0;
4783 pHMHandleData->dwShare = 0;
4784 pHMHandleData->dwCreation = 0;
4785 pHMHandleData->dwFlags = 0;
4786 pHMHandleData->lpHandlerData = NULL;
4787
4788 /* we've got to mark the handle as occupied here, since another device */
4789 /* could be created within the device handler -> deadlock */
4790
4791 /* write appropriate entry into the handle table if open succeeded */
4792 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
4793 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
4794
4795 /* call the device handler */
4796
4797 rc = pDeviceHandler->CreateMailslotA(&TabWin32Handles[iIndexNew].hmHandleData,
4798 lpName, nMaxMessageSize,
4799 lReadTimeout, lpSecurityAttributes);
4800
4801 if (rc == FALSE) /* oops, creation failed within the device handler */
4802 {
4803 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
4804 return 0; /* signal error */
4805 }
4806
4807 return iIndexNew;
4808}
4809/*****************************************************************************
4810 * Name : HMGetMailslotInfo
4811 * Purpose :
4812 * Parameters:
4813 * Variables :
4814 * Result :
4815 * Remark :
4816 * Status :
4817 *
4818 * Author : SvL
4819 *****************************************************************************/
4820BOOL HMGetMailslotInfo(HANDLE hMailslot,
4821 LPDWORD lpMaxMessageSize,
4822 LPDWORD lpNextSize,
4823 LPDWORD lpMessageCount,
4824 LPDWORD lpReadTimeout)
4825{
4826 int iIndex; /* index into the handle table */
4827 BOOL lpResult; /* result from the device handler's API */
4828 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4829
4830 SetLastError(ERROR_SUCCESS);
4831 /* validate handle */
4832 iIndex = _HMHandleQuery(hMailslot); /* get the index */
4833 if (-1 == iIndex) /* error ? */
4834 {
4835 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4836 return FALSE; /* signal failure */
4837 }
4838
4839 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4840 lpResult = pHMHandle->pDeviceHandler->GetMailslotInfo(&TabWin32Handles[iIndex].hmHandleData,
4841 lpMaxMessageSize,
4842 lpNextSize,
4843 lpMessageCount,
4844 lpReadTimeout);
4845 return (lpResult); /* deliver return code */
4846}
4847/*****************************************************************************
4848 * Name : HMSetMailslotInfo
4849 * Purpose :
4850 * Parameters:
4851 * Variables :
4852 * Result :
4853 * Remark :
4854 * Status :
4855 *
4856 * Author : SvL
4857 *****************************************************************************/
4858BOOL HMSetMailslotInfo(HANDLE hMailslot,
4859 DWORD dwReadTimeout)
4860{
4861 int iIndex; /* index into the handle table */
4862 BOOL lpResult; /* result from the device handler's API */
4863 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
4864
4865 SetLastError(ERROR_SUCCESS);
4866 /* validate handle */
4867 iIndex = _HMHandleQuery(hMailslot); /* get the index */
4868 if (-1 == iIndex) /* error ? */
4869 {
4870 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
4871 return FALSE; /* signal failure */
4872 }
4873
4874 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
4875 lpResult = pHMHandle->pDeviceHandler->SetMailslotInfo(&TabWin32Handles[iIndex].hmHandleData,
4876 dwReadTimeout);
4877
4878 return (lpResult); /* deliver return code */
4879}
Note: See TracBrowser for help on using the repository browser.