source: trunk/src/kernel32/HandleManager.cpp

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

kernel32: Use console input/output mode only if handle is attached to a real console.

Previously it would use this mode (which reads/writes directly to the attached VIO window)
for all character devices (e.g. NUL) which was clearly wrong.

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 DWORD type = OSLibDosQueryHType(handle, NULL);
1117 switch (type & 0x7)
1118 {
1119 case 0: /* disk file */
1120 {
1121 pHMHandleData->hHMHandle = handle;
1122 TabWin32Handles[hHandle].pDeviceHandler = HMGlobals.pHMFile;
1123 break;
1124 }
1125 case 1: /* character device */
1126 {
1127 // Note: we use a simple read/write device by default;
1128 // if this is a console application, iConsoleInit() will set up
1129 // proper devices with extended functionality
1130 pHMHandleData->hHMHandle = O32_GetStdHandle(nStdHandle);
1131 TabWin32Handles[hHandle].pDeviceHandler = HMGlobals.pHMStandard;
1132 break;
1133 }
1134 case 2: /* pipe */
1135 {
1136 pHMHandleData->hHMHandle = handle;
1137 TabWin32Handles[hHandle].pDeviceHandler = HMGlobals.pHMNamedPipe;
1138 break;
1139 }
1140 default:
1141 {
1142 SetLastError(ERROR_SYS_INTERNAL); /* set error information */
1143 return (FALSE); /* raise error condition */
1144 }
1145 }
1146
1147 return TRUE;
1148}
1149
1150/*****************************************************************************
1151 * Name : HANDLE _HMSetStdHandle
1152 * Purpose : replacement for Open32's SetStdHandle function
1153 * Parameters: DWORD nStdHandle
1154 * HANDLE hHandle
1155 * Variables :
1156 * Result : BOOL fSuccess
1157 * Remark :
1158 * Status :
1159 *
1160 * Author : Dmitry Froloff [Thu, 2003/03/03 17:44]
1161 *****************************************************************************/
1162
1163BOOL HMSetStdHandle(DWORD nStdHandle, HANDLE hHandle)
1164{
1165 switch (nStdHandle)
1166 {
1167 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
1168 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
1169 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
1170
1171 default:
1172 {
1173 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
1174 return (FALSE); /* raise error condition */
1175 }
1176 }
1177}
1178
1179
1180/*****************************************************************************
1181 * Name : HANDLE HMDuplicateHandle
1182 * Purpose : replacement for Open32's HMDuplicateHandle function
1183 * Parameters:
1184 *
1185 * Variables :
1186 * Result : BOOL fSuccess
1187 * Remark :
1188 * Status :
1189 *
1190 * Author : Sander van Leeuwen [Wed, 1999/08/25 15:44]
1191 *****************************************************************************/
1192
1193BOOL HMDuplicateHandle(HANDLE srcprocess,
1194 HANDLE srchandle,
1195 HANDLE destprocess,
1196 PHANDLE desthandle,
1197 DWORD fdwAccess,
1198 BOOL fInherit,
1199 DWORD fdwOptions)
1200{
1201 int iIndex; /* index into the handle table */
1202 int iIndexNew; /* index into the handle table */
1203 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1204 PHMHANDLEDATA pHMHandleData;
1205 BOOL rc; /* API return code */
1206
1207 if(HMHandleValidate(srchandle) != NO_ERROR)
1208 {
1209 dprintf(("KERNEL32: HMDuplicateHandle: invalid handle %x", srchandle));
1210 SetLastError(ERROR_INVALID_HANDLE); /* use this as error message */
1211 return FALSE;
1212 }
1213
1214 pDeviceHandler = TabWin32Handles[srchandle].pDeviceHandler; /* device is predefined */
1215 iIndexNew = _HMHandleGetFree(); /* get free handle */
1216 if (-1 == iIndexNew) /* oops, no free handles ! */
1217 {
1218 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1219 return FALSE; /* signal error */
1220 }
1221
1222 /* initialize the complete HMHANDLEDATA structure */
1223 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
1224 if (fdwOptions & DUPLICATE_SAME_ACCESS)
1225 pHMHandleData->dwAccess = TabWin32Handles[srchandle].hmHandleData.dwAccess;
1226 else
1227 pHMHandleData->dwAccess = fdwAccess;
1228
1229 pHMHandleData->dwShare = TabWin32Handles[srchandle].hmHandleData.dwShare;
1230 pHMHandleData->dwCreation = TabWin32Handles[srchandle].hmHandleData.dwCreation;
1231 pHMHandleData->dwFlags = TabWin32Handles[srchandle].hmHandleData.dwFlags;
1232 pHMHandleData->lpHandlerData = TabWin32Handles[srchandle].hmHandleData.lpHandlerData;
1233 pHMHandleData->dwInternalType = TabWin32Handles[srchandle].hmHandleData.dwInternalType;
1234
1235
1236 /* we've got to mark the handle as occupied here, since another device */
1237 /* could be created within the device handler -> deadlock */
1238
1239 /* write appropriate entry into the handle table if open succeeded */
1240 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
1241 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1242 /* call the device handler */
1243 rc = pDeviceHandler->DuplicateHandle(srchandle,
1244 &TabWin32Handles[iIndexNew].hmHandleData,
1245 srcprocess,
1246 &TabWin32Handles[srchandle].hmHandleData,
1247 destprocess,
1248 fdwAccess,
1249 fInherit,
1250 fdwOptions & ~DUPLICATE_CLOSE_SOURCE, 0);
1251
1252 //Don't let Open32 close it for us, but do it manually (regardless of error; see SDK docs))
1253 if (fdwOptions & DUPLICATE_CLOSE_SOURCE)
1254 HMCloseHandle(srchandle);
1255
1256 if(rc == FALSE) /* oops, creation failed within the device handler */
1257 {
1258// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1259 FREEHANDLE(iIndexNew);
1260 return FALSE; /* signal error */
1261 }
1262 else
1263 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1264
1265 *desthandle = iIndexNew;
1266 return TRUE; /* return valid handle */
1267}
1268
1269/*****************************************************************************
1270 * Name : HANDLE HMCreateFile
1271 * Purpose : Wrapper for the CreateFile() API
1272 * Parameters:
1273 * Variables :
1274 * Result :
1275 * Remark : Fix parameters passed to the HMDeviceManager::CreateFile
1276 * Supply access mode and share mode validation routines
1277 * Status :
1278 *
1279 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1280 *****************************************************************************/
1281
1282HANDLE HMCreateFile(LPCSTR lpFileName,
1283 DWORD dwDesiredAccess,
1284 DWORD dwShareMode,
1285 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1286 DWORD dwCreationDisposition,
1287 DWORD dwFlagsAndAttributes,
1288 HANDLE hTemplateFile)
1289{
1290 int iIndex; /* index into the handle table */
1291 int iIndexNew; /* index into the handle table */
1292 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1293 HANDLE hResult;
1294 DWORD rc; /* API return code */
1295 PHMHANDLEDATA pHMHandleData;
1296 HMHANDLEDATA HMHandleTemp; /* temporary buffer for handle data */
1297 VOID *pDevData;
1298
1299 /* create new handle by either lpFileName or hTemplateFile */
1300 if (lpFileName == NULL) /* this indicates creation from template */
1301 {
1302 iIndex = _HMHandleQuery(hTemplateFile); /* query table for template */
1303 if (-1 == iIndex) /* this device is unknown to us */
1304 {
1305 SetLastError (ERROR_INVALID_HANDLE);
1306 return INVALID_HANDLE_VALUE;
1307 }
1308 else
1309 {
1310 /* to pass to handler */
1311 pHMHandleData = &TabWin32Handles[iIndex].hmHandleData;
1312 pDeviceHandler = TabWin32Handles[iIndex].pDeviceHandler;
1313 }
1314 }
1315 else
1316 {
1317 // name resolving
1318 CHAR szFilename[260];
1319 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1320 szFilename,
1321 sizeof(szFilename),
1322 TRUE))
1323 {
1324 // use the resolved name
1325 lpFileName = szFilename;
1326 }
1327
1328
1329 pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1330 if (NULL == pDeviceHandler) /* this name is unknown to us */
1331 {
1332 SetLastError(ERROR_FILE_NOT_FOUND);
1333 return (INVALID_HANDLE_VALUE); /* signal error */
1334 }
1335 else
1336 pHMHandleData = NULL;
1337
1338 pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1339
1340 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1341 /* PF When create flag is set we do not care about zero in desired access
1342 verified in Win2k */
1343 if(dwDesiredAccess == 0 && dwCreationDisposition != CREATE_NEW) {
1344 dprintf(("File information access!"));
1345 pDeviceHandler = HMGlobals.pHMInfoFile;
1346 }
1347 else pDeviceHandler = HMGlobals.pHMFile;
1348 }
1349 }
1350
1351
1352 iIndexNew = _HMHandleGetFree(); /* get free handle */
1353 if (-1 == iIndexNew) /* oops, no free handles ! */
1354 {
1355 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1356 return (INVALID_HANDLE_VALUE); /* signal error */
1357 }
1358
1359
1360 /* initialize the complete HMHANDLEDATA structure */
1361 if (lpFileName == NULL) /* create from template */
1362 memcpy (&HMHandleTemp,
1363 &TabWin32Handles[iIndex].hmHandleData,
1364 sizeof(HMHANDLEDATA));
1365 else
1366 {
1367 memset(&HMHandleTemp, 0, sizeof(HMHandleTemp));
1368 HMHandleTemp.dwAccess = dwDesiredAccess;
1369 HMHandleTemp.dwShare = dwShareMode;
1370 HMHandleTemp.dwCreation = dwCreationDisposition;
1371 HMHandleTemp.dwFlags = dwFlagsAndAttributes;
1372 HMHandleTemp.hWin32Handle = iIndexNew;
1373 HMHandleTemp.lpDeviceData = pDevData;
1374 }
1375
1376 /* we've got to mark the handle as occupied here, since another device */
1377 /* could be created within the device handler -> deadlock */
1378
1379 /* write appropriate entry into the handle table if open succeeded */
1380 HMHandleTemp.hHMHandle = iIndexNew;
1381 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1382 /* now copy back our temporary handle data */
1383 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1384 &HMHandleTemp,
1385 sizeof(HMHANDLEDATA));
1386
1387 rc = pDeviceHandler->CreateFile(lpFileName, /* call the device handler */
1388 &HMHandleTemp,
1389 lpSecurityAttributes,
1390 pHMHandleData);
1391
1392#ifdef DEBUG_LOCAL
1393 dprintf(("KERNEL32/HandleManager:CheckPoint2: %s lpHandlerData=%08xh\n",
1394 lpFileName,
1395 HMHandleTemp.lpHandlerData));
1396#endif
1397
1398 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
1399 {
1400 FREEHANDLE(iIndexNew);
1401// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1402
1403 // Note:
1404 // device handlers have to return an Win32-style error code
1405 // from CreateFile() !
1406 SetLastError(rc);
1407 return (INVALID_HANDLE_VALUE); /* signal error */
1408 }
1409 else
1410 {
1411 /* copy data fields that might have been modified by CreateFile */
1412 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
1413 &HMHandleTemp,
1414 sizeof(HMHANDLEDATA));
1415
1416 if(lpSecurityAttributes && lpSecurityAttributes->bInheritHandle) {
1417 dprintf(("Set inheritance for child processes"));
1418 HMSetHandleInformation(iIndexNew, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
1419 }
1420
1421 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1422 }
1423
1424 return (HFILE)iIndexNew; /* return valid handle */
1425}
1426
1427
1428/*****************************************************************************
1429 * Name : HANDLE HMOpenFile
1430 * Purpose : Wrapper for the OpenFile() API
1431 * Parameters:
1432 * Variables :
1433 * Result :
1434 * Remark : Fix parameters passed to the HMDeviceManager::OpenFile
1435 * Supply access mode and share mode validation routines
1436 * Status :
1437 *
1438 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1439 *****************************************************************************/
1440
1441
1442/***********************************************************************
1443 * FILE_ConvertOFMode
1444 *
1445 * Convert OF_* mode into flags for CreateFile.
1446 */
1447static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
1448{
1449 switch(mode & 0x03)
1450 {
1451 case OF_READ: *access = GENERIC_READ; break;
1452 case OF_WRITE: *access = GENERIC_WRITE; break;
1453 case OF_READWRITE: *access = GENERIC_READ | GENERIC_WRITE; break;
1454 default: *access = 0; break;
1455 }
1456 switch(mode & 0x70)
1457 {
1458 case OF_SHARE_EXCLUSIVE: *sharing = 0; break;
1459 case OF_SHARE_DENY_WRITE: *sharing = FILE_SHARE_READ; break;
1460 case OF_SHARE_DENY_READ: *sharing = FILE_SHARE_WRITE; break;
1461 case OF_SHARE_DENY_NONE:
1462 case OF_SHARE_COMPAT:
1463 default: *sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; break;
1464 }
1465}
1466
1467HFILE WIN32API OpenFile(LPCSTR lpFileName, OFSTRUCT* pOFStruct,
1468 UINT fuMode)
1469{
1470 int iIndex; /* index into the handle table */
1471 int iIndexNew; /* index into the handle table */
1472 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
1473 VOID *pDevData;
1474 PHMHANDLEDATA pHMHandleData;
1475 DWORD rc; /* API return code */
1476
1477
1478 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
1479 lpFileName, pOFStruct, fuMode));
1480
1481 // name resolving
1482 CHAR szFilename[260];
1483 if (TRUE == HandleNamesResolveName((PSZ)lpFileName,
1484 szFilename,
1485 sizeof(szFilename),
1486 TRUE))
1487 {
1488 // use the resolved name
1489 lpFileName = szFilename;
1490 }
1491
1492
1493 if(fuMode & OF_REOPEN) {
1494 pDeviceHandler = _HMDeviceFind((LPSTR)pOFStruct->szPathName); /* find device */
1495 }
1496 else pDeviceHandler = _HMDeviceFind((LPSTR)lpFileName); /* find device */
1497 if (NULL == pDeviceHandler) /* this name is unknown to us */
1498 {
1499 SetLastError(ERROR_FILE_NOT_FOUND);
1500 return (INVALID_HANDLE_VALUE); /* signal error */
1501 }
1502 else
1503 pHMHandleData = NULL;
1504
1505 if(fuMode & OF_REOPEN) {
1506 pDevData = _HMDeviceGetData((LPSTR)pOFStruct->szPathName);
1507 }
1508 else pDevData = _HMDeviceGetData((LPSTR)lpFileName);
1509
1510
1511 if(pDeviceHandler == HMGlobals.pHMOpen32) {
1512 pDeviceHandler = HMGlobals.pHMFile;
1513 }
1514
1515 iIndexNew = _HMHandleGetFree(); /* get free handle */
1516 if (-1 == iIndexNew) /* oops, no free handles ! */
1517 {
1518 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
1519 return (INVALID_HANDLE_VALUE); /* signal error */
1520 }
1521
1522 /* initialize the complete HMHANDLEDATA structure */
1523 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
1524
1525 FILE_ConvertOFMode(fuMode, /* map OF_flags */
1526 &pHMHandleData->dwAccess,
1527 &pHMHandleData->dwShare);
1528
1529 //SvL; Must be OPEN_EXISTING because mmaps depend on it (to duplicate
1530 // the file handle when this handle is a parameter for CreateFileMappingA/W
1531 pHMHandleData->dwCreation = OPEN_EXISTING;
1532 pHMHandleData->dwFlags = 0;
1533 pHMHandleData->lpHandlerData = NULL;
1534 pHMHandleData->lpDeviceData = pDevData;
1535
1536 /* we've got to mark the handle as occupied here, since another device */
1537 /* could be created within the device handler -> deadlock */
1538
1539 /* write appropriate entry into the handle table if open succeeded */
1540 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
1541 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
1542
1543 rc = pDeviceHandler->OpenFile(lpFileName, /* call the device handler */
1544 &TabWin32Handles[iIndexNew].hmHandleData,
1545 pOFStruct,
1546 fuMode);
1547
1548#ifdef DEBUG_LOCAL
1549 dprintf(("KERNEL32/HandleManager:CheckPoint3: %s lpHandlerData=%08xh rc=%08xh\n",
1550 lpFileName,
1551 &TabWin32Handles[iIndexNew].hmHandleData.lpHandlerData,
1552 rc));
1553#endif
1554
1555 /*
1556 * Based on testcase (5) and MSDN:
1557 * "OF_PARSE Fills the OFSTRUCT structure but carries out no other action."
1558 */
1559 if (fuMode & OF_PARSE) {
1560 FREEHANDLE(iIndexNew);
1561// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1562 return 0;
1563 }
1564
1565 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
1566 {
1567 FREEHANDLE(iIndexNew);
1568// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1569 SetLastError(pOFStruct->nErrCode);
1570 return (INVALID_HANDLE_VALUE); /* signal error */
1571 }
1572 else {
1573 if(fuMode & (OF_DELETE|OF_EXIST)) {
1574 //file handle already closed
1575 FREEHANDLE(iIndexNew);
1576// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1577 return TRUE; //TODO: correct?
1578 }
1579
1580 if(fuMode & OF_VERIFY) {
1581 FREEHANDLE(iIndexNew);
1582// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
1583 return 1; //TODO: correct?
1584 }
1585 }
1586
1587#ifdef DEBUG_LOCAL
1588 dprintf(("KERNEL32/HandleManager: OpenFile(%s)=%08xh\n",
1589 lpFileName,
1590 iIndexNew));
1591#endif
1592
1593 return iIndexNew; /* return valid handle */
1594}
1595
1596/*****************************************************************************
1597 * Name : DWORD HMGetHandleInformation
1598 * Purpose : The GetHandleInformation function obtains information about certain
1599 * properties of an object handle. The information is obtained as a set of bit flags.
1600 * Parameters: HANDLE hObject
1601 * LPDWORD lpdwFlags
1602 * Variables :
1603 * Result : TRUE / FALSE
1604 * Remark :
1605 * Status :
1606 *
1607 * Author : SvL
1608 *****************************************************************************/
1609BOOL HMGetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags)
1610{
1611 int iIndex; /* index into the handle table */
1612 BOOL fResult; /* result from the device handler's CloseHandle() */
1613 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1614
1615 /* validate handle */
1616 iIndex = _HMHandleQuery(hObject); /* get the index */
1617 if (-1 == iIndex) /* error ? */
1618 {
1619 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1620 return (FALSE); /* signal failure */
1621 }
1622
1623 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1624
1625 //Handle information is stored in the handle structure; return it here
1626 if(lpdwFlags) {
1627 *lpdwFlags = pHMHandle->hmHandleData.dwHandleInformation;
1628 }
1629
1630 SetLastError(ERROR_SUCCESS);
1631 return TRUE; /* deliver return code */
1632}
1633
1634/*****************************************************************************
1635 * Name : BOOL HMSetHandleInformation
1636 * Purpose : The SetHandleInformation function sets certain properties of an
1637 * object handle. The information is specified as a set of bit flags.
1638 * Parameters: HANDLE hObject handle to an object
1639 * DWORD dwMask specifies flags to change
1640 * DWORD dwFlags specifies new values for flags
1641 * Variables :
1642 * Result : TRUE / FALSE
1643 * Remark :
1644 * Status :
1645 *
1646 * Author : SvL
1647 *****************************************************************************/
1648BOOL HMSetHandleInformation (HANDLE hObject,
1649 DWORD dwMask,
1650 DWORD dwFlags)
1651{
1652 int iIndex; /* index into the handle table */
1653 BOOL fResult; /* result from the device handler's CloseHandle() */
1654 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1655
1656 /* validate handle */
1657 iIndex = _HMHandleQuery(hObject); /* get the index */
1658 if (-1 == iIndex) /* error ? */
1659 {
1660 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1661 return (FALSE); /* signal failure */
1662 }
1663
1664 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1665 //SvL: Check if pDeviceHandler is set
1666 if (pHMHandle->pDeviceHandler)
1667 {
1668 fResult = pHMHandle->pDeviceHandler->SetHandleInformation(&pHMHandle->hmHandleData,
1669 dwMask, dwFlags);
1670 }
1671 else
1672 {
1673 dprintf(("HMSetHandleInformation(%08xh): pDeviceHandler not set", hObject));
1674 fResult = TRUE;
1675 }
1676
1677 if(fResult == TRUE) {
1678 SetLastError(ERROR_SUCCESS);
1679 }
1680 return (fResult); /* deliver return code */
1681}
1682
1683/*****************************************************************************
1684 * Name : HANDLE HMGetFileNameFromHandle
1685 * Purpose : Query the name of the file associated with the system handle (if any)
1686 * Parameters:
1687 * Variables :
1688 * Result :
1689 * Remark :
1690 * Status :
1691 *
1692 * Author : SvL
1693 *****************************************************************************/
1694BOOL HMGetFileNameFromHandle(HANDLE hObject, LPSTR lpszFileName, DWORD cbFileName)
1695{
1696 int iIndex; /* index into the handle table */
1697 BOOL fResult; /* result from the device handler's CloseHandle() */
1698 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1699
1700
1701 if(lpszFileName == NULL) {
1702 DebugInt3();
1703 SetLastError(ERROR_INVALID_PARAMETER);
1704 return FALSE;
1705 }
1706 /* validate handle */
1707 iIndex = _HMHandleQuery(hObject); /* get the index */
1708 if (-1 == iIndex) /* error ? */
1709 {
1710 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1711 return (FALSE); /* signal failure */
1712 }
1713
1714 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1715 //SvL: Check if pDeviceHandler is set
1716 if (pHMHandle->pDeviceHandler)
1717 {
1718 fResult = pHMHandle->pDeviceHandler->GetFileNameFromHandle(&pHMHandle->hmHandleData,
1719 lpszFileName, cbFileName);
1720 }
1721 else
1722 {
1723 dprintf(("HMGetFileNameFromHandle(%08xh): pDeviceHandler not set", hObject));
1724 fResult = FALSE;
1725 }
1726
1727 if(fResult == TRUE) {
1728 SetLastError(ERROR_SUCCESS);
1729 }
1730 return (fResult); /* deliver return code */
1731}
1732
1733/*****************************************************************************
1734 * Name : HANDLE HMCloseFile
1735 * Purpose : Wrapper for the CloseHandle() API
1736 * Parameters:
1737 * Variables :
1738 * Result :
1739 * Remark :
1740 * Status :
1741 *
1742 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1743 *****************************************************************************/
1744
1745BOOL HMCloseHandle(HANDLE hObject)
1746{
1747 int iIndex; /* index into the handle table */
1748 BOOL fResult; /* result from the device handler's CloseHandle() */
1749 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1750
1751 /* validate handle */
1752 iIndex = _HMHandleQuery(hObject); /* get the index */
1753 if (-1 == iIndex) /* error ? */
1754 {
1755 //@@@PH it may occur someone closes e.g. a semaphore handle
1756 // which is not registered through the HandleManager yet.
1757 // so we try to pass on to Open32 instead.
1758 dprintf(("KERNEL32: HandleManager:HMCloseHandle(%08xh) passed on to Open32.\n",
1759 hObject));
1760
1761 fResult = O32_CloseHandle(hObject);
1762 return (fResult);
1763
1764 //SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1765 //return (FALSE); /* signal failure */
1766 }
1767
1768 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1769
1770 if(pHMHandle->hmHandleData.dwHandleInformation & HANDLE_FLAG_PROTECT_FROM_CLOSE) {
1771 dprintf(("Handle not closed because of HANDLE_FLAG_PROTECT_FROM_CLOSE"));
1772 SetLastError(ERROR_SUCCESS);
1773 return TRUE;
1774 }
1775
1776 //SvL: Check if pDeviceHandler is set
1777 if (pHMHandle->pDeviceHandler)
1778 {
1779 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
1780 }
1781 else
1782 {
1783 dprintf(("HMCloseHAndle(%08xh): pDeviceHandler not set", hObject));
1784 fResult = TRUE;
1785 }
1786
1787 if (fResult == TRUE) /* remove handle if close succeeded */
1788 {
1789 FREEHANDLE(iIndex);
1790// pHMHandle->hmHandleData.hHMHandle = INVALID_HANDLE_VALUE; /* mark handle as free */
1791 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
1792 }
1793
1794 return (fResult); /* deliver return code */
1795}
1796
1797
1798/*****************************************************************************
1799 * Name : HANDLE HMReadFile
1800 * Purpose : Wrapper for the ReadHandle() API
1801 * Parameters:
1802 * Variables :
1803 * Result :
1804 * Remark :
1805 * Status :
1806 *
1807 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1808 *****************************************************************************/
1809
1810BOOL HMReadFile(HANDLE hFile,
1811 LPVOID lpBuffer,
1812 DWORD nNumberOfBytesToRead,
1813 LPDWORD lpNumberOfBytesRead,
1814 LPOVERLAPPED lpOverlapped,
1815 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1816{
1817 int iIndex; /* index into the handle table */
1818 BOOL fResult; /* result from the device handler's CloseHandle() */
1819 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1820
1821 /* validate handle */
1822 iIndex = _HMHandleQuery(hFile); /* get the index */
1823 if (-1 == iIndex) /* error ? */
1824 {
1825 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1826 return (FALSE); /* signal failure */
1827 }
1828
1829 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1830
1831 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1832 {
1833 SetLastError(ERROR_SYS_INTERNAL);
1834 return (FALSE);
1835 }
1836
1837 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
1838 lpBuffer,
1839 nNumberOfBytesToRead,
1840 lpNumberOfBytesRead,
1841 lpOverlapped, lpCompletionRoutine);
1842
1843 return (fResult); /* deliver return code */
1844}
1845
1846/*****************************************************************************
1847 * Name : HANDLE HMWriteFile
1848 * Purpose : Wrapper for the WriteHandle() API
1849 * Parameters:
1850 * Variables :
1851 * Result :
1852 * Remark :
1853 * Status :
1854 *
1855 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1856 *****************************************************************************/
1857
1858BOOL HMWriteFile(HANDLE hFile,
1859 LPCVOID lpBuffer,
1860 DWORD nNumberOfBytesToWrite,
1861 LPDWORD lpNumberOfBytesWritten,
1862 LPOVERLAPPED lpOverlapped,
1863 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1864{
1865 int iIndex; /* index into the handle table */
1866 BOOL fResult; /* result from the device handler's CloseHandle() */
1867 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1868
1869 /* validate handle */
1870 iIndex = _HMHandleQuery(hFile); /* get the index */
1871 if (-1 == iIndex) /* error ? */
1872 {
1873 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1874 return (FALSE); /* signal failure */
1875 }
1876
1877 /* watcom hack:
1878 * watcom may write -1 bytes to a device during flushall(), we should return
1879 * ERROR_NOT_ENOUGH_MEMORY or ERROR_NO_ACCESS
1880 */
1881 if (nNumberOfBytesToWrite == 0xffffffff)
1882 {
1883 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1884 return FALSE;
1885 }
1886
1887 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1888
1889 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1890 return ERROR_SYS_INTERNAL;
1891
1892 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
1893 lpBuffer,
1894 nNumberOfBytesToWrite,
1895 lpNumberOfBytesWritten,
1896 lpOverlapped, lpCompletionRoutine);
1897
1898 return (fResult); /* deliver return code */
1899}
1900
1901
1902/*****************************************************************************
1903 * Name : HANDLE HMGetFileType
1904 * Purpose : Wrapper for the GetFileType() API
1905 * Parameters:
1906 * Variables :
1907 * Result :
1908 * Remark :
1909 * Status :
1910 *
1911 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1912 *****************************************************************************/
1913
1914DWORD WIN32API GetFileType(HANDLE hFile)
1915{
1916 int iIndex; /* index into the handle table */
1917 DWORD dwResult; /* result from the device handler's API */
1918 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1919
1920 /* validate handle */
1921 iIndex = _HMHandleQuery(hFile); /* get the index */
1922 if (-1 == iIndex) /* error ? */
1923 {
1924 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1925 return FILE_TYPE_UNKNOWN; /* signal failure */
1926 }
1927
1928 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1929
1930 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1931 return ERROR_SYS_INTERNAL;
1932
1933 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1934
1935 return (dwResult); /* deliver return code */
1936}
1937
1938
1939/*****************************************************************************
1940 * Name : HMDeviceHandler::_DeviceReuqest
1941 * Purpose : entry method for special request functions
1942 * Parameters: ULONG ulRequestCode
1943 * various parameters as required
1944 * Variables :
1945 * Result :
1946 * Remark : the standard behaviour is to return an error code for non-
1947 * existant request codes
1948 * Status :
1949 *
1950 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1951 *****************************************************************************/
1952
1953DWORD HMDeviceRequest (HANDLE hFile,
1954 ULONG ulRequestCode,
1955 ULONG arg1,
1956 ULONG arg2,
1957 ULONG arg3,
1958 ULONG arg4)
1959{
1960 int iIndex; /* index into the handle table */
1961 DWORD dwResult; /* result from the device handler's API */
1962 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1963
1964 /* validate handle */
1965 iIndex = _HMHandleQuery(hFile); /* get the index */
1966 if (-1 == iIndex) /* error ? */
1967 {
1968 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1969 return (INVALID_HANDLE_ERROR); /* signal failure */
1970 }
1971
1972 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1973
1974 if (!pHMHandle || !pHMHandle->pDeviceHandler)
1975 return ERROR_SYS_INTERNAL;
1976
1977 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1978 ulRequestCode,
1979 arg1,
1980 arg2,
1981 arg3,
1982 arg4);
1983 return (dwResult); /* deliver return code */
1984}
1985
1986
1987/*****************************************************************************
1988 * Name : HMDeviceHandler::GetFileInformationByHandle
1989 * Purpose : router function for GetFileInformationByHandle
1990 * Parameters:
1991 * Variables :
1992 * Result :
1993 * Remark :
1994 * Status :
1995 *
1996 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1997 *****************************************************************************/
1998
1999BOOL WIN32API GetFileInformationByHandle (HANDLE hFile,
2000 BY_HANDLE_FILE_INFORMATION *pHFI)
2001{
2002 int iIndex; /* index into the handle table */
2003 DWORD dwResult; /* result from the device handler's API */
2004 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2005
2006 /* validate handle */
2007 iIndex = _HMHandleQuery(hFile); /* get the index */
2008 if (-1 == iIndex) /* error ? */
2009 {
2010 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2011 return FALSE; /* signal failure */
2012 }
2013
2014 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2015
2016 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2017 return ERROR_SYS_INTERNAL;
2018
2019 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
2020 pHFI);
2021
2022 return (dwResult); /* deliver return code */
2023}
2024
2025
2026/*****************************************************************************
2027 * Name : HMDeviceHandler::SetEndOfFile
2028 * Purpose : router function for SetEndOfFile
2029 * Parameters:
2030 * Variables :
2031 * Result :
2032 * Remark :
2033 * Status :
2034 *
2035 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2036 *****************************************************************************/
2037
2038BOOL WIN32API SetEndOfFile (HANDLE hFile)
2039{
2040 int iIndex; /* index into the handle table */
2041 BOOL bResult; /* result from the device handler's API */
2042 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2043
2044 /* validate handle */
2045 iIndex = _HMHandleQuery(hFile); /* get the index */
2046 if (-1 == iIndex) /* error ? */
2047 {
2048 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2049 return FALSE; /* signal failure */
2050 }
2051
2052 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2053
2054 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2055 return ERROR_SYS_INTERNAL;
2056
2057 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
2058
2059 return (bResult); /* deliver return code */
2060}
2061
2062
2063/*****************************************************************************
2064 * Name : HMDeviceHandler::SetFileTime
2065 * Purpose : router function for SetFileTime
2066 * Parameters:
2067 * Variables :
2068 * Result :
2069 * Remark :
2070 * Status :
2071 *
2072 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2073 *****************************************************************************/
2074
2075BOOL WIN32API SetFileTime (HANDLE hFile,
2076 const FILETIME *pFT1,
2077 const FILETIME *pFT2,
2078 const FILETIME *pFT3)
2079{
2080 int iIndex; /* index into the handle table */
2081 BOOL bResult; /* result from the device handler's API */
2082 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2083
2084 /* validate handle */
2085 iIndex = _HMHandleQuery(hFile); /* get the index */
2086 if (-1 == iIndex) /* error ? */
2087 {
2088 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2089 return FALSE; /* signal failure */
2090 }
2091
2092 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2093
2094 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2095 return ERROR_SYS_INTERNAL;
2096
2097 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
2098 (LPFILETIME)pFT1,
2099 (LPFILETIME)pFT2,
2100 (LPFILETIME)pFT3);
2101
2102 return (bResult); /* deliver return code */
2103}
2104
2105/*****************************************************************************
2106 * Name : HMDeviceHandler::GetFileTime
2107 * Purpose : router function for SetFileTime
2108 * Parameters:
2109 * Variables :
2110 * Result :
2111 * Remark :
2112 * Status :
2113 *
2114 * Author : SvL
2115 *****************************************************************************/
2116
2117BOOL WIN32API GetFileTime (HANDLE hFile, FILETIME *pFT1,
2118 FILETIME *pFT2, FILETIME *pFT3)
2119{
2120 int iIndex; /* index into the handle table */
2121 BOOL bResult; /* result from the device handler's API */
2122 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2123
2124 /* validate handle */
2125 iIndex = _HMHandleQuery(hFile); /* get the index */
2126 if (-1 == iIndex) /* error ? */
2127 {
2128 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2129 return FALSE; /* signal failure */
2130 }
2131
2132 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2133
2134 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2135 return ERROR_SYS_INTERNAL;
2136
2137 bResult = pHMHandle->pDeviceHandler->GetFileTime(&pHMHandle->hmHandleData,
2138 (LPFILETIME)pFT1,
2139 (LPFILETIME)pFT2,
2140 (LPFILETIME)pFT3);
2141
2142 return (bResult); /* deliver return code */
2143}
2144
2145
2146/*****************************************************************************
2147 * Name : HMDeviceHandler::GetFileSize
2148 * Purpose : router function for GetFileSize
2149 * Parameters:
2150 * Variables :
2151 * Result :
2152 * Remark :
2153 * Status :
2154 *
2155 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2156 *****************************************************************************/
2157
2158DWORD WIN32API GetFileSize (HANDLE hFile, PDWORD pSize)
2159{
2160 int iIndex; /* index into the handle table */
2161 DWORD dwResult; /* result from the device handler's API */
2162 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2163
2164 /* validate handle */
2165 iIndex = _HMHandleQuery(hFile); /* get the index */
2166 if (-1 == iIndex) /* error ? */
2167 {
2168 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2169 return -1; //INVALID_SET_FILE_POINTER
2170 }
2171
2172 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2173
2174 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2175 return ERROR_SYS_INTERNAL;
2176
2177 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
2178 pSize);
2179
2180 return (dwResult); /* deliver return code */
2181}
2182
2183/***********************************************************************
2184 * GetFileSizeEx (KERNEL32.@)
2185 */
2186BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
2187{
2188 lpFileSize->LowPart = GetFileSize(hFile, ((PDWORD)&lpFileSize->HighPart));
2189 return (lpFileSize->LowPart != INVALID_FILE_SIZE);
2190}
2191
2192/*****************************************************************************
2193 * Name : HMDeviceHandler::SetFilePointer
2194 * Purpose : router function for SetFilePointer
2195 * Parameters:
2196 * Variables :
2197 * Result :
2198 * Remark :
2199 * Status :
2200 *
2201 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2202 *****************************************************************************/
2203
2204DWORD WIN32API SetFilePointer (HANDLE hFile,
2205 LONG lDistanceToMove,
2206 PLONG lpDistanceToMoveHigh,
2207 DWORD dwMoveMethod)
2208{
2209 int iIndex; /* index into the handle table */
2210 DWORD dwResult; /* result from the device handler's API */
2211 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2212
2213 /* validate handle */
2214 iIndex = _HMHandleQuery(hFile); /* get the index */
2215 if (-1 == iIndex) /* error ? */
2216 {
2217 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2218 return (INVALID_HANDLE_ERROR); /* signal failure */
2219 }
2220
2221 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2222
2223 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2224 return ERROR_SYS_INTERNAL;
2225
2226 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
2227 lDistanceToMove,
2228 lpDistanceToMoveHigh,
2229 dwMoveMethod);
2230
2231 return (dwResult); /* deliver return code */
2232}
2233
2234/***********************************************************************
2235 * SetFilePointerEx (KERNEL32.@)
2236 */
2237BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
2238 LARGE_INTEGER *newpos, DWORD method )
2239{
2240 LONG pos;
2241 LONG newp;
2242 BOOL res;
2243
2244 dprintf(("KERNEL32::SetFilePointerEx"));
2245
2246 pos = (LONG)distance.LowPart;
2247 res = SetFilePointer(hFile, pos, &newp, method);
2248 if (res != -1)
2249 {
2250 if (newpos) newpos->LowPart = (LONG)res;
2251 return TRUE;
2252 }
2253 return FALSE;
2254}
2255
2256
2257/*****************************************************************************
2258 * Name : HMDeviceHandler::LockFile
2259 * Purpose : router function for LockFile
2260 * Parameters:
2261 * Variables :
2262 * Result :
2263 * Remark :
2264 * Status :
2265 *
2266 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2267 *****************************************************************************/
2268
2269BOOL WIN32API LockFile (HANDLE hFile,
2270 DWORD arg2,
2271 DWORD arg3,
2272 DWORD arg4,
2273 DWORD arg5)
2274{
2275 int iIndex; /* index into the handle table */
2276 DWORD dwResult; /* result from the device handler's API */
2277 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2278
2279 /* validate handle */
2280 iIndex = _HMHandleQuery(hFile); /* get the index */
2281 if (-1 == iIndex) /* error ? */
2282 {
2283 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2284 return FALSE; /* signal failure */
2285 }
2286
2287 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2288
2289 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2290 return ERROR_SYS_INTERNAL;
2291
2292 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
2293 arg2,
2294 arg3,
2295 arg4,
2296 arg5);
2297
2298 return (dwResult); /* deliver return code */
2299}
2300
2301
2302/*****************************************************************************
2303 * Name : BOOL LockFileEx
2304 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
2305 * Parameters: HANDLE hFile handle of file to lock
2306 * DWORD dwFlags functional behavior modification flags
2307 * DWORD dwReserved reserved, must be set to zero
2308 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2309 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2310 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2311 * Variables :
2312 * Result : TRUE / FALSE
2313 * Remark :
2314 * Status : UNTESTED STUB
2315 *
2316 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2317 *****************************************************************************/
2318
2319BOOL WIN32API LockFileEx(HANDLE hFile,
2320 DWORD dwFlags,
2321 DWORD dwReserved,
2322 DWORD nNumberOfBytesToLockLow,
2323 DWORD nNumberOfBytesToLockHigh,
2324 LPOVERLAPPED lpOverlapped)
2325{
2326 int iIndex; /* index into the handle table */
2327 BOOL dwResult; /* result from the device handler's API */
2328 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2329
2330 /* validate handle */
2331 iIndex = _HMHandleQuery(hFile); /* get the index */
2332 if (-1 == iIndex) /* error ? */
2333 {
2334 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2335 return FALSE; /* signal failure */
2336 }
2337
2338 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2339
2340 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2341 return ERROR_SYS_INTERNAL;
2342
2343 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
2344 dwFlags,
2345 dwReserved,
2346 nNumberOfBytesToLockLow,
2347 nNumberOfBytesToLockHigh,
2348 lpOverlapped);
2349
2350 return (dwResult); /* deliver return code */
2351}
2352
2353
2354
2355/*****************************************************************************
2356 * Name : HMDeviceHandler::UnlockFile
2357 * Purpose : router function for UnlockFile
2358 * Parameters:
2359 * Variables :
2360 * Result :
2361 * Remark :
2362 * Status :
2363 *
2364 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2365 *****************************************************************************/
2366
2367BOOL WIN32API UnlockFile (HANDLE hFile,
2368 DWORD arg2,
2369 DWORD arg3,
2370 DWORD arg4,
2371 DWORD arg5)
2372{
2373 int iIndex; /* index into the handle table */
2374 BOOL dwResult; /* result from the device handler's API */
2375 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2376
2377 /* validate handle */
2378 iIndex = _HMHandleQuery(hFile); /* get the index */
2379 if (-1 == iIndex) /* error ? */
2380 {
2381 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2382 return FALSE; /* signal failure */
2383 }
2384
2385 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2386
2387 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2388 return ERROR_SYS_INTERNAL;
2389
2390 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
2391 arg2,
2392 arg3,
2393 arg4,
2394 arg5);
2395
2396 return (dwResult); /* deliver return code */
2397}
2398
2399
2400/*****************************************************************************
2401 * Name : BOOL UnlockFileEx
2402 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
2403 * Parameters: HANDLE hFile handle of file to lock
2404 * DWORD dwReserved reserved, must be set to zero
2405 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2406 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2407 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2408 * Variables :
2409 * Result : TRUE / FALSE
2410 * Remark :
2411 * Status : UNTESTED STUB
2412 *
2413 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2414 *****************************************************************************/
2415
2416BOOL WIN32API UnlockFileEx(HANDLE hFile,
2417 DWORD dwReserved,
2418 DWORD nNumberOfBytesToLockLow,
2419 DWORD nNumberOfBytesToLockHigh,
2420 LPOVERLAPPED lpOverlapped)
2421{
2422 int iIndex; /* index into the handle table */
2423 BOOL bResult; /* result from the device handler's API */
2424 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2425
2426 /* validate handle */
2427 iIndex = _HMHandleQuery(hFile); /* get the index */
2428 if (-1 == iIndex) /* error ? */
2429 {
2430 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2431 return FALSE; /* signal failure */
2432 }
2433
2434 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2435
2436 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2437 return ERROR_SYS_INTERNAL;
2438
2439 bResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
2440 dwReserved,
2441 nNumberOfBytesToLockLow,
2442 nNumberOfBytesToLockHigh,
2443 lpOverlapped);
2444
2445 return (bResult); /* deliver return code */
2446}
2447
2448
2449/*****************************************************************************
2450 * Name : HMDeviceHandler::WaitForSingleObject
2451 * Purpose : router function for WaitForSingleObject
2452 * Parameters:
2453 * Variables :
2454 * Result :
2455 * Remark :
2456 * Status :
2457 *
2458 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2459 *****************************************************************************/
2460
2461DWORD HMWaitForSingleObject(HANDLE hObject,
2462 DWORD dwTimeout)
2463{
2464 int iIndex; /* index into the handle table */
2465 BOOL dwResult; /* result from the device handler's API */
2466 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2467
2468 /* validate handle */
2469 iIndex = _HMHandleQuery(hObject); /* get the index */
2470 if (-1 == iIndex) /* error ? */
2471 {
2472 dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n",
2473 hObject));
2474
2475 if(dwTimeout == INFINITE) {
2476 //Workaround for applications that block the PM input queue
2477 //while waiting for a child process to terminate.
2478 //(WaitSingleObject now calls MsgWaitMultipleObjects and
2479 // processes messages while waiting for the process to die)
2480 //(Napster install now doesn't block PM anymore (forcing a reboot))
2481
2482 HMODULE hUser32 = LoadLibraryA("USER32.DLL");
2483
2484 BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
2485 LONG (* WINAPI pfnDispatchMessageA)(const MSG*);
2486
2487 *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
2488 *(FARPROC *)&pfnDispatchMessageA = GetProcAddress(hUser32,"DispatchMessageA");
2489
2490 TEB *teb = GetThreadTEB();
2491
2492 if(!teb || !pfnPeekMessageA || !pfnDispatchMessageA) {
2493 dprintf(("ERROR: !teb || !pfnPeekMessageA || !pfnDispatchMessageA"));
2494 DebugInt3();
2495 return WAIT_FAILED;
2496 }
2497
2498 //TODO: Ignoring all messages could be dangerous. But processing them,
2499 //while the app doesn't expect any, isn't safe either.
2500//-> must active check in pmwindow.cpp if this is enabled again!
2501// teb->o.odin.fIgnoreMsgs = TRUE;
2502
2503 while(TRUE) {
2504 dwResult = HMMsgWaitForMultipleObjects(1, &hObject, FALSE,
2505 INFINITE, QS_ALLINPUT);
2506 if(dwResult == WAIT_OBJECT_0 + 1) {
2507 MSG msg ;
2508
2509 while (pfnPeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
2510 {
2511 if (msg.message == WM_QUIT) {
2512 dprintf(("ERROR: WaitForSingleObject call abandoned because WM_QUIT msg was received!!"));
2513// teb->o.odin.fIgnoreMsgs = FALSE;
2514 FreeLibrary(hUser32);
2515 return WAIT_ABANDONED;
2516 }
2517
2518 /* otherwise dispatch it */
2519 pfnDispatchMessageA(&msg);
2520
2521 } // end of PeekMessage while loop
2522 }
2523 else {
2524 dprintf(("WaitForSingleObject: Process %x terminated", hObject));
2525 break;
2526 }
2527 }
2528// teb->o.odin.fIgnoreMsgs = FALSE;
2529 FreeLibrary(hUser32);
2530 return dwResult;
2531 }
2532 else {
2533 // maybe handles from CreateProcess() ...
2534 dwResult = O32_WaitForSingleObject(hObject, dwTimeout);
2535 return (dwResult);
2536 }
2537 }
2538 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2539
2540 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2541 return ERROR_SYS_INTERNAL;
2542
2543 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObject(&pHMHandle->hmHandleData,
2544 dwTimeout);
2545
2546 return (dwResult); /* deliver return code */
2547}
2548
2549
2550/*****************************************************************************
2551 * Name : HMDeviceHandler::WaitForSingleObjectEx
2552 * Purpose : router function for WaitForSingleObjectEx
2553 * Parameters:
2554 * Variables :
2555 * Result :
2556 * Remark :
2557 * Status :
2558 *
2559 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2560 *****************************************************************************/
2561
2562DWORD HMWaitForSingleObjectEx(HANDLE hObject,
2563 DWORD dwTimeout,
2564 BOOL fAlertable)
2565{
2566 int iIndex; /* index into the handle table */
2567 DWORD dwResult; /* result from the device handler's API */
2568 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2569
2570 /* validate handle */
2571 iIndex = _HMHandleQuery(hObject); /* get the index */
2572 if (-1 == iIndex) /* error ? */
2573 {
2574 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2575 return WAIT_FAILED; /* signal failure */
2576 }
2577
2578 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2579
2580 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2581 return ERROR_SYS_INTERNAL;
2582
2583 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObjectEx(&pHMHandle->hmHandleData,
2584 dwTimeout,
2585 fAlertable);
2586
2587 return (dwResult); /* deliver return code */
2588}
2589
2590
2591/*****************************************************************************
2592 * Name : HMDeviceHandler::FlushFileBuffers
2593 * Purpose : router function for FlushFileBuffers
2594 * Parameters:
2595 * Variables :
2596 * Result :
2597 * Remark :
2598 * Status :
2599 *
2600 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2601 *****************************************************************************/
2602
2603BOOL WIN32API FlushFileBuffers(HANDLE hFile)
2604{
2605 int iIndex; /* index into the handle table */
2606 DWORD dwResult; /* result from the device handler's API */
2607 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2608
2609 /* validate handle */
2610 iIndex = _HMHandleQuery(hFile); /* get the index */
2611 if (-1 == iIndex) /* error ? */
2612 {
2613 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2614 return FALSE; /* signal failure */
2615 }
2616
2617 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2618
2619 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2620 return ERROR_SYS_INTERNAL;
2621
2622 dwResult = pHMHandle->pDeviceHandler->FlushFileBuffers(&pHMHandle->hmHandleData);
2623
2624 return (dwResult); /* deliver return code */
2625}
2626
2627
2628/*****************************************************************************
2629 * Name : HMDeviceHandler::GetOverlappedResult
2630 * Purpose : router function for GetOverlappedResult
2631 * Parameters:
2632 * Variables :
2633 * Result :
2634 * Remark :
2635 * Status :
2636 *
2637 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2638 *****************************************************************************/
2639
2640BOOL HMGetOverlappedResult(HANDLE hObject,
2641 LPOVERLAPPED lpOverlapped,
2642 LPDWORD arg3,
2643 BOOL arg4)
2644{
2645 int iIndex; /* index into the handle table */
2646 DWORD dwResult; /* result from the device handler's API */
2647 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2648
2649 /* validate handle */
2650 iIndex = _HMHandleQuery(hObject); /* get the index */
2651 if (-1 == iIndex) /* error ? */
2652 {
2653 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2654 return FALSE; /* signal failure */
2655 }
2656
2657 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2658
2659 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2660 return ERROR_SYS_INTERNAL;
2661
2662 dwResult = pHMHandle->pDeviceHandler->GetOverlappedResult(&pHMHandle->hmHandleData,
2663 lpOverlapped,
2664 arg3,
2665 arg4);
2666
2667 return (dwResult); /* deliver return code */
2668}
2669
2670
2671/*****************************************************************************
2672 * Name : HMReleaseMutex
2673 * Purpose : router function for ReleaseMutex
2674 * Parameters:
2675 * Variables :
2676 * Result :
2677 * Remark :
2678 * Status :
2679 *
2680 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2681 *****************************************************************************/
2682
2683BOOL WIN32API ReleaseMutex(HANDLE hObject)
2684{
2685 int iIndex; /* index into the handle table */
2686 DWORD dwResult; /* result from the device handler's API */
2687 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2688
2689 /* validate handle */
2690 iIndex = _HMHandleQuery(hObject); /* get the index */
2691 if (-1 == iIndex) /* error ? */
2692 {
2693 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2694 return FALSE; /* signal failure */
2695 }
2696
2697 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2698
2699 if (!pHMHandle || !pHMHandle->pDeviceHandler)
2700 return ERROR_SYS_INTERNAL;
2701
2702 dwResult = pHMHandle->pDeviceHandler->ReleaseMutex(&pHMHandle->hmHandleData);
2703
2704 return (dwResult); /* deliver return code */
2705}
2706
2707
2708
2709
2710/*****************************************************************************
2711 * Name : HANDLE HMCreateMutex
2712 * Purpose : Wrapper for the CreateMutex() API
2713 * Parameters:
2714 * Variables :
2715 * Result :
2716 * Remark :
2717 * Status :
2718 *
2719 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2720 *****************************************************************************/
2721
2722HANDLE WIN32API CreateMutexA(LPSECURITY_ATTRIBUTES lpsa,
2723 BOOL bInitialOwner,
2724 LPCTSTR lpName)
2725{
2726 int iIndex; /* index into the handle table */
2727 int iIndexNew; /* index into the handle table */
2728 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2729 PHMHANDLEDATA pHMHandleData;
2730 DWORD rc; /* API return code */
2731
2732
2733 if(lpName) { //check if shared mutex semaphore already exists
2734 dprintf(("Event semaphore name %s", lpName));
2735
2736 //TODO: No inheritance??
2737 HANDLE handle = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, lpName);
2738 if(handle) {
2739 dprintf(("CreateMutex: return handle of existing mutex semaphore %x", handle));
2740 SetLastError(ERROR_ALREADY_EXISTS);
2741 return handle;
2742 }
2743 }
2744
2745 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2746
2747 iIndexNew = _HMHandleGetFree(); /* get free handle */
2748 if (-1 == iIndexNew) /* oops, no free handles ! */
2749 {
2750 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2751 return 0; /* signal error */
2752 }
2753
2754
2755 /* initialize the complete HMHANDLEDATA structure */
2756 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2757 pHMHandleData->dwAccess = 0;
2758 pHMHandleData->dwShare = 0;
2759 pHMHandleData->dwCreation = 0;
2760 pHMHandleData->dwFlags = 0;
2761 pHMHandleData->lpHandlerData = NULL;
2762 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2763
2764
2765 /* we've got to mark the handle as occupied here, since another device */
2766 /* could be created within the device handler -> deadlock */
2767
2768 /* write appropriate entry into the handle table if open succeeded */
2769 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2770 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2771
2772 /* call the device handler */
2773 rc = pDeviceHandler->CreateMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2774 lpsa,
2775 bInitialOwner,
2776 lpName);
2777 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2778 {
2779 FREEHANDLE(iIndexNew);
2780// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2781 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2782 return 0; /* signal error */
2783 }
2784 else
2785 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2786
2787 return iIndexNew; /* return valid handle */
2788}
2789
2790
2791
2792/*****************************************************************************
2793 * Name : HANDLE HMOpenMutex
2794 * Purpose : Wrapper for the OpenMutex() API
2795 * Parameters:
2796 * Variables :
2797 * Result :
2798 * Remark :
2799 * Status :
2800 *
2801 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2802 *****************************************************************************/
2803
2804HANDLE WIN32API OpenMutexA(DWORD fdwAccess,
2805 BOOL fInherit,
2806 LPCTSTR lpName)
2807{
2808 int iIndex; /* index into the handle table */
2809 int iIndexNew; /* index into the handle table */
2810 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2811 PHMHANDLEDATA pHMHandleData;
2812 DWORD rc; /* API return code */
2813
2814
2815 if(lpName) {
2816 dprintf(("Mutex semaphore name %s", lpName));
2817 }
2818
2819 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2820
2821 iIndexNew = _HMHandleGetFree(); /* get free handle */
2822 if (-1 == iIndexNew) /* oops, no free handles ! */
2823 {
2824 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2825 return 0; /* signal error */
2826 }
2827
2828
2829 /* initialize the complete HMHANDLEDATA structure */
2830 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2831 pHMHandleData->dwAccess = fdwAccess;
2832 pHMHandleData->dwShare = 0;
2833 pHMHandleData->dwCreation = 0;
2834 pHMHandleData->dwFlags = 0;
2835 pHMHandleData->lpHandlerData = NULL;
2836 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2837
2838
2839 /* we've got to mark the handle as occupied here, since another device */
2840 /* could be created within the device handler -> deadlock */
2841
2842 /* write appropriate entry into the handle table if open succeeded */
2843 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2844 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2845
2846 /* call the device handler */
2847 rc = pDeviceHandler->OpenMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2848 fInherit,
2849 lpName);
2850 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2851 {
2852 FREEHANDLE(iIndexNew);
2853// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2854 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2855 return 0; /* signal error */
2856 }
2857 else
2858 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2859
2860 return iIndexNew; /* return valid handle */
2861}
2862
2863
2864/*****************************************************************************
2865 * Name : HANDLE HMCreateSemaphore
2866 * Purpose : Wrapper for the CreateSemaphore() API
2867 * Parameters:
2868 * Variables :
2869 * Result :
2870 * Remark :
2871 * Status :
2872 *
2873 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2874 *****************************************************************************/
2875
2876HANDLE WIN32API CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpsa,
2877 LONG lInitialCount,
2878 LONG lMaximumCount,
2879 LPCTSTR lpName)
2880{
2881 int iIndex; /* index into the handle table */
2882 int iIndexNew; /* index into the handle table */
2883 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2884 PHMHANDLEDATA pHMHandleData;
2885 DWORD rc; /* API return code */
2886
2887 if(lpName) { //check if shared event semaphore already exists
2888 //TODO: No inheritance??
2889 dprintf(("Semaphore name %s", lpName));
2890
2891 HANDLE handle = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, lpName);
2892 if(handle) {
2893 dprintf(("CreateSemaphore: return handle of existing semaphore %x", handle));
2894 SetLastError(ERROR_ALREADY_EXISTS);
2895 return handle;
2896 }
2897 }
2898
2899 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2900
2901 iIndexNew = _HMHandleGetFree(); /* get free handle */
2902 if (-1 == iIndexNew) /* oops, no free handles ! */
2903 {
2904 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2905 return 0; /* signal error */
2906 }
2907
2908
2909 /* initialize the complete HMHANDLEDATA structure */
2910 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2911 pHMHandleData->dwAccess = 0;
2912 pHMHandleData->dwShare = 0;
2913 pHMHandleData->dwCreation = 0;
2914 pHMHandleData->dwFlags = 0;
2915 pHMHandleData->lpHandlerData = NULL;
2916 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2917
2918
2919 /* we've got to mark the handle as occupied here, since another device */
2920 /* could be created within the device handler -> deadlock */
2921
2922 /* write appropriate entry into the handle table if open succeeded */
2923 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2924 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2925
2926 /* call the device handler */
2927 rc = pDeviceHandler->CreateSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2928 lpsa,
2929 lInitialCount,
2930 lMaximumCount,
2931 lpName);
2932 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2933 {
2934 FREEHANDLE(iIndexNew);
2935// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2936 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2937 return 0; /* signal failure */
2938 }
2939 else
2940 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2941
2942 return iIndexNew; /* return valid handle */
2943}
2944
2945
2946/*****************************************************************************
2947 * Name : HANDLE HMOpenSemaphore
2948 * Purpose : Wrapper for the OpenSemaphore() API
2949 * Parameters:
2950 * Variables :
2951 * Result :
2952 * Remark :
2953 * Status :
2954 *
2955 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2956 *****************************************************************************/
2957
2958HANDLE WIN32API OpenSemaphoreA(DWORD fdwAccess,
2959 BOOL fInherit,
2960 LPCTSTR lpName)
2961{
2962 int iIndex; /* index into the handle table */
2963 int iIndexNew; /* index into the handle table */
2964 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2965 PHMHANDLEDATA pHMHandleData;
2966 DWORD rc; /* API return code */
2967
2968
2969 if(lpName) {
2970 dprintf(("Semaphore name %s", lpName));
2971 }
2972
2973 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2974
2975 iIndexNew = _HMHandleGetFree(); /* get free handle */
2976 if (-1 == iIndexNew) /* oops, no free handles ! */
2977 {
2978 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2979 return 0; /* signal error */
2980 }
2981
2982
2983 /* initialize the complete HMHANDLEDATA structure */
2984 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2985 pHMHandleData->dwAccess = fdwAccess;
2986 pHMHandleData->dwShare = 0;
2987 pHMHandleData->dwCreation = 0;
2988 pHMHandleData->dwFlags = 0;
2989 pHMHandleData->lpHandlerData = NULL;
2990 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2991
2992
2993 /* we've got to mark the handle as occupied here, since another device */
2994 /* could be created within the device handler -> deadlock */
2995
2996 /* write appropriate entry into the handle table if open succeeded */
2997 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2998 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2999
3000 /* call the device handler */
3001 rc = pDeviceHandler->OpenSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
3002 fInherit,
3003 lpName);
3004 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3005 {
3006 FREEHANDLE(iIndexNew);
3007// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3008 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3009 return 0; /* signal failure */
3010 }
3011 else
3012 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3013
3014 return iIndexNew; /* return valid handle */
3015}
3016
3017
3018/*****************************************************************************
3019 * Name : HMReleaseSemaphore
3020 * Purpose : router function for ReleaseSemaphore
3021 * Parameters:
3022 * Variables :
3023 * Result :
3024 * Remark :
3025 * Status :
3026 *
3027 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3028 *****************************************************************************/
3029
3030BOOL WIN32API ReleaseSemaphore(HANDLE hEvent,
3031 LONG cReleaseCount,
3032 LPLONG lpPreviousCount)
3033{
3034 int iIndex; /* index into the handle table */
3035 DWORD dwResult; /* result from the device handler's API */
3036 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3037
3038 /* validate handle */
3039 iIndex = _HMHandleQuery(hEvent); /* get the index */
3040 if (-1 == iIndex) /* error ? */
3041 {
3042 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3043 return 0; /* signal failure */
3044 }
3045 else
3046 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3047
3048 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3049
3050 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3051 return ERROR_SYS_INTERNAL;
3052
3053 dwResult = pHMHandle->pDeviceHandler->ReleaseSemaphore(&pHMHandle->hmHandleData,
3054 cReleaseCount,
3055 lpPreviousCount);
3056
3057 return (dwResult); /* deliver return code */
3058}
3059
3060
3061/*****************************************************************************
3062 * Name : HANDLE HMCreateFileMapping
3063 * Purpose : Wrapper for the CreateFileMapping() API
3064 * Parameters:
3065 * Variables :
3066 * Result :
3067 * Remark :
3068 * Status :
3069 *
3070 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
3071 *****************************************************************************/
3072
3073HANDLE HMCreateFileMapping(HANDLE hFile,
3074 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
3075 DWORD flProtect,
3076 DWORD dwMaximumSizeHigh,
3077 DWORD dwMaximumSizeLow,
3078 LPCTSTR lpName)
3079{
3080 int iIndex; /* index into the handle table */
3081 int iIndexNew; /* index into the handle table */
3082 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3083 PHMHANDLEDATA pHMHandleData;
3084 DWORD rc; /* API return code */
3085
3086 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
3087
3088 iIndexNew = _HMHandleGetFree(); /* get free handle */
3089 if (-1 == iIndexNew) /* oops, no free handles ! */
3090 {
3091 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3092 return 0; /* signal error */
3093 }
3094
3095 /* initialize the complete HMHANDLEDATA structure */
3096 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3097 pHMHandleData->dwAccess = 0;
3098 pHMHandleData->dwShare = 0;
3099 pHMHandleData->dwCreation = 0;
3100 pHMHandleData->dwFlags = 0;
3101 pHMHandleData->lpHandlerData = NULL;
3102 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
3103
3104 /* we've got to mark the handle as occupied here, since another device */
3105 /* could be created within the device handler -> deadlock */
3106
3107 /* write appropriate entry into the handle table if open succeeded */
3108 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3109 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3110
3111 /* call the device handler */
3112
3113 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3114 // a valid HandleManager-internal handle!
3115 rc = pDeviceHandler->CreateFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
3116 hFile,
3117 lpFileMappingAttributes,
3118 flProtect,
3119 dwMaximumSizeHigh,
3120 dwMaximumSizeLow,
3121 lpName);
3122
3123 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
3124 {
3125 if(rc != ERROR_ALREADY_EXISTS) {
3126 FREEHANDLE(iIndexNew);
3127// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3128 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3129 return (NULL); /* signal error */
3130 }
3131 SetLastError(ERROR_ALREADY_EXISTS);
3132 return iIndexNew; /* return valid handle */
3133 }
3134 else
3135 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3136
3137 return iIndexNew; /* return valid handle */
3138}
3139
3140
3141/*****************************************************************************
3142 * Name : HANDLE HMOpenFileMapping
3143 * Purpose : Wrapper for the OpenFileMapping() API
3144 * Parameters:
3145 * Variables :
3146 * Result : HANDLE if succeeded,
3147 * NULL if failed.
3148 * Remark :
3149 * Status :
3150 *
3151 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
3152 *****************************************************************************/
3153
3154HANDLE HMOpenFileMapping(DWORD fdwAccess,
3155 BOOL fInherit,
3156 LPCTSTR lpName)
3157{
3158 int iIndex; /* index into the handle table */
3159 int iIndexNew; /* index into the handle table */
3160 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3161 PHMHANDLEDATA pHMHandleData;
3162 DWORD rc; /* API return code */
3163
3164
3165 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
3166
3167 iIndexNew = _HMHandleGetFree(); /* get free handle */
3168 if (-1 == iIndexNew) /* oops, no free handles ! */
3169 {
3170 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3171 return (NULL); /* signal error */
3172 }
3173
3174 /* initialize the complete HMHANDLEDATA structure */
3175 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3176 pHMHandleData->dwAccess = fdwAccess;
3177 pHMHandleData->dwShare = 0;
3178 pHMHandleData->dwCreation = 0;
3179 pHMHandleData->dwFlags = 0;
3180 pHMHandleData->lpHandlerData = NULL;
3181
3182
3183 /* we've got to mark the handle as occupied here, since another device */
3184 /* could be created within the device handler -> deadlock */
3185
3186 /* write appropriate entry into the handle table if open succeeded */
3187 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3188 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3189
3190 /* call the device handler */
3191 rc = pDeviceHandler->OpenFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
3192 fdwAccess,
3193 fInherit,
3194 lpName);
3195 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3196 {
3197 FREEHANDLE(iIndexNew);
3198// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3199 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3200 return (NULL); /* signal error */
3201 }
3202 else
3203 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3204
3205 return iIndexNew; /* return valid handle */
3206}
3207
3208
3209/*****************************************************************************
3210 * Name : HMMapViewOfFileEx
3211 * Purpose : router function for MapViewOfFileEx
3212 * Parameters:
3213 * Variables :
3214 * Result :
3215 * Remark :
3216 * Status :
3217 *
3218 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3219 *****************************************************************************/
3220
3221LPVOID HMMapViewOfFileEx(HANDLE hFileMappingObject,
3222 DWORD dwDesiredAccess,
3223 DWORD dwFileOffsetHigh,
3224 DWORD dwFileOffsetLow,
3225 DWORD dwNumberOfBytesToMap,
3226 LPVOID lpBaseAddress)
3227{
3228 int iIndex; /* index into the handle table */
3229 LPVOID lpResult; /* result from the device handler's API */
3230 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3231
3232 /* validate handle */
3233 iIndex = _HMHandleQuery(hFileMappingObject); /* get the index */
3234 if (-1 == iIndex) /* error ? */
3235 {
3236 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3237 return (NULL); /* signal failure */
3238 }
3239
3240 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3241
3242 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3243 return NULL;
3244
3245 lpResult = pHMHandle->pDeviceHandler->MapViewOfFileEx(&pHMHandle->hmHandleData,
3246 dwDesiredAccess,
3247 dwFileOffsetHigh,
3248 dwFileOffsetLow,
3249 dwNumberOfBytesToMap,
3250 lpBaseAddress);
3251
3252 return (lpResult); /* deliver return code */
3253}
3254
3255/*****************************************************************************
3256 * Name : HMWaitForMultipleObjects
3257 * Purpose : router function for WaitForMultipleObjects
3258 * Parameters:
3259 * Variables :
3260 * Result :
3261 * Remark :
3262 * Status :
3263 *
3264 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3265 *****************************************************************************/
3266
3267DWORD HMWaitForMultipleObjects (DWORD cObjects,
3268 PHANDLE lphObjects,
3269 BOOL fWaitAll,
3270 DWORD dwTimeout)
3271{
3272 ULONG ulIndex;
3273 PHANDLE pArrayOfHandles;
3274 PHANDLE pLoop1 = lphObjects;
3275 PHANDLE pLoop2;
3276 DWORD rc;
3277
3278 // allocate array for handle table
3279 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3280 if (pArrayOfHandles == NULL)
3281 {
3282 dprintf(("ERROR: HMWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3283 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3284 return WAIT_FAILED;
3285 }
3286 else
3287 pLoop2 = pArrayOfHandles;
3288
3289 // convert array to odin handles
3290 for (ulIndex = 0;
3291
3292 ulIndex < cObjects;
3293
3294 ulIndex++,
3295 pLoop1++,
3296 pLoop2++)
3297 {
3298 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3299 pLoop2);
3300
3301 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, Open32-%08xh\n",
3302 ulIndex,
3303 *pLoop1,
3304 *pLoop2));
3305
3306 // @@@PH to imlpement: check handle type!
3307 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3308 if (rc != NO_ERROR)
3309 {
3310 dprintf(("KERNEL32: HMWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3311 *pLoop1));
3312
3313 *pLoop2 = *pLoop1;
3314//// SetLastError(ERROR_INVALID_HANDLE);
3315//// return (WAIT_FAILED);
3316 }
3317 }
3318
3319 // OK, now forward to Open32.
3320 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3321 // but to i.e. the console subsystem!
3322 rc = O32_WaitForMultipleObjects(cObjects,
3323 pArrayOfHandles,
3324 fWaitAll,
3325 dwTimeout);
3326
3327 return (rc); // OK, done
3328}
3329
3330
3331/*****************************************************************************
3332 * Name : HMWaitForMultipleObjectsEx
3333 * Purpose : router function for WaitForMultipleObjectsEx
3334 * Parameters:
3335 * Variables :
3336 * Result :
3337 * Remark :
3338 * Status :
3339 *
3340 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3341 *****************************************************************************/
3342
3343DWORD HMWaitForMultipleObjectsEx (DWORD cObjects,
3344 PHANDLE lphObjects,
3345 BOOL fWaitAll,
3346 DWORD dwTimeout,
3347 BOOL fAlertable)
3348{
3349 // @@@PH: Note: fAlertable is ignored !
3350 return (HMWaitForMultipleObjects(cObjects,
3351 lphObjects,
3352 fWaitAll,
3353 dwTimeout));
3354}
3355
3356/*****************************************************************************
3357 * Name : HMMsgWaitForMultipleObjects
3358 * Purpose : router function for MsgWaitForMultipleObjects
3359 * Parameters:
3360 * Variables :
3361 * Result :
3362 * Remark : Open32 doesn't implement this properly! (doesn't check dwWakeMask)
3363 * Status :
3364 *
3365 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3366 *****************************************************************************/
3367
3368DWORD HMMsgWaitForMultipleObjects (DWORD cObjects,
3369 LPHANDLE lphObjects,
3370 BOOL fWaitAll,
3371 DWORD dwTimeout,
3372 DWORD dwWakeMask)
3373{
3374 ULONG ulIndex;
3375 PHANDLE pArrayOfHandles;
3376 PHANDLE pLoop1 = lphObjects;
3377 PHANDLE pLoop2;
3378 DWORD rc;
3379
3380 // allocate array for handle table
3381 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3382 if (pArrayOfHandles == NULL)
3383 {
3384 dprintf(("ERROR: HMMsgWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3385 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3386 return WAIT_FAILED;
3387 }
3388 else
3389 pLoop2 = pArrayOfHandles;
3390
3391 // convert array to odin handles
3392 for (ulIndex = 0;
3393
3394 ulIndex < cObjects;
3395
3396 ulIndex++,
3397 pLoop1++,
3398 pLoop2++)
3399 {
3400 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3401 pLoop2);
3402
3403 dprintf2(("MsgWaitForMultipleObjects handle %x->%x", *pLoop1, *pLoop2));
3404 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3405 if (rc != NO_ERROR)
3406 {
3407 dprintf(("KERNEL32: HMMsgWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3408 *pLoop1));
3409
3410 *pLoop2 = *pLoop1;
3411//// SetLastError(ERROR_INVALID_HANDLE);
3412//// return (WAIT_FAILED);
3413 }
3414 }
3415
3416 // OK, now forward to Open32.
3417 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3418 // but to i.e. the console subsystem!
3419 rc = O32_MsgWaitForMultipleObjects(cObjects,
3420 pArrayOfHandles,
3421 fWaitAll, dwTimeout,
3422 dwWakeMask);
3423
3424 dprintf2(("MsgWaitForMultipleObjects returned %d", rc));
3425 return (rc); // OK, done
3426}
3427/*****************************************************************************
3428 * Name : HMDeviceIoControl
3429 * Purpose : router function for DeviceIoControl
3430 * Parameters:
3431 * Variables :
3432 * Result :
3433 * Remark :
3434 * Status :
3435 *
3436 * Author : Sander van Leeuwen
3437 *****************************************************************************/
3438
3439BOOL WIN32API DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
3440 LPVOID lpInBuffer, DWORD nInBufferSize,
3441 LPVOID lpOutBuffer, DWORD nOutBufferSize,
3442 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
3443{
3444 int iIndex; /* index into the handle table */
3445 BOOL fResult; /* result from the device handler's CloseHandle() */
3446 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3447
3448 /* validate handle */
3449 iIndex = _HMHandleQuery(hDevice); /* get the index */
3450 if (-1 == iIndex) /* error ? */
3451 {
3452 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3453 return (FALSE); /* signal failure */
3454 }
3455
3456 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3457
3458 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3459 return ERROR_SYS_INTERNAL;
3460
3461 fResult = pHMHandle->pDeviceHandler->DeviceIoControl(&pHMHandle->hmHandleData,
3462 dwIoControlCode,
3463 lpInBuffer, nInBufferSize,
3464 lpOutBuffer, nOutBufferSize,
3465 lpBytesReturned, lpOverlapped);
3466
3467 return (fResult); /* deliver return code */
3468}
3469/*****************************************************************************
3470 * Name : BOOL WIN32API CancelIo
3471 * Purpose : The CancelIO function cancels all pending input and output
3472 * (I/O) operations that were issued by the calling thread for
3473 * the specified file handle. The function does not cancel
3474 * I/O operations issued for the file handle by other threads.
3475 * Parameters: HANDLE hFile file handle for which to cancel I/O
3476 * Variables :
3477 * Result : If the function succeeds, the return value is nonzero All pending
3478 * I/O operations issued by the calling thread for the file handle
3479 * were successfully canceled.
3480 * If the function fails, the return value is zero.
3481 * To get extended error information, call GetLastError.
3482 * Remark : If there are any I/O operations in progress for the specified
3483 * file HANDLE and they were issued by the calling thread, the
3484 * CancelIO function cancels them.
3485 * Note that the I/O operations must have been issued as
3486 * overlapped I/O. If they were not, the I/O operations would not
3487 * have returned to allow the thread to call the CancelIO function.
3488 * Calling the CancelIO function with a file handle that was not
3489 * opened with FILE_FLAG_OVERLAPPED does nothing.
3490 * All I/O operations that are canceled will complete with the
3491 * error ERROR_OPERATION_ABORTED. All completion notifications
3492 * for the I/O operations will occur normally.
3493 * Status :
3494 *
3495 * Author : Sander van Leeuwen
3496 *****************************************************************************/
3497BOOL WIN32API CancelIo(HANDLE hDevice)
3498{
3499 int iIndex; /* index into the handle table */
3500 BOOL fResult; /* result from the device handler's CloseHandle() */
3501 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3502
3503 /* validate handle */
3504 iIndex = _HMHandleQuery(hDevice); /* get the index */
3505 if (-1 == iIndex) /* error ? */
3506 {
3507 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3508 return (FALSE); /* signal failure */
3509 }
3510
3511 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3512
3513 if (!pHMHandle || !pHMHandle->pDeviceHandler)
3514 return ERROR_SYS_INTERNAL;
3515
3516 fResult = pHMHandle->pDeviceHandler->CancelIo(&pHMHandle->hmHandleData);
3517
3518 return (fResult); /* deliver return code */
3519}
3520
3521/*****************************************************************************
3522 * Name : HMOpenThreadToken
3523 * Purpose : router function for NtOpenThreadToken
3524 * Parameters:
3525 * Variables :
3526 * Result :
3527 * Remark :
3528 * Status :
3529 *
3530 * Author : SvL
3531 *****************************************************************************/
3532
3533DWORD HMOpenThreadToken(HANDLE ThreadHandle,
3534 DWORD DesiredAccess,
3535 DWORD OpenAsSelf,
3536 HANDLE *TokenHandle)
3537{
3538 int iIndex; /* index into the handle table */
3539 int iIndexNew; /* index into the handle table */
3540 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3541 PHMHANDLEDATA pHMHandleData;
3542 DWORD rc; /* API return code */
3543
3544 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3545
3546 iIndexNew = _HMHandleGetFree(); /* get free handle */
3547 if (-1 == iIndexNew) /* oops, no free handles ! */
3548 {
3549 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3550 return ERROR_NOT_ENOUGH_MEMORY;
3551 }
3552
3553 /* initialize the complete HMHANDLEDATA structure */
3554 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3555 pHMHandleData->dwAccess = DesiredAccess;
3556 pHMHandleData->dwShare = 0;
3557 pHMHandleData->dwCreation = 0;
3558 pHMHandleData->dwFlags = 0;
3559 pHMHandleData->lpHandlerData = NULL;
3560 pHMHandleData->dwInternalType = HMTYPE_THREADTOKEN;
3561
3562
3563 /* we've got to mark the handle as occupied here, since another device */
3564 /* could be created within the device handler -> deadlock */
3565
3566 /* write appropriate entry into the handle table if open succeeded */
3567 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3568 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3569
3570 /* call the device handler */
3571
3572 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3573 // a valid HandleManager-internal handle!
3574 rc = pDeviceHandler->OpenThreadToken(&TabWin32Handles[iIndexNew].hmHandleData,
3575 ThreadHandle,
3576 OpenAsSelf);
3577
3578 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3579 {
3580 FREEHANDLE(iIndexNew);
3581// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3582 return (rc); /* signal error */
3583 }
3584 else
3585 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3586
3587 *TokenHandle = iIndexNew; /* return valid handle */
3588 return STATUS_SUCCESS;
3589}
3590
3591/*****************************************************************************
3592 * Name : HMOpenProcessToken
3593 * Purpose : router function for NtOpenProcessToken
3594 * Parameters:
3595 * Variables :
3596 * Result :
3597 * Remark :
3598 * Status :
3599 *
3600 * Author : SvL
3601 *****************************************************************************/
3602DWORD HMOpenProcessToken(HANDLE ProcessHandle,
3603 DWORD DesiredAccess,
3604 DWORD dwUserData,
3605 HANDLE *TokenHandle)
3606{
3607 int iIndex; /* index into the handle table */
3608 int iIndexNew; /* index into the handle table */
3609 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3610 PHMHANDLEDATA pHMHandleData;
3611 DWORD rc; /* API return code */
3612
3613 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3614
3615 iIndexNew = _HMHandleGetFree(); /* get free handle */
3616 if (-1 == iIndexNew) /* oops, no free handles ! */
3617 {
3618 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3619 return ERROR_NOT_ENOUGH_MEMORY;
3620 }
3621
3622 /* initialize the complete HMHANDLEDATA structure */
3623 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3624 pHMHandleData->dwAccess = DesiredAccess;
3625 pHMHandleData->dwShare = 0;
3626 pHMHandleData->dwCreation = 0;
3627 pHMHandleData->dwFlags = 0;
3628 pHMHandleData->lpHandlerData = NULL;
3629 pHMHandleData->dwInternalType = HMTYPE_PROCESSTOKEN;
3630
3631
3632 /* we've got to mark the handle as occupied here, since another device */
3633 /* could be created within the device handler -> deadlock */
3634
3635 /* write appropriate entry into the handle table if open succeeded */
3636 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3637 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3638
3639 /* call the device handler */
3640
3641 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3642 // a valid HandleManager-internal handle!
3643 rc = pDeviceHandler->OpenProcessToken(&TabWin32Handles[iIndexNew].hmHandleData,
3644 dwUserData,
3645 ProcessHandle);
3646
3647 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3648 {
3649 FREEHANDLE(iIndexNew);
3650// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3651 return (rc); /* signal error */
3652 }
3653 else
3654 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3655
3656 *TokenHandle = iIndexNew; /* return valid handle */
3657 return STATUS_SUCCESS;
3658}
3659
3660
3661/**
3662 * Gets the type of an object.
3663 *
3664 * @returns the value of one of the HMMTYPE_ defines.
3665 * @returns HMTYPE_BAD_HANDLE if hObject isn't a valid handle.
3666 * @param hObject Handle to object.
3667 */
3668unsigned WIN32API HMQueryObjectType(HANDLE hObject)
3669{
3670 PHMHANDLEDATA pData = HMQueryHandleData(hObject);
3671 if (pData)
3672 return (unsigned)pData->dwInternalType;
3673 return HMTYPE_BAD_HANDLE;
3674}
3675
3676} // extern "C"
3677
Note: See TracBrowser for help on using the repository browser.