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

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

CreateFile for named pipes fix

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