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

Last change on this file since 21332 was 21332, checked in by vladest, 16 years ago

Added GetFileSizeEx function, required for Flash 9/10 plugin

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