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

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

OpenFile now checks for null pointer and returns ERROR_INVALID_NAME

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