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

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

removed share mode hack; no longer necessary due to fixed bugs

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