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

Last change on this file since 275 was 271, checked in by phaller, 26 years ago

Fix: streamlined Handlemanager

File size: 53.1 KB
Line 
1/* $Id: HandleManager.cpp,v 1.5 1999-07-05 09:58:14 phaller Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 */
8/*
9 * Win32 Unified Handle Manager for OS/2
10 *
11 * 1998/02/11 PH Patrick Haller (haller@zebra.fh-weingarten.de)
12 *
13 * @(#) HandleManager.Cpp 1.0.0 1998/02/11 PH start
14 */
15
16#undef DEBUG_LOCAL
17//#define DEBUG_LOCAL
18
19
20/*****************************************************************************
21 * Remark *
22 *****************************************************************************
23
24 1998/02/11 PH Even overlapped I/O could be simulated by another subsystem
25 thread with a request queue. We'll see if required ...
26
27
28 Flush (flush handle buffer)
29 WaitForSingleObject
30 WaitForMultipleObjects (?)
31
32 1998/02/12 PH IBM and Microsoft disagree about the definition of FILE_TYPE_xxx
33 Interesting, Open32 returns Microsoft's values ...
34
35 1998/02/12 PH Handles should be equipped with a locking mechanism, in particular
36 as we publish a pointer into the handle table via HMHandleQueryHandleData
37
38 */
39
40
41/*****************************************************************************
42 * Includes *
43 *****************************************************************************/
44
45#include <os2win.h>
46#include <stdlib.h>
47#include <string.h>
48#include "unicode.h"
49#include "misc.h"
50
51#include "HandleManager.H"
52#include "HMDevice.h"
53#include "HMOpen32.h"
54
55
56/*****************************************************************************
57 * Defines *
58 *****************************************************************************/
59
60 /* this is the size of our currently static handle table */
61#define MAX_OS2_HMHANDLES 1024
62
63
64/*****************************************************************************
65 * Structures *
66 *****************************************************************************/
67
68
69typedef struct _HMHANDLE
70{
71 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
72 HMHANDLEDATA hmHandleData; /* attributes of the handle */
73} HMHANDLE, *PHMHANDLE;
74
75
76typedef struct _HMDEVICE
77{
78 struct _HMDEVICE *pNext; /* pointer to next device in chain */
79
80 PSZ pszDeviceName; /* name or alias of the pseudo-device */
81 HMDeviceHandler *pDeviceHandler; /* handler for this pseudo-device */
82} HMDEVICE, *PHMDEVICE;
83
84
85typedef struct _HMTRANSHANDLE
86{
87/* @@@PH
88 UCHAR ucSubsystemID; to determine "lost" handles
89 */
90 /* the index position in the array is the 16bit windows part of the handle */
91 ULONG hHandle32; /* 32-bit OS/2 part of the handle */
92} HMTRANSHANDLE, *PHMTRANSHANDLE;
93
94
95/*****************************************************************************
96 * This pseudo-device logs all device requests to the logfile and returns *
97 * ERROR_INVALID_FUNCTION to virtually all requests -> debugging *
98 *****************************************************************************/
99class HMDeviceDebugClass : public HMDeviceHandler
100{
101 public:
102 HMDeviceDebugClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName) {}
103};
104
105
106/*****************************************************************************
107 * Process Global Structures *
108 *****************************************************************************/
109
110
111 /* the device name is repeated here to enable device alias names */
112static PHMDEVICE TabWin32Devices = NULL;
113static HMHANDLE TabWin32Handles[MAX_OS2_HMHANDLES]; /* static handle table */
114
115
116struct _HMGlobals
117{
118 HANDLE hStandardIn; /* stdin handle to CONIN$ */
119 HANDLE hStandardOut; /* stdout handle to CONOUT$ */
120 HANDLE hStandardError; /* stderr handle to CONOUT$ */
121
122 BOOL fIsInitialized; /* if HM is initialized already ? */
123 /* this MUST !!! be false initially */
124
125 HMDeviceHandler *pHMOpen32; /* default handle manager instance */
126
127 ULONG ulHandleLast; /* index of last used handle */
128} HMGlobals;
129
130
131/*****************************************************************************
132 * Local Prototypes *
133 *****************************************************************************/
134
135 /* get appropriate device handler by the device name */
136static HMDeviceHandler *_HMDeviceFind(PSZ pszDeviceName);
137
138 /* get next free handle from the handle table */
139static ULONG _HMHandleGetFree(void);
140
141 /* get handle table entry from handle */
142static ULONG _HMHandleQuery(HANDLE hHandle);
143
144
145
146/*****************************************************************************
147 * Name : static HMDeviceHandler * _HMDeviceFind
148 * Purpose : obtain appropriate device handler from the table by searching
149 * for a device name or alias
150 * Parameters: PSZ pszDeviceName
151 * Variables :
152 * Result : HMDeviceHandler * - pointer to the handler object
153 * Remark :
154 * Status :
155 *
156 * Author : Patrick Haller [Wed, 1998/02/11 20:42]
157 *****************************************************************************/
158
159static HMDeviceHandler *_HMDeviceFind (PSZ pszDeviceName)
160{
161 PHMDEVICE pHMDevice; /* iterator over the device table */
162
163 if (pszDeviceName != NULL)
164 for (pHMDevice = TabWin32Devices; /* loop over all devices in the table */
165 pHMDevice != NULL;
166 pHMDevice = pHMDevice->pNext)
167 {
168 if (stricmp(pHMDevice->pszDeviceName, /* case-insensitive search */
169 pszDeviceName) == 0)
170 return (pHMDevice->pDeviceHandler); /* OK, we've found our device */
171 }
172
173 return (HMGlobals.pHMOpen32); /* haven't found anything, return default */
174}
175
176
177/*****************************************************************************
178 * Name : static int _HMHandleGetFree
179 * Purpose : get index to first free handle in the handle table
180 * Parameters:
181 * Variables :
182 * Result : int iIndex - index to the table or -1 in case of error
183 * Remark :
184 * Status :
185 *
186 * Author : Patrick Haller [Wed, 1998/02/11 20:43]
187 *****************************************************************************/
188
189static ULONG _HMHandleGetFree(void)
190{
191 register ULONG ulLoop;
192
193 for (ulLoop = 0;
194 ulLoop < MAX_OS2_HMHANDLES;
195 ulLoop++)
196 {
197 /* free handle found ? */
198 if (INVALID_HANDLE_VALUE == TabWin32Handles[ulLoop].hmHandleData.hHMHandle)
199 return (ulLoop); /* OK, then return it to the caller */
200 }
201
202 return (INVALID_HANDLE_VALUE); /* haven't found any free handle */
203}
204
205
206/*****************************************************************************
207 * Name : static int _HMHandleQuery
208 * Purpose : gets the index of handle table entry as fast as possible from
209 * the specified handle
210 * Parameters: HANDLE hHandle
211 * Variables :
212 * Result : index or -1 in case of error
213 * Remark :
214 * Status :
215 *
216 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
217 *****************************************************************************/
218
219static ULONG _HMHandleQuery(HANDLE hHandle)
220{
221 if (hHandle > MAX_OS2_HMHANDLES) /* check the table range */
222 return (INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
223
224 /* Oops, invalid handle ! */
225 if (INVALID_HANDLE_VALUE == TabWin32Handles[hHandle].hmHandleData.hHMHandle)
226 return (INVALID_HANDLE_VALUE); /* nope, ERROR_INVALID_HANDLE */
227
228 return ( hHandle); /* OK, we've got our handle index */
229}
230
231
232/*****************************************************************************
233 * Name : DWORD HMDeviceRegister
234 * Purpose : register a device with the handle manager
235 * Parameters: PSZ pszDeviceName
236 * HMDeviceHandler *pDeviceHandler
237 * Variables :
238 * Result : API returncode
239 * Remark :
240 * Status :
241 *
242 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
243 *****************************************************************************/
244
245DWORD HMDeviceRegister(PSZ pszDeviceName,
246 HMDeviceHandler *pDeviceHandler)
247{
248 PHMDEVICE pHMDevice; /* our new device to be allocated */
249
250 if ( (pszDeviceName == NULL) || /* check parameters */
251 (pDeviceHandler == NULL) )
252 return (ERROR_INVALID_PARAMETER); /* raise error conditon */
253
254
255 pHMDevice = (PHMDEVICE) malloc (sizeof (HMDEVICE) ); /* allocate memory */
256 if (pHMDevice == NULL) /* check proper allocation */
257 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
258
259 pHMDevice->pszDeviceName = strdup(pszDeviceName); /* copy name */
260 if (pHMDevice->pszDeviceName == NULL) /* check proper allocation */
261 {
262 free (pHMDevice); /* free previously allocated memory */
263 return (ERROR_NOT_ENOUGH_MEMORY); /* signal error */
264 }
265
266 pHMDevice->pDeviceHandler = pDeviceHandler; /* store pointer to device */
267 pHMDevice->pNext = TabWin32Devices; /* establish linkage */
268
269 TabWin32Devices = pHMDevice; /* insert new node as root in the list */
270
271 return (NO_ERROR);
272}
273
274
275/*****************************************************************************
276 * Name : DWORD HMInitialize
277 * Purpose : Initialize the handlemanager
278 * Parameters: -
279 * Variables : -
280 * Result : always NO_ERROR
281 * Remark : this routine just stores the standard handles in the
282 * internal table within the HandleManager
283 * Status :
284 *
285 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
286 *****************************************************************************/
287
288DWORD HMInitialize(void)
289{
290 ULONG ulIndex;
291
292 if (HMGlobals.fIsInitialized != TRUE)
293 {
294 HMGlobals.fIsInitialized = TRUE; /* OK, done */
295
296 // fill handle table
297 for (ulIndex = 0;
298 ulIndex < MAX_OS2_HMHANDLES;
299 ulIndex++)
300 TabWin32Handles[ulIndex].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
301
302 dprintf(("KERNEL32:HandleManager:HMInitialize() storing handles.\n"));
303
304 memset(&HMGlobals, /* zero out the structure first */
305 0,
306 sizeof(HMGlobals));
307
308 /* copy standard handles from OS/2's Open32 Subsystem */
309 HMSetStdHandle(STD_INPUT_HANDLE, GetStdHandle(STD_INPUT_HANDLE));
310 HMSetStdHandle(STD_OUTPUT_HANDLE, GetStdHandle(STD_OUTPUT_HANDLE));
311 HMSetStdHandle(STD_ERROR_HANDLE, GetStdHandle(STD_ERROR_HANDLE));
312
313 /* create handle manager instance for Open32 handles */
314 HMGlobals.pHMOpen32 = new HMDeviceOpen32Class("\\\\.\\");
315 }
316 return (NO_ERROR);
317}
318
319
320/*****************************************************************************
321 * Name : DWORD HMTerminate
322 * Purpose : Terminate the handlemanager
323 * Parameters:
324 * Variables :
325 * Result :
326 * Remark :
327 * Status :
328 *
329 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
330 *****************************************************************************/
331
332DWORD HMTerminate(void)
333{
334 /* @@@PH we could deallocate the device list here */
335
336 return (NO_ERROR);
337}
338
339
340/*****************************************************************************/
341/* handle translation buffer management */
342/* */
343/* Since some Win32 applications rely (!) on 16-bit handles, we've got to do */
344/* 32-bit to 16-bit and vs vsa translation here. */
345/* Filehandle-based functions should be routed via the handlemanager instead */
346/* of going to Open32 directly. */
347/*****************************************************************************/
348
349
350/*****************************************************************************
351 * Name : DWORD HMHandleAllocate
352 * Purpose : allocate a handle in the translation table
353 * Parameters: PULONG pHandle16 - to return the allocated handle
354 * ULONG hHandle32 - the associated OS/2 handle
355 * Variables :
356 * Result : API returncode
357 * Remark : no parameter checking is done, phHandle may not be invalid
358 * hHandle32 shouldn't be 0
359 * Status :
360 *
361 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
362 *****************************************************************************/
363
364DWORD HMHandleAllocate (PULONG phHandle16,
365 ULONG hHandleOS2)
366{
367 register ULONG ulHandle;
368
369#ifdef DEBUG_LOCAL
370 dprintf(("KERNEL32: HMHandleAllocate (%08xh,%08xh)\n",
371 phHandle16,
372 hHandleOS2));
373#endif
374
375 ulHandle = HMGlobals.ulHandleLast; /* get free handle */
376
377 do
378 {
379 /* check if handle is free */
380 if (TabWin32Handles[ulHandle].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
381 {
382 *phHandle16 = ulHandle;
383 TabWin32Handles[ulHandle].hmHandleData.hHMHandle = hHandleOS2;
384 HMGlobals.ulHandleLast = ulHandle; /* to shorten search times */
385
386 return (NO_ERROR); /* OK */
387 }
388
389 ulHandle++; /* skip to next entry */
390
391 if (ulHandle >= MAX_OS2_HMHANDLES) /* check boundary */
392 ulHandle = 0;
393 }
394 while (ulHandle != HMGlobals.ulHandleLast);
395
396 return (ERROR_TOO_MANY_OPEN_FILES); /* OK, we're done */
397}
398
399
400/*****************************************************************************
401 * Name : DWORD HMHandleFree
402 * Purpose : free a handle from the translation table
403 * Parameters: ULONG hHandle16 - the handle to be freed
404 * Variables :
405 * Result : API returncode
406 * Remark : no parameter checking is done, hHandle16 MAY NEVER exceed
407 * the MAX_TRANSLATION_HANDLES boundary
408 * Status :
409 *
410 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
411 *****************************************************************************/
412
413DWORD HMHandleFree (ULONG hHandle16)
414{
415 ULONG rc; /* API returncode */
416
417#ifdef DEBUG_LOCAL
418 dprintf(("KERNEL32: HMHandleFree (%08xh)\n",
419 hHandle16));
420#endif
421
422 rc = HMHandleValidate(hHandle16); /* verify handle */
423 if (rc != NO_ERROR) /* check errors */
424 return (rc); /* raise error condition */
425
426 TabWin32Handles[hHandle16].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
427 /* OK, done */
428
429 return (NO_ERROR);
430}
431
432
433/*****************************************************************************
434 * Name : DWORD HMHandleValidate
435 * Purpose : validate a handle through the translation table
436 * Parameters: ULONG hHandle16 - the handle to be verified
437 * Variables :
438 * Result : API returncode
439 * Remark :
440 * Status :
441 *
442 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
443 *****************************************************************************/
444
445DWORD HMHandleValidate (ULONG hHandle16)
446{
447#ifdef DEBUG_LOCAL
448 dprintf(("KERNEL32: HMHandleValidate (%08xh)\n",
449 hHandle16));
450#endif
451
452 if (hHandle16 >= MAX_OS2_HMHANDLES) /* check boundary */
453 return (ERROR_INVALID_HANDLE); /* raise error condition */
454
455 if (TabWin32Handles[hHandle16].hmHandleData.hHMHandle == INVALID_HANDLE_VALUE)
456 /* valid ? */
457 return (ERROR_INVALID_HANDLE); /* raise error condition */
458
459 return (NO_ERROR);
460}
461
462
463/*****************************************************************************
464 * Name : DWORD HMHandleTranslateToWin
465 * Purpose : translate a 32-bit OS/2 handle to the associated windows handle
466 * Parameters: ULONG hHandle32 - the OS/2 handle
467 * PULONG phHandle16 - the associated windows handle
468 * Variables :
469 * Result : API returncode
470 * Remark :
471 * Status :
472 *
473 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
474 *****************************************************************************/
475
476DWORD HMHandleTranslateToWin (ULONG hHandleOS2,
477 PULONG phHandle16)
478{
479 ULONG rc; /* API returncode */
480 register ULONG ulIndex; /* index counter over the table */
481
482#ifdef DEBUG_LOCAL
483 dprintf(("KERNEL32: HMHandleTranslateToWin (%08xh, %08xh)\n",
484 hHandleOS2,
485 phHandle16));
486#endif
487
488 for (ulIndex = 0;
489 ulIndex < MAX_OS2_HMHANDLES;
490 ulIndex++)
491 {
492 /* look for the handle */
493 if (TabWin32Handles[ulIndex].hmHandleData.hHMHandle == hHandleOS2)
494 {
495 *phHandle16 = ulIndex; /* deliver result */
496 return (NO_ERROR); /* OK */
497 }
498 }
499
500 return (ERROR_INVALID_HANDLE); /* raise error condition */
501}
502
503
504/*****************************************************************************
505 * Name : DWORD HMHandleTranslateToOS2
506 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
507 * Parameters: ULONG hHandle16 - the windows handle
508 * PULONG phHandle32 - the associated OS/2 handle
509 * Variables :
510 * Result : API returncode
511 * Remark :
512 * Status :
513 *
514 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
515 *****************************************************************************/
516
517DWORD HMHandleTranslateToOS2 (ULONG hHandle16,
518 PULONG phHandleOS2)
519{
520#ifdef DEBUG_LOCAL
521 dprintf(("KERNEL32: HMHandleTranslateToOS2 (%08xh, %08xh)\n",
522 hHandle16,
523 phHandleOS2));
524#endif
525
526 if (HMHandleValidate(hHandle16) == NO_ERROR) /* verify handle */
527 {
528 *phHandleOS2 = TabWin32Handles[hHandle16].hmHandleData.hHMHandle;
529 return (NO_ERROR);
530 }
531
532 return (ERROR_INVALID_HANDLE); /* raise error condition */
533}
534
535
536/*****************************************************************************
537 * Name : DWORD HMHandleTranslateToOS2i
538 * Purpose : translate a 16-bit Win32 handle to the associated OS/2 handle
539 * Parameters: ULONG hHandle16 - the windows handle
540 * Variables :
541 * Result : OS/2 handle
542 * Remark : no checkinf
543 * Status :
544 *
545 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
546 *****************************************************************************/
547
548DWORD HMHandleTranslateToOS2i (ULONG hHandle16)
549{
550#ifdef DEBUG_LOCAL
551 dprintf(("KERNEL32: HMHandleTranslateToOS2i (%08xh)\n",
552 hHandle16));
553#endif
554
555 return(TabWin32Handles[hHandle16].hmHandleData.hHMHandle);
556}
557
558
559
560/*****************************************************************************
561 * Name : HANDLE _HMGetStdHandle
562 * Purpose : replacement for Open32's GetStdHandle function
563 * Parameters: DWORD nStdHandle
564 * Variables :
565 * Result : HANDLE to standard device
566 * Remark :
567 * Status :
568 *
569 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
570 *****************************************************************************/
571
572HANDLE HMGetStdHandle(DWORD nStdHandle)
573{
574 switch (nStdHandle)
575 {
576 case STD_INPUT_HANDLE: return (HMGlobals.hStandardIn);
577 case STD_OUTPUT_HANDLE: return (HMGlobals.hStandardOut);
578 case STD_ERROR_HANDLE: return (HMGlobals.hStandardError);
579
580 default:
581 {
582 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
583 return (INVALID_HANDLE_VALUE); /* raise error condition */
584 }
585 }
586}
587
588
589/*****************************************************************************
590 * Name : HANDLE _HMSetStdHandle
591 * Purpose : replacement for Open32's SetStdHandle function
592 * Parameters: DWORD nStdHandle
593 * HANDLE hHandle
594 * Variables :
595 * Result : BOOL fSuccess
596 * Remark :
597 * Status :
598 *
599 * Author : Patrick Haller [Wed, 1998/02/12 20:44]
600 *****************************************************************************/
601
602BOOL HMSetStdHandle(DWORD nStdHandle,
603 HANDLE hHandle)
604{
605 switch (nStdHandle)
606 {
607 case STD_INPUT_HANDLE: HMGlobals.hStandardIn = hHandle; return TRUE;
608 case STD_OUTPUT_HANDLE: HMGlobals.hStandardOut = hHandle; return TRUE;
609 case STD_ERROR_HANDLE: HMGlobals.hStandardError = hHandle; return TRUE;
610
611 default:
612 {
613 SetLastError(ERROR_INVALID_PARAMETER); /* set error information */
614 return (FALSE); /* raise error condition */
615 }
616 }
617}
618
619
620/*****************************************************************************
621 * Name : HANDLE HMCreateFile
622 * Purpose : Wrapper for the CreateFile() API
623 * Parameters:
624 * Variables :
625 * Result :
626 * Remark : Fix parameters passed to the HMDeviceManager::CreateFile
627 * Supply access mode and share mode validation routines
628 * Status :
629 *
630 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
631 *****************************************************************************/
632
633HFILE HMCreateFile(LPCSTR lpFileName,
634 DWORD dwDesiredAccess,
635 DWORD dwShareMode,
636 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
637 DWORD dwCreationDisposition,
638 DWORD dwFlagsAndAttributes,
639 HANDLE hTemplateFile)
640{
641 int iIndex; /* index into the handle table */
642 int iIndexNew; /* index into the handle table */
643 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
644 HANDLE hResult;
645 DWORD rc; /* API return code */
646 PHMHANDLEDATA pHMHandleData;
647 HMHANDLEDATA HMHandleTemp; /* temporary buffer for handle data */
648
649 /* create new handle by either lpFileName or hTemplateFile */
650 if (lpFileName == NULL) /* this indicates creation from template */
651 {
652 iIndex = _HMHandleQuery(hTemplateFile); /* query table for template */
653 if (-1 == iIndex) /* this device is unknown to us */
654 {
655 SetLastError (ERROR_INVALID_HANDLE);
656 return INVALID_HANDLE_VALUE;
657 }
658 else
659 {
660 /* to pass to handler */
661 pHMHandleData = &TabWin32Handles[iIndex].hmHandleData;
662 pDeviceHandler = TabWin32Handles[iIndex].pDeviceHandler;
663 }
664 }
665 else
666 {
667 pDeviceHandler = _HMDeviceFind((PSZ)lpFileName); /* find device */
668
669 if (NULL == pDeviceHandler) /* this name is unknown to us */
670 {
671 SetLastError(ERROR_FILE_NOT_FOUND);
672 return (INVALID_HANDLE_VALUE); /* signal error */
673 }
674 else
675 pHMHandleData = NULL;
676 }
677
678
679 iIndexNew = _HMHandleGetFree(); /* get free handle */
680 if (-1 == iIndexNew) /* oops, no free handles ! */
681 {
682 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
683 return (INVALID_HANDLE_VALUE); /* signal error */
684 }
685
686
687 /* initialize the complete HMHANDLEDATA structure */
688 if (lpFileName == NULL) /* create from template */
689 memcpy (&TabWin32Handles[iIndexNew].hmHandleData,
690 &TabWin32Handles[iIndex].hmHandleData,
691 sizeof(HMHANDLEDATA));
692 else
693 {
694 HMHandleTemp.dwType = FILE_TYPE_UNKNOWN; /* unknown handle type */
695 HMHandleTemp.dwAccess = dwDesiredAccess;
696 HMHandleTemp.dwShare = dwShareMode;
697 HMHandleTemp.dwCreation = dwCreationDisposition;
698 HMHandleTemp.dwFlags = dwFlagsAndAttributes;
699 HMHandleTemp.lpHandlerData = NULL;
700 }
701
702 /* we've got to mark the handle as occupied here, since another device */
703 /* could be created within the device handler -> deadlock */
704
705 /* write appropriate entry into the handle table if open succeeded */
706 HMHandleTemp.hHMHandle = iIndexNew;
707 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
708
709 /* now copy back our temporary handle data */
710 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
711 &HMHandleTemp,
712 sizeof(HMHANDLEDATA));
713
714 rc = pDeviceHandler->CreateFile(lpFileName, /* call the device handler */
715 &HMHandleTemp,
716 lpSecurityAttributes,
717 pHMHandleData);
718
719#ifdef DEBUG_LOCAL
720 dprintf(("KERNEL32/HandleManager:CheckPoint2: %s lpHandlerData=%08xh\n",
721 lpFileName,
722 HMHandleTemp.lpHandlerData));
723#endif
724
725 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
726 {
727 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
728 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
729 return (INVALID_HANDLE_VALUE); /* signal error */
730 }
731 else
732 {
733 /* copy data fields that might have been modified by CreateFile */
734 memcpy(&TabWin32Handles[iIndexNew].hmHandleData,
735 &HMHandleTemp,
736 sizeof(HMHANDLEDATA));
737 }
738
739
740#ifdef DEBUG_LOCAL
741 dprintf(("KERNEL32/HandleManager: CreateFile(%s)=%08xh\n",
742 lpFileName,
743 iIndexNew));
744#endif
745
746 return (HFILE)iIndexNew; /* return valid handle */
747}
748
749
750/*****************************************************************************
751 * Name : HANDLE HMOpenFile
752 * Purpose : Wrapper for the OpenFile() API
753 * Parameters:
754 * Variables :
755 * Result :
756 * Remark : Fix parameters passed to the HMDeviceManager::OpenFile
757 * Supply access mode and share mode validation routines
758 * Status :
759 *
760 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
761 *****************************************************************************/
762
763
764/***********************************************************************
765 * FILE_ConvertOFMode
766 *
767 * Convert OF_* mode into flags for CreateFile.
768 */
769static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
770{
771 switch(mode & 0x03)
772 {
773 case OF_READ: *access = GENERIC_READ; break;
774 case OF_WRITE: *access = GENERIC_WRITE; break;
775 case OF_READWRITE: *access = GENERIC_READ | GENERIC_WRITE; break;
776 default: *access = 0; break;
777 }
778 switch(mode & 0x70)
779 {
780 case OF_SHARE_EXCLUSIVE: *sharing = 0; break;
781 case OF_SHARE_DENY_WRITE: *sharing = FILE_SHARE_READ; break;
782 case OF_SHARE_DENY_READ: *sharing = FILE_SHARE_WRITE; break;
783 case OF_SHARE_DENY_NONE:
784 case OF_SHARE_COMPAT:
785 default: *sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; break;
786 }
787}
788
789HANDLE HMOpenFile(LPCSTR lpFileName,
790 OFSTRUCT* pOFStruct,
791 UINT fuMode)
792{
793 int iIndex; /* index into the handle table */
794 int iIndexNew; /* index into the handle table */
795 HMDeviceHandler *pDeviceHandler; /* device handler for this handle */
796 PHMHANDLEDATA pHMHandleData;
797 DWORD rc; /* API return code */
798
799
800 pDeviceHandler = _HMDeviceFind((PSZ)lpFileName); /* find device */
801 if (NULL == pDeviceHandler) /* this name is unknown to us */
802 {
803 SetLastError(ERROR_FILE_NOT_FOUND);
804 return (INVALID_HANDLE_VALUE); /* signal error */
805 }
806 else
807 pHMHandleData = NULL;
808
809
810 iIndexNew = _HMHandleGetFree(); /* get free handle */
811 if (-1 == iIndexNew) /* oops, no free handles ! */
812 {
813 SetLastError(ERROR_NOT_ENOUGH_MEMORY); /* use this as error message */
814 return (INVALID_HANDLE_VALUE); /* signal error */
815 }
816
817
818 /* initialize the complete HMHANDLEDATA structure */
819 pHMHandleData = &TabWin32Handles[iIndexNew].hmHandleData;
820 pHMHandleData->dwType = FILE_TYPE_UNKNOWN; /* unknown handle type */
821
822 FILE_ConvertOFMode(fuMode, /* map OF_flags */
823 &pHMHandleData->dwAccess,
824 &pHMHandleData->dwShare);
825
826 pHMHandleData->dwCreation = 0;
827 pHMHandleData->dwFlags = 0;
828 pHMHandleData->lpHandlerData = NULL;
829
830
831 /* we've got to mark the handle as occupied here, since another device */
832 /* could be created within the device handler -> deadlock */
833
834 /* write appropriate entry into the handle table if open succeeded */
835 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = iIndexNew;
836 TabWin32Handles[iIndexNew].pDeviceHandler = pDeviceHandler;
837
838 rc = pDeviceHandler->OpenFile (lpFileName, /* call the device handler */
839 &TabWin32Handles[iIndexNew].hmHandleData,
840 pOFStruct,
841 fuMode);
842
843#ifdef DEBUG_LOCAL
844 dprintf(("KERNEL32/HandleManager:CheckPoint3: %s lpHandlerData=%08xh rc=%08xh\n",
845 lpFileName,
846 &TabWin32Handles[iIndexNew].hmHandleData.lpHandlerData,
847 rc));
848#endif
849
850 if (rc != NO_ERROR) /* oops, creation failed within the device handler */
851 {
852 TabWin32Handles[iIndexNew].hmHandleData.hHMHandle = INVALID_HANDLE_VALUE;
853 SetLastError(rc); /* Hehe, OS/2 and NT are pretty compatible :) */
854 return (INVALID_HANDLE_VALUE); /* signal error */
855 }
856
857#ifdef DEBUG_LOCAL
858 dprintf(("KERNEL32/HandleManager: OpenFile(%s)=%08xh\n",
859 lpFileName,
860 hResult));
861#endif
862
863 return iIndexNew; /* return valid handle */
864}
865
866
867
868/*****************************************************************************
869 * Name : HANDLE HMCloseFile
870 * Purpose : Wrapper for the CloseHandle() API
871 * Parameters:
872 * Variables :
873 * Result :
874 * Remark :
875 * Status :
876 *
877 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
878 *****************************************************************************/
879
880BOOL HMCloseHandle(HANDLE hObject)
881{
882 int iIndex; /* index into the handle table */
883 BOOL fResult; /* result from the device handler's CloseHandle() */
884 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
885
886 /* validate handle */
887 iIndex = _HMHandleQuery(hObject); /* get the index */
888 if (-1 == iIndex) /* error ? */
889 {
890 //@@@PH it may occur someone closes e.g. a semaphore handle
891 // which is not registered through the HandleManager yet.
892 // so we try to pass on to Open32 instead.
893 dprintf(("KERNEL32: HandleManager:HMCloseHandle(%08xh) passed on to Open32.\n",
894 hObject));
895
896 fResult = O32_CloseHandle(hObject);
897 return (fResult);
898
899 //SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
900 //return (FALSE); /* signal failure */
901 }
902
903 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
904 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
905
906 if (fResult == TRUE) /* remove handle if close succeeded */
907 pHMHandle->hmHandleData.hHMHandle = 0; /* mark handle as free */
908
909 return (fResult); /* deliver return code */
910}
911
912
913/*****************************************************************************
914 * Name : HANDLE HMReadFile
915 * Purpose : Wrapper for the ReadHandle() API
916 * Parameters:
917 * Variables :
918 * Result :
919 * Remark :
920 * Status :
921 *
922 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
923 *****************************************************************************/
924BOOL HMReadFile(HANDLE hFile,
925 LPVOID lpBuffer,
926 DWORD nNumberOfBytesToRead,
927 LPDWORD lpNumberOfBytesRead,
928 LPOVERLAPPED lpOverlapped)
929{
930 int iIndex; /* index into the handle table */
931 BOOL fResult; /* result from the device handler's CloseHandle() */
932 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
933
934 /* validate handle */
935 iIndex = _HMHandleQuery(hFile); /* get the index */
936 if (-1 == iIndex) /* error ? */
937 {
938 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
939 return (FALSE); /* signal failure */
940 }
941
942 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
943 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
944 lpBuffer,
945 nNumberOfBytesToRead,
946 lpNumberOfBytesRead,
947 lpOverlapped);
948
949 return (fResult); /* deliver return code */
950}
951
952
953/*****************************************************************************
954 * Name : HANDLE HMWriteFile
955 * Purpose : Wrapper for the WriteHandle() API
956 * Parameters:
957 * Variables :
958 * Result :
959 * Remark :
960 * Status :
961 *
962 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
963 *****************************************************************************/
964
965BOOL HMWriteFile(HANDLE hFile,
966 LPCVOID lpBuffer,
967 DWORD nNumberOfBytesToWrite,
968 LPDWORD lpNumberOfBytesWritten,
969 LPOVERLAPPED lpOverlapped)
970{
971 int iIndex; /* index into the handle table */
972 BOOL fResult; /* result from the device handler's CloseHandle() */
973 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
974
975 /* validate handle */
976 iIndex = _HMHandleQuery(hFile); /* get the index */
977 if (-1 == iIndex) /* error ? */
978 {
979 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
980 return (FALSE); /* signal failure */
981 }
982
983 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
984 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
985 lpBuffer,
986 nNumberOfBytesToWrite,
987 lpNumberOfBytesWritten,
988 lpOverlapped);
989
990 return (fResult); /* deliver return code */
991}
992
993
994/*****************************************************************************
995 * Name : HANDLE HMGetFileType
996 * Purpose : Wrapper for the GetFileType() API
997 * Parameters:
998 * Variables :
999 * Result :
1000 * Remark :
1001 * Status :
1002 *
1003 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1004 *****************************************************************************/
1005
1006DWORD HMGetFileType(HANDLE hFile)
1007{
1008 int iIndex; /* index into the handle table */
1009 DWORD dwResult; /* result from the device handler's API */
1010 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1011
1012 /* validate handle */
1013 iIndex = _HMHandleQuery(hFile); /* get the index */
1014 if (-1 == iIndex) /* error ? */
1015 {
1016 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1017 return (INVALID_HANDLE_ERROR); /* signal failure */
1018 }
1019
1020 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1021 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1022
1023 return (dwResult); /* deliver return code */
1024}
1025
1026
1027/*****************************************************************************
1028 * Name : HMDeviceHandler::_DeviceReuqest
1029 * Purpose : entry method for special request functions
1030 * Parameters: ULONG ulRequestCode
1031 * various parameters as required
1032 * Variables :
1033 * Result :
1034 * Remark : the standard behaviour is to return an error code for non-
1035 * existant request codes
1036 * Status :
1037 *
1038 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1039 *****************************************************************************/
1040DWORD HMDeviceRequest (HANDLE hFile,
1041 ULONG ulRequestCode,
1042 ULONG arg1,
1043 ULONG arg2,
1044 ULONG arg3,
1045 ULONG arg4)
1046{
1047 int iIndex; /* index into the handle table */
1048 DWORD dwResult; /* result from the device handler's API */
1049 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1050
1051 /* validate handle */
1052 iIndex = _HMHandleQuery(hFile); /* get the index */
1053 if (-1 == iIndex) /* error ? */
1054 {
1055 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1056 return (INVALID_HANDLE_ERROR); /* signal failure */
1057 }
1058
1059 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1060 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1061 ulRequestCode,
1062 arg1,
1063 arg2,
1064 arg3,
1065 arg4);
1066
1067 return (dwResult); /* deliver return code */
1068}
1069
1070
1071/*****************************************************************************
1072 * Name : HMDeviceHandler::GetFileInformationByHandle
1073 * Purpose : router function for GetFileInformationByHandle
1074 * Parameters:
1075 * Variables :
1076 * Result :
1077 * Remark :
1078 * Status :
1079 *
1080 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1081 *****************************************************************************/
1082DWORD HMGetFileInformationByHandle (HANDLE hFile,
1083 BY_HANDLE_FILE_INFORMATION *pHFI)
1084{
1085 int iIndex; /* index into the handle table */
1086 DWORD dwResult; /* result from the device handler's API */
1087 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1088
1089 /* validate handle */
1090 iIndex = _HMHandleQuery(hFile); /* get the index */
1091 if (-1 == iIndex) /* error ? */
1092 {
1093 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1094 return (INVALID_HANDLE_ERROR); /* signal failure */
1095 }
1096
1097 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1098 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
1099 pHFI);
1100
1101 return (dwResult); /* deliver return code */
1102}
1103
1104
1105
1106/*****************************************************************************
1107 * Name : HMDeviceHandler::SetEndOfFile
1108 * Purpose : router function for SetEndOfFile
1109 * Parameters:
1110 * Variables :
1111 * Result :
1112 * Remark :
1113 * Status :
1114 *
1115 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1116 *****************************************************************************/
1117BOOL HMSetEndOfFile (HANDLE hFile)
1118{
1119 int iIndex; /* index into the handle table */
1120 BOOL bResult; /* result from the device handler's API */
1121 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1122
1123 /* validate handle */
1124 iIndex = _HMHandleQuery(hFile); /* get the index */
1125 if (-1 == iIndex) /* error ? */
1126 {
1127 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1128 return (INVALID_HANDLE_ERROR); /* signal failure */
1129 }
1130
1131 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1132 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
1133
1134 return (bResult); /* deliver return code */
1135}
1136
1137
1138/*****************************************************************************
1139 * Name : HMDeviceHandler::SetFileTime
1140 * Purpose : router function for SetFileTime
1141 * Parameters:
1142 * Variables :
1143 * Result :
1144 * Remark :
1145 * Status :
1146 *
1147 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1148 *****************************************************************************/
1149BOOL HMSetFileTime (HANDLE hFile,
1150 const FILETIME *pFT1,
1151 const FILETIME *pFT2,
1152 const FILETIME *pFT3)
1153{
1154 int iIndex; /* index into the handle table */
1155 BOOL bResult; /* result from the device handler's API */
1156 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1157
1158 /* validate handle */
1159 iIndex = _HMHandleQuery(hFile); /* get the index */
1160 if (-1 == iIndex) /* error ? */
1161 {
1162 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1163 return (INVALID_HANDLE_ERROR); /* signal failure */
1164 }
1165
1166 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1167 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
1168 (LPFILETIME)pFT1,
1169 (LPFILETIME)pFT2,
1170 (LPFILETIME)pFT3);
1171
1172 return (bResult); /* deliver return code */
1173}
1174
1175
1176/*****************************************************************************
1177 * Name : HMDeviceHandler::GetFileSize
1178 * Purpose : router function for GetFileSize
1179 * Parameters:
1180 * Variables :
1181 * Result :
1182 * Remark :
1183 * Status :
1184 *
1185 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1186 *****************************************************************************/
1187DWORD HMGetFileSize (HANDLE hFile,
1188 PDWORD pSize)
1189{
1190 int iIndex; /* index into the handle table */
1191 DWORD dwResult; /* result from the device handler's API */
1192 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1193
1194 /* validate handle */
1195 iIndex = _HMHandleQuery(hFile); /* get the index */
1196 if (-1 == iIndex) /* error ? */
1197 {
1198 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1199 return (INVALID_HANDLE_ERROR); /* signal failure */
1200 }
1201
1202 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1203 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
1204 pSize);
1205
1206 return (dwResult); /* deliver return code */
1207}
1208
1209
1210/*****************************************************************************
1211 * Name : HMDeviceHandler::SetFilePointer
1212 * Purpose : router function for SetFilePointer
1213 * Parameters:
1214 * Variables :
1215 * Result :
1216 * Remark :
1217 * Status :
1218 *
1219 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1220 *****************************************************************************/
1221DWORD HMSetFilePointer (HANDLE hFile,
1222 LONG lDistanceToMove,
1223 PLONG lpDistanceToMoveHigh,
1224 DWORD dwMoveMethod)
1225{
1226 int iIndex; /* index into the handle table */
1227 DWORD dwResult; /* result from the device handler's API */
1228 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1229
1230 /* validate handle */
1231 iIndex = _HMHandleQuery(hFile); /* get the index */
1232 if (-1 == iIndex) /* error ? */
1233 {
1234 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1235 return (INVALID_HANDLE_ERROR); /* signal failure */
1236 }
1237
1238 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1239 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
1240 lDistanceToMove,
1241 lpDistanceToMoveHigh,
1242 dwMoveMethod);
1243
1244 return (dwResult); /* deliver return code */
1245}
1246
1247
1248/*****************************************************************************
1249 * Name : HMDeviceHandler::LockFile
1250 * Purpose : router function for LockFile
1251 * Parameters:
1252 * Variables :
1253 * Result :
1254 * Remark :
1255 * Status :
1256 *
1257 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1258 *****************************************************************************/
1259BOOL HMLockFile (HFILE hFile,
1260 DWORD arg2,
1261 DWORD arg3,
1262 DWORD arg4,
1263 DWORD arg5)
1264{
1265 int iIndex; /* index into the handle table */
1266 DWORD dwResult; /* result from the device handler's API */
1267 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1268
1269 /* validate handle */
1270 iIndex = _HMHandleQuery(hFile); /* get the index */
1271 if (-1 == iIndex) /* error ? */
1272 {
1273 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1274 return (INVALID_HANDLE_ERROR); /* signal failure */
1275 }
1276
1277 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1278 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
1279 arg2,
1280 arg3,
1281 arg4,
1282 arg5);
1283
1284 return (dwResult); /* deliver return code */
1285}
1286
1287
1288/*****************************************************************************
1289 * Name : HMDeviceHandler::LockFileEx
1290 * Purpose : router function for LockFileEx
1291 * Parameters:
1292 * Variables :
1293 * Result :
1294 * Remark :
1295 * Status :
1296 *
1297 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1298 *****************************************************************************/
1299DWORD HMLockFileEx(HANDLE hFile,
1300 DWORD dwFlags,
1301 DWORD dwReserved,
1302 DWORD nNumberOfBytesToLockLow,
1303 DWORD nNumberOfBytesToLockHigh,
1304 LPOVERLAPPED lpOverlapped)
1305{
1306 int iIndex; /* index into the handle table */
1307 DWORD dwResult; /* result from the device handler's API */
1308 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1309
1310 /* validate handle */
1311 iIndex = _HMHandleQuery(hFile); /* get the index */
1312 if (-1 == iIndex) /* error ? */
1313 {
1314 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1315 return (INVALID_HANDLE_ERROR); /* signal failure */
1316 }
1317
1318 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1319 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
1320 dwFlags,
1321 dwReserved,
1322 nNumberOfBytesToLockLow,
1323 nNumberOfBytesToLockHigh,
1324 lpOverlapped);
1325
1326 return (dwResult); /* deliver return code */
1327}
1328
1329
1330
1331/*****************************************************************************
1332 * Name : HMDeviceHandler::UnlockFile
1333 * Purpose : router function for UnlockFile
1334 * Parameters:
1335 * Variables :
1336 * Result :
1337 * Remark :
1338 * Status :
1339 *
1340 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1341 *****************************************************************************/
1342BOOL HMUnlockFile (HFILE hFile,
1343 DWORD arg2,
1344 DWORD arg3,
1345 DWORD arg4,
1346 DWORD arg5)
1347{
1348 int iIndex; /* index into the handle table */
1349 DWORD dwResult; /* result from the device handler's API */
1350 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1351
1352 /* validate handle */
1353 iIndex = _HMHandleQuery(hFile); /* get the index */
1354 if (-1 == iIndex) /* error ? */
1355 {
1356 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1357 return (INVALID_HANDLE_ERROR); /* signal failure */
1358 }
1359
1360 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1361 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
1362 arg2,
1363 arg3,
1364 arg4,
1365 arg5);
1366
1367 return (dwResult); /* deliver return code */
1368}
1369
1370/*****************************************************************************
1371 * Name : HMDeviceHandler::UnlockFileEx
1372 * Purpose : router function for UnlockFileEx
1373 * Parameters:
1374 * Variables :
1375 * Result :
1376 * Remark :
1377 * Status :
1378 *
1379 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1380 *****************************************************************************/
1381BOOL HMUnlockFileEx(HANDLE hFile,
1382 DWORD dwFlags,
1383 DWORD dwReserved,
1384 DWORD nNumberOfBytesToLockLow,
1385 DWORD nNumberOfBytesToLockHigh,
1386 LPOVERLAPPED lpOverlapped)
1387{
1388 int iIndex; /* index into the handle table */
1389 DWORD dwResult; /* result from the device handler's API */
1390 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1391
1392 /* validate handle */
1393 iIndex = _HMHandleQuery(hFile); /* get the index */
1394 if (-1 == iIndex) /* error ? */
1395 {
1396 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1397 return (INVALID_HANDLE_ERROR); /* signal failure */
1398 }
1399
1400 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1401 dwResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
1402 dwFlags,
1403 dwReserved,
1404 nNumberOfBytesToLockLow,
1405 nNumberOfBytesToLockHigh,
1406 lpOverlapped);
1407
1408 return (dwResult); /* deliver return code */
1409}
1410
Note: See TracBrowser for help on using the repository browser.