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

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

WaitForSingleObject/(Msg)WaitForMultipleObject fixes to prevent thread priorities from being accidentally boosted to time critical

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