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

Last change on this file since 21302 was 21302, checked in by ydario, 16 years ago

Kernel32 updates.

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