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

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

Fix: preparing support for HandleManager on kernel objects

File size: 53.4 KB
Line 
1/* $Id: HandleManager.cpp,v 1.4 1999-06-17 21:52:00 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 //@@@PH it may occur someone closes e.g. a semaphore handle
897 // which is not registered through the HandleManager yet.
898 // so we try to pass on to Open32 instead.
899 dprintf(("KERNEL32: HandleManager:HMCloseHandle(%08xh) passed on to Open32.\n",
900 hObject));
901
902 fResult = O32_CloseHandle(hObject);
903 return (fResult);
904
905 //SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
906 //return (FALSE); /* signal failure */
907 }
908
909 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
910 fResult = pHMHandle->pDeviceHandler->CloseHandle(&pHMHandle->hmHandleData);
911
912 if (fResult == TRUE) /* remove handle if close succeeded */
913 pHMHandle->hmHandleData.hHMHandle = 0; /* mark handle as free */
914
915 return (fResult); /* deliver return code */
916}
917
918
919/*****************************************************************************
920 * Name : HANDLE HMReadFile
921 * Purpose : Wrapper for the ReadHandle() API
922 * Parameters:
923 * Variables :
924 * Result :
925 * Remark :
926 * Status :
927 *
928 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
929 *****************************************************************************/
930BOOL HMReadFile(HANDLE hFile,
931 LPVOID lpBuffer,
932 DWORD nNumberOfBytesToRead,
933 LPDWORD lpNumberOfBytesRead,
934 LPOVERLAPPED lpOverlapped)
935{
936 int iIndex; /* index into the handle table */
937 BOOL fResult; /* result from the device handler's CloseHandle() */
938 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
939
940 /* validate handle */
941 iIndex = _HMHandleQuery(hFile); /* get the index */
942 if (-1 == iIndex) /* error ? */
943 {
944 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
945 return (FALSE); /* signal failure */
946 }
947
948 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
949 fResult = pHMHandle->pDeviceHandler->ReadFile(&pHMHandle->hmHandleData,
950 lpBuffer,
951 nNumberOfBytesToRead,
952 lpNumberOfBytesRead,
953 lpOverlapped);
954
955 return (fResult); /* deliver return code */
956}
957
958
959/*****************************************************************************
960 * Name : HANDLE HMWriteFile
961 * Purpose : Wrapper for the WriteHandle() API
962 * Parameters:
963 * Variables :
964 * Result :
965 * Remark :
966 * Status :
967 *
968 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
969 *****************************************************************************/
970
971BOOL HMWriteFile(HANDLE hFile,
972 LPCVOID lpBuffer,
973 DWORD nNumberOfBytesToWrite,
974 LPDWORD lpNumberOfBytesWritten,
975 LPOVERLAPPED lpOverlapped)
976{
977 int iIndex; /* index into the handle table */
978 BOOL fResult; /* result from the device handler's CloseHandle() */
979 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
980
981 /* validate handle */
982 iIndex = _HMHandleQuery(hFile); /* get the index */
983 if (-1 == iIndex) /* error ? */
984 {
985 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
986 return (FALSE); /* signal failure */
987 }
988
989 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
990 fResult = pHMHandle->pDeviceHandler->WriteFile(&pHMHandle->hmHandleData,
991 lpBuffer,
992 nNumberOfBytesToWrite,
993 lpNumberOfBytesWritten,
994 lpOverlapped);
995
996 return (fResult); /* deliver return code */
997}
998
999
1000/*****************************************************************************
1001 * Name : HANDLE HMGetFileType
1002 * Purpose : Wrapper for the GetFileType() API
1003 * Parameters:
1004 * Variables :
1005 * Result :
1006 * Remark :
1007 * Status :
1008 *
1009 * Author : Patrick Haller [Wed, 1998/02/12 13:37]
1010 *****************************************************************************/
1011
1012DWORD HMGetFileType(HANDLE hFile)
1013{
1014 int iIndex; /* index into the handle table */
1015 DWORD dwResult; /* result from the device handler's API */
1016 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1017
1018 /* validate handle */
1019 iIndex = _HMHandleQuery(hFile); /* get the index */
1020 if (-1 == iIndex) /* error ? */
1021 {
1022 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1023 return (INVALID_HANDLE_ERROR); /* signal failure */
1024 }
1025
1026 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1027 dwResult = pHMHandle->pDeviceHandler->GetFileType(&pHMHandle->hmHandleData);
1028
1029 return (dwResult); /* deliver return code */
1030}
1031
1032
1033/*****************************************************************************
1034 * Name : HMDeviceHandler::_DeviceReuqest
1035 * Purpose : entry method for special request functions
1036 * Parameters: ULONG ulRequestCode
1037 * various parameters as required
1038 * Variables :
1039 * Result :
1040 * Remark : the standard behaviour is to return an error code for non-
1041 * existant request codes
1042 * Status :
1043 *
1044 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1045 *****************************************************************************/
1046DWORD HMDeviceRequest (HANDLE hFile,
1047 ULONG ulRequestCode,
1048 ULONG arg1,
1049 ULONG arg2,
1050 ULONG arg3,
1051 ULONG arg4)
1052{
1053 int iIndex; /* index into the handle table */
1054 DWORD dwResult; /* result from the device handler's API */
1055 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1056
1057 /* validate handle */
1058 iIndex = _HMHandleQuery(hFile); /* get the index */
1059 if (-1 == iIndex) /* error ? */
1060 {
1061 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1062 return (INVALID_HANDLE_ERROR); /* signal failure */
1063 }
1064
1065 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1066 dwResult = pHMHandle->pDeviceHandler->_DeviceRequest(&pHMHandle->hmHandleData,
1067 ulRequestCode,
1068 arg1,
1069 arg2,
1070 arg3,
1071 arg4);
1072
1073 return (dwResult); /* deliver return code */
1074}
1075
1076
1077/*****************************************************************************
1078 * Name : HMDeviceHandler::GetFileInformationByHandle
1079 * Purpose : router function for GetFileInformationByHandle
1080 * Parameters:
1081 * Variables :
1082 * Result :
1083 * Remark :
1084 * Status :
1085 *
1086 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1087 *****************************************************************************/
1088DWORD HMGetFileInformationByHandle (HANDLE hFile,
1089 BY_HANDLE_FILE_INFORMATION *pHFI)
1090{
1091 int iIndex; /* index into the handle table */
1092 DWORD dwResult; /* result from the device handler's API */
1093 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1094
1095 /* validate handle */
1096 iIndex = _HMHandleQuery(hFile); /* get the index */
1097 if (-1 == iIndex) /* error ? */
1098 {
1099 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1100 return (INVALID_HANDLE_ERROR); /* signal failure */
1101 }
1102
1103 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1104 dwResult = pHMHandle->pDeviceHandler->GetFileInformationByHandle(&pHMHandle->hmHandleData,
1105 pHFI);
1106
1107 return (dwResult); /* deliver return code */
1108}
1109
1110
1111
1112/*****************************************************************************
1113 * Name : HMDeviceHandler::SetEndOfFile
1114 * Purpose : router function for SetEndOfFile
1115 * Parameters:
1116 * Variables :
1117 * Result :
1118 * Remark :
1119 * Status :
1120 *
1121 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1122 *****************************************************************************/
1123BOOL HMSetEndOfFile (HANDLE hFile)
1124{
1125 int iIndex; /* index into the handle table */
1126 BOOL bResult; /* result from the device handler's API */
1127 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1128
1129 /* validate handle */
1130 iIndex = _HMHandleQuery(hFile); /* get the index */
1131 if (-1 == iIndex) /* error ? */
1132 {
1133 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1134 return (INVALID_HANDLE_ERROR); /* signal failure */
1135 }
1136
1137 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1138 bResult = pHMHandle->pDeviceHandler->SetEndOfFile(&pHMHandle->hmHandleData);
1139
1140 return (bResult); /* deliver return code */
1141}
1142
1143
1144/*****************************************************************************
1145 * Name : HMDeviceHandler::SetFileTime
1146 * Purpose : router function for SetFileTime
1147 * Parameters:
1148 * Variables :
1149 * Result :
1150 * Remark :
1151 * Status :
1152 *
1153 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1154 *****************************************************************************/
1155BOOL HMSetFileTime (HANDLE hFile,
1156 const FILETIME *pFT1,
1157 const FILETIME *pFT2,
1158 const FILETIME *pFT3)
1159{
1160 int iIndex; /* index into the handle table */
1161 BOOL bResult; /* result from the device handler's API */
1162 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1163
1164 /* validate handle */
1165 iIndex = _HMHandleQuery(hFile); /* get the index */
1166 if (-1 == iIndex) /* error ? */
1167 {
1168 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1169 return (INVALID_HANDLE_ERROR); /* signal failure */
1170 }
1171
1172 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1173 bResult = pHMHandle->pDeviceHandler->SetFileTime(&pHMHandle->hmHandleData,
1174 (LPFILETIME)pFT1,
1175 (LPFILETIME)pFT2,
1176 (LPFILETIME)pFT3);
1177
1178 return (bResult); /* deliver return code */
1179}
1180
1181
1182/*****************************************************************************
1183 * Name : HMDeviceHandler::GetFileSize
1184 * Purpose : router function for GetFileSize
1185 * Parameters:
1186 * Variables :
1187 * Result :
1188 * Remark :
1189 * Status :
1190 *
1191 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1192 *****************************************************************************/
1193DWORD HMGetFileSize (HANDLE hFile,
1194 PDWORD pSize)
1195{
1196 int iIndex; /* index into the handle table */
1197 DWORD dwResult; /* result from the device handler's API */
1198 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1199
1200 /* validate handle */
1201 iIndex = _HMHandleQuery(hFile); /* get the index */
1202 if (-1 == iIndex) /* error ? */
1203 {
1204 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1205 return (INVALID_HANDLE_ERROR); /* signal failure */
1206 }
1207
1208 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1209 dwResult = pHMHandle->pDeviceHandler->GetFileSize(&pHMHandle->hmHandleData,
1210 pSize);
1211
1212 return (dwResult); /* deliver return code */
1213}
1214
1215
1216/*****************************************************************************
1217 * Name : HMDeviceHandler::SetFilePointer
1218 * Purpose : router function for SetFilePointer
1219 * Parameters:
1220 * Variables :
1221 * Result :
1222 * Remark :
1223 * Status :
1224 *
1225 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1226 *****************************************************************************/
1227DWORD HMSetFilePointer (HANDLE hFile,
1228 LONG lDistanceToMove,
1229 PLONG lpDistanceToMoveHigh,
1230 DWORD dwMoveMethod)
1231{
1232 int iIndex; /* index into the handle table */
1233 DWORD dwResult; /* result from the device handler's API */
1234 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1235
1236 /* validate handle */
1237 iIndex = _HMHandleQuery(hFile); /* get the index */
1238 if (-1 == iIndex) /* error ? */
1239 {
1240 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1241 return (INVALID_HANDLE_ERROR); /* signal failure */
1242 }
1243
1244 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1245 dwResult = pHMHandle->pDeviceHandler->SetFilePointer(&pHMHandle->hmHandleData,
1246 lDistanceToMove,
1247 lpDistanceToMoveHigh,
1248 dwMoveMethod);
1249
1250 return (dwResult); /* deliver return code */
1251}
1252
1253
1254/*****************************************************************************
1255 * Name : HMDeviceHandler::LockFile
1256 * Purpose : router function for LockFile
1257 * Parameters:
1258 * Variables :
1259 * Result :
1260 * Remark :
1261 * Status :
1262 *
1263 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1264 *****************************************************************************/
1265BOOL HMLockFile (HFILE hFile,
1266 DWORD arg2,
1267 DWORD arg3,
1268 DWORD arg4,
1269 DWORD arg5)
1270{
1271 int iIndex; /* index into the handle table */
1272 DWORD dwResult; /* result from the device handler's API */
1273 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1274
1275 /* validate handle */
1276 iIndex = _HMHandleQuery(hFile); /* get the index */
1277 if (-1 == iIndex) /* error ? */
1278 {
1279 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1280 return (INVALID_HANDLE_ERROR); /* signal failure */
1281 }
1282
1283 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1284 dwResult = pHMHandle->pDeviceHandler->LockFile(&pHMHandle->hmHandleData,
1285 arg2,
1286 arg3,
1287 arg4,
1288 arg5);
1289
1290 return (dwResult); /* deliver return code */
1291}
1292
1293
1294/*****************************************************************************
1295 * Name : HMDeviceHandler::LockFileEx
1296 * Purpose : router function for LockFileEx
1297 * Parameters:
1298 * Variables :
1299 * Result :
1300 * Remark :
1301 * Status :
1302 *
1303 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1304 *****************************************************************************/
1305DWORD HMLockFileEx(HANDLE hFile,
1306 DWORD dwFlags,
1307 DWORD dwReserved,
1308 DWORD nNumberOfBytesToLockLow,
1309 DWORD nNumberOfBytesToLockHigh,
1310 LPOVERLAPPED lpOverlapped)
1311{
1312 int iIndex; /* index into the handle table */
1313 DWORD dwResult; /* result from the device handler's API */
1314 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1315
1316 /* validate handle */
1317 iIndex = _HMHandleQuery(hFile); /* get the index */
1318 if (-1 == iIndex) /* error ? */
1319 {
1320 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1321 return (INVALID_HANDLE_ERROR); /* signal failure */
1322 }
1323
1324 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1325 dwResult = pHMHandle->pDeviceHandler->LockFileEx(&pHMHandle->hmHandleData,
1326 dwFlags,
1327 dwReserved,
1328 nNumberOfBytesToLockLow,
1329 nNumberOfBytesToLockHigh,
1330 lpOverlapped);
1331
1332 return (dwResult); /* deliver return code */
1333}
1334
1335
1336
1337/*****************************************************************************
1338 * Name : HMDeviceHandler::UnlockFile
1339 * Purpose : router function for UnlockFile
1340 * Parameters:
1341 * Variables :
1342 * Result :
1343 * Remark :
1344 * Status :
1345 *
1346 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1347 *****************************************************************************/
1348BOOL HMUnlockFile (HFILE hFile,
1349 DWORD arg2,
1350 DWORD arg3,
1351 DWORD arg4,
1352 DWORD arg5)
1353{
1354 int iIndex; /* index into the handle table */
1355 DWORD dwResult; /* result from the device handler's API */
1356 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1357
1358 /* validate handle */
1359 iIndex = _HMHandleQuery(hFile); /* get the index */
1360 if (-1 == iIndex) /* error ? */
1361 {
1362 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1363 return (INVALID_HANDLE_ERROR); /* signal failure */
1364 }
1365
1366 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1367 dwResult = pHMHandle->pDeviceHandler->UnlockFile(&pHMHandle->hmHandleData,
1368 arg2,
1369 arg3,
1370 arg4,
1371 arg5);
1372
1373 return (dwResult); /* deliver return code */
1374}
1375
1376/*****************************************************************************
1377 * Name : HMDeviceHandler::UnlockFileEx
1378 * Purpose : router function for UnlockFileEx
1379 * Parameters:
1380 * Variables :
1381 * Result :
1382 * Remark :
1383 * Status :
1384 *
1385 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1386 *****************************************************************************/
1387BOOL HMUnlockFileEx(HANDLE hFile,
1388 DWORD dwFlags,
1389 DWORD dwReserved,
1390 DWORD nNumberOfBytesToLockLow,
1391 DWORD nNumberOfBytesToLockHigh,
1392 LPOVERLAPPED lpOverlapped)
1393{
1394 int iIndex; /* index into the handle table */
1395 DWORD dwResult; /* result from the device handler's API */
1396 PHMHANDLE pHMHandle; /* pointer to the handle structure in the table */
1397
1398 /* validate handle */
1399 iIndex = _HMHandleQuery(hFile); /* get the index */
1400 if (-1 == iIndex) /* error ? */
1401 {
1402 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */
1403 return (INVALID_HANDLE_ERROR); /* signal failure */
1404 }
1405
1406 pHMHandle = &TabWin32Handles[iIndex]; /* call device handler */
1407 dwResult = pHMHandle->pDeviceHandler->UnlockFileEx(&pHMHandle->hmHandleData,
1408 dwFlags,
1409 dwReserved,
1410 nNumberOfBytesToLockLow,
1411 nNumberOfBytesToLockHigh,
1412 lpOverlapped);
1413
1414 return (dwResult); /* deliver return code */
1415}
1416
Note: See TracBrowser for help on using the repository browser.