source: trunk/src/kernel32/oslibdos.cpp@ 4189

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

GetDiskFreeSpace(Ex) changes/fixes

File size: 61.3 KB
Line 
1/* $Id: oslibdos.cpp,v 1.40 2000-09-04 18:24:42 sandervl Exp $ */
2/*
3 * Wrappers for OS/2 Dos* API
4 *
5 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999-2000 Edgar Buerkle <Edgar.Buerkle@gmx.net>
7 * Copyright 2000 Przemyslaw Dobrowolski <dobrawka@asua.org.pl>
8 * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13#define INCL_BASE
14#define INCL_DOSEXCEPTIONS
15#define INCL_DOSMEMMGR
16#define INCL_DOSPROCESS
17#define INCL_DOSFILEMGR
18#define INCL_DOSERRORS
19#define INCL_NPIPES
20#include <os2wrap.h> //Odin32 OS/2 api wrappers
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <ctype.h>
25#include <win32api.h>
26#include <winconst.h>
27#include <misc.h>
28#include "initterm.h"
29#include "oslibdos.h"
30#include "dosqss.h"
31
32#define DBG_LOCALLOG DBG_oslibdos
33#include "dbglocal.h"
34
35static PROC_DosSetFileSizeL DosSetFileSizeLProc = 0;
36static PROC_DosSetFilePtrL DosSetFilePtrLProc = 0;
37static PROC_DosSetFileLocksL DosSetFileLocksLProc = 0;
38static BOOL f64BitIO = FALSE;
39//******************************************************************************
40//******************************************************************************
41void OSLibInitWSeBFileIO()
42{
43 HMODULE hDoscalls;
44
45 if(DosQueryModuleHandle("DOSCALLS", &hDoscalls) != NO_ERROR) {
46 return;
47 }
48 if(DosQueryProcAddr(hDoscalls, 989, NULL, (PFN *)&DosSetFileSizeLProc) != NO_ERROR) {
49 return;
50 }
51 if(DosQueryProcAddr(hDoscalls, 988, NULL, (PFN *)&DosSetFilePtrLProc) != NO_ERROR) {
52 return;
53 }
54 if(DosQueryProcAddr(hDoscalls, 986, NULL, (PFN *)&DosSetFileLocksLProc) != NO_ERROR) {
55 return;
56 }
57 f64BitIO = TRUE;
58}
59//******************************************************************************
60//******************************************************************************
61APIRET OdinDosSetFileSizeL(HFILE hFile, LONGLONG cbSize)
62{
63 APIRET yyrc;
64 USHORT sel = RestoreOS2FS();
65
66 yyrc = DosSetFileSizeLProc(hFile, cbSize);
67 SetFS(sel);
68
69 return yyrc;
70}
71//******************************************************************************
72//******************************************************************************
73APIRET OdinDosSetFilePtrL(HFILE hFile, LONGLONG ib, ULONG method, PLONGLONG ibActual)
74{
75 APIRET yyrc;
76 USHORT sel = RestoreOS2FS();
77
78 yyrc = DosSetFilePtrLProc(hFile, ib, method, ibActual);
79 SetFS(sel);
80
81 return yyrc;
82}
83//******************************************************************************
84//******************************************************************************
85APIRET OdinDosSetFileLocksL(HFILE hFile, PFILELOCKL pflUnlock, PFILELOCKL pflLock,
86 ULONG timeout, ULONG flags)
87{
88 APIRET yyrc;
89 USHORT sel = RestoreOS2FS();
90
91 yyrc = DosSetFileLocksLProc(hFile, pflUnlock, pflLock, timeout, flags);
92 SetFS(sel);
93
94 return yyrc;
95}
96//******************************************************************************
97// translate OS/2 error codes to Windows codes
98// NOTE: add all codes you need, list is not complete!
99//******************************************************************************
100DWORD error2WinError(APIRET rc,DWORD defaultCode = ERROR_NOT_ENOUGH_MEMORY_W)
101{
102 switch (rc)
103 {
104 case NO_ERROR: //0
105 return ERROR_SUCCESS_W;
106
107 case ERROR_INVALID_FUNCTION: //1
108 return ERROR_INVALID_FUNCTION_W;
109
110 case ERROR_FILE_NOT_FOUND: //2
111 return ERROR_FILE_NOT_FOUND_W;
112
113 case ERROR_PATH_NOT_FOUND: //3
114 return ERROR_PATH_NOT_FOUND_W;
115
116 case ERROR_TOO_MANY_OPEN_FILES: //4
117 return ERROR_TOO_MANY_OPEN_FILES_W;
118
119 case ERROR_ACCESS_DENIED: //5
120 return ERROR_ACCESS_DENIED_W;
121
122 case ERROR_INVALID_HANDLE: //6
123 return ERROR_INVALID_HANDLE_W;
124
125 case ERROR_NOT_ENOUGH_MEMORY: //8
126 return ERROR_NOT_ENOUGH_MEMORY_W;
127
128 case ERROR_BAD_FORMAT: //11
129 return ERROR_BAD_FORMAT_W;
130
131 case ERROR_INVALID_ACCESS: //12
132 return ERROR_INVALID_ACCESS_W;
133
134 case ERROR_NO_MORE_FILES: //18
135 return ERROR_NO_MORE_FILES_W;
136
137 case ERROR_WRITE_PROTECT: //19
138 return ERROR_WRITE_PROTECT_W;
139
140 case ERROR_NOT_DOS_DISK: //26
141 return ERROR_NOT_DOS_DISK_W;
142
143 case ERROR_WRITE_FAULT: //29
144 return ERROR_WRITE_FAULT_W;
145
146 case ERROR_SHARING_VIOLATION: //32
147 return ERROR_SHARING_VIOLATION_W;
148
149 case ERROR_LOCK_VIOLATION: //32
150 return ERROR_LOCK_VIOLATION_W;
151
152 case ERROR_SHARING_BUFFER_EXCEEDED: //36
153 return ERROR_SHARING_BUFFER_EXCEEDED_W;
154
155 case ERROR_CANNOT_MAKE: //82
156 return ERROR_CANNOT_MAKE_W;
157
158 case ERROR_OUT_OF_STRUCTURES: //84
159 return ERROR_OUT_OF_STRUCTURES_W;
160
161 case ERROR_INVALID_PARAMETER: //87
162 return ERROR_INVALID_PARAMETER_W;
163
164 case ERROR_INTERRUPT: //95
165 return ERROR_INVALID_AT_INTERRUPT_TIME_W; //CB: right???
166
167 case ERROR_DEVICE_IN_USE: //99
168 return ERROR_DEVICE_IN_USE_W;
169
170 case ERROR_DRIVE_LOCKED: //108
171 return ERROR_DRIVE_LOCKED_W;
172
173 case ERROR_BROKEN_PIPE: //109
174 return ERROR_BROKEN_PIPE_W;
175
176 case ERROR_OPEN_FAILED: //110
177 return ERROR_OPEN_FAILED_W;
178
179 case ERROR_BUFFER_OVERFLOW: //111
180 return ERROR_BUFFER_OVERFLOW_W;
181
182 case ERROR_DISK_FULL: //112
183 return ERROR_DISK_FULL_W;
184
185 case ERROR_NO_MORE_SEARCH_HANDLES: //113
186 return ERROR_NO_MORE_SEARCH_HANDLES_W;
187
188 case ERROR_SEM_TIMEOUT: //121
189 return ERROR_SEM_TIMEOUT_W;
190
191 case ERROR_DIRECT_ACCESS_HANDLE: //130
192 return ERROR_DIRECT_ACCESS_HANDLE_W;
193
194 case ERROR_NEGATIVE_SEEK: //131
195 return ERROR_NEGATIVE_SEEK;
196
197 case ERROR_SEEK_ON_DEVICE: //132
198 return ERROR_SEEK_ON_DEVICE_W;
199
200 case ERROR_DISCARDED: //157
201 return ERROR_DISCARDED_W;
202
203 case ERROR_FILENAME_EXCED_RANGE: //206
204 return ERROR_FILENAME_EXCED_RANGE_W;
205
206 case ERROR_META_EXPANSION_TOO_LONG: //208
207 return ERROR_META_EXPANSION_TOO_LONG_W;
208
209 case ERROR_BAD_PIPE: //230
210 return ERROR_BAD_PIPE_W;
211
212 case ERROR_PIPE_BUSY: //231
213 return ERROR_PIPE_BUSY_W;
214
215 case ERROR_NO_DATA: //232
216 return ERROR_NO_DATA_W;
217
218 case ERROR_PIPE_NOT_CONNECTED: //233
219 return ERROR_PIPE_NOT_CONNECTED_W;
220
221 case ERROR_MORE_DATA: //234
222 return ERROR_MORE_DATA_W;
223
224 case ERROR_INVALID_EA_NAME: //254
225 return ERROR_INVALID_EA_NAME_W;
226
227 case ERROR_EA_LIST_INCONSISTENT: //255
228 return ERROR_EA_LIST_INCONSISTENT_W;
229
230 case ERROR_EAS_DIDNT_FIT: //275
231 return ERROR_EAS_DIDNT_FIT;
232
233 default:
234 dprintf(("WARNING: error2WinError: error %d not included!!!!", rc));
235 return defaultCode;
236 }
237}
238//******************************************************************************
239//TODO: Assumes entire memory range has the same protection flags!
240//TODO: Check if this works for code aliases...
241//******************************************************************************
242DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
243{
244 DWORD rc;
245 DWORD attr;
246 DWORD size = cb;
247
248 cb = (cb-1) & ~0xfff;
249 cb+= PAGE_SIZE;
250
251 rc = DosQueryMem(pb, &size, &attr);
252 if(rc) {
253 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
254 return rc;
255 }
256 size = (size-1) & ~0xfff;
257 size+= PAGE_SIZE;
258 if(size != cb) {
259 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
260 //ignore this and continue return 5;
261 attr = fl; //just use original protection flags (NOT CORRECT)
262 }
263 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
264 if(attr != fl) {
265 rc = DosSetMem(pb, size, fl);
266 if(rc) {
267 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
268 attr = fl;
269 //just continue for now
270 //return rc;
271 }
272 }
273 rc = DosAliasMem(pb, cb, ppbAlias, 2);
274 if(rc) {
275 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
276 return rc;
277 }
278 if(attr != fl) {
279 rc = DosSetMem(pb, size, attr);
280 if(rc) {
281 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
282 return rc;
283 }
284 }
285 return 0;
286}
287//******************************************************************************
288//NT returns addresses aligned at 64k, so we do too.
289//******************************************************************************
290DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags)
291{
292 LPVOID memaddr;
293 DWORD offset;
294 APIRET rc;
295
296 rc = DosAllocMem(&memaddr, size, PAG_READ | flAllocMem);
297 if(rc) {
298 return rc;
299 }
300 DosEnterCritSec();
301 DosFreeMem(memaddr);
302 offset = (DWORD)memaddr & 0xFFFF;
303 if(offset) {
304 DosAllocMem(&memaddr, 64*1024 - offset, PAG_READ | flAllocMem);
305 }
306 rc = DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
307 DosExitCritSec();
308 if((DWORD)*lplpMemAddr & 0xFFFF) {//still not at 64k boundary?
309 DosFreeMem(*lplpMemAddr);
310 rc = OSLibDosAllocMem(lplpMemAddr, size, flags);
311 }
312 if(offset) {
313 DosFreeMem(memaddr);
314 }
315
316 return rc;
317}
318//******************************************************************************
319//******************************************************************************
320DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
321{
322 return DosFreeMem(lpMemAddr);
323}
324//******************************************************************************
325//NOTE: If name == NULL, allocated gettable unnamed shared memory
326//******************************************************************************
327DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
328{
329 APIRET rc;
330 char *sharedmemname = NULL;
331
332 if(name) {
333 sharedmemname = (char *)malloc(strlen(name) + 16);
334 strcpy(sharedmemname, "\\SHAREMEM\\");
335 strcat(sharedmemname, name);
336 }
337 else flags |= OBJ_GETTABLE;
338
339 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
340 if(name) {
341 free(sharedmemname);
342 }
343 return rc;
344}
345//******************************************************************************
346//NOTE: If name == NULL, assume gettable unnamed shared memory
347//******************************************************************************
348DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
349{
350 APIRET rc;
351 char *sharedmemname = NULL;
352
353 if(name) {
354 sharedmemname = (char *)malloc(strlen(name) + 16);
355 strcpy(sharedmemname, "\\SHAREMEM\\");
356 strcat(sharedmemname, name);
357 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
358 if(name) {
359 free(sharedmemname);
360 }
361 }
362 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
363
364 return rc;
365}
366//******************************************************************************
367//******************************************************************************
368DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
369{
370 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
371}
372//******************************************************************************
373//******************************************************************************
374DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
375{
376 APIRET rc;
377
378 rc = DosSetMem(lpMemAddr, size, flags);
379 switch(rc) {
380 case ERROR_INVALID_ADDRESS:
381 return OSLIB_ERROR_INVALID_ADDRESS;
382 case ERROR_ACCESS_DENIED:
383 return OSLIB_ERROR_ACCESS_DENIED;
384 default:
385 return rc;
386 }
387}
388//******************************************************************************
389//******************************************************************************
390DWORD OSLibDosOpen(char *lpszFileName, DWORD flags)
391{
392 APIRET rc;
393 HFILE hFile;
394 ULONG ulAction;
395 DWORD os2flags = OPEN_FLAGS_NOINHERIT;
396
397
398 if(flags & OSLIB_ACCESS_READONLY)
399 os2flags |= OPEN_ACCESS_READONLY;
400 else
401 if(flags & OSLIB_ACCESS_READWRITE)
402 os2flags |= OPEN_ACCESS_READWRITE;
403
404 if(flags & OSLIB_ACCESS_SHAREDENYNONE)
405 os2flags |= OPEN_SHARE_DENYNONE;
406 else
407 if(flags & OSLIB_ACCESS_SHAREDENYREAD)
408 os2flags |= OPEN_SHARE_DENYREAD;
409 else
410 if(flags & OSLIB_ACCESS_SHAREDENYWRITE)
411 os2flags |= OPEN_SHARE_DENYWRITE;
412
413tryopen:
414 rc = DosOpen(lpszFileName, /* File path name */
415 &hFile, /* File handle */
416 &ulAction, /* Action taken */
417 0L, /* File primary allocation */
418 0L, /* File attribute */
419 OPEN_ACTION_FAIL_IF_NEW |
420 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
421 os2flags,
422 0L); /* No extended attribute */
423
424 if(rc) {
425 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
426 ULONG CurMaxFH;
427 LONG ReqCount = 32;
428
429 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
430 if(rc) {
431 dprintf(("DosSetRelMaxFH returned %d", rc));
432 return 0;
433 }
434 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
435 goto tryopen;
436 }
437 return 0;
438 }
439 else return hFile;
440}
441//******************************************************************************
442//******************************************************************************
443BOOL OSLibDosClose(DWORD hFile)
444{
445 APIRET rc;
446
447 rc = DosClose(hFile);
448 SetLastError(error2WinError(rc));
449 return (rc == NO_ERROR);
450}
451//******************************************************************************
452//******************************************************************************
453DWORD OSLibDosChangeMaxFileHandles()
454{
455 ULONG CurMaxFH;
456 LONG ReqCount = 0;
457 APIRET rc;
458
459 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
460 if(rc) {
461 dprintf(("DosSetRelMaxFH returned %d", rc));
462 return rc;
463 }
464 if(ReqCount + ODIN_INCREMENT_MAX_FILEHANDLES > CurMaxFH) {
465 ReqCount = CurMaxFH + ODIN_INCREMENT_MAX_FILEHANDLES;
466 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
467 if(rc) {
468 dprintf(("DosSetRelMaxFH returned %d", rc));
469 return rc;
470 }
471 }
472 return 0;
473}
474//******************************************************************************
475//******************************************************************************
476DWORD OSLibDosSetInitialMaxFileHandles(DWORD maxhandles)
477{
478 ULONG CurMaxFH;
479 LONG ReqCount = 0;
480 APIRET rc;
481
482 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
483 if(rc) {
484 dprintf(("DosSetRelMaxFH returned %d", rc));
485 return rc;
486 }
487 if(CurMaxFH < maxhandles) {
488 rc = DosSetMaxFH(maxhandles);
489 if(rc) {
490 dprintf(("DosSetMaxFH returned %d", rc));
491 return rc;
492 }
493 }
494 return 0;
495}
496//******************************************************************************
497//******************************************************************************
498BOOL OSLibDosRead(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesRead)
499{
500 APIRET rc;
501
502 rc = DosRead(hFile, lpBuffer, size, nrBytesRead);
503 SetLastError(error2WinError(rc));
504 return (rc == NO_ERROR);
505}
506//******************************************************************************
507//******************************************************************************
508BOOL OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten)
509{
510 APIRET rc;
511
512 rc = DosWrite(hFile, lpBuffer, size, nrBytesWritten);
513 SetLastError(error2WinError(rc));
514 return (rc == NO_ERROR);
515}
516//******************************************************************************
517//******************************************************************************
518DWORD OSLibDosSetFilePtr(DWORD hFile, DWORD offset, DWORD method)
519{
520 DWORD os2method;
521 DWORD newoffset;
522 APIRET rc;
523
524 switch(method)
525 {
526 case OSLIB_SETPTR_FILE_CURRENT:
527 os2method = FILE_CURRENT;
528 break;
529 case OSLIB_SETPTR_FILE_BEGIN:
530 os2method = FILE_BEGIN ;
531 break;
532 case OSLIB_SETPTR_FILE_END:
533 os2method = FILE_END;
534 break;
535 default:
536 return OSLIB_ERROR_INVALID_PARAMETER;
537 }
538
539 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
540 if(rc)
541 {
542 SetLastError(error2WinError(rc));
543 return -1;
544 }
545 else return newoffset;
546}
547//******************************************************************************
548//******************************************************************************
549BOOL OSLibDosDelete(char *lpszFileName)
550{
551 APIRET rc;
552
553 rc = DosDelete(lpszFileName);
554 if(rc) {
555 SetLastError(error2WinError(rc));
556 return FALSE;
557 }
558 return TRUE;
559}
560//******************************************************************************
561//******************************************************************************
562BOOL pmDateTimeToFileTime(FDATE *pDate,FTIME *pTime,FILETIME *pFT)
563{
564 USHORT dosTime, dosDate;
565
566 dosTime = *(USHORT*)pTime;
567 dosDate = *(USHORT*)pDate;
568
569 return DosDateTimeToFileTime(dosDate,dosTime,pFT);
570}
571//******************************************************************************
572//******************************************************************************
573#define NOT_NORMAL (FILE_ATTRIBUTE_READONLY_W | \
574 FILE_ATTRIBUTE_HIDDEN_W | \
575 FILE_ATTRIBUTE_SYSTEM_W | \
576 FILE_ATTRIBUTE_ARCHIVE_W)
577
578inline DWORD pm2WinFileAttributes(DWORD attrFile)
579{
580 DWORD res = 0;
581
582 if (!(attrFile & NOT_NORMAL))
583 res |= FILE_ATTRIBUTE_NORMAL_W;
584 if (attrFile & FILE_READONLY)
585 res |= FILE_ATTRIBUTE_READONLY_W;
586 if (attrFile & FILE_HIDDEN)
587 res |= FILE_ATTRIBUTE_HIDDEN_W;
588 if (attrFile & FILE_SYSTEM)
589 res |= FILE_ATTRIBUTE_SYSTEM_W;
590 if (attrFile & FILE_DIRECTORY)
591 res |= FILE_ATTRIBUTE_DIRECTORY_W;
592 if (attrFile & FILE_ARCHIVED)
593 res |= FILE_ATTRIBUTE_ARCHIVE_W;
594
595 //CB: not used: FILE_ATTRIBUTE_COMPRESSED_W
596
597 return res;
598}
599//******************************************************************************
600//******************************************************************************
601BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
602 ULONG ulDummy,
603 PVOID pBuffer)
604{
605 APIRET rc; /* API return code */
606 FILESTATUS3 fs3; /* file information structure */
607 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
608
609 // Note: we only handle standard "GetFileExInfoStandard" requests
610 rc = DosQueryPathInfo(pszName, /* query the file information */
611 FIL_STANDARD,
612 &fs3,
613 sizeof(fs3));
614 if (rc != NO_ERROR) /* check for errors */
615 return FALSE; /* raise error condition */
616
617 // convert structure
618 lpFad->dwFileAttributes = pm2WinFileAttributes(fs3.attrFile);
619 pmDateTimeToFileTime(&fs3.fdateCreation, &fs3.ftimeCreation, &lpFad->ftCreationTime);
620 pmDateTimeToFileTime(&fs3.fdateLastAccess, &fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
621 pmDateTimeToFileTime(&fs3.fdateLastWrite, &fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
622
623 /* @@@PH we might add Aurora support ...
624 lpFad->nFileSizeHigh = info.nFileSizeHigh;
625 */
626 lpFad->nFileSizeHigh = 0;
627 lpFad->nFileSizeLow = fs3.cbFile;
628
629 return TRUE;
630}
631//******************************************************************************
632DWORD WIN32API GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD );
633//******************************************************************************
634DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
635 DWORD length_fullname)
636{
637 switch(cmd) {
638 case OSLIB_SEARCHDIR:
639 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
640 name, full_name, length_fullname) != 0) {
641 return 0;
642 }
643 return strlen(full_name);
644
645
646 case OSLIB_SEARCHCURDIR:
647 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
648 name, full_name, length_fullname) != 0) {
649 return 0;
650 }
651 return strlen(full_name);
652
653 case OSLIB_SEARCHFILE:
654 {
655 FILESTATUS3 fileinfo;
656
657 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
658 return 0;
659 }
660 strncpy(full_name, name, length_fullname);
661 full_name[length_fullname-1] = 0;
662 return strlen(full_name);
663 }
664
665 case OSLIB_SEARCHENV:
666 {
667 LPSTR envstring;
668 int envsize;
669 CHAR szResult[CCHMAXPATH];
670
671 envsize = GetEnvironmentVariableA(path, NULL, 0);
672 envstring = (LPSTR)malloc(envsize+1);
673 GetEnvironmentVariableA(path, envstring, envsize);
674 if(DosSearchPath(SEARCH_IGNORENETERRS, envstring,
675 name, szResult, sizeof(szResult)) != 0) {
676 free(envstring);
677 return 0;
678 }
679 free(envstring);
680 strcpy(full_name, szResult);
681 return strlen(full_name);
682 }
683 }
684 return 0;
685}
686//******************************************************************************
687//******************************************************************************
688APIRET OSLibDosQueryPathInfo(PSZ pszPathName,
689 ULONG ulInfoLevel,
690 PVOID pInfoBuf,
691 ULONG cbInfoBuf)
692{
693 APIRET rc = DosQueryPathInfo( pszPathName, ulInfoLevel,
694 pInfoBuf, cbInfoBuf );
695
696 if(rc == ERROR_TOO_MANY_OPEN_FILES)
697 {
698 LONG reqCount = 2;
699 ULONG maxFiles;
700
701 if(DosSetRelMaxFH(&reqCount, &maxFiles) == NO_ERROR)
702 rc = DosQueryPathInfo(pszPathName, ulInfoLevel,
703 pInfoBuf, cbInfoBuf );
704 }
705 return rc;
706}
707//******************************************************************************
708//******************************************************************************
709DWORD OSLibDosCreateFile(CHAR *lpszFile,
710 DWORD fuAccess,
711 DWORD fuShare,
712 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
713 DWORD fuCreate,
714 DWORD fuAttrFlags,
715 HANDLE hTemplateFile)
716{
717 HFILE hFile;
718 ULONG actionTaken = 0;
719 ULONG fileSize = 0;
720 ULONG fileAttr = FILE_NORMAL;
721 ULONG openFlag = 0;
722 ULONG openMode = 0;
723 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;;
724
725 //TODO: lpSecurityAttributes (inheritance)
726
727 if(fuAttrFlags & FILE_ATTRIBUTE_ARCHIVE_W)
728 fileAttr |= FILE_ARCHIVED;
729 if(fuAttrFlags & FILE_ATTRIBUTE_HIDDEN_W)
730 fileAttr |= FILE_HIDDEN;
731 if(fuAttrFlags & FILE_ATTRIBUTE_SYSTEM_W)
732 fileAttr |= FILE_SYSTEM;
733 if(fuAttrFlags & FILE_ATTRIBUTE_READONLY_W)
734 fileAttr |= FILE_READONLY;
735 // TODO: FILE_ATTRIBUTE_TEMPORARY_W
736
737 switch(fuCreate)
738 {
739 case CREATE_NEW_W:
740 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
741 break;
742 case CREATE_ALWAYS_W:
743 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
744 break;
745 case OPEN_EXISTING_W:
746 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
747 break;
748 case OPEN_ALWAYS_W:
749 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
750 break;
751 case TRUNCATE_EXISTING_W:
752 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
753 break;
754 }
755
756 if(fuAttrFlags & FILE_FLAG_WRITE_THROUGH_W) openMode |= OPEN_FLAGS_WRITE_THROUGH;
757 if(fuAttrFlags & FILE_FLAG_NO_BUFFERING_W) openMode |= OPEN_FLAGS_NO_CACHE;
758 if(fuAttrFlags & FILE_FLAG_RANDOM_ACCESS_W) openMode |= OPEN_FLAGS_RANDOM;
759 if(fuAttrFlags & FILE_FLAG_SEQUENTIAL_SCAN_W) openMode |= OPEN_FLAGS_SEQUENTIAL;
760 // TODO: FILE_FLAG_BACKUP_SEMANTICS_W
761 // FILE_FLAG_POSIX_SEMANTICS_W are not supported
762
763 //TODO: FILE_SHARE_DELETE
764 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == 0 )
765 openMode |= OPEN_SHARE_DENYREADWRITE;
766 else
767 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
768 openMode |= OPEN_SHARE_DENYNONE;
769 else
770 if(fuShare & FILE_SHARE_READ_W)
771 openMode |= OPEN_SHARE_DENYWRITE;
772 else
773 if(fuShare & FILE_SHARE_WRITE_W)
774 openMode |= OPEN_SHARE_DENYREAD;
775
776 if(fuAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
777 openMode |= OPEN_ACCESS_READWRITE;
778 else
779 if(fuAccess & GENERIC_READ_W)
780 openMode |= OPEN_ACCESS_READONLY;
781 else
782 if(fuAccess & GENERIC_WRITE_W)
783 openMode |= OPEN_ACCESS_WRITEONLY;
784
785#if 0
786 //SvL: Not true; verified in NT! (also messed up access of files on
787 // readonly volumes)
788 // CreateFile with OPEN_ALWAYS & GENERIC_READ on non-existing file
789 // -> creates 0 size file, WriteFile is not allowed
790 // Same in OS/2.
791 /* if creating a file, access cannot be readonly! */
792 if (openFlag & OPEN_ACTION_CREATE_IF_NEW &&
793 (!(openMode & OPEN_ACCESS_READWRITE) &&
794 !(openMode & OPEN_ACCESS_WRITEONLY))) {
795 openMode |= OPEN_ACCESS_READWRITE;
796 }
797#endif
798
799 int retry = 0;
800 while(retry < 2)
801 {
802 dprintf(("DosOpen %s openFlag=%x openMode=%x", lpszFile, openFlag, openMode));
803 rc = DosOpen((PSZ)lpszFile,
804 &hFile,
805 &actionTaken,
806 fileSize,
807 fileAttr,
808 openFlag,
809 openMode,
810 NULL);
811 if(rc == ERROR_TOO_MANY_OPEN_FILES)
812 {
813 ULONG CurMaxFH;
814 LONG ReqCount = 32;
815
816 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
817 if(rc) {
818 dprintf(("DosSetRelMaxFH returned %d", rc));
819 SetLastError(ERROR_TOO_MANY_OPEN_FILES_W);
820 return INVALID_HANDLE_VALUE_W;
821 }
822 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
823 }
824 else break;
825 retry++;
826 }
827
828 if(rc)
829 {
830 SetLastError(error2WinError(rc));
831 return INVALID_HANDLE_VALUE_W;
832 }
833 SetLastError(ERROR_SUCCESS_W);
834 return hFile;
835}
836//******************************************************************************
837//******************************************************************************
838DWORD OSLibDosOpenFile(CHAR *lpszFile, UINT fuMode)
839{
840 ULONG actionTaken = 0;
841 ULONG fileSize = 0;
842 ULONG fileAttr = FILE_NORMAL;
843 ULONG openFlag = 0;
844 ULONG openMode = 0;
845 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;
846 HFILE hFile;
847
848 if(!(fuMode & (OF_CREATE_W | OF_READWRITE_W | OF_WRITE_W)))
849 {
850 openMode |= OPEN_ACCESS_READONLY;
851 openFlag |= OPEN_ACTION_OPEN_IF_EXISTS;
852 }
853 else
854 {
855 if(fuMode & OF_CREATE_W) {
856 openFlag |= OPEN_ACTION_CREATE_IF_NEW |
857 OPEN_ACTION_REPLACE_IF_EXISTS;
858 }
859 else openFlag |= OPEN_ACTION_OPEN_IF_EXISTS; //180575
860
861 if(fuMode & OF_READWRITE_W)
862 openMode |= OPEN_ACCESS_READWRITE;
863 else
864 if(fuMode & OF_WRITE_W)
865 openMode |= OPEN_ACCESS_WRITEONLY;
866 else
867 if(fuMode & OF_CREATE_W)
868 openMode |= OPEN_ACCESS_READWRITE;
869 }
870
871 if((fuMode & OF_SHARE_DENY_WRITE_W) ||
872 !(fuMode & (OF_SHARE_DENY_READ_W | OF_SHARE_DENY_NONE_W | OF_SHARE_EXCLUSIVE_W)))
873 openMode |= OPEN_SHARE_DENYWRITE;
874 else
875 if (fuMode & OF_SHARE_DENY_NONE_W)
876 openMode |= OPEN_SHARE_DENYNONE;
877 else
878 if (fuMode & OF_SHARE_DENY_READ_W)
879 openMode |= OPEN_SHARE_DENYREAD;
880 else
881 if (fuMode & OF_SHARE_EXCLUSIVE_W)
882 openMode |= OPEN_SHARE_DENYREADWRITE;
883
884 rc = DosOpen((PSZ)lpszFile,
885 &hFile,
886 &actionTaken,
887 fileSize,
888 fileAttr,
889 openFlag,
890 openMode,
891 NULL);
892
893 if(rc != NO_ERROR)
894 {
895 if(fuMode & OF_EXIST_W)
896 {
897 if(rc == ERROR_OPEN_FAILED || rc == ERROR_FILE_NOT_FOUND)
898 {
899 SetLastError(ERROR_FILE_NOT_FOUND_W);
900 return HFILE_ERROR_W;
901 }
902 }
903 if((rc == ERROR_OPEN_FAILED) && (openFlag & OPEN_ACTION_OPEN_IF_EXISTS))
904 {
905 SetLastError(ERROR_FILE_NOT_FOUND_W);
906 }
907 else SetLastError(error2WinError(rc));
908
909 return HFILE_ERROR_W;
910 }
911 SetLastError(ERROR_SUCCESS_W);
912 return hFile;
913}
914//******************************************************************************
915//******************************************************************************
916BOOL OSLibDosLockFile(DWORD hFile, DWORD dwFlags,
917 DWORD OffsetLow, DWORD OffsetHigh,
918 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
919 LPOVERLAPPED lpOverlapped)
920{
921 APIRET rc;
922
923 // Set 5 secs timeout for locking file and no other can access this
924 // file region
925
926 if(lpOverlapped) {//TODO:
927 dprintf(("OSLibDosLockFile: overlapped lock not yet implemented!!"));
928 }
929 //TODO: Locking region crossing end of file is permitted. Works in OS/2??
930 if(f64BitIO)
931 {
932 FILELOCKL lockRangeL;
933
934 lockRangeL.lOffset.ulLo = OffsetLow;
935 lockRangeL.lOffset.ulHi = OffsetHigh;
936 lockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
937 lockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
938
939 rc = OdinDosSetFileLocksL(hFile, NULL, &lockRangeL,
940 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
941 //SvL: 64 bits values are only supported by JFS
942 // Try the 32 bits DosSetFileLocks if it fails
943 // (TODO: should check the partition type instead)
944 if(rc == ERROR_INVALID_PARAMETER && (OffsetHigh || nNumberOfBytesToLockHigh)) {
945 goto oldlock;
946 }
947 }
948 else
949 {
950oldlock:
951 FILELOCK lockRange = { OffsetLow, nNumberOfBytesToLockLow };
952
953 rc = DosSetFileLocks(hFile, NULL, &lockRange,
954 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
955 }
956 if(rc) {
957 SetLastError(error2WinError(rc));
958 return FALSE;
959 }
960 SetLastError(ERROR_SUCCESS_W);
961 return TRUE;
962}
963//******************************************************************************
964//******************************************************************************
965BOOL OSLibDosUnlockFile(DWORD hFile, DWORD OffsetLow, DWORD OffsetHigh,
966 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
967 LPOVERLAPPED lpOverlapped)
968{
969 APIRET rc;
970
971 // Set 5 secs timeout for unlocking file and no other can access this
972 // file region
973
974 if(lpOverlapped) {//TODO:
975 dprintf(("OSLibDosUnlockFile: overlapped unlock not yet implemented!!"));
976 }
977 if(f64BitIO)
978 {
979 FILELOCKL unlockRangeL;
980
981 unlockRangeL.lOffset.ulLo = OffsetLow;
982 unlockRangeL.lOffset.ulHi = OffsetHigh;
983 unlockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
984 unlockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
985
986 rc = OdinDosSetFileLocksL(hFile, &unlockRangeL, NULL, 5000, 0);
987 //SvL: 64 bits values are only supported by JFS
988 // Try the 32 bits DosSetFileLocks if it fails
989 // (TODO: should check the partition type instead)
990 if(rc == ERROR_INVALID_PARAMETER && (OffsetHigh || nNumberOfBytesToLockHigh)) {
991 goto oldlock;
992 }
993 }
994 else
995 {
996oldlock:
997 FILELOCK unlockRange = { OffsetLow, nNumberOfBytesToLockLow };
998
999 rc = DosSetFileLocks(hFile, &unlockRange, NULL, 5000, 0);
1000 }
1001 if(rc) {
1002 SetLastError(error2WinError(rc));
1003 return FALSE;
1004 }
1005 SetLastError(ERROR_SUCCESS_W);
1006 return TRUE;
1007}
1008//******************************************************************************
1009//******************************************************************************
1010BOOL OSLibDosFlushFileBuffers(DWORD hFile)
1011{
1012 APIRET rc;
1013
1014 rc = DosResetBuffer(hFile);
1015 SetLastError(error2WinError(rc));
1016 return (rc == NO_ERROR);
1017}
1018//******************************************************************************
1019//******************************************************************************
1020DWORD OSLibDosGetFileSize(DWORD hFile, LPDWORD lpdwFileSizeHigh)
1021{
1022 APIRET rc;
1023 ULONG sizeLow;
1024
1025 if(f64BitIO)
1026 {
1027 FILESTATUS3L fsts3ConfigInfoL = {{0}};
1028 ULONG ulBufSize = sizeof(FILESTATUS3L);
1029
1030 rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &fsts3ConfigInfoL, ulBufSize);
1031 if(lpdwFileSizeHigh) {
1032 *lpdwFileSizeHigh = fsts3ConfigInfoL.cbFile.ulHi;
1033 }
1034 sizeLow = fsts3ConfigInfoL.cbFile.ulLo;
1035 }
1036 else
1037 {
1038 FILESTATUS3 fsts3ConfigInfo = {{0}};
1039 ULONG ulBufSize = sizeof(FILESTATUS3);
1040
1041 if(lpdwFileSizeHigh) {
1042 *lpdwFileSizeHigh = 0;
1043 }
1044 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
1045 sizeLow = fsts3ConfigInfo.cbFile;
1046 }
1047 if(rc) {
1048 SetLastError(error2WinError(rc));
1049 return -1;
1050 }
1051 SetLastError(ERROR_SUCCESS_W);
1052 return sizeLow;
1053}
1054//******************************************************************************
1055//******************************************************************************
1056DWORD OSLibDosSetFilePointer(DWORD hFile, DWORD OffsetLow, DWORD *OffsetHigh, DWORD method)
1057{
1058 LONGLONG offsetL;
1059 LONGLONG newoffsetL;
1060 APIRET rc;
1061 DWORD newoffset;
1062
1063 switch(method)
1064 {
1065 case FILE_BEGIN_W:
1066 method = FILE_BEGIN;
1067 break;
1068
1069 case FILE_CURRENT_W:
1070 method = FILE_CURRENT;
1071 break;
1072
1073 case FILE_END_W:
1074 method = FILE_END;
1075 break;
1076 }
1077
1078 // PH Note: for a negative 32-bit seek, the OS/2 64-bit version
1079 // needs to be skipped.
1080 if( (f64BitIO) && (OffsetHigh) )
1081 {
1082 offsetL.ulLo = OffsetLow;
1083 offsetL.ulHi = (OffsetHigh) ? *OffsetHigh : 0;
1084 rc = OdinDosSetFilePtrL(hFile, offsetL, method, &newoffsetL);
1085 if(OffsetHigh) {
1086 *OffsetHigh = newoffsetL.ulHi;
1087 }
1088 newoffset = newoffsetL.ulLo;
1089 }
1090 else
1091 rc = DosSetFilePtr(hFile, OffsetLow, method, &newoffset);
1092
1093 if(rc)
1094 {
1095 SetLastError(error2WinError(rc));
1096 return -1;
1097 }
1098 SetLastError(ERROR_SUCCESS_W);
1099 return newoffset;
1100}
1101//******************************************************************************
1102//******************************************************************************
1103BOOL OSLibDosSetEndOfFile(DWORD hFile)
1104{
1105 ULONG newFilePos;
1106 LONGLONG FilePosL = {0,0};
1107 LONGLONG newFilePosL;
1108 APIRET rc;
1109
1110 if(f64BitIO) {
1111 rc = OdinDosSetFilePtrL(hFile, FilePosL, FILE_CURRENT, &newFilePosL);
1112 if(rc == 0) {
1113 rc = OdinDosSetFileSizeL(hFile, newFilePosL);
1114 }
1115 }
1116 else {
1117 rc = DosSetFilePtr(hFile, 0, FILE_CURRENT, &newFilePos);
1118 if(rc == 0) {
1119 rc = DosSetFileSize(hFile, newFilePos);
1120 }
1121 }
1122 if(rc) {
1123 SetLastError(error2WinError(rc));
1124 return FALSE;
1125 }
1126 SetLastError(ERROR_SUCCESS_W);
1127 return TRUE;
1128}
1129//******************************************************************************
1130//******************************************************************************
1131BOOL OSLibDosGetFileInformationByHandle(DWORD hFile, BY_HANDLE_FILE_INFORMATION* pInfo)
1132{
1133 APIRET rc;
1134
1135 if(f64BitIO)
1136 {
1137 FILESTATUS4L statusL = { 0 };
1138
1139 rc = DosQueryFileInfo(hFile,
1140 FIL_QUERYEASIZEL,
1141 &statusL,
1142 sizeof(statusL));
1143 if(rc == NO_ERROR)
1144 {
1145 pInfo->dwFileAttributes = 0;
1146 if(!(statusL.attrFile & NOT_NORMAL))
1147 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1148 if(statusL.attrFile & FILE_READONLY)
1149 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1150 if(statusL.attrFile & FILE_HIDDEN)
1151 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1152 if(statusL.attrFile & FILE_SYSTEM)
1153 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1154 if(statusL.attrFile & FILE_DIRECTORY)
1155 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1156 if(statusL.attrFile & FILE_ARCHIVED)
1157 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1158
1159 pmDateTimeToFileTime(&statusL.fdateCreation,
1160 &statusL.ftimeCreation,
1161 &pInfo->ftCreationTime);
1162 pmDateTimeToFileTime(&statusL.fdateLastAccess,
1163 &statusL.ftimeLastAccess,
1164 &pInfo->ftLastAccessTime);
1165 pmDateTimeToFileTime(&statusL.fdateLastWrite,
1166 &statusL.ftimeLastWrite,
1167 &pInfo->ftLastWriteTime);
1168
1169 pInfo->nFileSizeHigh = statusL.cbFile.ulHi;
1170 pInfo->nFileSizeLow = statusL.cbFile.ulLo;
1171 pInfo->dwVolumeSerialNumber = 0; //todo
1172 pInfo->nNumberOfLinks = 1;
1173 pInfo->nFileIndexHigh = 0;
1174 pInfo->nFileIndexLow = 0;
1175 }
1176 }
1177 else
1178 {
1179 FILESTATUS4 status = { 0 };
1180
1181 rc = DosQueryFileInfo(hFile,
1182 FIL_QUERYEASIZE,
1183 &status,
1184 sizeof(status));
1185 if(rc == NO_ERROR)
1186 {
1187 pInfo->dwFileAttributes = 0;
1188 if(!(status.attrFile & NOT_NORMAL))
1189 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1190 if(status.attrFile & FILE_READONLY)
1191 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1192 if(status.attrFile & FILE_HIDDEN)
1193 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1194 if(status.attrFile & FILE_SYSTEM)
1195 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1196 if(status.attrFile & FILE_DIRECTORY)
1197 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1198 if(status.attrFile & FILE_ARCHIVED)
1199 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1200
1201 pmDateTimeToFileTime(&status.fdateCreation,
1202 &status.ftimeCreation,
1203 &pInfo->ftCreationTime);
1204 pmDateTimeToFileTime(&status.fdateLastAccess,
1205 &status.ftimeLastAccess,
1206 &pInfo->ftLastAccessTime);
1207 pmDateTimeToFileTime(&status.fdateLastWrite,
1208 &status.ftimeLastWrite,
1209 &pInfo->ftLastWriteTime);
1210
1211 pInfo->nFileSizeHigh = 0;
1212 pInfo->nFileSizeLow = status.cbFile;
1213 pInfo->dwVolumeSerialNumber = 0; //todo
1214 pInfo->nNumberOfLinks = 1;
1215 pInfo->nFileIndexHigh = 0;
1216 pInfo->nFileIndexLow = 0;
1217 }
1218 }
1219 if(rc) {
1220 SetLastError(error2WinError(rc));
1221 return FALSE;
1222 }
1223 SetLastError(ERROR_SUCCESS_W);
1224 return TRUE;
1225}
1226//******************************************************************************
1227//******************************************************************************
1228BOOL OSLibDosSetFileTime(DWORD hFile, WORD creationdate, WORD creationtime,
1229 WORD lastaccessdate, WORD lastaccesstime,
1230 WORD lastwritedate, WORD lastwritetime)
1231{
1232 FILESTATUS3 fileInfo;
1233 APIRET rc;
1234
1235 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1236
1237 if(rc == NO_ERROR)
1238 {
1239 if(creationdate && creationtime) {
1240 fileInfo.fdateCreation = *(FDATE *)&creationdate;
1241 fileInfo.ftimeCreation = *(FTIME *)&creationtime;
1242 }
1243 if(lastaccessdate && lastaccesstime) {
1244 fileInfo.fdateLastAccess = *(FDATE *)&lastaccessdate;
1245 fileInfo.ftimeLastAccess = *(FTIME *)&lastaccesstime;
1246 }
1247 if(lastwritedate && lastwritetime) {
1248 fileInfo.fdateLastWrite = *(FDATE *)&lastwritedate;
1249 fileInfo.ftimeLastWrite = *(FTIME *)&lastwritetime;
1250 }
1251
1252 rc = DosSetFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1253 }
1254
1255 if(rc)
1256 {
1257 SetLastError(error2WinError(rc));
1258 return FALSE;
1259 }
1260 SetLastError(ERROR_SUCCESS_W);
1261 return TRUE;
1262}
1263//******************************************************************************
1264//******************************************************************************
1265BOOL OSLibDosGetFileTime(DWORD hFile, WORD *creationdate, WORD *creationtime,
1266 WORD *lastaccessdate, WORD *lastaccesstime,
1267 WORD *lastwritedate, WORD *lastwritetime)
1268{
1269 FILESTATUS3 fileInfo;
1270 APIRET rc;
1271
1272 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1273
1274 if(rc == NO_ERROR)
1275 {
1276 *creationdate = *(WORD *)&fileInfo.fdateCreation;
1277 *creationtime = *(WORD *)&fileInfo.ftimeCreation;
1278 *lastaccessdate = *(WORD *)&fileInfo.fdateLastAccess;
1279 *lastaccesstime = *(WORD *)&fileInfo.ftimeLastAccess;
1280 *lastwritedate = *(WORD *)&fileInfo.fdateLastWrite;
1281 *lastwritetime = *(WORD *)&fileInfo.ftimeLastWrite;
1282 }
1283
1284 if(rc)
1285 {
1286 SetLastError(error2WinError(rc));
1287 return FALSE;
1288 }
1289 SetLastError(ERROR_SUCCESS_W);
1290 return TRUE;
1291}
1292//******************************************************************************
1293//******************************************************************************
1294DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
1295{
1296 DWORD newoffset;
1297 APIRET rc;
1298
1299
1300 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
1301 if(rc) {
1302 dprintf(("DosSetFilePtr Error rc:%d", rc));
1303 return -1;
1304 }
1305 else return newoffset;
1306}
1307//******************************************************************************
1308//******************************************************************************
1309DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
1310{
1311 *hNew = -1;
1312 return DosDupHandle(hFile, hNew);
1313}
1314//******************************************************************************
1315//******************************************************************************
1316void OSLibDosDisableHardError(BOOL fTurnOff)
1317{
1318 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
1319}
1320//******************************************************************************
1321//Returns time spent in kernel & user mode in milliseconds
1322//******************************************************************************
1323BOOL OSLibDosQueryProcTimes(DWORD procid, ULONG *kerneltime, ULONG *usertime)
1324{
1325 APIRET rc;
1326 char *buf;
1327 ULONG size;
1328 ULONG nrthreads = 4;
1329
1330tryagain:
1331 size = sizeof(QTOPLEVEL)+sizeof(QGLOBAL)+sizeof(QPROCESS) + nrthreads*sizeof(QTHREAD);
1332 buf = (char *)malloc(size);
1333 rc = DosQuerySysState(0x1, RESERVED, procid, RESERVED, (PCHAR)buf, size);
1334
1335 if(rc) {
1336 free(buf);
1337 if(rc == ERROR_BUFFER_OVERFLOW) {
1338 nrthreads += 4;
1339 goto tryagain;
1340 }
1341 return FALSE;
1342 }
1343 PQTOPLEVEL top = (PQTOPLEVEL)buf;
1344
1345 *kerneltime = 0;
1346 *usertime = 0;
1347 for(int i=0;i<top->procdata->threadcnt;i++) {
1348 *kerneltime += top->procdata->threads[i].systime;
1349 *usertime += top->procdata->threads[i].usertime;
1350 }
1351 free(buf);
1352 return TRUE;
1353}
1354//******************************************************************************
1355//******************************************************************************
1356// TODO: implement SecurityAttributes parameter
1357DWORD OSLibDosCreateNamedPipe(LPCTSTR lpName,
1358 DWORD dwOpenMode,
1359 DWORD dwPipeMode,
1360 DWORD nMaxInstances,
1361 DWORD nOutBufferSize,
1362 DWORD nInBufferSize,
1363 DWORD nDefaultTimeOut,
1364 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
1365{ DWORD dwOS2Mode = 0;
1366 DWORD dwOS2PipeMode = 0;
1367 LPSTR lpOS2Name;
1368 DWORD hPipe;
1369 DWORD rc;
1370
1371 if (dwOpenMode & PIPE_ACCESS_DUPLEX_W)
1372 dwOS2Mode |= NP_ACCESS_DUPLEX;
1373 else
1374 if (dwOpenMode & PIPE_ACCESS_INBOUND_W)
1375 dwOS2Mode |= NP_ACCESS_INBOUND;
1376 else
1377 if (dwOpenMode & PIPE_ACCESS_OUTBOUND_W)
1378 dwOS2Mode |= NP_ACCESS_OUTBOUND;
1379 // TODO:
1380 // if(dwOpenMode & FILE_FLAG_OVERLAPPED)
1381 // if(dwOpenMode & WRITE_DAC)
1382 // if(dwOpenMode & WRITE_OWNER)
1383 // if(dwOpenMode & ACCESS_SYSTEM_SECURITY)
1384 if(dwOpenMode & FILE_FLAG_WRITE_THROUGH_W)
1385 dwOS2Mode |= NP_WRITEBEHIND; // FIXME: I'm not sure!
1386
1387 if (dwPipeMode & PIPE_WAIT_W)
1388 dwOS2PipeMode |= NP_WAIT;
1389 if (dwPipeMode & PIPE_NOWAIT_W)
1390 dwOS2PipeMode |= NP_NOWAIT;
1391 if (dwPipeMode & PIPE_READMODE_BYTE_W)
1392 dwOS2PipeMode |= NP_READMODE_BYTE;
1393 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
1394 dwOS2PipeMode |= NP_READMODE_MESSAGE;
1395 if (dwPipeMode & PIPE_TYPE_BYTE_W)
1396 dwOS2PipeMode |= NP_TYPE_BYTE;
1397 if (dwPipeMode & PIPE_TYPE_MESSAGE_W)
1398 dwOS2PipeMode |= NP_TYPE_MESSAGE;
1399
1400 if (nMaxInstances>0xff)
1401 {
1402 SetLastError(ERROR_INVALID_PARAMETER_W); // ERROR_INVALID_PARAMETER
1403 return -1; // INVALID_HANDLE_VALUE
1404 }
1405 dwOS2PipeMode |= nMaxInstances;
1406
1407 if (strstr(lpName,"\\\\."))
1408 {
1409 // If pipe is created on the local machine
1410 // we must delete string \\. because
1411 // in Windows named pipes scheme is a \\.\PIPE\pipename
1412 // but in OS/2 only \PIPE\pipename
1413 lpOS2Name = (LPSTR)lpName + 3;
1414 }
1415 else lpOS2Name = (LPSTR)lpName;
1416
1417 dprintf(("DosCreateNPipe(%s,%x,%x,%x,%x,%x)",lpOS2Name,dwOS2Mode,dwOS2PipeMode,nInBufferSize,nOutBufferSize,nDefaultTimeOut));
1418 rc=DosCreateNPipe(lpOS2Name,
1419 &hPipe,
1420 dwOS2Mode,
1421 dwOS2PipeMode,
1422 nInBufferSize,
1423 nInBufferSize,
1424 nDefaultTimeOut); // Timeouts must be tested!
1425
1426 dprintf(("DosCreateNPipe rc=%d",rc));
1427 if (rc)
1428 {
1429 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
1430 return -1; // INVALID_HANDLE_VALUE
1431 }
1432 return hPipe;
1433}
1434
1435//******************************************************************************
1436//******************************************************************************
1437// TODO: implement lpOverlapped parameter!
1438BOOL OSLibDosConnectNamedPipe(DWORD hNamedPipe, LPOVERLAPPED lpOverlapped)
1439{
1440 DWORD rc;
1441
1442 rc=DosConnectNPipe(hNamedPipe);
1443 dprintf(("DosConnectNPipe rc=%d",rc));
1444
1445 if (!rc) return (TRUE);
1446 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1447
1448 return (FALSE);
1449}
1450
1451//******************************************************************************
1452//******************************************************************************
1453BOOL OSLibDosCallNamedPipe( LPCTSTR lpNamedPipeName,
1454 LPVOID lpInBuffer,
1455 DWORD nInBufferSize,
1456 LPVOID lpOutBuffer,
1457 DWORD nOutBufferSize,
1458 LPDWORD lpBytesRead,
1459 DWORD nTimeOut )
1460{
1461 LPSTR lpOS2Name;
1462 DWORD rc;
1463
1464 if (strstr(lpNamedPipeName,"\\\\."))
1465 {
1466 // If pipe is created on the local machine
1467 // we must delete string \\. because
1468 // in Windows named pipes scheme is a \\.\PIPE\pipename
1469 // but in OS/2 only \PIPE\pipename
1470 lpOS2Name = (LPSTR)lpNamedPipeName + 3;
1471 }
1472 else lpOS2Name = (LPSTR)lpNamedPipeName;
1473
1474 rc=DosCallNPipe(lpOS2Name,
1475 lpInBuffer,
1476 nInBufferSize,
1477 lpOutBuffer,
1478 nOutBufferSize,
1479 lpBytesRead,
1480 nTimeOut );
1481
1482
1483 if (!rc) return (TRUE);
1484 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1485
1486 return (FALSE);
1487}
1488
1489//******************************************************************************
1490//******************************************************************************
1491BOOL OSLibDosTransactNamedPipe( DWORD hNamedPipe,
1492 LPVOID lpInBuffer,
1493 DWORD nInBufferSize,
1494 LPVOID lpOutBuffer,
1495 DWORD nOutBufferSize,
1496 LPDWORD lpBytesRead,
1497 LPOVERLAPPED lpOverlapped)
1498{
1499 DWORD rc;
1500
1501 rc=DosTransactNPipe(hNamedPipe,
1502 lpOutBuffer,
1503 nOutBufferSize,
1504 lpInBuffer,
1505 nInBufferSize,
1506 lpBytesRead);
1507
1508 dprintf(("DosTransactNPipe returned rc=%d");)
1509 if (!rc) return (TRUE);
1510 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1511
1512 return (FALSE);
1513}
1514
1515//******************************************************************************
1516//******************************************************************************
1517BOOL OSLibDosPeekNamedPipe(DWORD hPipe,
1518 LPVOID lpvBuffer,
1519 DWORD cbBuffer,
1520 LPDWORD lpcbRead,
1521 LPDWORD lpcbAvail,
1522 LPDWORD lpcbMessage)
1523{
1524 DWORD rc;
1525 AVAILDATA availData ={0};
1526 ULONG ulDummy;
1527
1528 rc=DosPeekNPipe(hPipe,lpvBuffer,cbBuffer,lpcbRead,&availData,&ulDummy);
1529
1530 dprintf(("DosPeekNPipe returned rc=%d",rc));
1531
1532 if (!rc)
1533 {
1534 *lpcbAvail = availData.cbpipe;
1535 *lpcbMessage = availData.cbmessage;
1536 return (TRUE);
1537 }
1538 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1539
1540 return (FALSE);
1541}
1542//******************************************************************************
1543//******************************************************************************
1544BOOL OSLibDosDisconnectNamedPipe(DWORD hPipe)
1545{
1546 DWORD rc;
1547
1548 rc=DosDisConnectNPipe(hPipe);
1549
1550 dprintf(("DosDisConnectNPipe returned rc=%d",rc));
1551
1552 if (!rc) return TRUE;
1553 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1554
1555 return (FALSE);
1556}
1557//******************************************************************************
1558//******************************************************************************
1559BOOL OSLibDosWaitNamedPipe(LPCSTR lpszNamedPipeName,
1560 DWORD dwTimeout)
1561{
1562 LPSTR lpOS2Name;
1563 DWORD rc;
1564
1565 if (strstr(lpszNamedPipeName,"\\\\."))
1566 {
1567 // If pipe is created on the local machine
1568 // we must delete string \\. because
1569 // in Windows named pipes scheme is a \\.\PIPE\pipename
1570 // but in OS/2 only \PIPE\pipename
1571 lpOS2Name = (LPSTR)lpszNamedPipeName + 3;
1572 }
1573 else lpOS2Name = (LPSTR)lpszNamedPipeName;
1574
1575 rc=DosWaitNPipe(lpOS2Name,dwTimeout);
1576
1577 dprintf(("DosWaitNPipe returned rc=%d",rc));
1578
1579 if (!rc) return TRUE;
1580 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1581
1582 return (FALSE);
1583}
1584//******************************************************************************
1585//******************************************************************************
1586BOOL isRoot(CHAR* name)
1587{
1588 if (name[1] == ':')
1589 {
1590 //local name (x:\)
1591 return (name[2] == 0) || !strchr(&name[3],'\\');
1592 } else if (name[0] == '\\')
1593 {
1594 //UNC name (\\resource\drive\)
1595 CHAR *drive,*dir;
1596
1597 drive = strchr(&name[2],'\\');
1598 if (!drive) return FALSE;
1599 dir = strchr(&drive[1],'\\');
1600 if (!dir) return TRUE;
1601 return !strchr(&dir[1],'\\');
1602 } else return FALSE; //unknown
1603}
1604//******************************************************************************
1605//******************************************************************************
1606inline CHAR system2DOSCharacter(CHAR ch)
1607{
1608 switch(ch)
1609 {
1610 case ' ':
1611 case '.':
1612 case '~':
1613 return '_';
1614
1615 default:
1616 return toupper(ch);
1617 }
1618}
1619
1620VOID long2ShortName(CHAR* longName,CHAR* shortName)
1621{
1622 INT x;
1623 CHAR *source = longName,*dest = shortName,*ext = strrchr(longName,'.');
1624
1625 if ((strcmp(longName,".") == 0) || (strcmp(longName,"..") == 0))
1626 {
1627 strcpy(shortName,longName);
1628 return;
1629 }
1630
1631 //CB: quick and dirty, real FILE~12.EXT is too slow
1632
1633 //8 character file name
1634 for (x = 0;x < 8;x++)
1635 {
1636 if ((source == ext) || (source[0] == 0)) break;
1637 dest[0] = system2DOSCharacter(source[0]);
1638 source++;
1639 dest++;
1640 }
1641
1642 if (source[0] == 0)
1643 {
1644 dest[0] = 0;
1645 return;
1646 }
1647
1648 if (source != ext)
1649 {
1650 //longName > 8 characters, insert ~1
1651 shortName[6] = '~';
1652 shortName[7] = '1';
1653 }
1654
1655 if (ext)
1656 {
1657 //add extension, 3 characters
1658 dest[0] = ext[0];
1659 dest++;
1660 ext++;
1661 for (x = 0;x < 3;x++)
1662 {
1663 if (ext[0] == 0) break;
1664 dest[0] = system2DOSCharacter(ext[0]);
1665 ext++;
1666 dest++;
1667 }
1668 }
1669 dest[0] = 0;
1670}
1671//******************************************************************************
1672//******************************************************************************
1673VOID translateFileResults(FILESTATUS3 *pResult,LPWIN32_FIND_DATAA pFind,CHAR* achName)
1674{
1675 CHAR* name;
1676
1677 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1678
1679 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1680 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1681 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1682
1683 pFind->nFileSizeHigh = 0; //CB: fixme
1684 pFind->nFileSizeLow = pResult->cbFile;
1685 name = strrchr(achName,'\\');
1686 if (name)
1687 {
1688 name++;
1689 strcpy(pFind->cFileName,name);
1690 } else pFind->cFileName[0] = 0;
1691 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1692}
1693
1694VOID translateFindResults(FILEFINDBUF3 *pResult,LPWIN32_FIND_DATAA pFind)
1695{
1696 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1697
1698 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1699 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1700 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1701
1702 pFind->nFileSizeHigh = 0; //CB: fixme
1703 pFind->nFileSizeLow = pResult->cbFile;
1704 strcpy(pFind->cFileName,pResult->achName);
1705 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1706}
1707//******************************************************************************
1708//******************************************************************************
1709DWORD OSLibDosFindFirst(LPCSTR lpFileName,WIN32_FIND_DATAA* lpFindFileData)
1710{
1711 HDIR hDir = -1;
1712 ULONG attrs;
1713 FILEFINDBUF3 result;
1714 ULONG searchCount = 1;
1715
1716 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1717 result.achName[0] = 0;
1718
1719 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1720 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,&result,sizeof(result),&searchCount,FIL_STANDARD);
1721 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1722
1723 //check root: skip "." and ".." (HPFS, not on FAT)
1724 //check in OSLibDosFindNext not necessary: "." and ".." are the first two entries
1725 if ((rc == 0) && isRoot((LPSTR)lpFileName))
1726 {
1727 while ((strcmp(result.achName,".") == 0) || (strcmp(result.achName,"..") == 0))
1728 {
1729 result.achName[0] = 0;
1730 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1731 searchCount = 1;
1732 APIRET rc = DosFindNext(hDir,&result,sizeof(result),&searchCount);
1733 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1734 if (rc)
1735 {
1736 DosFindClose(hDir);
1737 SetLastError(error2WinError(rc));
1738
1739 return INVALID_HANDLE_VALUE_W;
1740 }
1741 }
1742 }
1743 if(rc) {
1744 DosFindClose(hDir);
1745 SetLastError(error2WinError(rc));
1746 return INVALID_HANDLE_VALUE_W;
1747 }
1748 translateFindResults(&result,lpFindFileData);
1749 return hDir;
1750}
1751//******************************************************************************
1752// NOTE: returns "." and ".." in root
1753//******************************************************************************
1754DWORD OSLibDosFindFirstMulti(LPCSTR lpFileName,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1755{
1756 HDIR hDir = -1;
1757 ULONG attrs;
1758 FILEFINDBUF3 *result,*data;
1759 ULONG searchCount = *count;
1760
1761 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1762 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1763
1764 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1765 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,result,searchCount*sizeof(FILEFINDBUF3),&searchCount,FIL_STANDARD);
1766 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1767 if (rc)
1768 {
1769 free(result);
1770 *count = 0;
1771 SetLastError(error2WinError(rc));
1772
1773 return INVALID_HANDLE_VALUE_W;
1774 }
1775
1776 data = result;
1777 for (int x = 0;x < searchCount;x++)
1778 {
1779 translateFindResults(data,&lpFindFileData[x]);
1780 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1781 }
1782 free(result);
1783 *count = searchCount;
1784
1785 return hDir;
1786}
1787//******************************************************************************
1788//******************************************************************************
1789BOOL OSLibDosFindNext(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData)
1790{
1791 FILEFINDBUF3 result;
1792 ULONG searchCount = 1;
1793
1794 APIRET rc = DosFindNext((HDIR)hFindFile,&result,sizeof(result),&searchCount);
1795 if (rc)
1796 {
1797 SetLastError(error2WinError(rc));
1798
1799 return FALSE;
1800 }
1801
1802 translateFindResults(&result,lpFindFileData);
1803
1804 return TRUE;
1805}
1806//******************************************************************************
1807//******************************************************************************
1808BOOL OSLibDosFindNextMulti(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1809{
1810 FILEFINDBUF3 *result,*data;
1811 ULONG searchCount = *count;
1812
1813 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1814 APIRET rc = DosFindNext((HDIR)hFindFile,result,searchCount*sizeof(FILEFINDBUF3),&searchCount);
1815 if (rc)
1816 {
1817 free(result);
1818 *count = 0;
1819 SetLastError(error2WinError(rc));
1820
1821 return FALSE;
1822 }
1823
1824 data = result;
1825 for (int x = 0;x < searchCount;x++)
1826 {
1827 translateFindResults(data,&lpFindFileData[x]);
1828 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1829 }
1830 free(result);
1831 *count = searchCount;
1832
1833 return TRUE;
1834}
1835//******************************************************************************
1836//******************************************************************************
1837BOOL OSLibDosFindClose(DWORD hFindFile)
1838{
1839 APIRET rc = DosFindClose((HDIR)hFindFile);
1840 if (rc)
1841 {
1842 SetLastError(error2WinError(rc));
1843
1844 return FALSE;
1845 }
1846
1847 return TRUE;
1848}
1849//******************************************************************************
1850#define FSATTACH_SIZE 256
1851//******************************************************************************
1852DWORD OSLibDosQueryVolumeFS(int drive, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
1853{
1854 PFSQBUFFER2 fsinfo = (PFSQBUFFER2) alloca(FSATTACH_SIZE);
1855 ULONG cb = FSATTACH_SIZE;
1856 char drv[3] = "A:";
1857 char *fsname;
1858 APIRET rc;
1859
1860 if(lpFileSystemNameBuffer == NULL) {
1861 DebugInt3();
1862 return ERROR_INVALID_PARAMETER_W;
1863 }
1864 drv[0] = (char)('A' + drive - 1);
1865
1866 DosError(FERR_DISABLEHARDERR);
1867 rc = DosQueryFSAttach(drv, 1, FSAIL_QUERYNAME, fsinfo, &cb);
1868 DosError(FERR_ENABLEHARDERR);
1869
1870 switch(rc) {
1871 case ERROR_INVALID_DRIVE:
1872 return ERROR_INVALID_DRIVE_W;
1873 case ERROR_NO_VOLUME_LABEL:
1874 return ERROR_NO_VOLUME_LABEL_W;
1875 case NO_ERROR:
1876 break;
1877 default:
1878 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1879 }
1880
1881 fsname = (char *)&fsinfo->szName[0] + fsinfo->cbName + 1;
1882
1883 /* @@@PH 2000/08/10 CMD.EXE querys with nFileSystemNameSize == 0
1884 * however does NOT expect to receive an error.
1885 */
1886 strncpy(lpFileSystemNameBuffer,
1887 fsname,
1888 nFileSystemNameSize);
1889 /*
1890 if(strlen(fsname) < nFileSystemNameSize) {
1891 strcpy(lpFileSystemNameBuffer, fsname);
1892 }
1893 else return ERROR_BUFFER_OVERFLOW_W;
1894 */
1895 return 0;
1896}
1897//******************************************************************************
1898typedef struct _FSINFOBUF
1899{
1900 ULONG ulVolser; /* Volume serial number */
1901 VOLUMELABEL vol; /* Volume lable */
1902} FSINFOBUF;
1903//******************************************************************************
1904DWORD OSLibDosQueryVolumeSerialAndName(int drive, LPDWORD lpVolumeSerialNumber,
1905 LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
1906{
1907 FSINFOBUF fsi;
1908 APIRET rc;
1909
1910 DosError(FERR_DISABLEHARDERR);
1911 rc = DosQueryFSInfo(drive, FSIL_VOLSER, &fsi, sizeof(fsi));
1912 DosError(FERR_ENABLEHARDERR);
1913
1914 switch(rc) {
1915 case ERROR_INVALID_DRIVE:
1916 return ERROR_INVALID_DRIVE_W;
1917 case ERROR_NO_VOLUME_LABEL:
1918 return ERROR_NO_VOLUME_LABEL_W;
1919 case NO_ERROR:
1920 break;
1921 default:
1922 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1923 }
1924
1925 if(lpVolumeSerialNumber) {
1926 *lpVolumeSerialNumber = fsi.ulVolser;
1927 }
1928 if(lpVolumeNameBuffer)
1929 {
1930 if(nVolumeNameSize > fsi.vol.cch) {
1931 strcpy(lpVolumeNameBuffer, (PCHAR)fsi.vol.szVolLabel);
1932 }
1933 else return ERROR_BUFFER_OVERFLOW_W;
1934 }
1935
1936 return ERROR_SUCCESS_W;
1937}
1938//******************************************************************************
1939//******************************************************************************
1940BOOL OSLibGetDiskFreeSpace(LPSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
1941 LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters,
1942 LPDWORD lpTotalNumberOfClusters)
1943{
1944 ULONG diskNum;
1945 FSALLOCATE fsAlloc;
1946 APIRET rc;
1947
1948 if(lpRootPathName == 0)
1949 diskNum = 0;
1950 else
1951 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z' )
1952 diskNum = *lpRootPathName - 'A' + 1;
1953 else
1954 if('a' <= *lpRootPathName && *lpRootPathName <= 'z' )
1955 diskNum = *lpRootPathName - 'a' + 1;
1956 else
1957 diskNum = 0;
1958
1959 DosError(FERR_DISABLEHARDERR);
1960 rc = DosQueryFSInfo(diskNum, FSIL_ALLOC, &fsAlloc, sizeof(fsAlloc));
1961 DosError(FERR_ENABLEHARDERR);
1962
1963 if(rc == 0)
1964 {
1965 *lpSectorsPerCluster = fsAlloc.cSectorUnit;
1966 *lpBytesPerSector = fsAlloc.cbSector;
1967 *lpNumberOfFreeClusters = fsAlloc.cUnitAvail;
1968 *lpTotalNumberOfClusters = fsAlloc.cUnit;
1969 SetLastError(ERROR_SUCCESS_W);
1970 return TRUE;
1971 }
1972 SetLastError(error2WinError(rc));
1973 return FALSE;
1974}
1975//******************************************************************************
1976//******************************************************************************
1977BOOL OSLibDosCreatePipe(PHANDLE phfRead,
1978 PHANDLE phfWrite,
1979 LPSECURITY_ATTRIBUTES lpsa,
1980 DWORD dwSize)
1981{
1982 APIRET rc;
1983
1984 dprintf(("DosCreatePipe(%08xh,%08xh,%08xh)\n",
1985 phfRead,
1986 phfWrite,
1987 dwSize));
1988
1989 // select default buffer size
1990 if (dwSize == 0)
1991 dwSize = 4096;
1992
1993 rc = DosCreatePipe(phfRead,
1994 phfWrite,
1995 dwSize);
1996 dprintf(("DosCreatePipe rc=%d",rc));
1997 if (rc)
1998 {
1999 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
2000 return -1; // INVALID_HANDLE_VALUE
2001 }
2002 return NO_ERROR;
2003}
Note: See TracBrowser for help on using the repository browser.