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

Last change on this file since 10064 was 10064, checked in by sandervl, 22 years ago

Handle files opened with 0 for dwDesiredAccess seperately

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