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

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

kernel32: Use file/pipe device classes when standard handles are redirected/piped.

This fixes working with standard handles (stdin/stdout/stderr) broken after r22024.

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