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

Last change on this file since 6666 was 5791, checked in by sandervl, 24 years ago

OpenFile fixes

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