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

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

CreateFile (multiple backslash) fix

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