source: branches/gcc-kmk/src/kernel32/HandleManager.cpp@ 21730

Last change on this file since 21730 was 21730, checked in by dmik, 14 years ago

Common compiler warnings and errors.

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