source: trunk/src/kernel32/HandleManager.cpp

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

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

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

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