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

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

CreateFile fix (don't add write access when creating files)

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