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

Last change on this file since 21324 was 21324, checked in by ydario, 16 years ago

kernel32 implemented SetFilePointerEx and SetWaitableTimer.

File size: 133.5 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 (4*1024)
87
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 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
1781 lpBuffer,
1782 nNumberOfBytesToRead,
1783 lpNumberOfBytesRead,
1784 lpOverlapped, lpCompletionRoutine);
1785
1786 return (fResult); /* deliver return code */
1787}
1788
1789/*****************************************************************************
1790 * Name : HANDLE HMWriteFile
1791 * Purpose : Wrapper for the WriteHandle() API
1792 * Parameters:
1793 * Variables :
1794 * Result :
1795 * Remark :
1796 * Status :
1797 *
1798 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1799 *****************************************************************************/
1800
1801BOOL HMWriteFile(HANDLE hFile,
1802 LPCVOID lpBuffer,
1803 DWORD nNumberOfBytesToWrite,
1804 LPDWORD lpNumberOfBytesWritten,
1805 LPOVERLAPPED lpOverlapped,
1806 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
1807{
1808 int iIndex; /* index into the handle table */
1809 BOOL fResult; /* result from the device handler's CloseHandle() */
1810 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1811
1812 /* validate handle */
1813 iIndex = _HMHandleQuery(hFile); /* get the index */
1814 if (-1 == iIndex) /* error ? */
1815 {
1816 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1817 return (FALSE); /* signal failure */
1818 }
1819
1820 /* watcom hack:
1821 * watcom may write -1 bytes to a device during flushall(), we should return
1822 * ERROR_NOT_ENOUGH_MEMORY or ERROR_NO_ACCESS
1823 */
1824 if (nNumberOfBytesToWrite == 0xffffffff)
1825 {
1826 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1827 return FALSE;
1828 }
1829
1830 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1831 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
1832 lpBuffer,
1833 nNumberOfBytesToWrite,
1834 lpNumberOfBytesWritten,
1835 lpOverlapped, lpCompletionRoutine);
1836
1837 return (fResult); /* deliver return code */
1838}
1839
1840
1841/*****************************************************************************
1842 * Name : HANDLE HMGetFileType
1843 * Purpose : Wrapper for the GetFileType() API
1844 * Parameters:
1845 * Variables :
1846 * Result :
1847 * Remark :
1848 * Status :
1849 *
1850 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1851 *****************************************************************************/
1852
1853DWORD WIN32API GetFileType(HANDLE hFile)
1854{
1855 int iIndex; /* index into the handle table */
1856 DWORD dwResult; /* result from the device handler's API */
1857 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1858
1859 /* validate handle */
1860 iIndex = _HMHandleQuery(hFile); /* get the index */
1861 if (-1 == iIndex) /* error ? */
1862 {
1863 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1864 return FILE_TYPE_UNKNOWN; /* signal failure */
1865 }
1866
1867 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1868 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1869
1870 return (dwResult); /* deliver return code */
1871}
1872
1873
1874/*****************************************************************************
1875 * Name : HMDeviceHandler::_DeviceReuqest
1876 * Purpose : entry method for special request functions
1877 * Parameters: ULONG ulRequestCode
1878 * various parameters as required
1879 * Variables :
1880 * Result :
1881 * Remark : the standard behaviour is to return an error code for non-
1882 * existant request codes
1883 * Status :
1884 *
1885 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1886 *****************************************************************************/
1887
1888DWORD HMDeviceRequest (HANDLE hFile,
1889 ULONG ulRequestCode,
1890 ULONG arg1,
1891 ULONG arg2,
1892 ULONG arg3,
1893 ULONG arg4)
1894{
1895 int iIndex; /* index into the handle table */
1896 DWORD dwResult; /* result from the device handler's API */
1897 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1898
1899 /* validate handle */
1900 iIndex = _HMHandleQuery(hFile); /* get the index */
1901 if (-1 == iIndex) /* error ? */
1902 {
1903 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1904 return (INVALID_HANDLE_ERROR); /* signal failure */
1905 }
1906
1907 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1908 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1909 ulRequestCode,
1910 arg1,
1911 arg2,
1912 arg3,
1913 arg4);
1914
1915 return (dwResult); /* deliver return code */
1916}
1917
1918
1919/*****************************************************************************
1920 * Name : HMDeviceHandler::GetFileInformationByHandle
1921 * Purpose : router function for GetFileInformationByHandle
1922 * Parameters:
1923 * Variables :
1924 * Result :
1925 * Remark :
1926 * Status :
1927 *
1928 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1929 *****************************************************************************/
1930
1931BOOL WIN32API GetFileInformationByHandle (HANDLE hFile,
1932 BY_HANDLE_FILE_INFORMATION *pHFI)
1933{
1934 int iIndex; /* index into the handle table */
1935 DWORD dwResult; /* result from the device handler's API */
1936 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1937
1938 /* validate handle */
1939 iIndex = _HMHandleQuery(hFile); /* get the index */
1940 if (-1 == iIndex) /* error ? */
1941 {
1942 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1943 return FALSE; /* signal failure */
1944 }
1945
1946 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1947 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
1948 pHFI);
1949
1950 return (dwResult); /* deliver return code */
1951}
1952
1953
1954/*****************************************************************************
1955 * Name : HMDeviceHandler::SetEndOfFile
1956 * Purpose : router function for SetEndOfFile
1957 * Parameters:
1958 * Variables :
1959 * Result :
1960 * Remark :
1961 * Status :
1962 *
1963 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1964 *****************************************************************************/
1965
1966BOOL WIN32API SetEndOfFile (HANDLE hFile)
1967{
1968 int iIndex; /* index into the handle table */
1969 BOOL bResult; /* result from the device handler's API */
1970 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1971
1972 /* validate handle */
1973 iIndex = _HMHandleQuery(hFile); /* get the index */
1974 if (-1 == iIndex) /* error ? */
1975 {
1976 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1977 return FALSE; /* signal failure */
1978 }
1979
1980 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1981 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
1982
1983 return (bResult); /* deliver return code */
1984}
1985
1986
1987/*****************************************************************************
1988 * Name : HMDeviceHandler::SetFileTime
1989 * Purpose : router function for SetFileTime
1990 * Parameters:
1991 * Variables :
1992 * Result :
1993 * Remark :
1994 * Status :
1995 *
1996 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1997 *****************************************************************************/
1998
1999BOOL WIN32API SetFileTime (HANDLE hFile,
2000 const FILETIME *pFT1,
2001 const FILETIME *pFT2,
2002 const FILETIME *pFT3)
2003{
2004 int iIndex; /* index into the handle table */
2005 BOOL bResult; /* result from the device handler's API */
2006 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2007
2008 /* validate handle */
2009 iIndex = _HMHandleQuery(hFile); /* get the index */
2010 if (-1 == iIndex) /* error ? */
2011 {
2012 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2013 return FALSE; /* signal failure */
2014 }
2015
2016 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2017 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
2018 (LPFILETIME)pFT1,
2019 (LPFILETIME)pFT2,
2020 (LPFILETIME)pFT3);
2021
2022 return (bResult); /* deliver return code */
2023}
2024
2025/*****************************************************************************
2026 * Name : HMDeviceHandler::GetFileTime
2027 * Purpose : router function for SetFileTime
2028 * Parameters:
2029 * Variables :
2030 * Result :
2031 * Remark :
2032 * Status :
2033 *
2034 * Author : SvL
2035 *****************************************************************************/
2036
2037BOOL WIN32API GetFileTime (HANDLE hFile, FILETIME *pFT1,
2038 FILETIME *pFT2, FILETIME *pFT3)
2039{
2040 int iIndex; /* index into the handle table */
2041 BOOL bResult; /* result from the device handler's API */
2042 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2043
2044 /* validate handle */
2045 iIndex = _HMHandleQuery(hFile); /* get the index */
2046 if (-1 == iIndex) /* error ? */
2047 {
2048 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2049 return FALSE; /* signal failure */
2050 }
2051
2052 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2053 bResult = pHMHandle->pDeviceHandler->GetFileTime(&pHMHandle->hmHandleData,
2054 (LPFILETIME)pFT1,
2055 (LPFILETIME)pFT2,
2056 (LPFILETIME)pFT3);
2057
2058 return (bResult); /* deliver return code */
2059}
2060
2061
2062/*****************************************************************************
2063 * Name : HMDeviceHandler::GetFileSize
2064 * Purpose : router function for GetFileSize
2065 * Parameters:
2066 * Variables :
2067 * Result :
2068 * Remark :
2069 * Status :
2070 *
2071 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2072 *****************************************************************************/
2073
2074DWORD WIN32API GetFileSize (HANDLE hFile, PDWORD pSize)
2075{
2076 int iIndex; /* index into the handle table */
2077 DWORD dwResult; /* result from the device handler's API */
2078 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2079
2080 /* validate handle */
2081 iIndex = _HMHandleQuery(hFile); /* get the index */
2082 if (-1 == iIndex) /* error ? */
2083 {
2084 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2085 return -1; //INVALID_SET_FILE_POINTER
2086 }
2087
2088 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2089 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
2090 pSize);
2091
2092 return (dwResult); /* deliver return code */
2093}
2094
2095
2096/*****************************************************************************
2097 * Name : HMDeviceHandler::SetFilePointer
2098 * Purpose : router function for SetFilePointer
2099 * Parameters:
2100 * Variables :
2101 * Result :
2102 * Remark :
2103 * Status :
2104 *
2105 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2106 *****************************************************************************/
2107
2108DWORD WIN32API SetFilePointer (HANDLE hFile,
2109 LONG lDistanceToMove,
2110 PLONG lpDistanceToMoveHigh,
2111 DWORD dwMoveMethod)
2112{
2113 int iIndex; /* index into the handle table */
2114 DWORD dwResult; /* result from the device handler's API */
2115 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2116
2117 /* validate handle */
2118 iIndex = _HMHandleQuery(hFile); /* get the index */
2119 if (-1 == iIndex) /* error ? */
2120 {
2121 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2122 return (INVALID_HANDLE_ERROR); /* signal failure */
2123 }
2124
2125 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2126 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
2127 lDistanceToMove,
2128 lpDistanceToMoveHigh,
2129 dwMoveMethod);
2130
2131 return (dwResult); /* deliver return code */
2132}
2133
2134/***********************************************************************
2135 * SetFilePointerEx (KERNEL32.@)
2136 */
2137BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
2138 LARGE_INTEGER *newpos, DWORD method )
2139{
2140 LONG pos;
2141 LONG newp;
2142 BOOL res;
2143
2144 dprintf(("KERNEL32::SetFilePointerEx"));
2145
2146 pos = (LONG)distance.LowPart;
2147 res = SetFilePointer(hFile, pos, &newp, method);
2148 if (res != -1)
2149 {
2150 if (newpos) newpos->LowPart = (LONG)res;
2151 return TRUE;
2152 }
2153 return FALSE;
2154}
2155
2156
2157/*****************************************************************************
2158 * Name : HMDeviceHandler::LockFile
2159 * Purpose : router function for LockFile
2160 * Parameters:
2161 * Variables :
2162 * Result :
2163 * Remark :
2164 * Status :
2165 *
2166 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2167 *****************************************************************************/
2168
2169BOOL WIN32API LockFile (HANDLE hFile,
2170 DWORD arg2,
2171 DWORD arg3,
2172 DWORD arg4,
2173 DWORD arg5)
2174{
2175 int iIndex; /* index into the handle table */
2176 DWORD dwResult; /* result from the device handler's API */
2177 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2178
2179 /* validate handle */
2180 iIndex = _HMHandleQuery(hFile); /* get the index */
2181 if (-1 == iIndex) /* error ? */
2182 {
2183 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2184 return FALSE; /* signal failure */
2185 }
2186
2187 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2188 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
2189 arg2,
2190 arg3,
2191 arg4,
2192 arg5);
2193
2194 return (dwResult); /* deliver return code */
2195}
2196
2197
2198/*****************************************************************************
2199 * Name : BOOL LockFileEx
2200 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
2201 * Parameters: HANDLE hFile handle of file to lock
2202 * DWORD dwFlags functional behavior modification flags
2203 * DWORD dwReserved reserved, must be set to zero
2204 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2205 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2206 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2207 * Variables :
2208 * Result : TRUE / FALSE
2209 * Remark :
2210 * Status : UNTESTED STUB
2211 *
2212 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2213 *****************************************************************************/
2214
2215BOOL WIN32API LockFileEx(HANDLE hFile,
2216 DWORD dwFlags,
2217 DWORD dwReserved,
2218 DWORD nNumberOfBytesToLockLow,
2219 DWORD nNumberOfBytesToLockHigh,
2220 LPOVERLAPPED lpOverlapped)
2221{
2222 int iIndex; /* index into the handle table */
2223 BOOL dwResult; /* result from the device handler's API */
2224 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2225
2226 /* validate handle */
2227 iIndex = _HMHandleQuery(hFile); /* get the index */
2228 if (-1 == iIndex) /* error ? */
2229 {
2230 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2231 return FALSE; /* signal failure */
2232 }
2233
2234 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2235 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
2236 dwFlags,
2237 dwReserved,
2238 nNumberOfBytesToLockLow,
2239 nNumberOfBytesToLockHigh,
2240 lpOverlapped);
2241
2242 return (dwResult); /* deliver return code */
2243}
2244
2245
2246
2247/*****************************************************************************
2248 * Name : HMDeviceHandler::UnlockFile
2249 * Purpose : router function for UnlockFile
2250 * Parameters:
2251 * Variables :
2252 * Result :
2253 * Remark :
2254 * Status :
2255 *
2256 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2257 *****************************************************************************/
2258
2259BOOL WIN32API UnlockFile (HANDLE hFile,
2260 DWORD arg2,
2261 DWORD arg3,
2262 DWORD arg4,
2263 DWORD arg5)
2264{
2265 int iIndex; /* index into the handle table */
2266 BOOL dwResult; /* result from the device handler's API */
2267 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2268
2269 /* validate handle */
2270 iIndex = _HMHandleQuery(hFile); /* get the index */
2271 if (-1 == iIndex) /* error ? */
2272 {
2273 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2274 return FALSE; /* signal failure */
2275 }
2276
2277 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2278 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
2279 arg2,
2280 arg3,
2281 arg4,
2282 arg5);
2283
2284 return (dwResult); /* deliver return code */
2285}
2286
2287
2288/*****************************************************************************
2289 * Name : BOOL UnlockFileEx
2290 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
2291 * Parameters: HANDLE hFile handle of file to lock
2292 * DWORD dwReserved reserved, must be set to zero
2293 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
2294 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
2295 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
2296 * Variables :
2297 * Result : TRUE / FALSE
2298 * Remark :
2299 * Status : UNTESTED STUB
2300 *
2301 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
2302 *****************************************************************************/
2303
2304BOOL WIN32API UnlockFileEx(HANDLE hFile,
2305 DWORD dwReserved,
2306 DWORD nNumberOfBytesToLockLow,
2307 DWORD nNumberOfBytesToLockHigh,
2308 LPOVERLAPPED lpOverlapped)
2309{
2310 int iIndex; /* index into the handle table */
2311 BOOL dwResult; /* result from the device handler's API */
2312 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2313
2314 /* validate handle */
2315 iIndex = _HMHandleQuery(hFile); /* get the index */
2316 if (-1 == iIndex) /* error ? */
2317 {
2318 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2319 return FALSE; /* signal failure */
2320 }
2321
2322 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2323 dwResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
2324 dwReserved,
2325 nNumberOfBytesToLockLow,
2326 nNumberOfBytesToLockHigh,
2327 lpOverlapped);
2328
2329 return (dwResult); /* deliver return code */
2330}
2331
2332
2333/*****************************************************************************
2334 * Name : HMDeviceHandler::WaitForSingleObject
2335 * Purpose : router function for WaitForSingleObject
2336 * Parameters:
2337 * Variables :
2338 * Result :
2339 * Remark :
2340 * Status :
2341 *
2342 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2343 *****************************************************************************/
2344
2345DWORD HMWaitForSingleObject(HANDLE hObject,
2346 DWORD dwTimeout)
2347{
2348 int iIndex; /* index into the handle table */
2349 BOOL dwResult; /* result from the device handler's API */
2350 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2351
2352 /* validate handle */
2353 iIndex = _HMHandleQuery(hObject); /* get the index */
2354 if (-1 == iIndex) /* error ? */
2355 {
2356 dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n",
2357 hObject));
2358
2359 if(dwTimeout == INFINITE) {
2360 //Workaround for applications that block the PM input queue
2361 //while waiting for a child process to terminate.
2362 //(WaitSingleObject now calls MsgWaitMultipleObjects and
2363 // processes messages while waiting for the process to die)
2364 //(Napster install now doesn't block PM anymore (forcing a reboot))
2365
2366 HMODULE hUser32 = LoadLibraryA("USER32.DLL");
2367
2368 BOOL (* WINAPI pfnPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT);
2369 LONG (* WINAPI pfnDispatchMessageA)(const MSG*);
2370
2371 *(FARPROC *)&pfnPeekMessageA = GetProcAddress(hUser32,"PeekMessageA");
2372 *(FARPROC *)&pfnDispatchMessageA = GetProcAddress(hUser32,"DispatchMessageA");
2373
2374 TEB *teb = GetThreadTEB();
2375
2376 if(!teb || !pfnPeekMessageA || !pfnDispatchMessageA) {
2377 dprintf(("ERROR: !teb || !pfnPeekMessageA || !pfnDispatchMessageA"));
2378 DebugInt3();
2379 return WAIT_FAILED;
2380 }
2381
2382 //TODO: Ignoring all messages could be dangerous. But processing them,
2383 //while the app doesn't expect any, isn't safe either.
2384//-> must active check in pmwindow.cpp if this is enabled again!
2385// teb->o.odin.fIgnoreMsgs = TRUE;
2386
2387 while(TRUE) {
2388 dwResult = HMMsgWaitForMultipleObjects(1, &hObject, FALSE,
2389 INFINITE, QS_ALLINPUT);
2390 if(dwResult == WAIT_OBJECT_0 + 1) {
2391 MSG msg ;
2392
2393 while (pfnPeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
2394 {
2395 if (msg.message == WM_QUIT) {
2396 dprintf(("ERROR: WaitForSingleObject call abandoned because WM_QUIT msg was received!!"));
2397// teb->o.odin.fIgnoreMsgs = FALSE;
2398 FreeLibrary(hUser32);
2399 return WAIT_ABANDONED;
2400 }
2401
2402 /* otherwise dispatch it */
2403 pfnDispatchMessageA(&msg);
2404
2405 } // end of PeekMessage while loop
2406 }
2407 else {
2408 dprintf(("WaitForSingleObject: Process %x terminated", hObject));
2409 break;
2410 }
2411 }
2412// teb->o.odin.fIgnoreMsgs = FALSE;
2413 FreeLibrary(hUser32);
2414 return dwResult;
2415 }
2416 else {
2417 // maybe handles from CreateProcess() ...
2418 dwResult = O32_WaitForSingleObject(hObject, dwTimeout);
2419 return (dwResult);
2420 }
2421 }
2422 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2423 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObject(&pHMHandle->hmHandleData,
2424 dwTimeout);
2425
2426 return (dwResult); /* deliver return code */
2427}
2428
2429
2430/*****************************************************************************
2431 * Name : HMDeviceHandler::WaitForSingleObjectEx
2432 * Purpose : router function for WaitForSingleObjectEx
2433 * Parameters:
2434 * Variables :
2435 * Result :
2436 * Remark :
2437 * Status :
2438 *
2439 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2440 *****************************************************************************/
2441
2442DWORD HMWaitForSingleObjectEx(HANDLE hObject,
2443 DWORD dwTimeout,
2444 BOOL fAlertable)
2445{
2446 int iIndex; /* index into the handle table */
2447 DWORD dwResult; /* result from the device handler's API */
2448 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2449
2450 /* validate handle */
2451 iIndex = _HMHandleQuery(hObject); /* get the index */
2452 if (-1 == iIndex) /* error ? */
2453 {
2454 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2455 return WAIT_FAILED; /* signal failure */
2456 }
2457
2458 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2459 dwResult = pHMHandle->pDeviceHandler->WaitForSingleObjectEx(&pHMHandle->hmHandleData,
2460 dwTimeout,
2461 fAlertable);
2462
2463 return (dwResult); /* deliver return code */
2464}
2465
2466
2467/*****************************************************************************
2468 * Name : HMDeviceHandler::FlushFileBuffers
2469 * Purpose : router function for FlushFileBuffers
2470 * Parameters:
2471 * Variables :
2472 * Result :
2473 * Remark :
2474 * Status :
2475 *
2476 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2477 *****************************************************************************/
2478
2479BOOL WIN32API FlushFileBuffers(HANDLE hFile)
2480{
2481 int iIndex; /* index into the handle table */
2482 DWORD dwResult; /* result from the device handler's API */
2483 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2484
2485 /* validate handle */
2486 iIndex = _HMHandleQuery(hFile); /* get the index */
2487 if (-1 == iIndex) /* error ? */
2488 {
2489 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2490 return FALSE; /* signal failure */
2491 }
2492
2493 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2494 dwResult = pHMHandle->pDeviceHandler->FlushFileBuffers(&pHMHandle->hmHandleData);
2495
2496 return (dwResult); /* deliver return code */
2497}
2498
2499
2500/*****************************************************************************
2501 * Name : HMDeviceHandler::GetOverlappedResult
2502 * Purpose : router function for GetOverlappedResult
2503 * Parameters:
2504 * Variables :
2505 * Result :
2506 * Remark :
2507 * Status :
2508 *
2509 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2510 *****************************************************************************/
2511
2512BOOL HMGetOverlappedResult(HANDLE hObject,
2513 LPOVERLAPPED lpOverlapped,
2514 LPDWORD arg3,
2515 BOOL arg4)
2516{
2517 int iIndex; /* index into the handle table */
2518 DWORD dwResult; /* result from the device handler's API */
2519 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2520
2521 /* validate handle */
2522 iIndex = _HMHandleQuery(hObject); /* get the index */
2523 if (-1 == iIndex) /* error ? */
2524 {
2525 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2526 return FALSE; /* signal failure */
2527 }
2528
2529 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2530 dwResult = pHMHandle->pDeviceHandler->GetOverlappedResult(&pHMHandle->hmHandleData,
2531 lpOverlapped,
2532 arg3,
2533 arg4);
2534
2535 return (dwResult); /* deliver return code */
2536}
2537
2538
2539/*****************************************************************************
2540 * Name : HMReleaseMutex
2541 * Purpose : router function for ReleaseMutex
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 ReleaseMutex(HANDLE hObject)
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(hObject); /* 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 dwResult = pHMHandle->pDeviceHandler->ReleaseMutex(&pHMHandle->hmHandleData);
2567
2568 return (dwResult); /* deliver return code */
2569}
2570
2571
2572
2573
2574/*****************************************************************************
2575 * Name : HANDLE HMCreateMutex
2576 * Purpose : Wrapper for the CreateMutex() API
2577 * Parameters:
2578 * Variables :
2579 * Result :
2580 * Remark :
2581 * Status :
2582 *
2583 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2584 *****************************************************************************/
2585
2586HANDLE WIN32API CreateMutexA(LPSECURITY_ATTRIBUTES lpsa,
2587 BOOL bInitialOwner,
2588 LPCTSTR lpName)
2589{
2590 int iIndex; /* index into the handle table */
2591 int iIndexNew; /* index into the handle table */
2592 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2593 PHMHANDLEDATA pHMHandleData;
2594 DWORD rc; /* API return code */
2595
2596
2597 if(lpName) { //check if shared mutex semaphore already exists
2598 dprintf(("Event semaphore name %s", lpName));
2599
2600 //TODO: No inheritance??
2601 HANDLE handle = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, lpName);
2602 if(handle) {
2603 dprintf(("CreateMutex: return handle of existing mutex semaphore %x", handle));
2604 SetLastError(ERROR_ALREADY_EXISTS);
2605 return handle;
2606 }
2607 }
2608
2609 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2610
2611 iIndexNew = _HMHandleGetFree(); /* get free handle */
2612 if (-1 == iIndexNew) /* oops, no free handles ! */
2613 {
2614 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2615 return 0; /* signal error */
2616 }
2617
2618
2619 /* initialize the complete HMHANDLEDATA structure */
2620 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2621 pHMHandleData->dwAccess = 0;
2622 pHMHandleData->dwShare = 0;
2623 pHMHandleData->dwCreation = 0;
2624 pHMHandleData->dwFlags = 0;
2625 pHMHandleData->lpHandlerData = NULL;
2626 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2627
2628
2629 /* we've got to mark the handle as occupied here, since another device */
2630 /* could be created within the device handler -> deadlock */
2631
2632 /* write appropriate entry into the handle table if open succeeded */
2633 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2634 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2635
2636 /* call the device handler */
2637 rc = pDeviceHandler->CreateMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2638 lpsa,
2639 bInitialOwner,
2640 lpName);
2641 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2642 {
2643 FREEHANDLE(iIndexNew);
2644// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2645 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2646 return 0; /* signal error */
2647 }
2648 else
2649 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2650
2651 return iIndexNew; /* return valid handle */
2652}
2653
2654
2655
2656/*****************************************************************************
2657 * Name : HANDLE HMOpenMutex
2658 * Purpose : Wrapper for the OpenMutex() API
2659 * Parameters:
2660 * Variables :
2661 * Result :
2662 * Remark :
2663 * Status :
2664 *
2665 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2666 *****************************************************************************/
2667
2668HANDLE WIN32API OpenMutexA(DWORD fdwAccess,
2669 BOOL fInherit,
2670 LPCTSTR lpName)
2671{
2672 int iIndex; /* index into the handle table */
2673 int iIndexNew; /* index into the handle table */
2674 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2675 PHMHANDLEDATA pHMHandleData;
2676 DWORD rc; /* API return code */
2677
2678
2679 if(lpName) {
2680 dprintf(("Mutex semaphore name %s", lpName));
2681 }
2682
2683 pDeviceHandler = HMGlobals.pHMMutex; /* device is predefined */
2684
2685 iIndexNew = _HMHandleGetFree(); /* get free handle */
2686 if (-1 == iIndexNew) /* oops, no free handles ! */
2687 {
2688 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2689 return 0; /* signal error */
2690 }
2691
2692
2693 /* initialize the complete HMHANDLEDATA structure */
2694 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2695 pHMHandleData->dwAccess = fdwAccess;
2696 pHMHandleData->dwShare = 0;
2697 pHMHandleData->dwCreation = 0;
2698 pHMHandleData->dwFlags = 0;
2699 pHMHandleData->lpHandlerData = NULL;
2700 pHMHandleData->dwInternalType = HMTYPE_MUTEXSEM;
2701
2702
2703 /* we've got to mark the handle as occupied here, since another device */
2704 /* could be created within the device handler -> deadlock */
2705
2706 /* write appropriate entry into the handle table if open succeeded */
2707 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2708 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2709
2710 /* call the device handler */
2711 rc = pDeviceHandler->OpenMutex(&TabWin32Handles[iIndexNew].hmHandleData,
2712 fInherit,
2713 lpName);
2714 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2715 {
2716 FREEHANDLE(iIndexNew);
2717// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2718 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2719 return 0; /* signal error */
2720 }
2721 else
2722 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2723
2724 return iIndexNew; /* return valid handle */
2725}
2726
2727
2728/*****************************************************************************
2729 * Name : HANDLE HMCreateSemaphore
2730 * Purpose : Wrapper for the CreateSemaphore() API
2731 * Parameters:
2732 * Variables :
2733 * Result :
2734 * Remark :
2735 * Status :
2736 *
2737 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2738 *****************************************************************************/
2739
2740HANDLE WIN32API CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpsa,
2741 LONG lInitialCount,
2742 LONG lMaximumCount,
2743 LPCTSTR lpName)
2744{
2745 int iIndex; /* index into the handle table */
2746 int iIndexNew; /* index into the handle table */
2747 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2748 PHMHANDLEDATA pHMHandleData;
2749 DWORD rc; /* API return code */
2750
2751 if(lpName) { //check if shared event semaphore already exists
2752 //TODO: No inheritance??
2753 dprintf(("Semaphore name %s", lpName));
2754
2755 HANDLE handle = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, lpName);
2756 if(handle) {
2757 dprintf(("CreateSemaphore: return handle of existing semaphore %x", handle));
2758 SetLastError(ERROR_ALREADY_EXISTS);
2759 return handle;
2760 }
2761 }
2762
2763 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2764
2765 iIndexNew = _HMHandleGetFree(); /* get free handle */
2766 if (-1 == iIndexNew) /* oops, no free handles ! */
2767 {
2768 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2769 return 0; /* signal error */
2770 }
2771
2772
2773 /* initialize the complete HMHANDLEDATA structure */
2774 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2775 pHMHandleData->dwAccess = 0;
2776 pHMHandleData->dwShare = 0;
2777 pHMHandleData->dwCreation = 0;
2778 pHMHandleData->dwFlags = 0;
2779 pHMHandleData->lpHandlerData = NULL;
2780 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2781
2782
2783 /* we've got to mark the handle as occupied here, since another device */
2784 /* could be created within the device handler -> deadlock */
2785
2786 /* write appropriate entry into the handle table if open succeeded */
2787 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2788 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2789
2790 /* call the device handler */
2791 rc = pDeviceHandler->CreateSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2792 lpsa,
2793 lInitialCount,
2794 lMaximumCount,
2795 lpName);
2796 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2797 {
2798 FREEHANDLE(iIndexNew);
2799// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2800 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2801 return 0; /* signal failure */
2802 }
2803 else
2804 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2805
2806 return iIndexNew; /* return valid handle */
2807}
2808
2809
2810/*****************************************************************************
2811 * Name : HANDLE HMOpenSemaphore
2812 * Purpose : Wrapper for the OpenSemaphore() API
2813 * Parameters:
2814 * Variables :
2815 * Result :
2816 * Remark :
2817 * Status :
2818 *
2819 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2820 *****************************************************************************/
2821
2822HANDLE WIN32API OpenSemaphoreA(DWORD fdwAccess,
2823 BOOL fInherit,
2824 LPCTSTR lpName)
2825{
2826 int iIndex; /* index into the handle table */
2827 int iIndexNew; /* index into the handle table */
2828 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2829 PHMHANDLEDATA pHMHandleData;
2830 DWORD rc; /* API return code */
2831
2832
2833 if(lpName) {
2834 dprintf(("Semaphore name %s", lpName));
2835 }
2836
2837 pDeviceHandler = HMGlobals.pHMSemaphore; /* device is predefined */
2838
2839 iIndexNew = _HMHandleGetFree(); /* get free handle */
2840 if (-1 == iIndexNew) /* oops, no free handles ! */
2841 {
2842 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2843 return 0; /* signal error */
2844 }
2845
2846
2847 /* initialize the complete HMHANDLEDATA structure */
2848 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2849 pHMHandleData->dwAccess = fdwAccess;
2850 pHMHandleData->dwShare = 0;
2851 pHMHandleData->dwCreation = 0;
2852 pHMHandleData->dwFlags = 0;
2853 pHMHandleData->lpHandlerData = NULL;
2854 pHMHandleData->dwInternalType = HMTYPE_SEMAPHORE;
2855
2856
2857 /* we've got to mark the handle as occupied here, since another device */
2858 /* could be created within the device handler -> deadlock */
2859
2860 /* write appropriate entry into the handle table if open succeeded */
2861 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2862 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2863
2864 /* call the device handler */
2865 rc = pDeviceHandler->OpenSemaphore(&TabWin32Handles[iIndexNew].hmHandleData,
2866 fInherit,
2867 lpName);
2868 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
2869 {
2870 FREEHANDLE(iIndexNew);
2871// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2872 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2873 return 0; /* signal failure */
2874 }
2875 else
2876 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2877
2878 return iIndexNew; /* return valid handle */
2879}
2880
2881
2882/*****************************************************************************
2883 * Name : HMReleaseSemaphore
2884 * Purpose : router function for ReleaseSemaphore
2885 * Parameters:
2886 * Variables :
2887 * Result :
2888 * Remark :
2889 * Status :
2890 *
2891 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
2892 *****************************************************************************/
2893
2894BOOL WIN32API ReleaseSemaphore(HANDLE hEvent,
2895 LONG cReleaseCount,
2896 LPLONG lpPreviousCount)
2897{
2898 int iIndex; /* index into the handle table */
2899 DWORD dwResult; /* result from the device handler's API */
2900 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
2901
2902 /* validate handle */
2903 iIndex = _HMHandleQuery(hEvent); /* get the index */
2904 if (-1 == iIndex) /* error ? */
2905 {
2906 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
2907 return 0; /* signal failure */
2908 }
2909 else
2910 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2911
2912 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
2913 dwResult = pHMHandle->pDeviceHandler->ReleaseSemaphore(&pHMHandle->hmHandleData,
2914 cReleaseCount,
2915 lpPreviousCount);
2916
2917 return (dwResult); /* deliver return code */
2918}
2919
2920
2921/*****************************************************************************
2922 * Name : HANDLE HMCreateFileMapping
2923 * Purpose : Wrapper for the CreateFileMapping() API
2924 * Parameters:
2925 * Variables :
2926 * Result :
2927 * Remark :
2928 * Status :
2929 *
2930 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
2931 *****************************************************************************/
2932
2933HANDLE HMCreateFileMapping(HANDLE hFile,
2934 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
2935 DWORD flProtect,
2936 DWORD dwMaximumSizeHigh,
2937 DWORD dwMaximumSizeLow,
2938 LPCTSTR lpName)
2939{
2940 int iIndex; /* index into the handle table */
2941 int iIndexNew; /* index into the handle table */
2942 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
2943 PHMHANDLEDATA pHMHandleData;
2944 DWORD rc; /* API return code */
2945
2946 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
2947
2948 iIndexNew = _HMHandleGetFree(); /* get free handle */
2949 if (-1 == iIndexNew) /* oops, no free handles ! */
2950 {
2951 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
2952 return 0; /* signal error */
2953 }
2954
2955 /* initialize the complete HMHANDLEDATA structure */
2956 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
2957 pHMHandleData->dwAccess = 0;
2958 pHMHandleData->dwShare = 0;
2959 pHMHandleData->dwCreation = 0;
2960 pHMHandleData->dwFlags = 0;
2961 pHMHandleData->lpHandlerData = NULL;
2962 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
2963
2964 /* we've got to mark the handle as occupied here, since another device */
2965 /* could be created within the device handler -> deadlock */
2966
2967 /* write appropriate entry into the handle table if open succeeded */
2968 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
2969 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
2970
2971 /* call the device handler */
2972
2973 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
2974 // a valid HandleManager-internal handle!
2975 rc = pDeviceHandler->CreateFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
2976 hFile,
2977 lpFileMappingAttributes,
2978 flProtect,
2979 dwMaximumSizeHigh,
2980 dwMaximumSizeLow,
2981 lpName);
2982
2983 if(rc != NO_ERROR) /* oops, creation failed within the device handler */
2984 {
2985 if(rc != ERROR_ALREADY_EXISTS) {
2986 FREEHANDLE(iIndexNew);
2987// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
2988 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
2989 return (NULL); /* signal error */
2990 }
2991 SetLastError(ERROR_ALREADY_EXISTS);
2992 return iIndexNew; /* return valid handle */
2993 }
2994 else
2995 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
2996
2997 return iIndexNew; /* return valid handle */
2998}
2999
3000
3001/*****************************************************************************
3002 * Name : HANDLE HMOpenFileMapping
3003 * Purpose : Wrapper for the OpenFileMapping() API
3004 * Parameters:
3005 * Variables :
3006 * Result : HANDLE if succeeded,
3007 * NULL if failed.
3008 * Remark :
3009 * Status :
3010 *
3011 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
3012 *****************************************************************************/
3013
3014HANDLE HMOpenFileMapping(DWORD fdwAccess,
3015 BOOL fInherit,
3016 LPCTSTR lpName)
3017{
3018 int iIndex; /* index into the handle table */
3019 int iIndexNew; /* index into the handle table */
3020 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3021 PHMHANDLEDATA pHMHandleData;
3022 DWORD rc; /* API return code */
3023
3024
3025 pDeviceHandler = HMGlobals.pHMFileMapping; /* device is predefined */
3026
3027 iIndexNew = _HMHandleGetFree(); /* get free handle */
3028 if (-1 == iIndexNew) /* oops, no free handles ! */
3029 {
3030 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3031 return (NULL); /* signal error */
3032 }
3033
3034 /* initialize the complete HMHANDLEDATA structure */
3035 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3036 pHMHandleData->dwAccess = fdwAccess;
3037 pHMHandleData->dwShare = 0;
3038 pHMHandleData->dwCreation = 0;
3039 pHMHandleData->dwFlags = 0;
3040 pHMHandleData->lpHandlerData = NULL;
3041
3042
3043 /* we've got to mark the handle as occupied here, since another device */
3044 /* could be created within the device handler -> deadlock */
3045
3046 /* write appropriate entry into the handle table if open succeeded */
3047 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3048 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3049
3050 /* call the device handler */
3051 rc = pDeviceHandler->OpenFileMapping(&TabWin32Handles[iIndexNew].hmHandleData,
3052 fdwAccess,
3053 fInherit,
3054 lpName);
3055 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3056 {
3057 FREEHANDLE(iIndexNew);
3058// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3059 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
3060 return (NULL); /* signal error */
3061 }
3062 else
3063 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3064
3065 return iIndexNew; /* return valid handle */
3066}
3067
3068
3069/*****************************************************************************
3070 * Name : HMMapViewOfFileEx
3071 * Purpose : router function for MapViewOfFileEx
3072 * Parameters:
3073 * Variables :
3074 * Result :
3075 * Remark :
3076 * Status :
3077 *
3078 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3079 *****************************************************************************/
3080
3081LPVOID HMMapViewOfFileEx(HANDLE hFileMappingObject,
3082 DWORD dwDesiredAccess,
3083 DWORD dwFileOffsetHigh,
3084 DWORD dwFileOffsetLow,
3085 DWORD dwNumberOfBytesToMap,
3086 LPVOID lpBaseAddress)
3087{
3088 int iIndex; /* index into the handle table */
3089 LPVOID lpResult; /* result from the device handler's API */
3090 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3091
3092 /* validate handle */
3093 iIndex = _HMHandleQuery(hFileMappingObject); /* get the index */
3094 if (-1 == iIndex) /* error ? */
3095 {
3096 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3097 return (NULL); /* signal failure */
3098 }
3099
3100 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3101 lpResult = pHMHandle->pDeviceHandler->MapViewOfFileEx(&pHMHandle->hmHandleData,
3102 dwDesiredAccess,
3103 dwFileOffsetHigh,
3104 dwFileOffsetLow,
3105 dwNumberOfBytesToMap,
3106 lpBaseAddress);
3107
3108 return (lpResult); /* deliver return code */
3109}
3110
3111/*****************************************************************************
3112 * Name : HMWaitForMultipleObjects
3113 * Purpose : router function for WaitForMultipleObjects
3114 * Parameters:
3115 * Variables :
3116 * Result :
3117 * Remark :
3118 * Status :
3119 *
3120 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3121 *****************************************************************************/
3122
3123DWORD HMWaitForMultipleObjects (DWORD cObjects,
3124 PHANDLE lphObjects,
3125 BOOL fWaitAll,
3126 DWORD dwTimeout)
3127{
3128 ULONG ulIndex;
3129 PHANDLE pArrayOfHandles;
3130 PHANDLE pLoop1 = lphObjects;
3131 PHANDLE pLoop2;
3132 DWORD rc;
3133
3134 // allocate array for handle table
3135 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3136 if (pArrayOfHandles == NULL)
3137 {
3138 dprintf(("ERROR: HMWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3139 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3140 return WAIT_FAILED;
3141 }
3142 else
3143 pLoop2 = pArrayOfHandles;
3144
3145 // convert array to odin handles
3146 for (ulIndex = 0;
3147
3148 ulIndex < cObjects;
3149
3150 ulIndex++,
3151 pLoop1++,
3152 pLoop2++)
3153 {
3154 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3155 pLoop2);
3156
3157 dprintf(("KERNEL32: HMWaitForMultipleObjects: handle %3i: ODIN-%08xh, Open32-%08xh\n",
3158 ulIndex,
3159 *pLoop1,
3160 *pLoop2));
3161
3162 // @@@PH to imlpement: check handle type!
3163 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3164 if (rc != NO_ERROR)
3165 {
3166 dprintf(("KERNEL32: HMWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3167 *pLoop1));
3168
3169 *pLoop2 = *pLoop1;
3170//// SetLastError(ERROR_INVALID_HANDLE);
3171//// return (WAIT_FAILED);
3172 }
3173 }
3174
3175 // OK, now forward to Open32.
3176 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3177 // but to i.e. the console subsystem!
3178 rc = O32_WaitForMultipleObjects(cObjects,
3179 pArrayOfHandles,
3180 fWaitAll,
3181 dwTimeout);
3182
3183 return (rc); // OK, done
3184}
3185
3186
3187/*****************************************************************************
3188 * Name : HMWaitForMultipleObjectsEx
3189 * Purpose : router function for WaitForMultipleObjectsEx
3190 * Parameters:
3191 * Variables :
3192 * Result :
3193 * Remark :
3194 * Status :
3195 *
3196 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3197 *****************************************************************************/
3198
3199DWORD HMWaitForMultipleObjectsEx (DWORD cObjects,
3200 PHANDLE lphObjects,
3201 BOOL fWaitAll,
3202 DWORD dwTimeout,
3203 BOOL fAlertable)
3204{
3205 // @@@PH: Note: fAlertable is ignored !
3206 return (HMWaitForMultipleObjects(cObjects,
3207 lphObjects,
3208 fWaitAll,
3209 dwTimeout));
3210}
3211
3212/*****************************************************************************
3213 * Name : HMMsgWaitForMultipleObjects
3214 * Purpose : router function for MsgWaitForMultipleObjects
3215 * Parameters:
3216 * Variables :
3217 * Result :
3218 * Remark : Open32 doesn't implement this properly! (doesn't check dwWakeMask)
3219 * Status :
3220 *
3221 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
3222 *****************************************************************************/
3223
3224DWORD HMMsgWaitForMultipleObjects (DWORD cObjects,
3225 LPHANDLE lphObjects,
3226 BOOL fWaitAll,
3227 DWORD dwTimeout,
3228 DWORD dwWakeMask)
3229{
3230 ULONG ulIndex;
3231 PHANDLE pArrayOfHandles;
3232 PHANDLE pLoop1 = lphObjects;
3233 PHANDLE pLoop2;
3234 DWORD rc;
3235
3236 // allocate array for handle table
3237 pArrayOfHandles = (PHANDLE)alloca(cObjects * sizeof(HANDLE));
3238 if (pArrayOfHandles == NULL)
3239 {
3240 dprintf(("ERROR: HMMsgWaitForMultipleObjects: alloca failed to allocate %d handles", cObjects));
3241 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3242 return WAIT_FAILED;
3243 }
3244 else
3245 pLoop2 = pArrayOfHandles;
3246
3247 // convert array to odin handles
3248 for (ulIndex = 0;
3249
3250 ulIndex < cObjects;
3251
3252 ulIndex++,
3253 pLoop1++,
3254 pLoop2++)
3255 {
3256 rc = HMHandleTranslateToOS2 (*pLoop1, // translate handle
3257 pLoop2);
3258
3259 dprintf2(("MsgWaitForMultipleObjects handle %x->%x", *pLoop1, *pLoop2));
3260 // SvL: We still use Open32 handles for threads & processes -> don't fail here!
3261 if (rc != NO_ERROR)
3262 {
3263 dprintf(("KERNEL32: HMMsgWaitForMultipleObjects - WARNING: handle %08xh is NOT an Odin handle (probably Open32 thread or process)\n",
3264 *pLoop1));
3265
3266 *pLoop2 = *pLoop1;
3267//// SetLastError(ERROR_INVALID_HANDLE);
3268//// return (WAIT_FAILED);
3269 }
3270 }
3271
3272 // OK, now forward to Open32.
3273 // @@@PH: Note this will fail on handles that do NOT belong to Open32
3274 // but to i.e. the console subsystem!
3275 rc = O32_MsgWaitForMultipleObjects(cObjects,
3276 pArrayOfHandles,
3277 fWaitAll, dwTimeout,
3278 dwWakeMask);
3279
3280 dprintf2(("MsgWaitForMultipleObjects returned %d", rc));
3281 return (rc); // OK, done
3282}
3283/*****************************************************************************
3284 * Name : HMDeviceIoControl
3285 * Purpose : router function for DeviceIoControl
3286 * Parameters:
3287 * Variables :
3288 * Result :
3289 * Remark :
3290 * Status :
3291 *
3292 * Author : Sander van Leeuwen
3293 *****************************************************************************/
3294
3295BOOL WIN32API DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
3296 LPVOID lpInBuffer, DWORD nInBufferSize,
3297 LPVOID lpOutBuffer, DWORD nOutBufferSize,
3298 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
3299{
3300 int iIndex; /* index into the handle table */
3301 BOOL fResult; /* result from the device handler's CloseHandle() */
3302 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3303
3304 /* validate handle */
3305 iIndex = _HMHandleQuery(hDevice); /* get the index */
3306 if (-1 == iIndex) /* error ? */
3307 {
3308 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3309 return (FALSE); /* signal failure */
3310 }
3311
3312 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3313 fResult = pHMHandle->pDeviceHandler->DeviceIoControl(&pHMHandle->hmHandleData,
3314 dwIoControlCode,
3315 lpInBuffer, nInBufferSize,
3316 lpOutBuffer, nOutBufferSize,
3317 lpBytesReturned, lpOverlapped);
3318
3319 return (fResult); /* deliver return code */
3320}
3321/*****************************************************************************
3322 * Name : BOOL WIN32API CancelIo
3323 * Purpose : The CancelIO function cancels all pending input and output
3324 * (I/O) operations that were issued by the calling thread for
3325 * the specified file handle. The function does not cancel
3326 * I/O operations issued for the file handle by other threads.
3327 * Parameters: HANDLE hFile file handle for which to cancel I/O
3328 * Variables :
3329 * Result : If the function succeeds, the return value is nonzero All pending
3330 * I/O operations issued by the calling thread for the file handle
3331 * were successfully canceled.
3332 * If the function fails, the return value is zero.
3333 * To get extended error information, call GetLastError.
3334 * Remark : If there are any I/O operations in progress for the specified
3335 * file HANDLE and they were issued by the calling thread, the
3336 * CancelIO function cancels them.
3337 * Note that the I/O operations must have been issued as
3338 * overlapped I/O. If they were not, the I/O operations would not
3339 * have returned to allow the thread to call the CancelIO function.
3340 * Calling the CancelIO function with a file handle that was not
3341 * opened with FILE_FLAG_OVERLAPPED does nothing.
3342 * All I/O operations that are canceled will complete with the
3343 * error ERROR_OPERATION_ABORTED. All completion notifications
3344 * for the I/O operations will occur normally.
3345 * Status :
3346 *
3347 * Author : Sander van Leeuwen
3348 *****************************************************************************/
3349BOOL WIN32API CancelIo(HANDLE hDevice)
3350{
3351 int iIndex; /* index into the handle table */
3352 BOOL fResult; /* result from the device handler's CloseHandle() */
3353 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
3354
3355 /* validate handle */
3356 iIndex = _HMHandleQuery(hDevice); /* get the index */
3357 if (-1 == iIndex) /* error ? */
3358 {
3359 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
3360 return (FALSE); /* signal failure */
3361 }
3362
3363 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
3364 fResult = pHMHandle->pDeviceHandler->CancelIo(&pHMHandle->hmHandleData);
3365
3366 return (fResult); /* deliver return code */
3367}
3368
3369/*****************************************************************************
3370 * Name : HMOpenThreadToken
3371 * Purpose : router function for NtOpenThreadToken
3372 * Parameters:
3373 * Variables :
3374 * Result :
3375 * Remark :
3376 * Status :
3377 *
3378 * Author : SvL
3379 *****************************************************************************/
3380
3381DWORD HMOpenThreadToken(HANDLE ThreadHandle,
3382 DWORD DesiredAccess,
3383 DWORD OpenAsSelf,
3384 HANDLE *TokenHandle)
3385{
3386 int iIndex; /* index into the handle table */
3387 int iIndexNew; /* index into the handle table */
3388 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3389 PHMHANDLEDATA pHMHandleData;
3390 DWORD rc; /* API return code */
3391
3392 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3393
3394 iIndexNew = _HMHandleGetFree(); /* get free handle */
3395 if (-1 == iIndexNew) /* oops, no free handles ! */
3396 {
3397 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3398 return ERROR_NOT_ENOUGH_MEMORY;
3399 }
3400
3401 /* initialize the complete HMHANDLEDATA structure */
3402 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3403 pHMHandleData->dwAccess = DesiredAccess;
3404 pHMHandleData->dwShare = 0;
3405 pHMHandleData->dwCreation = 0;
3406 pHMHandleData->dwFlags = 0;
3407 pHMHandleData->lpHandlerData = NULL;
3408 pHMHandleData->dwInternalType = HMTYPE_THREADTOKEN;
3409
3410
3411 /* we've got to mark the handle as occupied here, since another device */
3412 /* could be created within the device handler -> deadlock */
3413
3414 /* write appropriate entry into the handle table if open succeeded */
3415 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3416 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3417
3418 /* call the device handler */
3419
3420 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3421 // a valid HandleManager-internal handle!
3422 rc = pDeviceHandler->OpenThreadToken(&TabWin32Handles[iIndexNew].hmHandleData,
3423 ThreadHandle,
3424 OpenAsSelf);
3425
3426 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3427 {
3428 FREEHANDLE(iIndexNew);
3429// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3430 return (rc); /* signal error */
3431 }
3432 else
3433 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3434
3435 *TokenHandle = iIndexNew; /* return valid handle */
3436 return STATUS_SUCCESS;
3437}
3438
3439/*****************************************************************************
3440 * Name : HMOpenProcessToken
3441 * Purpose : router function for NtOpenProcessToken
3442 * Parameters:
3443 * Variables :
3444 * Result :
3445 * Remark :
3446 * Status :
3447 *
3448 * Author : SvL
3449 *****************************************************************************/
3450DWORD HMOpenProcessToken(HANDLE ProcessHandle,
3451 DWORD DesiredAccess,
3452 DWORD dwUserData,
3453 HANDLE *TokenHandle)
3454{
3455 int iIndex; /* index into the handle table */
3456 int iIndexNew; /* index into the handle table */
3457 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
3458 PHMHANDLEDATA pHMHandleData;
3459 DWORD rc; /* API return code */
3460
3461 pDeviceHandler = HMGlobals.pHMToken; /* device is predefined */
3462
3463 iIndexNew = _HMHandleGetFree(); /* get free handle */
3464 if (-1 == iIndexNew) /* oops, no free handles ! */
3465 {
3466 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
3467 return ERROR_NOT_ENOUGH_MEMORY;
3468 }
3469
3470 /* initialize the complete HMHANDLEDATA structure */
3471 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
3472 pHMHandleData->dwAccess = DesiredAccess;
3473 pHMHandleData->dwShare = 0;
3474 pHMHandleData->dwCreation = 0;
3475 pHMHandleData->dwFlags = 0;
3476 pHMHandleData->lpHandlerData = NULL;
3477 pHMHandleData->dwInternalType = HMTYPE_PROCESSTOKEN;
3478
3479
3480 /* we've got to mark the handle as occupied here, since another device */
3481 /* could be created within the device handler -> deadlock */
3482
3483 /* write appropriate entry into the handle table if open succeeded */
3484 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
3485 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
3486
3487 /* call the device handler */
3488
3489 // @@@PH: Note: hFile is a Win32-style handle, it's not (yet) converted to
3490 // a valid HandleManager-internal handle!
3491 rc = pDeviceHandler->OpenProcessToken(&TabWin32Handles[iIndexNew].hmHandleData,
3492 dwUserData,
3493 ProcessHandle);
3494
3495 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
3496 {
3497 FREEHANDLE(iIndexNew);
3498// TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
3499 return (rc); /* signal error */
3500 }
3501 else
3502 SetLastError(ERROR_SUCCESS); //@@@PH 1999/10/27 rc5desg requires this?
3503
3504 *TokenHandle = iIndexNew; /* return valid handle */
3505 return STATUS_SUCCESS;
3506}
3507
3508
3509/**
3510 * Gets the type of an object.
3511 *
3512 * @returns the value of one of the HMMTYPE_ defines.
3513 * @returns HMTYPE_BAD_HANDLE if hObject isn't a valid handle.
3514 * @param hObject Handle to object.
3515 */
3516unsigned WIN32API HMQueryObjectType(HANDLE hObject)
3517{
3518 PHMHANDLEDATA pData = HMQueryHandleData(hObject);
3519 if (pData)
3520 return (unsigned)pData->dwInternalType;
3521 return HMTYPE_BAD_HANDLE;
3522}
3523
Note: See TracBrowser for help on using the repository browser.