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

Last change on this file since 21329 was 21329, checked in by vladest, 16 years ago

Added functionality, required for Flash10 to kernel32

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
871 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
872 lDistanceToMove,
873 (DWORD *)lpDistanceToMoveHigh,
874 dwMoveMethod);
875
876 if(ret == -1) {
877 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
878 }
879 return ret;
880}
881
882
883/*****************************************************************************
884 * Name : BOOL HMDeviceFileClass::LockFile
885 * Purpose : file locking
886 * Parameters: PHMHANDLEDATA pHMHandleData
887 * DWORD arg2
888 * DWORD arg3
889 * DWORD arg4
890 * DWORD arg5
891 * Variables :
892 * Result : API returncode
893 * Remark :
894 * Status :
895 *
896 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
897 *****************************************************************************/
898
899BOOL HMDeviceFileClass::LockFile(PHMHANDLEDATA pHMHandleData,
900 DWORD dwFileOffsetLow,
901 DWORD dwFileOffsetHigh,
902 DWORD cbLockLow,
903 DWORD cbLockHigh)
904{
905 dprintfl(("KERNEL32: HMDeviceFileClass::LockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
906 lpHMDeviceName,
907 pHMHandleData,
908 dwFileOffsetLow,
909 dwFileOffsetHigh,
910 cbLockLow,
911 cbLockHigh));
912
913 return OSLibDosLockFile(pHMHandleData->hHMHandle,
914 LOCKFILE_EXCLUSIVE_LOCK,
915 dwFileOffsetLow,
916 dwFileOffsetHigh,
917 cbLockLow,
918 cbLockHigh,
919 NULL);
920}
921
922/*****************************************************************************
923 * Name : DWORD HMDeviceFileClass::LockFileEx
924 * Purpose : file locking
925 * Parameters: PHMHANDLEDATA pHMHandleData
926 * DWORD dwFlags
927 * DWORD dwReserved
928 * DWORD nNumberOfBytesToLockLow
929 * DWORD nNumberOfBytesToLockHigh
930 * LPOVERLAPPED lpOverlapped
931 * Variables :
932 * Result : API returncode
933 * Remark :
934 * Status :
935 *
936 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
937 *****************************************************************************/
938
939BOOL HMDeviceFileClass::LockFileEx(PHMHANDLEDATA pHMHandleData,
940 DWORD dwFlags,
941 DWORD dwReserved,
942 DWORD nNumberOfBytesToLockLow,
943 DWORD nNumberOfBytesToLockHigh,
944 LPOVERLAPPED lpOverlapped)
945{
946
947 dprintfl(("KERNEL32: HMDeviceFileClass::LockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
948 lpHMDeviceName,
949 pHMHandleData,
950 dwFlags,
951 dwReserved,
952 nNumberOfBytesToLockLow,
953 nNumberOfBytesToLockHigh,
954 lpOverlapped));
955
956
957 return(OSLibDosLockFile(pHMHandleData->hHMHandle,
958 dwFlags,
959 lpOverlapped->Offset,
960 lpOverlapped->OffsetHigh,
961 nNumberOfBytesToLockLow,
962 nNumberOfBytesToLockHigh,
963 lpOverlapped));
964}
965
966
967/*****************************************************************************
968 * Name : DWORD HMDeviceFileClass::UnlockFile
969 * Purpose : file locking
970 * Parameters: PHMHANDLEDATA pHMHandleData
971 * DWORD arg2
972 * DWORD arg3
973 * DWORD arg4
974 * DWORD arg5
975 * Variables :
976 * Result : API returncode
977 * Remark :
978 * Status :
979 *
980 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
981 *****************************************************************************/
982
983BOOL HMDeviceFileClass::UnlockFile(PHMHANDLEDATA pHMHandleData,
984 DWORD dwFileOffsetLow,
985 DWORD dwFileOffsetHigh,
986 DWORD cbLockLow,
987 DWORD cbLockHigh)
988{
989 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
990 lpHMDeviceName,
991 pHMHandleData,
992 dwFileOffsetLow,
993 dwFileOffsetHigh,
994 cbLockLow,
995 cbLockHigh));
996
997 return OSLibDosUnlockFile(pHMHandleData->hHMHandle,
998 dwFileOffsetLow,
999 dwFileOffsetHigh,
1000 cbLockLow,
1001 cbLockHigh,
1002 NULL);
1003}
1004
1005
1006
1007/*****************************************************************************
1008 * Name : DWORD HMDeviceFileClass::UnlockFileEx
1009 * Purpose : file locking
1010 * Parameters: PHMHANDLEDATA pHMHandleData
1011 * DWORD dwFlags
1012 * DWORD dwReserved
1013 * DWORD nNumberOfBytesToLockLow
1014 * DWORD nNumberOfBytesToLockHigh
1015 * LPOVERLAPPED lpOverlapped
1016 * Variables :
1017 * Result : API returncode
1018 * Remark :
1019 * Status :
1020 *
1021 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1022 *****************************************************************************/
1023
1024BOOL HMDeviceFileClass::UnlockFileEx(PHMHANDLEDATA pHMHandleData,
1025 DWORD dwReserved,
1026 DWORD nNumberOfBytesToLockLow,
1027 DWORD nNumberOfBytesToLockHigh,
1028 LPOVERLAPPED lpOverlapped)
1029{
1030
1031 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
1032 lpHMDeviceName,
1033 pHMHandleData,
1034 dwReserved,
1035 nNumberOfBytesToLockLow,
1036 nNumberOfBytesToLockHigh,
1037 lpOverlapped));
1038
1039
1040 return(OSLibDosUnlockFile(pHMHandleData->hHMHandle,
1041 lpOverlapped->Offset,
1042 lpOverlapped->OffsetHigh,
1043 nNumberOfBytesToLockLow,
1044 nNumberOfBytesToLockHigh,
1045 lpOverlapped));
1046}
1047
1048
1049/*****************************************************************************
1050 * Name : DWORD HMDeviceFileClass::FlushFileBuffers
1051 * Purpose : flush the buffers of a file
1052 * Parameters: PHMHANDLEDATA pHMHandleData
1053 * Variables :
1054 * Result : API returncode
1055 * Remark :
1056 * Status :
1057 *
1058 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1059 *****************************************************************************/
1060
1061BOOL HMDeviceFileClass::FlushFileBuffers(PHMHANDLEDATA pHMHandleData)
1062{
1063 dprintfl(("KERNEL32: HMDeviceFileClass:FlushFileBuffers(%08xh)\n",
1064 pHMHandleData->hHMHandle));
1065
1066 return(OSLibDosFlushFileBuffers(pHMHandleData->hHMHandle));
1067}
1068
1069
1070/*****************************************************************************
1071 * Name : DWORD HMDeviceFileClass::GetOverlappedResult
1072 * Purpose : asynchronus I/O
1073 * Parameters: PHMHANDLEDATA pHMHandleData
1074 * LPOVERLAPPED arg2
1075 * LPDWORD arg3
1076 * BOOL arg4
1077 * Variables :
1078 * Result : API returncode
1079 * Remark :
1080 * Status :
1081 *
1082 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1083 *****************************************************************************/
1084
1085BOOL HMDeviceFileClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
1086 LPOVERLAPPED arg2,
1087 LPDWORD arg3,
1088 BOOL arg4)
1089{
1090 dprintfl(("KERNEL32-WARNING: HMDeviceFileClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) STUB!!",
1091 pHMHandleData->hHMHandle,
1092 arg2,
1093 arg3,
1094 arg4));
1095
1096 return FALSE;
1097// return(O32_GetOverlappedResult(pHMHandleData->hHMHandle,
1098// arg2,
1099// arg3,
1100// arg4));
1101}
1102/******************************************************************************
1103 * Name : DWORD HMDeviceFileClass::GetFileNameFromHandle
1104 * Purpose : the name of the file associated with the system handle (if any)
1105 * Parameters: PHMHANDLEDATA pHMHandleData
1106 * Variables :
1107 * Result : BOOLEAN
1108 * Remark :
1109 * Status :
1110 *
1111 * Author : SvL
1112 ******************************************************************************/
1113BOOL HMDeviceFileClass::GetFileNameFromHandle(PHMHANDLEDATA pHMHandleData,
1114 LPSTR lpszFileName, DWORD cbFileName)
1115{
1116 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1117
1118 if(fileInfo == NULL || strlen(fileInfo->lpszFileName) >= cbFileName) {
1119 if(fileInfo) DebugInt3();
1120 return FALSE;
1121 }
1122 strcpy(lpszFileName, fileInfo->lpszFileName);
1123
1124 return TRUE;
1125}
1126
1127//******************************************************************************
1128//******************************************************************************
1129// File information handle class
1130//
1131// When the application opens a file with CreateFile and 0 for desired access,
1132// then we need to create a handle with limited access.
1133//
1134// MSDN:
1135//
1136// If this parameter is zero, the application can query file and device attributes
1137// without accessing the device. This is useful if an application wants to determine
1138// the size of a floppy disk drive and the formats it supports without requiring
1139// a floppy in the drive. It can also be used to test for the file's or directory's
1140// existence without opening it for read or write access.
1141//
1142//******************************************************************************
1143//******************************************************************************
1144
1145/******************************************************************************
1146 * Name : DWORD HMDeviceInfoFileClass::CreateFile
1147 * Purpose : this is called from the handle manager if a CreateFile() is
1148 * performed on a handle
1149 * Parameters: LPCSTR lpFileName name of the file / device
1150 * PHMHANDLEDATA pHMHandleData data of the NEW handle
1151 * PVOID lpSecurityAttributes ignored
1152 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
1153 * Variables :
1154 * Result :
1155 * Remark :
1156 * Status : NO_ERROR - API succeeded
1157 * other - what is to be set in SetLastError
1158 *
1159 * Author : SvL
1160 *****************************************************************************/
1161DWORD HMDeviceInfoFileClass::CreateFile (LPCSTR lpFileName,
1162 PHMHANDLEDATA pHMHandleData,
1163 PVOID lpSecurityAttributes,
1164 PHMHANDLEDATA pHMHandleDataTemplate)
1165{
1166 char filepath[260];
1167 DWORD dwAttr;
1168
1169 dprintfl(("KERNEL32: HMDeviceInfoFileClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
1170 lpHMDeviceName,
1171 lpFileName,
1172 pHMHandleData,
1173 lpSecurityAttributes,
1174 pHMHandleDataTemplate));
1175
1176 ParsePath(lpFileName, filepath, sizeof(filepath));
1177
1178 //convert to long file name if in 8.3 hashed format
1179 GetLongPathNameA(filepath, filepath, sizeof(filepath));
1180 lpFileName = filepath;
1181
1182
1183 dwAttr = GetFileAttributesA(lpFileName);
1184 if(dwAttr == -1) {
1185 return GetLastError();
1186 }
1187
1188 pHMHandleData->dwUserData = (DWORD) new HMFileInfo(0, (LPSTR)lpFileName, lpSecurityAttributes);
1189 pHMHandleData->hHMHandle = 0x8000000;
1190 return (NO_ERROR);
1191
1192}
1193/******************************************************************************
1194 * Name : BOOL HMDeviceFileClass::CloseHandle
1195 * Purpose : close the handle
1196 * Parameters: PHMHANDLEDATA pHMHandleData
1197 * Variables :
1198 * Result : API returncode
1199 * Remark :
1200 * Status :
1201 *
1202 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1203 *****************************************************************************/
1204BOOL HMDeviceInfoFileClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
1205{
1206 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1207
1208 dprintfl(("KERNEL32: HMDeviceInfoFileClass::CloseHandle(%08x)\n",
1209 pHMHandleData->hHMHandle));
1210
1211 if(fileInfo) {
1212 delete fileInfo;
1213 }
1214 return TRUE;
1215}
1216/******************************************************************************
1217 * Name : BOOL HMDeviceInfoFileClass::GetFileTime
1218 * Purpose : Get file time
1219 * Parameters: PHMHANDLEDATA pHMHandleData
1220 * PFILETIME pFT1
1221 * PFILETIME pFT2
1222 * PFILETIME pFT3
1223 * Variables :
1224 * Result : API returncode
1225 * Remark :
1226 * Status :
1227 *
1228 * Author : SvL
1229 *****************************************************************************/
1230BOOL HMDeviceInfoFileClass::GetFileTime (PHMHANDLEDATA pHMHandleData,
1231 LPFILETIME pFT1,
1232 LPFILETIME pFT2,
1233 LPFILETIME pFT3)
1234{
1235 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1236
1237 if(!pFT1 && !pFT2 && !pFT3) {//TODO: does NT do this?
1238 dprintf(("ERROR: GetFileTime: invalid parameter!"));
1239 SetLastError(ERROR_INVALID_PARAMETER);
1240 return FALSE;
1241 }
1242 WIN32_FIND_DATAA finddata;
1243 HANDLE hFind;
1244
1245 hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
1246 if(hFind == INVALID_HANDLE_VALUE) {
1247 return GetLastError();
1248 }
1249 if(pFT1) {
1250 *pFT1 = finddata.ftCreationTime;
1251 }
1252 if(pFT2) {
1253 *pFT2 = finddata.ftLastAccessTime;
1254 }
1255 if(pFT3) {
1256 *pFT3 = finddata.ftLastWriteTime;
1257 }
1258 FindClose(hFind);
1259 SetLastError(ERROR_SUCCESS);
1260 return TRUE;
1261}
1262/******************************************************************************
1263 * Name : DWORD HMDeviceInfoFileClass::GetFileSize
1264 * Purpose : get file size
1265 * Parameters: PHMHANDLEDATA pHMHandleData
1266 * PDWORD pSize
1267 * Variables :
1268 * Result : API returncode
1269 * Remark : Doesn't fail for directories; just returns 0 (verified in NT4, SP6)
1270 * Status :
1271 *
1272 * Author : SvL
1273 *****************************************************************************/
1274DWORD HMDeviceInfoFileClass::GetFileSize(PHMHANDLEDATA pHMHandleData,
1275 PDWORD lpdwFileSizeHigh)
1276{
1277 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1278
1279 SetLastError(ERROR_SUCCESS);
1280
1281 if(lpdwFileSizeHigh)
1282 *lpdwFileSizeHigh = 0;
1283
1284 if(fileInfo == NULL) {
1285 DebugInt3();
1286 SetLastError(ERROR_INVALID_PARAMETER); //TODO
1287 return -1; //INVALID_FILE_SIZE;
1288 }
1289
1290 WIN32_FIND_DATAA finddata;
1291 HANDLE hFind;
1292
1293 hFind = FindFirstFileA(fileInfo->lpszFileName, &finddata);
1294 if(hFind == INVALID_HANDLE_VALUE) {
1295 return GetLastError();
1296 }
1297 if(lpdwFileSizeHigh) {
1298 *lpdwFileSizeHigh = finddata.nFileSizeHigh;
1299 }
1300 FindClose(hFind);
1301
1302 if(fileInfo->dwLXOffset)
1303 {
1304 //subtract the LX header and magic qword from the file size
1305 dprintf(("GetFileSize (LX) -> change size from %x to %x", finddata.nFileSizeLow, finddata.nFileSizeLow-fileInfo->dwLXOffset-MAGIC_STUBEXE_SIZE));
1306 finddata.nFileSizeLow -= (fileInfo->dwLXOffset+MAGIC_STUBEXE_SIZE);
1307 }
1308 return finddata.nFileSizeLow;
1309}
1310/******************************************************************************
1311 * Name : DWORD HMDeviceFileClass::GetFileNameFromHandle
1312 * Purpose : the name of the file associated with the system handle (if any)
1313 * Parameters: PHMHANDLEDATA pHMHandleData
1314 * Variables :
1315 * Result : BOOLEAN
1316 * Remark :
1317 * Status :
1318 *
1319 * Author : SvL
1320 ******************************************************************************/
1321BOOL HMDeviceInfoFileClass::GetFileNameFromHandle(PHMHANDLEDATA pHMHandleData,
1322 LPSTR lpszFileName, DWORD cbFileName)
1323{
1324 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
1325
1326 if(fileInfo == NULL || strlen(fileInfo->lpszFileName) >= cbFileName) {
1327 if(fileInfo) DebugInt3();
1328 return FALSE;
1329 }
1330 strcpy(lpszFileName, fileInfo->lpszFileName);
1331
1332 return TRUE;
1333}
1334/******************************************************************************
1335 * Name : DWORD HMDeviceFileClass::GetFileType
1336 * Purpose : determine the handle type
1337 * Parameters: PHMHANDLEDATA pHMHandleData
1338 * Variables :
1339 * Result : API returncode
1340 * Remark : Returns FILE_TYPE_DISK for both files and directories
1341 * Status :
1342 *
1343 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1344 ******************************************************************************/
1345DWORD HMDeviceInfoFileClass::GetFileType(PHMHANDLEDATA pHMHandleData)
1346{
1347 dprintfl(("KERNEL32: HMDeviceInfoFileClass::GetFileType %s(%08x)\n",
1348 lpHMDeviceName,
1349 pHMHandleData));
1350
1351 return FILE_TYPE_DISK;
1352}
1353//******************************************************************************
1354//******************************************************************************
1355HMFileInfo::HMFileInfo(HANDLE hFile, LPSTR lpszFileName, PVOID lpSecurityAttributes)
1356{
1357 this->lpszFileName = (LPSTR)malloc(strlen(lpszFileName)+1);
1358 if(!this->lpszFileName) {
1359 DebugInt3();
1360 }
1361 strcpy(this->lpszFileName, lpszFileName);
1362 this->lpSecurityAttributes = lpSecurityAttributes;
1363 dwLXOffset = 0;
1364
1365 //Only check files that end with .exe for now; they might be prepended with
1366 //an LX header. We need to skip that to present the original file to the
1367 //caller
1368 if(hFile && !stricmp(lpszFileName + strlen(lpszFileName) - 4, ".EXE"))
1369 {
1370 ULONG action, ulRead, signature, ulFileSize;
1371 ULONG magic[2];
1372 IMAGE_DOS_HEADER doshdr;
1373
1374 //read dos header
1375 if(!OSLibDosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {
1376 goto failure;
1377 }
1378 if(OSLibDosSetFilePointer(hFile, doshdr.e_lfanew, NULL, FILE_BEGIN) != doshdr.e_lfanew) {
1379 goto failure;
1380 }
1381 //read signature dword
1382 if(!OSLibDosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {
1383 goto failure;
1384 }
1385
1386 //Make sure it's an LX executable before continueing
1387 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || (WORD)signature != IMAGE_OS2_SIGNATURE_LX)
1388 {
1389 goto failure;
1390 }
1391
1392 //magic signature located at 8 bytes from file end
1393 if(OSLibDosSetFilePointer(hFile, -8, NULL, FILE_END) == -1) {
1394 goto failure;
1395 }
1396 //read magic signature + pe offset
1397 if(!OSLibDosRead(hFile, (LPVOID)&magic[0], sizeof(magic), &ulRead)) {
1398 goto failure;
1399 }
1400 if(magic[0] != MAGIC_STUBEXE_SIGNATURE || magic[1] > ulFileSize) {
1401 goto failure;
1402 }
1403 //this is the offset of the PE image inside our LX executable
1404 dwLXOffset = magic[1];
1405
1406 dprintf(("LX wrapper: PE file %s starts at %x", lpszFileName, dwLXOffset));
1407 //reset file pointer to PE image start
1408 if(OSLibDosSetFilePointer(hFile, dwLXOffset, NULL, FILE_BEGIN) != dwLXOffset) {
1409 DebugInt3();
1410 }
1411 goto end;
1412
1413failure:
1414 //reset file pointer to file start
1415 if(OSLibDosSetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
1416 DebugInt3();
1417 }
1418 }
1419end:
1420 return;
1421}
1422//******************************************************************************
1423//******************************************************************************
1424HMFileInfo::~HMFileInfo()
1425{
1426 if(lpszFileName) {
1427 free(lpszFileName);
1428 lpszFileName = NULL;
1429 }
1430}
1431
1432//*****************************************************************************
1433//Parses and copies path
1434//OpenFile in NT4, SP6 accepts double (or more) backslashes as separators for directories!
1435//(OS/2 doesn't)
1436//Girotel 2.0 (Dutch banking app) seems to depend on this behaviour
1437//*****************************************************************************
1438static void ParsePath(LPCSTR lpszFileName, LPSTR lpszParsedFileName, DWORD length)
1439{
1440 int i=0;
1441
1442 while(*lpszFileName != 0 && i < length-1) {
1443 *lpszParsedFileName++ = *lpszFileName;
1444 if(*lpszFileName == '\\') {
1445 while(*lpszFileName == '\\') {
1446 lpszFileName++;
1447 }
1448 }
1449 else {
1450 lpszFileName++;
1451 }
1452 i++;
1453 }
1454 *lpszParsedFileName = 0;
1455}
1456//******************************************************************************
1457//******************************************************************************
Note: See TracBrowser for help on using the repository browser.