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

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

misc fixes

File size: 39.0 KB
Line 
1/* $Id: hmfile.cpp,v 1.15 2000-08-11 18:42:54 sandervl Exp $ */
2
3/*
4 * File IO win32 apis
5 *
6 * Copyright 1999-2000 Sander van Leeuwen
7 *
8 * Notes: (#define SHARE_WORKAROUND)
9 * - Temporary workaround for differences in share mode between
10 * OS/2 & NT (for opening the same file multiple times):
11 * NT: CreateFile with FILE_SHARE_READ
12 * CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE
13 * -> 2nd CreateFile overrides share flags of first one
14 * -> CreateFile with GENERIC_WRITE is now allowed
15 * OS2: DosOpen with OPEN_SHARE_DENYWRITE
16 * DosOpen with OPEN_SHARE_DENYNONE
17 * -> sharing violation; can't change share flags while
18 * handle returned by 1st DosOpen isn't closed
19 * --> 'Solution': always open files in FILE_SHARE_DENYNONE mode
20 * (several installation programs depend on this behaviour)
21 *
22 * - Only for CreateFile; might also be necessary for OpenFile, but I haven't
23 * seen any apps that require it (yet).
24 *
25 * Project Odin Software License can be found in LICENSE.TXT
26 *
27 */
28
29/*****************************************************************************
30 * Remark *
31 *****************************************************************************
32 */
33
34//#define DEBUG_LOCAL
35
36#ifdef DEBUG_LOCAL
37# define dprintfl(a) dprintf(a)
38#else
39inline void ignore_dprintf(...){}
40# define dprintfl(a) ignore_dprintf(a)
41#endif
42
43/*****************************************************************************
44 * Includes *
45 *****************************************************************************/
46
47#include <os2win.h>
48#include <string.h>
49#include "HandleManager.h"
50#include "HMFile.h"
51#include "mmap.h"
52#include "oslibdos.h"
53
54#define DBG_LOCALLOG DBG_hmfile
55#include "dbglocal.h"
56
57//SvL: Share violation workaround for CreateFile
58#define SHARE_WORKAROUND
59
60/*****************************************************************************
61 * Name : DWORD HMDeviceFileClass::CreateFile
62 * Purpose : this is called from the handle manager if a CreateFile() is
63 * performed on a handle
64 * Parameters: LPCSTR lpFileName name of the file / device
65 * PHMHANDLEDATA pHMHandleData data of the NEW handle
66 * PVOID lpSecurityAttributes ignored
67 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
68 * Variables :
69 * Result :
70 * Remark :
71 * Status : NO_ERROR - API succeeded
72 * other - what is to be set in SetLastError
73 *
74 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
75 *****************************************************************************/
76
77DWORD HMDeviceFileClass::CreateFile (LPCSTR lpFileName,
78 PHMHANDLEDATA pHMHandleData,
79 PVOID lpSecurityAttributes,
80 PHMHANDLEDATA pHMHandleDataTemplate)
81{
82 HFILE hFile;
83 HFILE hTemplate;
84
85 dprintfl(("KERNEL32: HMDeviceFileClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
86 lpHMDeviceName,
87 lpFileName,
88 pHMHandleData,
89 lpSecurityAttributes,
90 pHMHandleDataTemplate));
91
92 if(strncmp(lpFileName, // "support" for local unc names
93 "\\\\.\\",
94 4) == 0)
95 {
96 // check the named pipes
97 if (strnicmp("\\\\.\\PIPE",lpFileName,8)==0)
98 lpFileName+=3;
99 else
100 lpFileName+=4;
101 }
102
103
104 // create from template
105 if (pHMHandleDataTemplate != NULL)
106 hTemplate = pHMHandleDataTemplate->hHMHandle;
107 else
108 hTemplate = 0;
109
110 //SvL: Open32 doesn't like this flag
111 if(pHMHandleData->dwShare & FILE_SHARE_DELETE) {
112 pHMHandleData->dwShare &= ~FILE_SHARE_DELETE;
113 }
114#ifdef SHARE_WORKAROUND
115 pHMHandleData->dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
116#endif
117 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
118 pHMHandleData->dwAccess,
119 pHMHandleData->dwShare,
120 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
121 pHMHandleData->dwCreation,
122 pHMHandleData->dwFlags,
123 hTemplate);
124#ifdef SHARE_WORKAROUND
125 if (hFile == INVALID_HANDLE_ERROR) {
126 //could be a read-only drive -> FILE_SHARE_WRITE is illegal
127 pHMHandleData->dwShare = FILE_SHARE_READ;
128 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
129 pHMHandleData->dwAccess,
130 pHMHandleData->dwShare,
131 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
132 pHMHandleData->dwCreation,
133 pHMHandleData->dwFlags,
134 hTemplate);
135 }
136#endif
137
138 if (hFile != INVALID_HANDLE_ERROR)
139 {
140 pHMHandleData->dwUserData = (DWORD) new HMFileInfo((LPSTR)lpFileName, lpSecurityAttributes);
141 pHMHandleData->hHMHandle = hFile;
142 return (NO_ERROR);
143 }
144 else {
145 dprintf(("CreateFile failed; error %d", GetLastError()));
146 return(GetLastError());
147 }
148}
149
150/*****************************************************************************
151 * Name : DWORD HMDeviceFileClass::OpenFile
152 * Purpose : this is called from the handle manager if a OpenFile() is
153 * performed on a handle
154 * Parameters: LPCSTR lpFileName name of the file / device
155 * PHMHANDLEDATA pHMHandleData data of the NEW handle
156 * PVOID lpSecurityAttributes ignored
157 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
158 * Variables :
159 * Result :
160 * Remark : TODO: Check if this implementation is complete and 100% correct
161 * Status : NO_ERROR - API succeeded
162 * other - what is to be set in SetLastError
163 *
164 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
165 *****************************************************************************/
166
167DWORD HMDeviceFileClass::OpenFile (LPCSTR lpszFileName,
168 PHMHANDLEDATA pHMHandleData,
169 OFSTRUCT *pOFStruct,
170 UINT fuMode)
171{
172 HFILE hFile;
173 FILETIME filetime;
174 WORD filedatetime[2];
175 char filepath[260];
176 LPSTR lpFileName = (LPSTR)lpszFileName;
177
178 SetLastError(ERROR_SUCCESS);
179
180 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile %s(%s,%08x,%08x,%08x)",
181 lpHMDeviceName,
182 lpFileName,
183 pHMHandleData,
184 pOFStruct,
185 fuMode));
186
187 //Re-open using name in OFSTRUCT
188 if(fuMode & OF_REOPEN)
189 lpFileName = (LPSTR)pOFStruct->szPathName;
190 else memset(pOFStruct, 0, sizeof(OFSTRUCT));
191
192 if(strcmp(lpFileName, // "support" for local unc names
193 "\\\\.\\") == 0)
194 {
195 lpFileName+=4;
196 }
197 else
198 if(!strchr(lpFileName, ':') && !strchr(lpFileName, '\\'))
199 {
200 //filename only; search for file in following order
201 //1: dir from which the app loaded
202 //2: current dir
203 //3: windows system dir
204 //4: windows dir
205 //5: dirs in path path environment variable
206 //SearchPath does exactly that
207 LPSTR filenameinpath;
208
209 if(SearchPathA(NULL, lpFileName, NULL, sizeof(filepath), filepath, &filenameinpath) == 0
210 && !(fuMode & OF_CREATE) )
211 {
212 pOFStruct->nErrCode = ERROR_FILE_NOT_FOUND;
213 SetLastError(ERROR_FILE_NOT_FOUND);
214 return HFILE_ERROR;
215 }
216 lpFileName = filepath;
217 }
218 // filling OFSTRUCT
219 pOFStruct->cBytes = sizeof(OFSTRUCT);
220 pOFStruct->nErrCode = 0;
221 strncpy((char *)pOFStruct->szPathName, lpFileName, OFS_MAXPATHNAME);
222 pOFStruct->szPathName[OFS_MAXPATHNAME-1] = 0;
223
224 hFile = OSLibDosOpenFile((LPSTR)lpFileName, fuMode);
225
226 if(hFile != INVALID_HANDLE_ERROR)
227 {
228 //Needed for GetFileTime
229 pHMHandleData->hHMHandle = hFile;
230 GetFileTime(pHMHandleData,
231 NULL,
232 NULL,
233 &filetime );
234
235 FileTimeToDosDateTime(&filetime,
236 &filedatetime[0],
237 &filedatetime[1] );
238 memcpy(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved));
239
240 if(fuMode & OF_DELETE)
241 {
242 OSLibDosClose(hFile);
243 OSLibDosDelete((LPSTR)lpFileName);
244 }
245 else
246 if(fuMode & OF_EXIST)
247 {
248 OSLibDosClose(hFile);
249 hFile = HFILE_ERROR;
250 }
251 if(fuMode & OF_PARSE)
252 {
253 CHAR drive[4];
254
255 drive[0] = pOFStruct->szPathName[0];
256 drive[1] = pOFStruct->szPathName[1];
257 drive[2] = pOFStruct->szPathName[2];
258 drive[3] = 0;
259
260 pOFStruct->fFixedDisk = (GetDriveTypeA(drive) != DRIVE_REMOVABLE);
261
262 OSLibDosClose(hFile);
263 hFile = HFILE_ERROR;
264 }
265
266 if((fuMode & OF_VERIFY))
267 {
268 if(memcmp(pOFStruct->reserved, filedatetime, sizeof(pOFStruct->reserved)))
269 {
270 OSLibDosClose(hFile);
271 SetLastError(ERROR_FILE_NOT_FOUND);
272 }
273 hFile = HFILE_ERROR;
274 }
275
276 pOFStruct->nErrCode = GetLastError();
277 pHMHandleData->hHMHandle = hFile;
278
279 if(hFile != HFILE_ERROR) {
280 pHMHandleData->dwUserData = (DWORD) new HMFileInfo((LPSTR)lpFileName, NULL);
281 }
282 return (NO_ERROR);
283 }
284 else {
285 DWORD rc = GetLastError();
286
287 if(fuMode & OF_EXIST)
288 {
289 if(rc == ERROR_OPEN_FAILED) {
290 SetLastError(ERROR_FILE_NOT_FOUND);
291 }
292 }
293 //todo: OF_PROMPT handling (pop up message box)
294 }
295 // error branch
296 pOFStruct->nErrCode = GetLastError();
297 dprintf(("KERNEL32: HMDeviceFileClass::OpenFile Error %08xh\n",
298 pOFStruct->nErrCode));
299
300 // return != NO_ERROR => error code
301 return(hFile);
302}
303
304/*****************************************************************************
305 * Name : HMDeviceFileClass::DuplicateHandle
306 * Purpose :
307 * Parameters:
308 * various parameters as required
309 * Variables :
310 * Result :
311 * Remark : DUPLICATE_CLOSE_SOURCE flag handled in HMDuplicateHandle
312 *
313 * Status : partially implemented
314 *
315 * Author : SvL
316 *****************************************************************************/
317BOOL HMDeviceFileClass::DuplicateHandle(PHMHANDLEDATA pHMHandleData,
318 HANDLE srcprocess,
319 PHMHANDLEDATA pHMSrcHandle,
320 HANDLE destprocess,
321 PHANDLE desthandle,
322 DWORD fdwAccess,
323 BOOL fInherit,
324 DWORD fdwOptions,
325 DWORD fdwOdinOptions)
326{
327 HMFileInfo *srcfileinfo = (HMFileInfo *)pHMSrcHandle->dwUserData;
328 DWORD rc;
329
330 dprintf(("KERNEL32:HMDeviceFileClass::DuplicateHandle (%08x,%08x,%08x,%08x,%08x)",
331 pHMHandleData,
332 srcprocess,
333 pHMSrcHandle->hHMHandle,
334 destprocess,
335 desthandle));
336
337 //TODO: Inheritance of file handles won't work!
338
339 if(destprocess != srcprocess)
340 {
341 //TODO:!!!!
342 dprintf(("ERROR: DuplicateHandle; different processes not yet supported!!"));
343 return FALSE;
344 }
345
346 if(srcfileinfo)
347 {
348 //SvL: Special duplicatehandle option used by memory mapped class to duplicate
349 // file handle
350 // Can't use DosDupHandle or else there can be a sharing violation
351 // when an app tries to access the same file again
352 if(fdwOdinOptions)
353 {
354 if(CreateFile(srcfileinfo->lpszFileName, pHMHandleData,
355 srcfileinfo->lpSecurityAttributes, NULL) == NO_ERROR)
356 {
357 return TRUE;
358 }
359 dprintf(("ERROR: DuplicateHandle; CreateFile %s failed!",
360 srcfileinfo->lpszFileName));
361 return FALSE;
362 }
363
364 if(!(fdwOptions & DUPLICATE_SAME_ACCESS) && fdwAccess != pHMSrcHandle->dwAccess) {
365 dprintf(("WARNING: DuplicateHandle; app wants different access permission; Not supported!! (%x, %x)", fdwAccess, pHMSrcHandle->dwAccess));
366 }
367
368 rc = OSLibDosDupHandle(pHMSrcHandle->hHMHandle,
369 desthandle);
370 if (rc)
371 {
372 dprintf(("ERROR: DulicateHandle: OSLibDosDupHandle(%s) failed = %u\n",
373 rc,
374 srcfileinfo->lpszFileName));
375 SetLastError(rc);
376 return FALSE; // ERROR
377 }
378 else {
379 pHMHandleData->hHMHandle = *desthandle;
380 return TRUE; // OK
381 }
382 }
383 else
384 {
385 SetLastError(ERROR_INVALID_PARAMETER);
386 return FALSE;
387 }
388}
389
390/*****************************************************************************
391 * Name : DWORD HMDeviceFileClass::CloseHandle
392 * Purpose : close the handle
393 * Parameters: PHMHANDLEDATA pHMHandleData
394 * Variables :
395 * Result : API returncode
396 * Remark :
397 * Status :
398 *
399 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
400 *****************************************************************************/
401
402DWORD HMDeviceFileClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
403{
404 HMFileInfo *fileInfo = (HMFileInfo *)pHMHandleData->dwUserData;
405 BOOL bRC;
406
407 dprintfl(("KERNEL32: HMDeviceFileClass::CloseHandle(%08x)\n",
408 pHMHandleData->hHMHandle));
409
410 bRC = OSLibDosClose(pHMHandleData->hHMHandle);
411
412 if(pHMHandleData->dwFlags & FILE_FLAG_DELETE_ON_CLOSE) {
413 //TODO: should only do this after all handles have been closed
414 if(fileInfo) {
415 DeleteFileA(fileInfo->lpszFileName);
416 }
417 }
418 if(fileInfo) {
419 delete fileInfo;
420 }
421 dprintf(("KERNEL32: HMDeviceFileClass::CloseHandle returned %08xh\n",
422 bRC));
423
424 return (DWORD)bRC;
425}
426
427
428/*****************************************************************************
429 * Name : BOOL HMDeviceFileClass::ReadFile
430 * Purpose : read data from handle / device
431 * Parameters: PHMHANDLEDATA pHMHandleData,
432 * LPCVOID lpBuffer,
433 * DWORD nNumberOfBytesToRead,
434 * LPDWORD lpNumberOfBytesRead,
435 * LPOVERLAPPED lpOverlapped
436 * Variables :
437 * Result : Boolean
438 * Remark :
439 * Status :
440 *
441 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
442 *****************************************************************************/
443
444BOOL HMDeviceFileClass::ReadFile(PHMHANDLEDATA pHMHandleData,
445 LPCVOID lpBuffer,
446 DWORD nNumberOfBytesToRead,
447 LPDWORD lpNumberOfBytesRead,
448 LPOVERLAPPED lpOverlapped)
449{
450 LPVOID lpRealBuf;
451 Win32MemMap *map;
452 DWORD offset, bytesread;
453 BOOL bRC;
454
455 dprintfl(("KERNEL32: HMDeviceFileClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
456 lpHMDeviceName,
457 pHMHandleData,
458 lpBuffer,
459 nNumberOfBytesToRead,
460 lpNumberOfBytesRead,
461 lpOverlapped));
462
463 //SvL: It's legal for this pointer to be NULL
464 if(lpNumberOfBytesRead)
465 *lpNumberOfBytesRead = 0;
466 else
467 lpNumberOfBytesRead = &bytesread;
468
469 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
470 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
471 SetLastError(ERROR_INVALID_PARAMETER);
472 return FALSE;
473 }
474 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
475 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
476 }
477
478 //SvL: DosRead doesn't like writing to memory addresses returned by
479 // DosAliasMem -> search for original memory mapped pointer and use
480 // that one + commit pages if not already present
481 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
482 if(map) {
483 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
484 DWORD nrpages = nNumberOfBytesToRead/4096;
485 if(offset & 0xfff)
486 nrpages++;
487 if(nNumberOfBytesToRead & 0xfff)
488 nrpages++;
489
490 map->commitPage(offset & ~0xfff, TRUE, nrpages);
491 }
492 else lpRealBuf = (LPVOID)lpBuffer;
493
494 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
495 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
496 }
497// else {
498 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
499 (PVOID)lpRealBuf,
500 nNumberOfBytesToRead,
501 lpNumberOfBytesRead);
502// }
503
504 if(bRC == 0) {
505 dprintf(("KERNEL32: HMDeviceFileClass::ReadFile returned %08xh %x\n",
506 bRC, GetLastError()));
507 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
508 }
509
510 return bRC;
511}
512
513/*****************************************************************************
514 * Name : BOOL ReadFileEx
515 * Purpose : The ReadFileEx function reads data from a file asynchronously.
516 * It is designed solely for asynchronous operation, unlike the
517 * ReadFile function, which is designed for both synchronous and
518 * asynchronous operation. ReadFileEx lets an application perform
519 * other processing during a file read operation.
520 * The ReadFileEx function reports its completion status asynchronously,
521 * calling a specified completion routine when reading is completed
522 * and the calling thread is in an alertable wait state.
523 * Parameters: HANDLE hFile handle of file to read
524 * LPVOID lpBuffer address of buffer
525 * DWORD nNumberOfBytesToRead number of bytes to read
526 * LPOVERLAPPED lpOverlapped address of offset
527 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
528 * Variables :
529 * Result : TRUE / FALSE
530 * Remark :
531 * Status : UNTESTED STUB
532 *
533 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
534 *****************************************************************************/
535BOOL HMDeviceFileClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
536 LPVOID lpBuffer,
537 DWORD nNumberOfBytesToRead,
538 LPOVERLAPPED lpOverlapped,
539 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
540{
541 dprintf(("ERROR: ReadFileEx(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
542 pHMHandleData->hHMHandle,
543 lpBuffer,
544 nNumberOfBytesToRead,
545 lpOverlapped,
546 lpCompletionRoutine));
547 return FALSE;
548}
549
550
551/*****************************************************************************
552 * Name : BOOL HMDeviceFileClass::WriteFile
553 * Purpose : write data to handle / device
554 * Parameters: PHMHANDLEDATA pHMHandleData,
555 * LPCVOID lpBuffer,
556 * DWORD nNumberOfBytesToWrite,
557 * LPDWORD lpNumberOfBytesWritten,
558 * LPOVERLAPPED lpOverlapped
559 * Variables :
560 * Result : Boolean
561 * Remark :
562 * Status :
563 *
564 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
565 *****************************************************************************/
566
567BOOL HMDeviceFileClass::WriteFile(PHMHANDLEDATA pHMHandleData,
568 LPCVOID lpBuffer,
569 DWORD nNumberOfBytesToWrite,
570 LPDWORD lpNumberOfBytesWritten,
571 LPOVERLAPPED lpOverlapped)
572{
573 LPVOID lpRealBuf;
574 Win32MemMap *map;
575 DWORD offset, byteswritten;
576 BOOL bRC;
577
578 dprintfl(("KERNEL32: HMDeviceFileClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
579 lpHMDeviceName,
580 pHMHandleData,
581 lpBuffer,
582 nNumberOfBytesToWrite,
583 lpNumberOfBytesWritten,
584 lpOverlapped));
585
586 //SvL: It's legal for this pointer to be NULL
587 if(lpNumberOfBytesWritten)
588 *lpNumberOfBytesWritten = 0;
589 else
590 lpNumberOfBytesWritten = &byteswritten;
591
592 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
593 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
594 SetLastError(ERROR_INVALID_PARAMETER);
595 return FALSE;
596 }
597 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
598 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
599 }
600
601 //SvL: DosWrite doesn't like reading from memory addresses returned by
602 // DosAliasMem -> search for original memory mapped pointer and use
603 // that one + commit pages if not already present
604 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
605 if(map) {
606 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
607 DWORD nrpages = nNumberOfBytesToWrite/4096;
608 if(offset & 0xfff)
609 nrpages++;
610 if(nNumberOfBytesToWrite & 0xfff)
611 nrpages++;
612
613 map->commitPage(offset & ~0xfff, TRUE, nrpages);
614 }
615 else lpRealBuf = (LPVOID)lpBuffer;
616
617 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
618 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
619 }
620// else {
621 bRC = OSLibDosWrite(pHMHandleData->hHMHandle,
622 (PVOID)lpRealBuf,
623 nNumberOfBytesToWrite,
624 lpNumberOfBytesWritten);
625// }
626
627 dprintf(("KERNEL32: HMDeviceFileClass::WriteFile returned %08xh\n",
628 bRC));
629
630 return bRC;
631}
632
633/*****************************************************************************
634 * Name : BOOL WriteFileEx
635 * Purpose : The WriteFileEx function writes data to a file. It is designed
636 * solely for asynchronous operation, unlike WriteFile, which is
637 * designed for both synchronous and asynchronous operation.
638 * WriteFileEx reports its completion status asynchronously,
639 * calling a specified completion routine when writing is completed
640 * and the calling thread is in an alertable wait state.
641 * Parameters: HANDLE hFile handle of file to write
642 * LPVOID lpBuffer address of buffer
643 * DWORD nNumberOfBytesToRead number of bytes to write
644 * LPOVERLAPPED lpOverlapped address of offset
645 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
646 * Variables :
647 * Result : TRUE / FALSE
648 * Remark :
649 * Status : UNTESTED STUB
650 *
651 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
652 *****************************************************************************/
653
654BOOL HMDeviceFileClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
655 LPVOID lpBuffer,
656 DWORD nNumberOfBytesToWrite,
657 LPOVERLAPPED lpOverlapped,
658 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
659{
660 dprintf(("ERROR: WriteFileEx(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
661 pHMHandleData->hHMHandle,
662 lpBuffer,
663 nNumberOfBytesToWrite,
664 lpOverlapped,
665 lpCompletionRoutine));
666 return FALSE;
667}
668
669/*****************************************************************************
670 * Name : DWORD HMDeviceFileClass::GetFileType
671 * Purpose : determine the handle type
672 * Parameters: PHMHANDLEDATA pHMHandleData
673 * Variables :
674 * Result : API returncode
675 * Remark :
676 * Status :
677 *
678 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
679 *****************************************************************************/
680
681DWORD HMDeviceFileClass::GetFileType(PHMHANDLEDATA pHMHandleData)
682{
683 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileType %s(%08x)\n",
684 lpHMDeviceName,
685 pHMHandleData));
686
687 return FILE_TYPE_DISK;
688}
689
690
691/*****************************************************************************
692 * Name : DWORD HMDeviceFileClass::GetFileInformationByHandle
693 * Purpose : determine the handle type
694 * Parameters: PHMHANDLEDATA pHMHandleData
695 * BY_HANDLE_FILE_INFORMATION* pHFI
696 * Variables :
697 * Result : API returncode
698 * Remark :
699 * Status :
700 *
701 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
702 *****************************************************************************/
703
704DWORD HMDeviceFileClass::GetFileInformationByHandle(PHMHANDLEDATA pHMHandleData,
705 BY_HANDLE_FILE_INFORMATION* pHFI)
706{
707 dprintfl(("KERNEL32: HMDeviceFileClass::GetFileInformationByHandle %s(%08xh,%08xh)\n",
708 lpHMDeviceName,
709 pHMHandleData,
710 pHFI));
711
712 if(OSLibDosGetFileInformationByHandle(pHMHandleData->hHMHandle,
713 pHFI))
714 {
715 return TRUE;
716 }
717 dprintf(("GetFileInformationByHandle failed with error %d", GetLastError()));
718 return FALSE;
719
720}
721
722
723/*****************************************************************************
724 * Name : BOOL HMDeviceFileClass::SetEndOfFile
725 * Purpose : set end of file marker
726 * Parameters: PHMHANDLEDATA pHMHandleData
727 * Variables :
728 * Result : API returncode
729 * Remark :
730 * Status :
731 *
732 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
733 *****************************************************************************/
734
735BOOL HMDeviceFileClass::SetEndOfFile(PHMHANDLEDATA pHMHandleData)
736{
737 dprintfl(("KERNEL32: HMDeviceFileClass::SetEndOfFile %s(%08xh)\n",
738 lpHMDeviceName,
739 pHMHandleData));
740
741 if(OSLibDosSetEndOfFile(pHMHandleData->hHMHandle)) {
742 return TRUE;
743 }
744 dprintf(("SetEndOfFile failed with error %d", GetLastError()));
745 return FALSE;
746}
747
748
749/*****************************************************************************
750 * Name : BOOL HMDeviceFileClass::SetFileTime
751 * Purpose : set file time
752 * Parameters: PHMHANDLEDATA pHMHandleData
753 * PFILETIME pFT1
754 * PFILETIME pFT2
755 * PFILETIME pFT3
756 * Variables :
757 * Result : API returncode
758 * Remark :
759 * Status :
760 *
761 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
762 *****************************************************************************/
763
764BOOL HMDeviceFileClass::SetFileTime(PHMHANDLEDATA pHMHandleData,
765 LPFILETIME pFT1,
766 LPFILETIME pFT2,
767 LPFILETIME pFT3)
768{
769 WORD creationdate = 0, creationtime = 0;
770 WORD lastaccessdate = 0, lastaccesstime = 0;
771 WORD lastwritedate = 0, lastwritetime = 0;
772
773 dprintfl(("KERNEL32: HMDeviceFileClass::SetFileTime %s(%08xh,%08xh,%08xh,%08xh)\n",
774 lpHMDeviceName,
775 pHMHandleData,
776 pFT1,
777 pFT2,
778 pFT3));
779
780 if(pFT1 && pFT1->dwLowDateTime && pFT1->dwHighDateTime) {
781 FileTimeToDosDateTime(pFT1, &creationdate, &creationtime);
782 }
783
784 if(pFT2 && pFT2->dwLowDateTime && pFT2->dwHighDateTime) {
785 FileTimeToDosDateTime(pFT2, &lastaccessdate, &lastaccesstime);
786 }
787
788 if(pFT3 && pFT3->dwLowDateTime && pFT3->dwHighDateTime) {
789 FileTimeToDosDateTime(pFT3, &lastwritedate, &lastwritetime);
790 }
791
792 if(OSLibDosSetFileTime(pHMHandleData->hHMHandle,
793 creationdate, creationtime,
794 lastaccessdate, lastaccesstime,
795 lastwritedate, lastwritetime))
796 {
797 return TRUE;
798 }
799 dprintf(("SetFileTime failed with error %d", GetLastError()));
800 return FALSE;
801}
802
803/*****************************************************************************
804 * Name : BOOL HMDeviceFileClass::GetFileTime
805 * Purpose : get file time
806 * Parameters: PHMHANDLEDATA pHMHandleData
807 * PFILETIME pFT1
808 * PFILETIME pFT2
809 * PFILETIME pFT3
810 * Variables :
811 * Result : API returncode
812 * Remark :
813 * Status :
814 *
815 * Author : SvL
816 *****************************************************************************/
817
818BOOL HMDeviceFileClass::GetFileTime(PHMHANDLEDATA pHMHandleData,
819 LPFILETIME pFT1,
820 LPFILETIME pFT2,
821 LPFILETIME pFT3)
822{
823 WORD creationdate, creationtime;
824 WORD lastaccessdate, lastaccesstime;
825 WORD lastwritedate, lastwritetime;
826 BOOL rc;
827
828 if(!pFT1 && !pFT2 && !pFT3) {//TODO: does NT do this?
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.