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

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