source: trunk/src/kernel32/hmfile.cpp@ 21310

Last change on this file since 21310 was 21302, checked in by ydario, 16 years ago

Kernel32 updates.

File size: 49.6 KB
Line 
1/* $Id: hmfile.cpp,v 1.46 2004-04-02 15:14:54 sandervl Exp $ */
2
3/*
4 * File IO win32 apis
5 *
6 * Copyright 1999-2000 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13/*****************************************************************************
14 * Remark *
15 *****************************************************************************
16 */
17
18//#define DEBUG_LOCAL
19
20#ifdef DEBUG_LOCAL
21# define dprintfl(a) dprintf(a)
22#else
23inline void ignore_dprintf(...){}
24# define dprintfl(a) ignore_dprintf(a)
25#endif
26
27/*****************************************************************************
28 * Includes *
29 *****************************************************************************/
30
31#include <os2win.h>
32#include <string.h>
33#include "HandleManager.h"
34#include "HMFile.h"
35#include "mmap.h"
36#include "oslibdos.h"
37#include <customloader.h>
38
39#define DBG_LOCALLOG DBG_hmfile
40#include "dbglocal.h"
41
42static void ParsePath(LPCSTR lpszFileName, LPSTR lpszParsedFileName, DWORD length);
43
44/*****************************************************************************
45 * Name : DWORD HMDeviceFileClass::CreateFile
46 * Purpose : this is called from the handle manager if a CreateFile() is
47 * performed on a handle
48 * Parameters: LPCSTR lpFileName name of the file / device
49 * PHMHANDLEDATA pHMHandleData data of the NEW handle
50 * PVOID lpSecurityAttributes ignored
51 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
52 * Variables :
53 * Result :
54 * Remark :
55 * Status : NO_ERROR - API succeeded
56 * other - what is to be set in SetLastError
57 *
58 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
59 *****************************************************************************/
60
61DWORD HMDeviceFileClass::CreateFile (LPCSTR lpFileName,
62 PHMHANDLEDATA pHMHandleData,
63 PVOID lpSecurityAttributes,
64 PHMHANDLEDATA pHMHandleDataTemplate)
65{
66 HFILE hFile;
67 HFILE hTemplate;
68 char filepath[260];
69
70 dprintfl(("KERNEL32: HMDeviceFileClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
71 lpHMDeviceName,
72 lpFileName,
73 pHMHandleData,
74 lpSecurityAttributes,
75 pHMHandleDataTemplate));
76
77 ParsePath(lpFileName, filepath, sizeof(filepath));
78
79 //convert to long file name if in 8.3 hashed format
80 GetLongPathNameA(filepath, filepath, sizeof(filepath));
81 lpFileName = filepath;
82
83 // create from template
84 if (pHMHandleDataTemplate != NULL)
85 hTemplate = pHMHandleDataTemplate->hHMHandle;
86 else
87 hTemplate = 0;
88
89 //TODO: FILE_SHARE_DELETE
90 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
91 pHMHandleData->dwAccess,
92 pHMHandleData->dwShare,
93 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
94 pHMHandleData->dwCreation,
95 pHMHandleData->dwFlags,
96 hTemplate);
97
98 if (hFile != INVALID_HANDLE_ERROR)
99 {
100 pHMHandleData->dwUserData = (DWORD) new HMFileInfo(hFile, (LPSTR)lpFileName, lpSecurityAttributes);
101 pHMHandleData->hHMHandle = hFile;
102 return (NO_ERROR);
103 }
104 else {
105 dprintf(("CreateFile failed; error %d", GetLastError()));
106 return(GetLastError());
107 }
108}
109
110/*****************************************************************************
111 * Name : DWORD HMDeviceFileClass::OpenFile
112 * Purpose : this is called from the handle manager if a OpenFile() is
113 * performed on a handle
114 * Parameters: LPCSTR lpFileName name of the file / device
115 * PHMHANDLEDATA pHMHandleData data of the NEW handle
116 * PVOID lpSecurityAttributes ignored
117 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
118 * Variables :
119 * Result :
120 * Remark : TODO: Check if this implementation is complete and 100% correct
121 * UTC Time or Localtime ?
122 * GetFileTime is changed, Returns UTC-time yet !!!!!
123 * Status : NO_ERROR - API succeeded
124 * other - what is to be set in SetLastError
125 *
126 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
127 *****************************************************************************/
128
129DWORD HMDeviceFileClass::OpenFile (LPCSTR lpszFileName,
130 PHMHANDLEDATA pHMHandleData,
131 OFSTRUCT *pOFStruct,
132 UINT fuMode)
133{
134 HFILE hFile;
135 FILETIME filetime;
136 WORD filedatetime[2];
137 char filepath[260];
138 LPSTR lpFileName = (LPSTR)lpszFileName;
139
140 SetLastError(ERROR_SUCCESS);
141
142 //Re-open using name in OFSTRUCT
143 if(fuMode & OF_REOPEN)
144 lpFileName = (LPSTR)pOFStruct->szPathName;
145 else memset(pOFStruct, 0, sizeof(OFSTRUCT));
146
147 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile %s(%s,%08x,%08x,%08x)", lpHMDeviceName,
148 lpFileName, pHMHandleData, pOFStruct, fuMode));
149
150 if(lpFileName == NULL) {
151 dprintf(("Invalid name (NULL)!"));
152 SetLastError(ERROR_INVALID_NAME);
153 return HFILE_ERROR;
154 }
155
156 if(!strchr(lpFileName, ':') && !strchr(lpFileName, '\\'))
157 {
158 //filename only; search for file in following order
159 //1: dir from which the app loaded
160 //2: current dir
161 //3: windows system dir
162 //4: windows dir
163 //5: dirs in path path environment variable
164 //SearchPath does exactly that
165 LPSTR filenameinpath;
166
167 if (SearchPathA(NULL, lpFileName, NULL, sizeof(filepath), filepath, &filenameinpath) == 0)
168 {
169 if (!(fuMode & (OF_CREATE | OF_PARSE)))
170 {
171 pOFStruct->nErrCode = ERROR_FILE_NOT_FOUND; /* What about initializing the struct? */
172 SetLastError(ERROR_FILE_NOT_FOUND);
173 return HFILE_ERROR;
174 }
175
176 /*
177 * OF_PARSE | OF_CREATE:
178 * Assume file in current directory.
179 */
180 GetCurrentDirectoryA(sizeof(filepath), filepath);
181 strcat(strcat(filepath, "\\"), lpFileName);
182 GetLongPathNameA(filepath, filepath, sizeof(filepath));
183 }
184 lpFileName = filepath;
185 }
186 else {
187 #if 1 /* Canonicalize the path should be the right thing to do I think... */
188 GetFullPathNameA(lpFileName, sizeof(filepath), filepath, NULL);
189 #else
190 ParsePath(lpFileName, filepath, sizeof(filepath));
191 #endif
192
193 //convert to long file name if in 8.3 hashed format
194 GetLongPathNameA(filepath, filepath, sizeof(filepath));
195 lpFileName = filepath;
196 }
197
198 // filling OFSTRUCT
199 pOFStruct->cBytes = sizeof(OFSTRUCT);
200 pOFStruct->nErrCode = 0;
201 strncpy((char *)pOFStruct->szPathName, lpFileName, OFS_MAXPATHNAME);
202 pOFStruct->szPathName[OFS_MAXPATHNAME-1] = 0;
203
204
205 /*
206 * Do the parse stuff now and do a quick exit.
207 * Based on testcase (5) and MSDN:
208 * "OF_PARSE Fills the OFSTRUCT structure but carries out no other action."
209 */
210 if (fuMode & OF_PARSE)
211 {
212 CHAR szDrive[4];
213 *(PULONG)&szDrive[0] = *(PULONG)&pOFStruct->szPathName[0];
214 szDrive[3] = '\0';
215 pOFStruct->fFixedDisk = (GetDriveTypeA(szDrive) != DRIVE_REMOVABLE);
216 SetLastError(NO_ERROR);
217 return NO_ERROR;
218 }
219
220
221 hFile = OSLibDosOpenFile((LPSTR)lpFileName, fuMode);
222
223 if(hFile != INVALID_HANDLE_ERROR)
224 {
225 //Needed for GetFileTime
226 pHMHandleData->hHMHandle = hFile;
227 GetFileTime(pHMHandleData,
228 NULL,
229 NULL,
230 &filetime );
231
232 /* UTC Time or Localtime ? GetFileTime Returns UTC-time yet ? !!!!! */
233 FileTimeToDosDateTime(&filetime,
234 &filedatetime[0],
235 &filedatetime[1] );
236 memcpy(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved));
237
238 if(fuMode & OF_DELETE)
239 {
240 OSLibDosClose(hFile);
241 OSLibDosDelete((LPSTR)lpFileName);
242 }
243 else
244 if(fuMode & OF_EXIST)
245 {
246 OSLibDosClose(hFile);
247 hFile = HFILE_ERROR;
248 }
249
250 if((fuMode & OF_VERIFY))
251 {//TODO: what's this?? we copy the time above...
252 if(memcmp(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved)))
253 {
254 OSLibDosClose(hFile);
255 SetLastError(ERROR_FILE_NOT_FOUND);
256 }
257 hFile = HFILE_ERROR;
258 }
259
260 pOFStruct->nErrCode = GetLastError();
261 pHMHandleData->hHMHandle = hFile;
262
263 if(hFile != HFILE_ERROR) {
264 pHMHandleData->dwUserData = (DWORD) new HMFileInfo(hFile, (LPSTR)lpFileName, NULL);
265 }
266 return (NO_ERROR);
267 }
268 else {
269 DWORD rc = GetLastError();
270
271 if(fuMode & OF_EXIST)
272 {
273 if(rc == ERROR_OPEN_FAILED) {
274 SetLastError(ERROR_FILE_NOT_FOUND);
275 }
276 }
277 //todo: OF_PROMPT handling (pop up message box)
278 }
279 // error branch
280 pOFStruct->nErrCode = GetLastError();
281 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile Error %08xh\n",
282 pOFStruct->nErrCode));
283
284 // return != NO_ERROR => error code
285 return(hFile);
286}
287
288/*****************************************************************************
289 * Name : HMDeviceFileClass::DuplicateHandle
290 * Purpose :
291 * Parameters:
292 * various parameters as required
293 * Variables :
294 * Result :
295 * Remark : DUPLICATE_CLOSE_SOURCE flag handled in HMDuplicateHandle
296 *
297 * Status : partially implemented
298 *
299 * Author : SvL
300 *****************************************************************************/
301BOOL HMDeviceFileClass::DuplicateHandle(HANDLE srchandle, PHMHANDLEDATA pHMHandleData,
302 HANDLE srcprocess,
303 PHMHANDLEDATA pHMSrcHandle,
304 HANDLE destprocess,
305 DWORD fdwAccess,
306 BOOL fInherit,
307 DWORD fdwOptions,
308 DWORD fdwOdinOptions)
309{
310 HMFileInfo *srcfileinfo = (HMFileInfo *)pHMSrcHandle->dwUserData;
311 DWORD rc;
312
313 dprintf(("KERNEL32:HMDeviceFileClass::DuplicateHandle (%08x,%08x,%08x,%08x)",
314 pHMHandleData,
315 srcprocess,
316 pHMSrcHandle->hHMHandle,
317 destprocess));
318
319 //TODO: Inheritance of file handles won't work!
320
321 if(destprocess != srcprocess)
322 {
323 //TODO:!!!!
324 dprintf(("ERROR: DuplicateHandle; different processes not yet supported!!"));
325 return FALSE;
326 }
327
328 if(srcfileinfo)
329 {
330 //SvL: Special duplicatehandle option used by memory mapped class to duplicate
331 // file handle
332 // Can't use DosDupHandle or else there can be a sharing violation
333 // when an app tries to access the same file again
334 if(fdwOdinOptions)
335 {
336 HMHANDLEDATA duphdata;
337
338 memcpy(&duphdata, pHMHandleData, sizeof(duphdata));
339 duphdata.dwCreation = OPEN_EXISTING;
340
341 if(CreateFile(srcfileinfo->lpszFileName, &duphdata,
342 srcfileinfo->lpSecurityAttributes, NULL) == NO_ERROR)
343 {
344 memcpy(pHMHandleData, &duphdata, sizeof(duphdata));
345
346 SetHandleInformation(pHMHandleData, HANDLE_FLAG_INHERIT, (fInherit) ? HANDLE_FLAG_INHERIT : 0);
347
348 SetLastError(ERROR_SUCCESS);
349 return TRUE;
350 }
351 dprintf(("ERROR: DuplicateHandle; CreateFile %s failed -> trying DosDupHandle instead!",
352 srcfileinfo->lpszFileName));
353 //SvL: IE5 setup opens file with DENYREADWRITE, so CreateFile can't
354 // be used for duplicating the handle; try DosDupHandle instead
355 }
356
357 if(!(fdwOptions & DUPLICATE_SAME_ACCESS) && fdwAccess != pHMSrcHandle->dwAccess) {
358 dprintf(("WARNING: DuplicateHandle; app wants different access permission; Not supported!! (%x, %x)", fdwAccess, pHMSrcHandle->dwAccess));
359 }
360
361 pHMHandleData->hHMHandle = 0;
362 rc = OSLibDosDupHandle(pHMSrcHandle->hHMHandle, &pHMHandleData->hHMHandle);
363 if (rc)
364 {
365 dprintf(("ERROR: DuplicateHandle: OSLibDosDupHandle(%s) failed = %u",
366 srcfileinfo->lpszFileName, rc));
367 SetLastError(rc);
368 return FALSE; // ERROR
369 }
370 else {
371 SetHandleInformation(pHMHandleData, HANDLE_FLAG_INHERIT, (fInherit) ? HANDLE_FLAG_INHERIT : 0);
372
373 SetLastError(ERROR_SUCCESS);
374 return TRUE; // OK
375 }
376 }
377 else
378 {
379 dprintf(("ERROR: DuplicateHandle; invalid parameter!!"));
380 SetLastError(ERROR_INVALID_PARAMETER);
381 return FALSE;
382 }
383}
384
385/*****************************************************************************
386 * Name : BOOL HMDeviceFileClass::SetHandleInformation
387 * Purpose : The SetHandleInformation function sets certain properties of an
388 * object handle. The information is specified as a set of bit flags.
389 * Parameters: HANDLE hObject handle to an object
390 * DWORD dwMask specifies flags to change
391 * DWORD dwFlags specifies new values for flags
392 * Variables :
393 * Result : TRUE / FALSE
394 * Remark :
395 * Status :
396 *
397 * Author : SvL
398 *****************************************************************************/
399BOOL HMDeviceFileClass::SetHandleInformation(PHMHANDLEDATA pHMHandleData,
400 DWORD dwMask,
401 DWORD dwFlags)
402{
403 DWORD rc;
404
405 pHMHandleData->dwHandleInformation &= ~dwMask;
406 pHMHandleData->dwHandleInformation |= (dwFlags & dwMask);
407
408 rc = OSLibDosSetFHState(pHMHandleData->hHMHandle,
409 pHMHandleData->dwHandleInformation);
410 if (rc)
411 {
412 dprintf(("ERROR: SetHandleInformation: OSLibDosSetFHState failed with %d", rc));
413
414 SetLastError(rc);
415 return FALSE;
416 }
417
418 SetLastError(ERROR_SUCCESS);
419 return TRUE;
420}
421
422/*****************************************************************************
423 * Name : BOOL HMDeviceFileClass::CloseHandle
424 * Purpose : close the handle
425 * Parameters: PHMHANDLEDATA pHMHandleData
426 * Variables :
427 * Result : API returncode
428 * Remark :
429 * Status :
430 *
431 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
432 *****************************************************************************/
433
434BOOL HMDeviceFileClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
435{
436 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
437 BOOL bRC;
438
439 dprintfl(("KERNEL32: HMDeviceFileClass::CloseHandle(%08x)\n",
440 pHMHandleData->hHMHandle));
441
442 bRC = OSLibDosClose(pHMHandleData->hHMHandle);
443
444 if(pHMHandleData->dwFlags & FILE_FLAG_DELETE_ON_CLOSE) {
445 //TODO: should only do this after all handles have been closed
446 if(fileInfo) {
447 DeleteFileA(fileInfo->lpszFileName);
448 }
449 }
450 if(fileInfo) {
451 delete fileInfo;
452 }
453 dprintf(("KERNEL32: HMDeviceFileClass::CloseHandle returned %08xh\n",
454 bRC));
455
456 return (DWORD)bRC;
457}
458
459
460/*****************************************************************************
461 * Name : BOOL HMDeviceFileClass::ReadFile
462 * Purpose : read data from handle / device
463 * Parameters: PHMHANDLEDATA pHMHandleData,
464 * LPCVOID lpBuffer,
465 * DWORD nNumberOfBytesToRead,
466 * LPDWORD lpNumberOfBytesRead,
467 * LPOVERLAPPED lpOverlapped
468 * Variables :
469 * Result : Boolean
470 * Remark :
471 * Status :
472 *
473 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
474 *****************************************************************************/
475
476BOOL HMDeviceFileClass::ReadFile(PHMHANDLEDATA pHMHandleData,
477 LPCVOID lpBuffer,
478 DWORD nNumberOfBytesToRead,
479 LPDWORD lpNumberOfBytesRead,
480 LPOVERLAPPED lpOverlapped,
481 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
482{
483 LPVOID lpRealBuf;
484 Win32MemMap *map;
485 DWORD offset, bytesread;
486 BOOL bRC;
487
488 dprintfl(("KERNEL32: HMDeviceFileClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
489 lpHMDeviceName,
490 pHMHandleData,
491 lpBuffer,
492 nNumberOfBytesToRead,
493 lpNumberOfBytesRead,
494 lpOverlapped));
495
496 //SvL: It's legal for this pointer to be NULL
497 if(lpNumberOfBytesRead)
498 *lpNumberOfBytesRead = 0;
499 else
500 lpNumberOfBytesRead = &bytesread;
501
502 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
503 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
504 SetLastError(ERROR_INVALID_PARAMETER);
505 return FALSE;
506 }
507 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
508 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
509 }
510 if(lpCompletionRoutine) {
511 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
512 }
513
514 //SvL: DosRead doesn't like writing to memory addresses returned by
515 // DosAliasMem -> search for original memory mapped pointer and use
516 // that one + commit pages if not already present
517 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
518 if(map) {
519 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
520 DWORD nrpages = nNumberOfBytesToRead/4096;
521 if((nNumberOfBytesToRead+offset) & 0xfff)
522 nrpages++;
523
524 map->commitRange((ULONG)lpBuffer, offset & ~0xfff, TRUE, nrpages);
525 map->Release();
526 }
527 else lpRealBuf = (LPVOID)lpBuffer;
528
529 //If this file is also used in a memory map somewhere, then we need
530 //to tell the map to flush all modified contents to disk right NOW
531 map = Win32MemMap::findMapByFile(pHMHandleData->hWin32Handle);
532 if(map) {
533 DWORD curpos = SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT);
534
535 dprintf(("Flush memory maps to disk before reading!!"));
536 map->flushView(MMAP_FLUSHVIEW_ALL, curpos, nNumberOfBytesToRead);
537 }
538
539 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
540 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
541 }
542// else {
543 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
544 (PVOID)lpRealBuf,
545 nNumberOfBytesToRead,
546 lpNumberOfBytesRead);
547// }
548
549 if(bRC == 0) {
550 dprintf(("KERNEL32: HMDeviceFileClass::ReadFile returned %08xh %x\n",
551 bRC, GetLastError()));
552 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
553 }
554
555 return bRC;
556}
557
558
559/*****************************************************************************
560 * Name : BOOL HMDeviceFileClass::WriteFile
561 * Purpose : write data to handle / device
562 * Parameters: PHMHANDLEDATA pHMHandleData,
563 * LPCVOID lpBuffer,
564 * DWORD nNumberOfBytesToWrite,
565 * LPDWORD lpNumberOfBytesWritten,
566 * LPOVERLAPPED lpOverlapped
567 * Variables :
568 * Result : Boolean
569 * Remark :
570 * Status :
571 *
572 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
573 *****************************************************************************/
574
575BOOL HMDeviceFileClass::WriteFile(PHMHANDLEDATA pHMHandleData,
576 LPCVOID lpBuffer,
577 DWORD nNumberOfBytesToWrite,
578 LPDWORD lpNumberOfBytesWritten,
579 LPOVERLAPPED lpOverlapped,
580 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
581{
582 LPVOID lpRealBuf;
583 Win32MemMap *map;
584 DWORD offset, byteswritten;
585 BOOL bRC;
586
587 dprintfl(("KERNEL32: HMDeviceFileClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
588 lpHMDeviceName,
589 pHMHandleData,
590 lpBuffer,
591 nNumberOfBytesToWrite,
592 lpNumberOfBytesWritten,
593 lpOverlapped));
594
595 //SvL: It's legal for this pointer to be NULL
596 if(lpNumberOfBytesWritten)
597 *lpNumberOfBytesWritten = 0;
598 else
599 lpNumberOfBytesWritten = &byteswritten;
600
601 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
602 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
603 SetLastError(ERROR_INVALID_PARAMETER);
604 return FALSE;
605 }
606 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
607 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
608 }
609
610 //SvL: DosWrite doesn't like reading from memory addresses returned by
611 // DosAliasMem -> search for original memory mapped pointer and use
612 // that one + commit pages if not already present
613 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
614 if(map) {
615 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
616 DWORD nrpages = nNumberOfBytesToWrite/4096;
617 if((nNumberOfBytesToWrite+offset) & 0xfff)
618 nrpages++;
619
620 map->commitRange((ULONG)lpBuffer, offset & ~0xfff, FALSE, nrpages);
621 map->Release();
622 }
623 else lpRealBuf = (LPVOID)lpBuffer;
624
625 //If this file is also used in a memory map somewhere, then we need
626 //to tell the map to flush all modified contents to disk right NOW
627 DWORD curfilepos;
628 map = Win32MemMap::findMapByFile(pHMHandleData->hWin32Handle);
629 if(map) {
630 curfilepos = SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT);
631
632 dprintf(("Flush memory maps to disk before writing!!"));
633 map->flushView(MMAP_FLUSHVIEW_ALL, curfilepos, nNumberOfBytesToWrite);
634 }
635
636 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
637 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
638 }
639// else {
640 bRC = OSLibDosWrite(pHMHandleData->hHMHandle,
641 (PVOID)lpRealBuf,
642 nNumberOfBytesToWrite,
643 lpNumberOfBytesWritten);
644// }
645
646 if(map && bRC) {
647 dprintf(("Invalidate memory map after file writing!!"));
648 map->invalidatePages(curfilepos, *lpNumberOfBytesWritten);
649 }
650
651 dprintf(("KERNEL32: HMDeviceFileClass::WriteFile returned %08xh\n",
652 bRC));
653
654 return bRC;
655}
656
657
658/*****************************************************************************
659 * Name : DWORD HMDeviceFileClass::GetFileType
660 * Purpose : determine the handle type
661 * Parameters: PHMHANDLEDATA pHMHandleData
662 * Variables :
663 * Result : API returncode
664 * Remark :
665 * Status :
666 *
667 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
668 *****************************************************************************/
669
670DWORD HMDeviceFileClass::GetFileType(PHMHANDLEDATA pHMHandleData)
671{
672 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileType %s(%08x)\n",
673 lpHMDeviceName,
674 pHMHandleData));
675
676 return FILE_TYPE_DISK;
677}
678
679
680/*****************************************************************************
681 * Name : DWORD HMDeviceFileClass::GetFileInformationByHandle
682 * Purpose : determine the handle type
683 * Parameters: PHMHANDLEDATA pHMHandleData
684 * BY_HANDLE_FILE_INFORMATION* pHFI
685 * Variables :
686 * Result : API returncode
687 * Remark :
688 * Status :
689 *
690 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
691 *****************************************************************************/
692
693DWORD HMDeviceFileClass::GetFileInformationByHandle(PHMHANDLEDATA pHMHandleData,
694 BY_HANDLE_FILE_INFORMATION* pHFI)
695{
696 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileInformationByHandle %s(%08xh,%08xh)\n",
697 lpHMDeviceName, pHMHandleData, pHFI));
698
699 if(OSLibDosGetFileInformationByHandle(pHMHandleData->hHMHandle,
700 pHFI))
701 {
702 return TRUE;
703 }
704 dprintf(("GetFileInformationByHandle failed with error %d", GetLastError()));
705 return FALSE;
706
707}
708
709
710/*****************************************************************************
711 * Name : BOOL HMDeviceFileClass::SetEndOfFile
712 * Purpose : set end of file marker
713 * Parameters: PHMHANDLEDATA pHMHandleData
714 * Variables :
715 * Result : API returncode
716 * Remark :
717 * Status :
718 *
719 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
720 *****************************************************************************/
721
722BOOL HMDeviceFileClass::SetEndOfFile(PHMHANDLEDATA pHMHandleData)
723{
724 dprintfl(("KERNEL32: HMDeviceFileClass::SetEndOfFile %s(%08xh)\n",
725 lpHMDeviceName,
726 pHMHandleData));
727
728 if(OSLibDosSetEndOfFile(pHMHandleData->hHMHandle)) {
729 return TRUE;
730 }
731 dprintf(("SetEndOfFile failed with error %d", GetLastError()));
732 return FALSE;
733}
734
735//******************************************************************************
736/*****************************************************************************
737 * Name : BOOL HMDeviceFileClass::SetFileTime
738 * Purpose : set file time
739 * Parameters: PHMHANDLEDATA pHMHandleData
740 * PFILETIME pFT1
741 * PFILETIME pFT2
742 * PFILETIME pFT3
743 * Variables :
744 * Result : API returncode
745 * Remark :
746 * Status :
747 *
748 * Author : Patrick Haller [Wed, 1999/06/17 20:44] mod. DT
749 *****************************************************************************/
750
751BOOL HMDeviceFileClass::SetFileTime(PHMHANDLEDATA pHMHandleData,
752 LPFILETIME pFT1,
753 LPFILETIME pFT2,
754 LPFILETIME pFT3)
755{
756 dprintfl(("KERNEL32: HMDeviceFileClass::SetFileTime %s(%08xh,%08xh,%08xh,%08xh)\n",
757 lpHMDeviceName, pHMHandleData, pFT1, pFT2, pFT3));
758
759 if(OSLibDosSetFileTime(pHMHandleData->hHMHandle, pFT1, pFT2, pFT3)) return TRUE;
760
761 dprintf(("SetFileTime failed with error %d", GetLastError()));
762 return FALSE;
763}
764
765/*****************************************************************************
766 * Name : BOOL HMDeviceFileClass::GetFileTime
767 * Purpose : get file time
768 * Parameters: PHMHANDLEDATA pHMHandleData
769 * PFILETIME pFT1
770 * PFILETIME pFT2
771 * PFILETIME pFT3
772 * Variables :
773 * Result : API returncode
774 * Remark :
775 * Status :
776 *
777 * Author : SvL mod. DT
778 *****************************************************************************/
779
780BOOL HMDeviceFileClass::GetFileTime(PHMHANDLEDATA pHMHandleData,
781 LPFILETIME pFT1,
782 LPFILETIME pFT2,
783 LPFILETIME pFT3)
784{
785 if(!pFT1 && !pFT2 && !pFT3) {//TODO: does NT do this?
786 dprintf(("ERROR: GetFileTime: invalid parameter!"));
787 SetLastError(ERROR_INVALID_PARAMETER);
788 return FALSE;
789 }
790
791 if(OSLibDosGetFileTime(pHMHandleData->hHMHandle, pFT1, pFT2, pFT3)) return TRUE;
792 dprintf(("GetFileTime failed with error %d", GetLastError()));
793 return FALSE;
794}
795
796/*****************************************************************************
797 * Name : DWORD HMDeviceFileClass::GetFileSize
798 * Purpose : set file time
799 * Parameters: PHMHANDLEDATA pHMHandleData
800 * PDWORD pSize
801 * Variables :
802 * Result : API returncode
803 * Remark :
804 * Status :
805 *
806 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
807 *****************************************************************************/
808
809DWORD HMDeviceFileClass::GetFileSize(PHMHANDLEDATA pHMHandleData,
810 PDWORD lpdwFileSizeHigh)
811{
812 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileSize %s(%08xh,%08xh)\n",
813 lpHMDeviceName,
814 pHMHandleData,
815 lpdwFileSizeHigh));
816
817 if(lpdwFileSizeHigh)
818 *lpdwFileSizeHigh = 0;
819
820 return OSLibDosGetFileSize(pHMHandleData->hHMHandle, lpdwFileSizeHigh);
821}
822
823/*****************************************************************************
824 * Name : DWORD HMDeviceFileClass::SetFilePointer
825 * Purpose : set file pointer
826 * Parameters: PHMHANDLEDATA pHMHandleData
827 * LONG lDistanceToMove
828 * PLONG lpDistanceToMoveHigh
829 * DWORD dwMoveMethod
830 * Variables :
831 * Result : API returncode
832 * Remark :
833 * Status :
834 *
835 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
836 *****************************************************************************/
837
838DWORD HMDeviceFileClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
839 LONG lDistanceToMove,
840 PLONG lpDistanceToMoveHigh,
841 DWORD dwMoveMethod)
842{
843 DWORD ret;
844 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
845
846 dprintfl(("KERNEL32: HMDeviceFileClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
847 lpHMDeviceName,
848 pHMHandleData,
849 lDistanceToMove,
850 lpDistanceToMoveHigh,
851 dwMoveMethod));
852
853 if(fileInfo && fileInfo->dwLXOffset)
854 {
855 switch(dwMoveMethod)
856 {
857 case FILE_BEGIN:
858 dprintf(("SetFilePointer FILE_BEGIN (LX) -> change offset from %x to %x", lDistanceToMove, lDistanceToMove+fileInfo->dwLXOffset));
859 lDistanceToMove += fileInfo->dwLXOffset;
860 break;
861
862 case FILE_END:
863 //Could overshoot the virtual beginning of the PE file
864 lDistanceToMove -= MAGIC_STUBEXE_SIZE;
865 dprintf(("SetFilePointer FILE_END -> might be dangerous!!"));
866 break;
867
868 }
869 }
870 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
871 lDistanceToMove,
872 (DWORD *)lpDistanceToMoveHigh,
873 dwMoveMethod);
874
875 if(ret == -1) {
876 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
877 }
878 return ret;
879}
880
881
882/*****************************************************************************
883 * Name : BOOL HMDeviceFileClass::LockFile
884 * Purpose : file locking
885 * Parameters: PHMHANDLEDATA pHMHandleData
886 * DWORD arg2
887 * DWORD arg3
888 * DWORD arg4
889 * DWORD arg5
890 * Variables :
891 * Result : API returncode
892 * Remark :
893 * Status :
894 *
895 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
896 *****************************************************************************/
897
898BOOL HMDeviceFileClass::LockFile(PHMHANDLEDATA pHMHandleData,
899 DWORD dwFileOffsetLow,
900 DWORD dwFileOffsetHigh,
901 DWORD cbLockLow,
902 DWORD cbLockHigh)
903{
904 dprintfl(("KERNEL32: HMDeviceFileClass::LockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
905 lpHMDeviceName,
906 pHMHandleData,
907 dwFileOffsetLow,
908 dwFileOffsetHigh,
909 cbLockLow,
910 cbLockHigh));
911
912 return OSLibDosLockFile(pHMHandleData->hHMHandle,
913 LOCKFILE_EXCLUSIVE_LOCK,
914 dwFileOffsetLow,
915 dwFileOffsetHigh,
916 cbLockLow,
917 cbLockHigh,
918 NULL);
919}
920
921/*****************************************************************************
922 * Name : DWORD HMDeviceFileClass::LockFileEx
923 * Purpose : file locking
924 * Parameters: PHMHANDLEDATA pHMHandleData
925 * DWORD dwFlags
926 * DWORD dwReserved
927 * DWORD nNumberOfBytesToLockLow
928 * DWORD nNumberOfBytesToLockHigh
929 * LPOVERLAPPED lpOverlapped
930 * Variables :
931 * Result : API returncode
932 * Remark :
933 * Status :
934 *
935 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
936 *****************************************************************************/
937
938BOOL HMDeviceFileClass::LockFileEx(PHMHANDLEDATA pHMHandleData,
939 DWORD dwFlags,
940 DWORD dwReserved,
941 DWORD nNumberOfBytesToLockLow,
942 DWORD nNumberOfBytesToLockHigh,
943 LPOVERLAPPED lpOverlapped)
944{
945
946 dprintfl(("KERNEL32: HMDeviceFileClass::LockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
947 lpHMDeviceName,
948 pHMHandleData,
949 dwFlags,
950 dwReserved,
951 nNumberOfBytesToLockLow,
952 nNumberOfBytesToLockHigh,
953 lpOverlapped));
954
955
956 return(OSLibDosLockFile(pHMHandleData->hHMHandle,
957 dwFlags,
958 lpOverlapped->Offset,
959 lpOverlapped->OffsetHigh,
960 nNumberOfBytesToLockLow,
961 nNumberOfBytesToLockHigh,
962 lpOverlapped));
963}
964
965
966/*****************************************************************************
967 * Name : DWORD HMDeviceFileClass::UnlockFile
968 * Purpose : file locking
969 * Parameters: PHMHANDLEDATA pHMHandleData
970 * DWORD arg2
971 * DWORD arg3
972 * DWORD arg4
973 * DWORD arg5
974 * Variables :
975 * Result : API returncode
976 * Remark :
977 * Status :
978 *
979 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
980 *****************************************************************************/
981
982BOOL HMDeviceFileClass::UnlockFile(PHMHANDLEDATA pHMHandleData,
983 DWORD dwFileOffsetLow,
984 DWORD dwFileOffsetHigh,
985 DWORD cbLockLow,
986 DWORD cbLockHigh)
987{
988 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
989 lpHMDeviceName,
990 pHMHandleData,
991 dwFileOffsetLow,
992 dwFileOffsetHigh,
993 cbLockLow,
994 cbLockHigh));
995
996 return OSLibDosUnlockFile(pHMHandleData->hHMHandle,
997 dwFileOffsetLow,
998 dwFileOffsetHigh,
999 cbLockLow,
1000 cbLockHigh,
1001 NULL);
1002}
1003
1004
1005
1006/*****************************************************************************
1007 * Name : DWORD HMDeviceFileClass::UnlockFileEx
1008 * Purpose : file locking
1009 * Parameters: PHMHANDLEDATA pHMHandleData
1010 * DWORD dwFlags
1011 * DWORD dwReserved
1012 * DWORD nNumberOfBytesToLockLow
1013 * DWORD nNumberOfBytesToLockHigh
1014 * LPOVERLAPPED lpOverlapped
1015 * Variables :
1016 * Result : API returncode
1017 * Remark :
1018 * Status :
1019 *
1020 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1021 *****************************************************************************/
1022
1023BOOL HMDeviceFileClass::UnlockFileEx(PHMHANDLEDATA pHMHandleData,
1024 DWORD dwReserved,
1025 DWORD nNumberOfBytesToLockLow,
1026 DWORD nNumberOfBytesToLockHigh,
1027 LPOVERLAPPED lpOverlapped)
1028{
1029
1030 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
1031 lpHMDeviceName,
1032 pHMHandleData,
1033 dwReserved,
1034 nNumberOfBytesToLockLow,
1035 nNumberOfBytesToLockHigh,
1036 lpOverlapped));
1037
1038
1039 return(OSLibDosUnlockFile(pHMHandleData->hHMHandle,
1040 lpOverlapped->Offset,
1041 lpOverlapped->OffsetHigh,
1042 nNumberOfBytesToLockLow,
1043 nNumberOfBytesToLockHigh,
1044 lpOverlapped));
1045}
1046
1047
1048/*****************************************************************************
1049 * Name : DWORD HMDeviceFileClass::FlushFileBuffers
1050 * Purpose : flush the buffers of a file
1051 * Parameters: PHMHANDLEDATA pHMHandleData
1052 * Variables :
1053 * Result : API returncode
1054 * Remark :
1055 * Status :
1056 *
1057 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1058 *****************************************************************************/
1059
1060BOOL HMDeviceFileClass::FlushFileBuffers(PHMHANDLEDATA pHMHandleData)
1061{
1062 dprintfl(("KERNEL32: HMDeviceFileClass:FlushFileBuffers(%08xh)\n",
1063 pHMHandleData->hHMHandle));
1064
1065 return(OSLibDosFlushFileBuffers(pHMHandleData->hHMHandle));
1066}
1067
1068
1069/*****************************************************************************
1070 * Name : DWORD HMDeviceFileClass::GetOverlappedResult
1071 * Purpose : asynchronus I/O
1072 * Parameters: PHMHANDLEDATA pHMHandleData
1073 * LPOVERLAPPED arg2
1074 * LPDWORD arg3
1075 * BOOL arg4
1076 * Variables :
1077 * Result : API returncode
1078 * Remark :
1079 * Status :
1080 *
1081 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1082 *****************************************************************************/
1083
1084BOOL HMDeviceFileClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
1085 LPOVERLAPPED arg2,
1086 LPDWORD arg3,
1087 BOOL arg4)
1088{
1089 dprintfl(("KERNEL32-WARNING: HMDeviceFileClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) STUB!!",
1090 pHMHandleData->hHMHandle,
1091 arg2,
1092 arg3,
1093 arg4));
1094
1095 return FALSE;
1096// return(O32_GetOverlappedResult(pHMHandleData->hHMHandle,
1097// arg2,
1098// arg3,
1099// arg4));
1100}
1101/******************************************************************************
1102 * Name : DWORD HMDeviceFileClass::GetFileNameFromHandle
1103 * Purpose : the name of the file associated with the system handle (if any)
1104 * Parameters: PHMHANDLEDATA pHMHandleData
1105 * Variables :
1106 * Result : BOOLEAN
1107 * Remark :
1108 * Status :
1109 *
1110 * Author : SvL
1111 ******************************************************************************/
1112BOOL HMDeviceFileClass::GetFileNameFromHandle(PHMHANDLEDATA pHMHandleData,
1113 LPSTR lpszFileName, DWORD cbFileName)
1114{
1115 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1116
1117 if(fileInfo == NULL || strlen(fileInfo->lpszFileName) >= cbFileName) {
1118 if(fileInfo) DebugInt3();
1119 return FALSE;
1120 }
1121 strcpy(lpszFileName, fileInfo->lpszFileName);
1122
1123 return TRUE;
1124}
1125
1126//******************************************************************************
1127//******************************************************************************
1128// File information handle class
1129//
1130// When the application opens a file with CreateFile and 0 for desired access,
1131// then we need to create a handle with limited access.
1132//
1133// MSDN:
1134//
1135// If this parameter is zero, the application can query file and device attributes
1136// without accessing the device. This is useful if an application wants to determine
1137// the size of a floppy disk drive and the formats it supports without requiring
1138// a floppy in the drive. It can also be used to test for the file's or directory's
1139// existence without opening it for read or write access.
1140//
1141//******************************************************************************
1142//******************************************************************************
1143
1144/******************************************************************************
1145 * Name : DWORD HMDeviceInfoFileClass::CreateFile
1146 * Purpose : this is called from the handle manager if a CreateFile() is
1147 * performed on a handle
1148 * Parameters: LPCSTR lpFileName name of the file / device
1149 * PHMHANDLEDATA pHMHandleData data of the NEW handle
1150 * PVOID lpSecurityAttributes ignored
1151 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
1152 * Variables :
1153 * Result :
1154 * Remark :
1155 * Status : NO_ERROR - API succeeded
1156 * other - what is to be set in SetLastError
1157 *
1158 * Author : SvL
1159 *****************************************************************************/
1160DWORD HMDeviceInfoFileClass::CreateFile (LPCSTR lpFileName,
1161 PHMHANDLEDATA pHMHandleData,
1162 PVOID lpSecurityAttributes,
1163 PHMHANDLEDATA pHMHandleDataTemplate)
1164{
1165 char filepath[260];
1166 DWORD dwAttr;
1167
1168 dprintfl(("KERNEL32: HMDeviceInfoFileClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
1169 lpHMDeviceName,
1170 lpFileName,
1171 pHMHandleData,
1172 lpSecurityAttributes,
1173 pHMHandleDataTemplate));
1174
1175 ParsePath(lpFileName, filepath, sizeof(filepath));
1176
1177 //convert to long file name if in 8.3 hashed format
1178 GetLongPathNameA(filepath, filepath, sizeof(filepath));
1179 lpFileName = filepath;
1180
1181
1182 dwAttr = GetFileAttributesA(lpFileName);
1183 if(dwAttr == -1) {
1184 return GetLastError();
1185 }
1186
1187 pHMHandleData->dwUserData = (DWORD) new HMFileInfo(0, (LPSTR)lpFileName, lpSecurityAttributes);
1188 pHMHandleData->hHMHandle = 0x8000000;
1189 return (NO_ERROR);
1190
1191}
1192/******************************************************************************
1193 * Name : BOOL HMDeviceFileClass::CloseHandle
1194 * Purpose : close the handle
1195 * Parameters: PHMHANDLEDATA pHMHandleData
1196 * Variables :
1197 * Result : API returncode
1198 * Remark :
1199 * Status :
1200 *
1201 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1202 *****************************************************************************/
1203BOOL HMDeviceInfoFileClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
1204{
1205 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1206
1207 dprintfl(("KERNEL32: HMDeviceInfoFileClass::CloseHandle(%08x)\n",
1208 pHMHandleData->hHMHandle));
1209
1210 if(fileInfo) {
1211 delete fileInfo;
1212 }
1213 return TRUE;
1214}
1215/******************************************************************************
1216 * Name : BOOL HMDeviceInfoFileClass::GetFileTime
1217 * Purpose : Get file time
1218 * Parameters: PHMHANDLEDATA pHMHandleData
1219 * PFILETIME pFT1
1220 * PFILETIME pFT2
1221 * PFILETIME pFT3
1222 * Variables :
1223 * Result : API returncode
1224 * Remark :
1225 * Status :
1226 *
1227 * Author : SvL
1228 *****************************************************************************/
1229BOOL HMDeviceInfoFileClass::GetFileTime (PHMHANDLEDATA pHMHandleData,
1230 LPFILETIME pFT1,
1231 LPFILETIME pFT2,
1232 LPFILETIME pFT3)
1233{
1234 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1235
1236 if(!pFT1 && !pFT2 && !pFT3) {//TODO: does NT do this?
1237 dprintf(("ERROR: GetFileTime: invalid parameter!"));
1238 SetLastError(ERROR_INVALID_PARAMETER);
1239 return FALSE;
1240 }
1241 WIN32_FIND_DATAA finddata;
1242 HANDLE hFind;
1243
1244 hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
1245 if(hFind == INVALID_HANDLE_VALUE) {
1246 return GetLastError();
1247 }
1248 if(pFT1) {
1249 *pFT1 = finddata.ftCreationTime;
1250 }
1251 if(pFT2) {
1252 *pFT2 = finddata.ftLastAccessTime;
1253 }
1254 if(pFT3) {
1255 *pFT3 = finddata.ftLastWriteTime;
1256 }
1257 FindClose(hFind);
1258 SetLastError(ERROR_SUCCESS);
1259 return TRUE;
1260}
1261/******************************************************************************
1262 * Name : DWORD HMDeviceInfoFileClass::GetFileSize
1263 * Purpose : get file size
1264 * Parameters: PHMHANDLEDATA pHMHandleData
1265 * PDWORD pSize
1266 * Variables :
1267 * Result : API returncode
1268 * Remark : Doesn't fail for directories; just returns 0 (verified in NT4, SP6)
1269 * Status :
1270 *
1271 * Author : SvL
1272 *****************************************************************************/
1273DWORD HMDeviceInfoFileClass::GetFileSize(PHMHANDLEDATA pHMHandleData,
1274 PDWORD lpdwFileSizeHigh)
1275{
1276 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1277
1278 SetLastError(ERROR_SUCCESS);
1279
1280 if(lpdwFileSizeHigh)
1281 *lpdwFileSizeHigh = 0;
1282
1283 if(fileInfo == NULL) {
1284 DebugInt3();
1285 SetLastError(ERROR_INVALID_PARAMETER); //TODO
1286 return -1; //INVALID_FILE_SIZE;
1287 }
1288
1289 WIN32_FIND_DATAA finddata;
1290 HANDLE hFind;
1291
1292 hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
1293 if(hFind == INVALID_HANDLE_VALUE) {
1294 return GetLastError();
1295 }
1296 if(lpdwFileSizeHigh) {
1297 *lpdwFileSizeHigh = finddata.nFileSizeHigh;
1298 }
1299 FindClose(hFind);
1300
1301 if(fileInfo->dwLXOffset)
1302 {
1303 //subtract the LX header and magic qword from the file size
1304 dprintf(("GetFileSize (LX) -> change size from %x to %x", finddata.nFileSizeLow, finddata.nFileSizeLow-fileInfo->dwLXOffset-MAGIC_STUBEXE_SIZE));
1305 finddata.nFileSizeLow -= (fileInfo->dwLXOffset+MAGIC_STUBEXE_SIZE);
1306 }
1307 return finddata.nFileSizeLow;
1308}
1309/******************************************************************************
1310 * Name : DWORD HMDeviceFileClass::GetFileNameFromHandle
1311 * Purpose : the name of the file associated with the system handle (if any)
1312 * Parameters: PHMHANDLEDATA pHMHandleData
1313 * Variables :
1314 * Result : BOOLEAN
1315 * Remark :
1316 * Status :
1317 *
1318 * Author : SvL
1319 ******************************************************************************/
1320BOOL HMDeviceInfoFileClass::GetFileNameFromHandle(PHMHANDLEDATA pHMHandleData,
1321 LPSTR lpszFileName, DWORD cbFileName)
1322{
1323 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1324
1325 if(fileInfo == NULL || strlen(fileInfo->lpszFileName) >= cbFileName) {
1326 if(fileInfo) DebugInt3();
1327 return FALSE;
1328 }
1329 strcpy(lpszFileName, fileInfo->lpszFileName);
1330
1331 return TRUE;
1332}
1333/******************************************************************************
1334 * Name : DWORD HMDeviceFileClass::GetFileType
1335 * Purpose : determine the handle type
1336 * Parameters: PHMHANDLEDATA pHMHandleData
1337 * Variables :
1338 * Result : API returncode
1339 * Remark : Returns FILE_TYPE_DISK for both files and directories
1340 * Status :
1341 *
1342 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1343 ******************************************************************************/
1344DWORD HMDeviceInfoFileClass::GetFileType(PHMHANDLEDATA pHMHandleData)
1345{
1346 dprintfl(("KERNEL32: HMDeviceInfoFileClass::GetFileType %s(%08x)\n",
1347 lpHMDeviceName,
1348 pHMHandleData));
1349
1350 return FILE_TYPE_DISK;
1351}
1352//******************************************************************************
1353//******************************************************************************
1354HMFileInfo::HMFileInfo(HANDLE hFile, LPSTR lpszFileName, PVOID lpSecurityAttributes)
1355{
1356 this->lpszFileName = (LPSTR)malloc(strlen(lpszFileName)+1);
1357 if(!this->lpszFileName) {
1358 DebugInt3();
1359 }
1360 strcpy(this->lpszFileName, lpszFileName);
1361 this->lpSecurityAttributes = lpSecurityAttributes;
1362 dwLXOffset = 0;
1363
1364 //Only check files that end with .exe for now; they might be prepended with
1365 //an LX header. We need to skip that to present the original file to the
1366 //caller
1367 if(hFile && !stricmp(lpszFileName + strlen(lpszFileName) - 4, ".EXE"))
1368 {
1369 ULONG action, ulRead, signature, ulFileSize;
1370 ULONG magic[2];
1371 IMAGE_DOS_HEADER doshdr;
1372
1373 //read dos header
1374 if(!OSLibDosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {
1375 goto failure;
1376 }
1377 if(OSLibDosSetFilePointer(hFile, doshdr.e_lfanew, NULL, FILE_BEGIN) != doshdr.e_lfanew) {
1378 goto failure;
1379 }
1380 //read signature dword
1381 if(!OSLibDosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {
1382 goto failure;
1383 }
1384
1385 //Make sure it's an LX executable before continueing
1386 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || (WORD)signature != IMAGE_OS2_SIGNATURE_LX)
1387 {
1388 goto failure;
1389 }
1390
1391 //magic signature located at 8 bytes from file end
1392 if(OSLibDosSetFilePointer(hFile, -8, NULL, FILE_END) == -1) {
1393 goto failure;
1394 }
1395 //read magic signature + pe offset
1396 if(!OSLibDosRead(hFile, (LPVOID)&magic[0], sizeof(magic), &ulRead)) {
1397 goto failure;
1398 }
1399 if(magic[0] != MAGIC_STUBEXE_SIGNATURE || magic[1] > ulFileSize) {
1400 goto failure;
1401 }
1402 //this is the offset of the PE image inside our LX executable
1403 dwLXOffset = magic[1];
1404
1405 dprintf(("LX wrapper: PE file %s starts at %x", lpszFileName, dwLXOffset));
1406 //reset file pointer to PE image start
1407 if(OSLibDosSetFilePointer(hFile, dwLXOffset, NULL, FILE_BEGIN) != dwLXOffset) {
1408 DebugInt3();
1409 }
1410 goto end;
1411
1412failure:
1413 //reset file pointer to file start
1414 if(OSLibDosSetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
1415 DebugInt3();
1416 }
1417 }
1418end:
1419 return;
1420}
1421//******************************************************************************
1422//******************************************************************************
1423HMFileInfo::~HMFileInfo()
1424{
1425 if(lpszFileName) {
1426 free(lpszFileName);
1427 lpszFileName = NULL;
1428 }
1429}
1430
1431//*****************************************************************************
1432//Parses and copies path
1433//OpenFile in NT4, SP6 accepts double (or more) backslashes as separators for directories!
1434//(OS/2 doesn't)
1435//Girotel 2.0 (Dutch banking app) seems to depend on this behaviour
1436//*****************************************************************************
1437static void ParsePath(LPCSTR lpszFileName, LPSTR lpszParsedFileName, DWORD length)
1438{
1439 int i=0;
1440
1441 while(*lpszFileName != 0 && i < length-1) {
1442 *lpszParsedFileName++ = *lpszFileName;
1443 if(*lpszFileName == '\\') {
1444 while(*lpszFileName == '\\') {
1445 lpszFileName++;
1446 }
1447 }
1448 else {
1449 lpszFileName++;
1450 }
1451 i++;
1452 }
1453 *lpszParsedFileName = 0;
1454}
1455//******************************************************************************
1456//******************************************************************************
Note: See TracBrowser for help on using the repository browser.