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

Last change on this file since 4682 was 4682, checked in by sandervl, 25 years ago

CreateProcessA (path with spaces) + OpenFile (multiple backslash) fixes

File size: 39.1 KB
Line 
1/* $Id: hmfile.cpp,v 1.24 2000-11-23 19:23:50 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
41/*****************************************************************************
42 * Name : DWORD HMDeviceFileClass::CreateFile
43 * Purpose : this is called from the handle manager if a CreateFile() is
44 * performed on a handle
45 * Parameters: LPCSTR lpFileName name of the file / device
46 * PHMHANDLEDATA pHMHandleData data of the NEW handle
47 * PVOID lpSecurityAttributes ignored
48 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
49 * Variables :
50 * Result :
51 * Remark : TODO: \\.\PHYSICALDRIVEx opens physical drive x
52 * Status : NO_ERROR - API succeeded
53 * other - what is to be set in SetLastError
54 *
55 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
56 *****************************************************************************/
57
58DWORD HMDeviceFileClass::CreateFile (LPCSTR lpFileName,
59 PHMHANDLEDATA pHMHandleData,
60 PVOID lpSecurityAttributes,
61 PHMHANDLEDATA pHMHandleDataTemplate)
62{
63 HFILE hFile;
64 HFILE hTemplate;
65
66 dprintfl(("KERNEL32: HMDeviceFileClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
67 lpHMDeviceName,
68 lpFileName,
69 pHMHandleData,
70 lpSecurityAttributes,
71 pHMHandleDataTemplate));
72
73 if(strncmp(lpFileName, // "support" for local unc names
74 "\\\\.\\",
75 4) == 0)
76 {
77 // check the named pipes
78 if (strnicmp("\\\\.\\PIPE",lpFileName,8)==0)
79 lpFileName+=3;
80 else
81 lpFileName+=4;
82 }
83
84
85 // create from template
86 if (pHMHandleDataTemplate != NULL)
87 hTemplate = pHMHandleDataTemplate->hHMHandle;
88 else
89 hTemplate = 0;
90
91 //TODO: FILE_SHARE_DELETE
92 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
93 pHMHandleData->dwAccess,
94 pHMHandleData->dwShare,
95 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
96 pHMHandleData->dwCreation,
97 pHMHandleData->dwFlags,
98 hTemplate);
99
100 if (hFile != INVALID_HANDLE_ERROR)
101 {
102 pHMHandleData->dwUserData = (DWORD) new HMFileInfo((LPSTR)lpFileName, lpSecurityAttributes);
103 pHMHandleData->hHMHandle = hFile;
104 return (NO_ERROR);
105 }
106 else {
107 dprintf(("CreateFile failed; error %d", GetLastError()));
108 return(GetLastError());
109 }
110}
111
112//*****************************************************************************
113//Parses and copies path
114//OpenFile in NT4, SP6 accepts double (or more) backslashes as separators for directories!
115//(OS/2 doesn't)
116//Girotel 2.0 (Dutch banking app) seems to depend on this behaviour
117//*****************************************************************************
118void HMDeviceFileClass::ParsePath(LPCSTR lpszFileName, LPSTR lpszParsedFileName, DWORD length)
119{
120
121 while(*lpszFileName != 0) {
122 *lpszParsedFileName++ = *lpszFileName;
123 if(*lpszFileName == '\\') {
124 while(*lpszFileName == '\\') {
125 lpszFileName++;
126 }
127 }
128 else {
129 lpszFileName++;
130 }
131 }
132 *lpszParsedFileName = 0;
133}
134
135/*****************************************************************************
136 * Name : DWORD HMDeviceFileClass::OpenFile
137 * Purpose : this is called from the handle manager if a OpenFile() is
138 * performed on a handle
139 * Parameters: LPCSTR lpFileName name of the file / device
140 * PHMHANDLEDATA pHMHandleData data of the NEW handle
141 * PVOID lpSecurityAttributes ignored
142 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
143 * Variables :
144 * Result :
145 * Remark : TODO: Check if this implementation is complete and 100% correct
146 * Status : NO_ERROR - API succeeded
147 * other - what is to be set in SetLastError
148 *
149 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
150 *****************************************************************************/
151
152DWORD HMDeviceFileClass::OpenFile (LPCSTR lpszFileName,
153 PHMHANDLEDATA pHMHandleData,
154 OFSTRUCT *pOFStruct,
155 UINT fuMode)
156{
157 HFILE hFile;
158 FILETIME filetime;
159 WORD filedatetime[2];
160 char filepath[260];
161 LPSTR lpFileName = (LPSTR)lpszFileName;
162
163 SetLastError(ERROR_SUCCESS);
164
165 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile %s(%s,%08x,%08x,%08x)",
166 lpHMDeviceName,
167 lpFileName,
168 pHMHandleData,
169 pOFStruct,
170 fuMode));
171
172 //Re-open using name in OFSTRUCT
173 if(fuMode & OF_REOPEN)
174 lpFileName = (LPSTR)pOFStruct->szPathName;
175 else memset(pOFStruct, 0, sizeof(OFSTRUCT));
176
177 if(strcmp(lpFileName, // "support" for local unc names
178 "\\\\.\\") == 0)
179 {
180 lpFileName+=4;
181 }
182 else
183 if(!strchr(lpFileName, ':') && !strchr(lpFileName, '\\'))
184 {
185 //filename only; search for file in following order
186 //1: dir from which the app loaded
187 //2: current dir
188 //3: windows system dir
189 //4: windows dir
190 //5: dirs in path path environment variable
191 //SearchPath does exactly that
192 LPSTR filenameinpath;
193
194 if(SearchPathA(NULL, lpFileName, NULL, sizeof(filepath), filepath, &filenameinpath) == 0
195 && !(fuMode & OF_CREATE) )
196 {
197 pOFStruct->nErrCode = ERROR_FILE_NOT_FOUND;
198 SetLastError(ERROR_FILE_NOT_FOUND);
199 return HFILE_ERROR;
200 }
201 lpFileName = filepath;
202 }
203 else {
204 ParsePath(lpFileName, filepath, sizeof(filepath));
205 lpFileName = filepath;
206 }
207
208 // filling OFSTRUCT
209 pOFStruct->cBytes = sizeof(OFSTRUCT);
210 pOFStruct->nErrCode = 0;
211 strncpy((char *)pOFStruct->szPathName, lpFileName, OFS_MAXPATHNAME);
212 pOFStruct->szPathName[OFS_MAXPATHNAME-1] = 0;
213
214 hFile = OSLibDosOpenFile((LPSTR)lpFileName, fuMode);
215
216 if(hFile != INVALID_HANDLE_ERROR)
217 {
218 //Needed for GetFileTime
219 pHMHandleData->hHMHandle = hFile;
220 GetFileTime(pHMHandleData,
221 NULL,
222 NULL,
223 &filetime );
224
225 FileTimeToDosDateTime(&filetime,
226 &filedatetime[0],
227 &filedatetime[1] );
228 memcpy(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved));
229
230 if(fuMode & OF_DELETE)
231 {
232 OSLibDosClose(hFile);
233 OSLibDosDelete((LPSTR)lpFileName);
234 }
235 else
236 if(fuMode & OF_EXIST)
237 {
238 OSLibDosClose(hFile);
239 hFile = HFILE_ERROR;
240 }
241 if(fuMode & OF_PARSE)
242 {
243 CHAR drive[4];
244
245 drive[0] = pOFStruct->szPathName[0];
246 drive[1] = pOFStruct->szPathName[1];
247 drive[2] = pOFStruct->szPathName[2];
248 drive[3] = 0;
249
250 pOFStruct->fFixedDisk = (GetDriveTypeA(drive) != DRIVE_REMOVABLE);
251
252 OSLibDosClose(hFile);
253 hFile = HFILE_ERROR;
254 }
255
256 if((fuMode & OF_VERIFY))
257 {
258 if(memcmp(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved)))
259 {
260 OSLibDosClose(hFile);
261 SetLastError(ERROR_FILE_NOT_FOUND);
262 }
263 hFile = HFILE_ERROR;
264 }
265
266 pOFStruct->nErrCode = GetLastError();
267 pHMHandleData->hHMHandle = hFile;
268
269 if(hFile != HFILE_ERROR) {
270 pHMHandleData->dwUserData = (DWORD) new HMFileInfo((LPSTR)lpFileName, NULL);
271 }
272 return (NO_ERROR);
273 }
274 else {
275 DWORD rc = GetLastError();
276
277 if(fuMode & OF_EXIST)
278 {
279 if(rc == ERROR_OPEN_FAILED) {
280 SetLastError(ERROR_FILE_NOT_FOUND);
281 }
282 }
283 //todo: OF_PROMPT handling (pop up message box)
284 }
285 // error branch
286 pOFStruct->nErrCode = GetLastError();
287 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile Error %08xh\n",
288 pOFStruct->nErrCode));
289
290 // return != NO_ERROR => error code
291 return(hFile);
292}
293
294/*****************************************************************************
295 * Name : HMDeviceFileClass::DuplicateHandle
296 * Purpose :
297 * Parameters:
298 * various parameters as required
299 * Variables :
300 * Result :
301 * Remark : DUPLICATE_CLOSE_SOURCE flag handled in HMDuplicateHandle
302 *
303 * Status : partially implemented
304 *
305 * Author : SvL
306 *****************************************************************************/
307BOOL HMDeviceFileClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData,
308 HANDLE srcprocess,
309 PHMHANDLEDATA pHMSrcHandle,
310 HANDLE destprocess,
311 PHANDLE desthandle,
312 DWORD fdwAccess,
313 BOOL fInherit,
314 DWORD fdwOptions,
315 DWORD fdwOdinOptions)
316{
317 HMFileInfo *srcfileinfo = (HMFileInfo *)pHMSrcHandle->dwUserData;
318 DWORD rc;
319
320 dprintf(("KERNEL32:HMDeviceFileClass::DuplicateHandle (%08x,%08x,%08x,%08x,%08x)",
321 pHMHandleData,
322 srcprocess,
323 pHMSrcHandle->hHMHandle,
324 destprocess,
325 desthandle));
326
327 //TODO: Inheritance of file handles won't work!
328
329 if(destprocess != srcprocess)
330 {
331 //TODO:!!!!
332 dprintf(("ERROR: DuplicateHandle; different processes not yet supported!!"));
333 return FALSE;
334 }
335
336 if(srcfileinfo)
337 {
338 //SvL: Special duplicatehandle option used by memory mapped class to duplicate
339 // file handle
340 // Can't use DosDupHandle or else there can be a sharing violation
341 // when an app tries to access the same file again
342 if(fdwOdinOptions)
343 {
344 HMHANDLEDATA duphdata;
345
346 memcpy(&duphdata, pHMHandleData, sizeof(duphdata));
347 duphdata.dwCreation = OPEN_EXISTING;
348
349 if(CreateFile(srcfileinfo->lpszFileName, &duphdata,
350 srcfileinfo->lpSecurityAttributes, NULL) == NO_ERROR)
351 {
352 memcpy(pHMHandleData, &duphdata, sizeof(duphdata));
353 SetLastError(ERROR_SUCCESS);
354 return TRUE;
355 }
356 dprintf(("ERROR: DuplicateHandle; CreateFile %s failed -> trying DosDupHandle instead!",
357 srcfileinfo->lpszFileName));
358 //SvL: IE5 setup opens file with DENYREADWRITE, so CreateFile can't
359 // be used for duplicating the handle; try DosDupHandle instead
360 }
361
362 if(!(fdwOptions & DUPLICATE_SAME_ACCESS) && fdwAccess != pHMSrcHandle->dwAccess) {
363 dprintf(("WARNING: DuplicateHandle; app wants different access permission; Not supported!! (%x, %x)", fdwAccess, pHMSrcHandle->dwAccess));
364 }
365
366 rc = OSLibDosDupHandle(pHMSrcHandle->hHMHandle,
367 desthandle);
368 if (rc)
369 {
370 dprintf(("ERROR: DulicateHandle: OSLibDosDupHandle(%s) failed = %u\n",
371 rc,
372 srcfileinfo->lpszFileName));
373 SetLastError(rc);
374 return FALSE; // ERROR
375 }
376 else {
377 SetLastError(ERROR_SUCCESS);
378 pHMHandleData->hHMHandle = *desthandle;
379 return TRUE; // OK
380 }
381 }
382 else
383 {
384 dprintf(("ERROR: DuplicateHandle; invalid parameter!!"));
385 SetLastError(ERROR_INVALID_PARAMETER);
386 return FALSE;
387 }
388}
389
390/*****************************************************************************
391 * Name : DWORD HMDeviceFileClass::CloseHandle
392 * Purpose : close the handle
393 * Parameters: PHMHANDLEDATA pHMHandleData
394 * Variables :
395 * Result : API returncode
396 * Remark :
397 * Status :
398 *
399 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
400 *****************************************************************************/
401
402DWORD HMDeviceFileClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
403{
404 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
405 BOOL bRC;
406
407 dprintfl(("KERNEL32: HMDeviceFileClass::CloseHandle(%08x)\n",
408 pHMHandleData->hHMHandle));
409
410 bRC = OSLibDosClose(pHMHandleData->hHMHandle);
411
412 if(pHMHandleData->dwFlags & FILE_FLAG_DELETE_ON_CLOSE) {
413 //TODO: should only do this after all handles have been closed
414 if(fileInfo) {
415 DeleteFileA(fileInfo->lpszFileName);
416 }
417 }
418 if(fileInfo) {
419 delete fileInfo;
420 }
421 dprintf(("KERNEL32: HMDeviceFileClass::CloseHandle returned %08xh\n",
422 bRC));
423
424 return (DWORD)bRC;
425}
426
427
428/*****************************************************************************
429 * Name : BOOL HMDeviceFileClass::ReadFile
430 * Purpose : read data from handle / device
431 * Parameters: PHMHANDLEDATA pHMHandleData,
432 * LPCVOID lpBuffer,
433 * DWORD nNumberOfBytesToRead,
434 * LPDWORD lpNumberOfBytesRead,
435 * LPOVERLAPPED lpOverlapped
436 * Variables :
437 * Result : Boolean
438 * Remark :
439 * Status :
440 *
441 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
442 *****************************************************************************/
443
444BOOL HMDeviceFileClass::ReadFile(PHMHANDLEDATA pHMHandleData,
445 LPCVOID lpBuffer,
446 DWORD nNumberOfBytesToRead,
447 LPDWORD lpNumberOfBytesRead,
448 LPOVERLAPPED lpOverlapped)
449{
450 LPVOID lpRealBuf;
451 Win32MemMap *map;
452 DWORD offset, bytesread;
453 BOOL bRC;
454
455 dprintfl(("KERNEL32: HMDeviceFileClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
456 lpHMDeviceName,
457 pHMHandleData,
458 lpBuffer,
459 nNumberOfBytesToRead,
460 lpNumberOfBytesRead,
461 lpOverlapped));
462
463 //SvL: It's legal for this pointer to be NULL
464 if(lpNumberOfBytesRead)
465 *lpNumberOfBytesRead = 0;
466 else
467 lpNumberOfBytesRead = &bytesread;
468
469 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
470 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
471 SetLastError(ERROR_INVALID_PARAMETER);
472 return FALSE;
473 }
474 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
475 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
476 }
477
478 //SvL: DosRead doesn't like writing to memory addresses returned by
479 // DosAliasMem -> search for original memory mapped pointer and use
480 // that one + commit pages if not already present
481 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
482 if(map) {
483 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
484 DWORD nrpages = nNumberOfBytesToRead/4096;
485 if(offset & 0xfff)
486 nrpages++;
487 if(nNumberOfBytesToRead & 0xfff)
488 nrpages++;
489
490 map->commitPage(offset & ~0xfff, TRUE, nrpages);
491 }
492 else lpRealBuf = (LPVOID)lpBuffer;
493
494 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
495 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
496 }
497// else {
498 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
499 (PVOID)lpRealBuf,
500 nNumberOfBytesToRead,
501 lpNumberOfBytesRead);
502// }
503
504 if(bRC == 0) {
505 dprintf(("KERNEL32: HMDeviceFileClass::ReadFile returned %08xh %x\n",
506 bRC, GetLastError()));
507 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
508 }
509
510 return bRC;
511}
512
513/*****************************************************************************
514 * Name : BOOL ReadFileEx
515 * Purpose : The ReadFileEx function reads data from a file asynchronously.
516 * It is designed solely for asynchronous operation, unlike the
517 * ReadFile function, which is designed for both synchronous and
518 * asynchronous operation. ReadFileEx lets an application perform
519 * other processing during a file read operation.
520 * The ReadFileEx function reports its completion status asynchronously,
521 * calling a specified completion routine when reading is completed
522 * and the calling thread is in an alertable wait state.
523 * Parameters: HANDLE hFile handle of file to read
524 * LPVOID lpBuffer address of buffer
525 * DWORD nNumberOfBytesToRead number of bytes to read
526 * LPOVERLAPPED lpOverlapped address of offset
527 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
528 * Variables :
529 * Result : TRUE / FALSE
530 * Remark :
531 * Status : UNTESTED STUB
532 *
533 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
534 *****************************************************************************/
535BOOL HMDeviceFileClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
536 LPVOID lpBuffer,
537 DWORD nNumberOfBytesToRead,
538 LPOVERLAPPED lpOverlapped,
539 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
540{
541 dprintf(("ERROR: ReadFileEx(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
542 pHMHandleData->hHMHandle,
543 lpBuffer,
544 nNumberOfBytesToRead,
545 lpOverlapped,
546 lpCompletionRoutine));
547 return FALSE;
548}
549
550
551/*****************************************************************************
552 * Name : BOOL HMDeviceFileClass::WriteFile
553 * Purpose : write data to handle / device
554 * Parameters: PHMHANDLEDATA pHMHandleData,
555 * LPCVOID lpBuffer,
556 * DWORD nNumberOfBytesToWrite,
557 * LPDWORD lpNumberOfBytesWritten,
558 * LPOVERLAPPED lpOverlapped
559 * Variables :
560 * Result : Boolean
561 * Remark :
562 * Status :
563 *
564 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
565 *****************************************************************************/
566
567BOOL HMDeviceFileClass::WriteFile(PHMHANDLEDATA pHMHandleData,
568 LPCVOID lpBuffer,
569 DWORD nNumberOfBytesToWrite,
570 LPDWORD lpNumberOfBytesWritten,
571 LPOVERLAPPED lpOverlapped)
572{
573 LPVOID lpRealBuf;
574 Win32MemMap *map;
575 DWORD offset, byteswritten;
576 BOOL bRC;
577
578 dprintfl(("KERNEL32: HMDeviceFileClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
579 lpHMDeviceName,
580 pHMHandleData,
581 lpBuffer,
582 nNumberOfBytesToWrite,
583 lpNumberOfBytesWritten,
584 lpOverlapped));
585
586 //SvL: It's legal for this pointer to be NULL
587 if(lpNumberOfBytesWritten)
588 *lpNumberOfBytesWritten = 0;
589 else
590 lpNumberOfBytesWritten = &byteswritten;
591
592 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
593 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
594 SetLastError(ERROR_INVALID_PARAMETER);
595 return FALSE;
596 }
597 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
598 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
599 }
600
601 //SvL: DosWrite doesn't like reading from memory addresses returned by
602 // DosAliasMem -> search for original memory mapped pointer and use
603 // that one + commit pages if not already present
604 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
605 if(map) {
606 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
607 DWORD nrpages = nNumberOfBytesToWrite/4096;
608 if(offset & 0xfff)
609 nrpages++;
610 if(nNumberOfBytesToWrite & 0xfff)
611 nrpages++;
612
613 map->commitPage(offset & ~0xfff, TRUE, nrpages);
614 }
615 else lpRealBuf = (LPVOID)lpBuffer;
616
617 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
618 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
619 }
620// else {
621 bRC = OSLibDosWrite(pHMHandleData->hHMHandle,
622 (PVOID)lpRealBuf,
623 nNumberOfBytesToWrite,
624 lpNumberOfBytesWritten);
625// }
626
627 dprintf(("KERNEL32: HMDeviceFileClass::WriteFile returned %08xh\n",
628 bRC));
629
630 return bRC;
631}
632
633/*****************************************************************************
634 * Name : BOOL WriteFileEx
635 * Purpose : The WriteFileEx function writes data to a file. It is designed
636 * solely for asynchronous operation, unlike WriteFile, which is
637 * designed for both synchronous and asynchronous operation.
638 * WriteFileEx reports its completion status asynchronously,
639 * calling a specified completion routine when writing is completed
640 * and the calling thread is in an alertable wait state.
641 * Parameters: HANDLE hFile handle of file to write
642 * LPVOID lpBuffer address of buffer
643 * DWORD nNumberOfBytesToRead number of bytes to write
644 * LPOVERLAPPED lpOverlapped address of offset
645 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
646 * Variables :
647 * Result : TRUE / FALSE
648 * Remark :
649 * Status : UNTESTED STUB
650 *
651 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
652 *****************************************************************************/
653
654BOOL HMDeviceFileClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
655 LPVOID lpBuffer,
656 DWORD nNumberOfBytesToWrite,
657 LPOVERLAPPED lpOverlapped,
658 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
659{
660 dprintf(("ERROR: WriteFileEx(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
661 pHMHandleData->hHMHandle,
662 lpBuffer,
663 nNumberOfBytesToWrite,
664 lpOverlapped,
665 lpCompletionRoutine));
666 return FALSE;
667}
668
669/*****************************************************************************
670 * Name : DWORD HMDeviceFileClass::GetFileType
671 * Purpose : determine the handle type
672 * Parameters: PHMHANDLEDATA pHMHandleData
673 * Variables :
674 * Result : API returncode
675 * Remark :
676 * Status :
677 *
678 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
679 *****************************************************************************/
680
681DWORD HMDeviceFileClass::GetFileType(PHMHANDLEDATA pHMHandleData)
682{
683 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileType %s(%08x)\n",
684 lpHMDeviceName,
685 pHMHandleData));
686
687 return FILE_TYPE_DISK;
688}
689
690
691/*****************************************************************************
692 * Name : DWORD HMDeviceFileClass::GetFileInformationByHandle
693 * Purpose : determine the handle type
694 * Parameters: PHMHANDLEDATA pHMHandleData
695 * BY_HANDLE_FILE_INFORMATION* pHFI
696 * Variables :
697 * Result : API returncode
698 * Remark :
699 * Status :
700 *
701 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
702 *****************************************************************************/
703
704DWORD HMDeviceFileClass::GetFileInformationByHandle(PHMHANDLEDATA pHMHandleData,
705 BY_HANDLE_FILE_INFORMATION* pHFI)
706{
707 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileInformationByHandle %s(%08xh,%08xh)\n",
708 lpHMDeviceName, pHMHandleData, pHFI));
709
710 if(OSLibDosGetFileInformationByHandle(pHMHandleData->hHMHandle,
711 pHFI))
712 {
713 return TRUE;
714 }
715 dprintf(("GetFileInformationByHandle failed with error %d", GetLastError()));
716 return FALSE;
717
718}
719
720
721/*****************************************************************************
722 * Name : BOOL HMDeviceFileClass::SetEndOfFile
723 * Purpose : set end of file marker
724 * Parameters: PHMHANDLEDATA pHMHandleData
725 * Variables :
726 * Result : API returncode
727 * Remark :
728 * Status :
729 *
730 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
731 *****************************************************************************/
732
733BOOL HMDeviceFileClass::SetEndOfFile(PHMHANDLEDATA pHMHandleData)
734{
735 dprintfl(("KERNEL32: HMDeviceFileClass::SetEndOfFile %s(%08xh)\n",
736 lpHMDeviceName,
737 pHMHandleData));
738
739 if(OSLibDosSetEndOfFile(pHMHandleData->hHMHandle)) {
740 return TRUE;
741 }
742 dprintf(("SetEndOfFile failed with error %d", GetLastError()));
743 return FALSE;
744}
745
746
747/*****************************************************************************
748 * Name : BOOL HMDeviceFileClass::SetFileTime
749 * Purpose : set file time
750 * Parameters: PHMHANDLEDATA pHMHandleData
751 * PFILETIME pFT1
752 * PFILETIME pFT2
753 * PFILETIME pFT3
754 * Variables :
755 * Result : API returncode
756 * Remark :
757 * Status :
758 *
759 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
760 *****************************************************************************/
761
762BOOL HMDeviceFileClass::SetFileTime(PHMHANDLEDATA pHMHandleData,
763 LPFILETIME pFT1,
764 LPFILETIME pFT2,
765 LPFILETIME pFT3)
766{
767 WORD creationdate = 0, creationtime = 0;
768 WORD lastaccessdate = 0, lastaccesstime = 0;
769 WORD lastwritedate = 0, lastwritetime = 0;
770
771 dprintfl(("KERNEL32: HMDeviceFileClass::SetFileTime %s(%08xh,%08xh,%08xh,%08xh)\n",
772 lpHMDeviceName, pHMHandleData, pFT1, pFT2, pFT3));
773
774 if(pFT1 && pFT1->dwLowDateTime && pFT1->dwHighDateTime) {
775 FileTimeToDosDateTime(pFT1, &creationdate, &creationtime);
776 }
777
778 if(pFT2 && pFT2->dwLowDateTime && pFT2->dwHighDateTime) {
779 FileTimeToDosDateTime(pFT2, &lastaccessdate, &lastaccesstime);
780 }
781
782 if(pFT3 && pFT3->dwLowDateTime && pFT3->dwHighDateTime) {
783 FileTimeToDosDateTime(pFT3, &lastwritedate, &lastwritetime);
784 }
785
786 if(OSLibDosSetFileTime(pHMHandleData->hHMHandle,
787 creationdate, creationtime,
788 lastaccessdate, lastaccesstime,
789 lastwritedate, lastwritetime))
790 {
791 return TRUE;
792 }
793 dprintf(("SetFileTime failed with error %d", GetLastError()));
794 return FALSE;
795}
796
797/*****************************************************************************
798 * Name : BOOL HMDeviceFileClass::GetFileTime
799 * Purpose : get file time
800 * Parameters: PHMHANDLEDATA pHMHandleData
801 * PFILETIME pFT1
802 * PFILETIME pFT2
803 * PFILETIME pFT3
804 * Variables :
805 * Result : API returncode
806 * Remark :
807 * Status :
808 *
809 * Author : SvL
810 *****************************************************************************/
811
812BOOL HMDeviceFileClass::GetFileTime(PHMHANDLEDATA pHMHandleData,
813 LPFILETIME pFT1,
814 LPFILETIME pFT2,
815 LPFILETIME pFT3)
816{
817 WORD creationdate, creationtime;
818 WORD lastaccessdate, lastaccesstime;
819 WORD lastwritedate, lastwritetime;
820 BOOL rc;
821
822 if(!pFT1 && !pFT2 && !pFT3) {//TODO: does NT do this?
823 dprintf(("ERROR: GetFileTime: invalid parameter!"));
824 SetLastError(ERROR_INVALID_PARAMETER);
825 return FALSE;
826 }
827
828 if(OSLibDosGetFileTime(pHMHandleData->hHMHandle,
829 &creationdate, &creationtime,
830 &lastaccessdate, &lastaccesstime,
831 &lastwritedate, &lastwritetime))
832 {
833 if(pFT1) {
834 DosDateTimeToFileTime(creationdate, creationtime, pFT1);
835 }
836 if(pFT2) {
837 DosDateTimeToFileTime(lastaccessdate, lastaccesstime, pFT2);
838 }
839 if(pFT3) {
840 DosDateTimeToFileTime(lastwritedate, lastwritetime, pFT3);
841 }
842 return TRUE;
843 }
844 dprintf(("GetFileTime failed with error %d", GetLastError()));
845 return FALSE;
846}
847
848/*****************************************************************************
849 * Name : DWORD HMDeviceFileClass::GetFileSize
850 * Purpose : set file time
851 * Parameters: PHMHANDLEDATA pHMHandleData
852 * PDWORD pSize
853 * Variables :
854 * Result : API returncode
855 * Remark :
856 * Status :
857 *
858 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
859 *****************************************************************************/
860
861DWORD HMDeviceFileClass::GetFileSize(PHMHANDLEDATA pHMHandleData,
862 PDWORD lpdwFileSizeHigh)
863{
864 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileSize %s(%08xh,%08xh)\n",
865 lpHMDeviceName,
866 pHMHandleData,
867 lpdwFileSizeHigh));
868
869 if(lpdwFileSizeHigh)
870 *lpdwFileSizeHigh = 0;
871
872 return OSLibDosGetFileSize(pHMHandleData->hHMHandle, lpdwFileSizeHigh);
873}
874
875/*****************************************************************************
876 * Name : DWORD HMDeviceFileClass::SetFilePointer
877 * Purpose : set file pointer
878 * Parameters: PHMHANDLEDATA pHMHandleData
879 * LONG lDistanceToMove
880 * PLONG lpDistanceToMoveHigh
881 * DWORD dwMoveMethod
882 * Variables :
883 * Result : API returncode
884 * Remark :
885 * Status :
886 *
887 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
888 *****************************************************************************/
889
890DWORD HMDeviceFileClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
891 LONG lDistanceToMove,
892 PLONG lpDistanceToMoveHigh,
893 DWORD dwMoveMethod)
894{
895 DWORD ret;
896
897 dprintfl(("KERNEL32: HMDeviceFileClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
898 lpHMDeviceName,
899 pHMHandleData,
900 lDistanceToMove,
901 lpDistanceToMoveHigh,
902 dwMoveMethod));
903
904 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
905 lDistanceToMove,
906 (DWORD *)lpDistanceToMoveHigh,
907 dwMoveMethod);
908
909 if(ret == -1) {
910 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
911 }
912 return ret;
913}
914
915
916/*****************************************************************************
917 * Name : DWORD HMDeviceFileClass::LockFile
918 * Purpose : file locking
919 * Parameters: PHMHANDLEDATA pHMHandleData
920 * DWORD arg2
921 * DWORD arg3
922 * DWORD arg4
923 * DWORD arg5
924 * Variables :
925 * Result : API returncode
926 * Remark :
927 * Status :
928 *
929 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
930 *****************************************************************************/
931
932BOOL HMDeviceFileClass::LockFile(PHMHANDLEDATA pHMHandleData,
933 DWORD dwFileOffsetLow,
934 DWORD dwFileOffsetHigh,
935 DWORD cbLockLow,
936 DWORD cbLockHigh)
937{
938 dprintfl(("KERNEL32: HMDeviceFileClass::LockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
939 lpHMDeviceName,
940 pHMHandleData,
941 dwFileOffsetLow,
942 dwFileOffsetHigh,
943 cbLockLow,
944 cbLockHigh));
945
946 return OSLibDosLockFile(pHMHandleData->hHMHandle,
947 LOCKFILE_EXCLUSIVE_LOCK,
948 dwFileOffsetLow,
949 dwFileOffsetHigh,
950 cbLockLow,
951 cbLockHigh,
952 NULL);
953}
954
955/*****************************************************************************
956 * Name : DWORD HMDeviceFileClass::LockFileEx
957 * Purpose : file locking
958 * Parameters: PHMHANDLEDATA pHMHandleData
959 * DWORD dwFlags
960 * DWORD dwReserved
961 * DWORD nNumberOfBytesToLockLow
962 * DWORD nNumberOfBytesToLockHigh
963 * LPOVERLAPPED lpOverlapped
964 * Variables :
965 * Result : API returncode
966 * Remark :
967 * Status :
968 *
969 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
970 *****************************************************************************/
971
972BOOL HMDeviceFileClass::LockFileEx(PHMHANDLEDATA pHMHandleData,
973 DWORD dwFlags,
974 DWORD dwReserved,
975 DWORD nNumberOfBytesToLockLow,
976 DWORD nNumberOfBytesToLockHigh,
977 LPOVERLAPPED lpOverlapped)
978{
979
980 dprintfl(("KERNEL32: HMDeviceFileClass::LockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
981 lpHMDeviceName,
982 pHMHandleData,
983 dwFlags,
984 dwReserved,
985 nNumberOfBytesToLockLow,
986 nNumberOfBytesToLockHigh,
987 lpOverlapped));
988
989
990 return(OSLibDosLockFile(pHMHandleData->hHMHandle,
991 dwFlags,
992 lpOverlapped->Offset,
993 lpOverlapped->OffsetHigh,
994 nNumberOfBytesToLockLow,
995 nNumberOfBytesToLockHigh,
996 lpOverlapped));
997}
998
999
1000/*****************************************************************************
1001 * Name : DWORD HMDeviceFileClass::UnlockFile
1002 * Purpose : file locking
1003 * Parameters: PHMHANDLEDATA pHMHandleData
1004 * DWORD arg2
1005 * DWORD arg3
1006 * DWORD arg4
1007 * DWORD arg5
1008 * Variables :
1009 * Result : API returncode
1010 * Remark :
1011 * Status :
1012 *
1013 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1014 *****************************************************************************/
1015
1016BOOL HMDeviceFileClass::UnlockFile(PHMHANDLEDATA pHMHandleData,
1017 DWORD dwFileOffsetLow,
1018 DWORD dwFileOffsetHigh,
1019 DWORD cbLockLow,
1020 DWORD cbLockHigh)
1021{
1022 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFile %s(%08xh,%08xh,%08xh,%08xh,%08xh)\n",
1023 lpHMDeviceName,
1024 pHMHandleData,
1025 dwFileOffsetLow,
1026 dwFileOffsetHigh,
1027 cbLockLow,
1028 cbLockHigh));
1029
1030 return OSLibDosUnlockFile(pHMHandleData->hHMHandle,
1031 dwFileOffsetLow,
1032 dwFileOffsetHigh,
1033 cbLockLow,
1034 cbLockHigh,
1035 NULL);
1036}
1037
1038
1039
1040/*****************************************************************************
1041 * Name : DWORD HMDeviceFileClass::UnlockFileEx
1042 * Purpose : file locking
1043 * Parameters: PHMHANDLEDATA pHMHandleData
1044 * DWORD dwFlags
1045 * DWORD dwReserved
1046 * DWORD nNumberOfBytesToLockLow
1047 * DWORD nNumberOfBytesToLockHigh
1048 * LPOVERLAPPED lpOverlapped
1049 * Variables :
1050 * Result : API returncode
1051 * Remark :
1052 * Status :
1053 *
1054 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1055 *****************************************************************************/
1056
1057BOOL HMDeviceFileClass::UnlockFileEx(PHMHANDLEDATA pHMHandleData,
1058 DWORD dwReserved,
1059 DWORD nNumberOfBytesToLockLow,
1060 DWORD nNumberOfBytesToLockHigh,
1061 LPOVERLAPPED lpOverlapped)
1062{
1063
1064 dprintfl(("KERNEL32: HMDeviceFileClass::UnlockFileEx %s(%08xh,%08xh,%08xh,%08xh,%08xh) not completely implemented!",
1065 lpHMDeviceName,
1066 pHMHandleData,
1067 dwReserved,
1068 nNumberOfBytesToLockLow,
1069 nNumberOfBytesToLockHigh,
1070 lpOverlapped));
1071
1072
1073 return(OSLibDosUnlockFile(pHMHandleData->hHMHandle,
1074 lpOverlapped->Offset,
1075 lpOverlapped->OffsetHigh,
1076 nNumberOfBytesToLockLow,
1077 nNumberOfBytesToLockHigh,
1078 lpOverlapped));
1079}
1080
1081
1082/*****************************************************************************
1083 * Name : DWORD HMDeviceFileClass::FlushFileBuffers
1084 * Purpose : flush the buffers of a file
1085 * Parameters: PHMHANDLEDATA pHMHandleData
1086 * Variables :
1087 * Result : API returncode
1088 * Remark :
1089 * Status :
1090 *
1091 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1092 *****************************************************************************/
1093
1094BOOL HMDeviceFileClass::FlushFileBuffers(PHMHANDLEDATA pHMHandleData)
1095{
1096 dprintfl(("KERNEL32: HMDeviceFileClass:FlushFileBuffers(%08xh)\n",
1097 pHMHandleData->hHMHandle));
1098
1099 return(OSLibDosFlushFileBuffers(pHMHandleData->hHMHandle));
1100}
1101
1102
1103/*****************************************************************************
1104 * Name : DWORD HMDeviceFileClass::GetOverlappedResult
1105 * Purpose : asynchronus I/O
1106 * Parameters: PHMHANDLEDATA pHMHandleData
1107 * LPOVERLAPPED arg2
1108 * LPDWORD arg3
1109 * BOOL arg4
1110 * Variables :
1111 * Result : API returncode
1112 * Remark :
1113 * Status :
1114 *
1115 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1116 *****************************************************************************/
1117
1118BOOL HMDeviceFileClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
1119 LPOVERLAPPED arg2,
1120 LPDWORD arg3,
1121 BOOL arg4)
1122{
1123 dprintfl(("KERNEL32-WARNING: HMDeviceFileClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) STUB!!",
1124 pHMHandleData->hHMHandle,
1125 arg2,
1126 arg3,
1127 arg4));
1128
1129 return FALSE;
1130// return(O32_GetOverlappedResult(pHMHandleData->hHMHandle,
1131// arg2,
1132// arg3,
1133// arg4));
1134}
1135//******************************************************************************
1136//******************************************************************************
1137HMFileInfo::HMFileInfo(LPSTR lpszFileName, PVOID lpSecurityAttributes)
1138{
1139 this->lpszFileName = (LPSTR)malloc(strlen(lpszFileName)+1);
1140 if(!this->lpszFileName) {
1141 DebugInt3();
1142 }
1143 strcpy(this->lpszFileName, lpszFileName);
1144 this->lpSecurityAttributes = lpSecurityAttributes;
1145}
1146//******************************************************************************
1147//******************************************************************************
1148HMFileInfo::~HMFileInfo()
1149{
1150 if(lpszFileName) {
1151 free(lpszFileName);
1152 lpszFileName = NULL;
1153 }
1154}
1155//******************************************************************************
1156//******************************************************************************
Note: See TracBrowser for help on using the repository browser.