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

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

DF: Console updates

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