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

Last change on this file since 10564 was 10564, checked in by sandervl, 21 years ago

ReadFile/WriteFile: wrong page calculation for memory maps

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