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

Last change on this file since 112 was 111, checked in by phaller, 26 years ago

Fix: major restructuring of Open32 handle management, HandleManager

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