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

Last change on this file since 21564 was 21564, checked in by dmik, 15 years ago

kernel32: Implemented generating the high/low index values (using a CRC32 and a hash function on the fuill file name) and filling up the volume serial number in the BY_HANDLE_FILE_INFORMATION structure returned by GetFileInformationByHandle().

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