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

Last change on this file since 10064 was 10064, checked in by sandervl, 22 years ago

Handle files opened with 0 for dwDesiredAccess seperately

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