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

Last change on this file since 22024 was 22024, checked in by dmik, 13 years ago

kernel32: Fix inverted return values in dummy HMDeviceHandler implementations.

This in particular affected GetFileInformationByHandle and other APIs. Some applications
(like Flash 10.1+) could be completely confused by the fact that the unimplemented API
returns success.

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