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

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

CloseHandle fix

File size: 57.7 KB
Line 
1/* $Id: oslibdos.cpp,v 1.30 2000-06-01 14:01:43 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 case OSLIB_SETPTR_FILE_CURRENT:
526 os2method = FILE_CURRENT;
527 break;
528 case OSLIB_SETPTR_FILE_BEGIN:
529 os2method = FILE_BEGIN ;
530 break;
531 case OSLIB_SETPTR_FILE_END:
532 os2method = FILE_END;
533 break;
534 default:
535 return OSLIB_ERROR_INVALID_PARAMETER;
536 }
537 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
538 if(rc) {
539 return -1;
540 }
541 else return newoffset;
542}
543//******************************************************************************
544//******************************************************************************
545BOOL OSLibDosDelete(char *lpszFileName)
546{
547 APIRET rc;
548
549 rc = DosDelete(lpszFileName);
550 if(rc) {
551 SetLastError(error2WinError(rc));
552 return FALSE;
553 }
554 return TRUE;
555}
556//******************************************************************************
557//******************************************************************************
558BOOL pmDateTimeToFileTime(FDATE *pDate,FTIME *pTime,FILETIME *pFT)
559{
560 USHORT dosTime, dosDate;
561
562 dosTime = *(USHORT*)pTime;
563 dosDate = *(USHORT*)pDate;
564
565 return DosDateTimeToFileTime(dosDate,dosTime,pFT);
566}
567//******************************************************************************
568//******************************************************************************
569#define NOT_NORMAL (FILE_ATTRIBUTE_READONLY_W | \
570 FILE_ATTRIBUTE_HIDDEN_W | \
571 FILE_ATTRIBUTE_SYSTEM_W | \
572 FILE_ATTRIBUTE_ARCHIVE_W)
573
574inline DWORD pm2WinFileAttributes(DWORD attrFile)
575{
576 DWORD res = 0;
577
578 if (!(attrFile & NOT_NORMAL))
579 res |= FILE_ATTRIBUTE_NORMAL_W;
580 if (attrFile & FILE_READONLY)
581 res |= FILE_ATTRIBUTE_READONLY_W;
582 if (attrFile & FILE_HIDDEN)
583 res |= FILE_ATTRIBUTE_HIDDEN_W;
584 if (attrFile & FILE_SYSTEM)
585 res |= FILE_ATTRIBUTE_SYSTEM_W;
586 if (attrFile & FILE_DIRECTORY)
587 res |= FILE_ATTRIBUTE_DIRECTORY_W;
588 if (attrFile & FILE_ARCHIVED)
589 res |= FILE_ATTRIBUTE_ARCHIVE_W;
590
591 //CB: not used: FILE_ATTRIBUTE_COMPRESSED_W
592
593 return res;
594}
595//******************************************************************************
596//******************************************************************************
597BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
598 ULONG ulDummy,
599 PVOID pBuffer)
600{
601 APIRET rc; /* API return code */
602 FILESTATUS3 fs3; /* file information structure */
603 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
604
605 // Note: we only handle standard "GetFileExInfoStandard" requests
606 rc = DosQueryPathInfo(pszName, /* query the file information */
607 FIL_STANDARD,
608 &fs3,
609 sizeof(fs3));
610 if (rc != NO_ERROR) /* check for errors */
611 return FALSE; /* raise error condition */
612
613 // convert structure
614 lpFad->dwFileAttributes = pm2WinFileAttributes(fs3.attrFile);
615 pmDateTimeToFileTime(&fs3.fdateCreation, &fs3.ftimeCreation, &lpFad->ftCreationTime);
616 pmDateTimeToFileTime(&fs3.fdateLastAccess, &fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
617 pmDateTimeToFileTime(&fs3.fdateLastWrite, &fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
618
619 /* @@@PH we might add Aurora support ...
620 lpFad->nFileSizeHigh = info.nFileSizeHigh;
621 */
622 lpFad->nFileSizeHigh = 0;
623 lpFad->nFileSizeLow = fs3.cbFile;
624
625 return TRUE;
626}
627//******************************************************************************
628DWORD WIN32API GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD );
629//******************************************************************************
630DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
631 DWORD length_fullname)
632{
633 switch(cmd) {
634 case OSLIB_SEARCHDIR:
635 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
636 name, full_name, length_fullname) != 0) {
637 return 0;
638 }
639 return strlen(full_name);
640
641
642 case OSLIB_SEARCHCURDIR:
643 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
644 name, full_name, length_fullname) != 0) {
645 return 0;
646 }
647 return strlen(full_name);
648
649 case OSLIB_SEARCHFILE:
650 {
651 FILESTATUS3 fileinfo;
652
653 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
654 return 0;
655 }
656 strncpy(full_name, name, length_fullname);
657 return strlen(full_name);
658 }
659
660 case OSLIB_SEARCHENV:
661 {
662 LPSTR envstring;
663 int envsize;
664 CHAR szResult[CCHMAXPATH];
665
666 envsize = GetEnvironmentVariableA(path, NULL, 0);
667 envstring = (LPSTR)malloc(envsize+1);
668 GetEnvironmentVariableA(path, envstring, envsize);
669 if(DosSearchPath(SEARCH_IGNORENETERRS, envstring,
670 name, szResult, sizeof(szResult)) != 0) {
671 free(envstring);
672 return 0;
673 }
674 free(envstring);
675 strcpy(full_name, szResult);
676 return strlen(full_name);
677 }
678 }
679 return 0;
680}
681//******************************************************************************
682//******************************************************************************
683APIRET OSLibDosQueryPathInfo(PSZ pszPathName,
684 ULONG ulInfoLevel,
685 PVOID pInfoBuf,
686 ULONG cbInfoBuf)
687{
688 APIRET rc = DosQueryPathInfo( pszPathName, ulInfoLevel,
689 pInfoBuf, cbInfoBuf );
690
691 if(rc == ERROR_TOO_MANY_OPEN_FILES)
692 {
693 LONG reqCount = 2;
694 ULONG maxFiles;
695
696 if(DosSetRelMaxFH(&reqCount, &maxFiles) == NO_ERROR)
697 rc = DosQueryPathInfo(pszPathName, ulInfoLevel,
698 pInfoBuf, cbInfoBuf );
699 }
700 return rc;
701}
702//******************************************************************************
703//******************************************************************************
704DWORD OSLibDosCreateFile(CHAR *lpszFile,
705 DWORD fuAccess,
706 DWORD fuShare,
707 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
708 DWORD fuCreate,
709 DWORD fuAttrFlags,
710 HANDLE hTemplateFile)
711{
712 HFILE hFile;
713 ULONG actionTaken = 0;
714 ULONG fileSize = 0;
715 ULONG fileAttr = FILE_NORMAL;
716 ULONG openFlag = 0;
717 ULONG openMode = 0;
718 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;;
719
720 //TODO: lpSecurityAttributes (inheritance)
721
722 if(fuAttrFlags & FILE_ATTRIBUTE_ARCHIVE_W)
723 fileAttr |= FILE_ARCHIVED;
724 if(fuAttrFlags & FILE_ATTRIBUTE_HIDDEN_W)
725 fileAttr |= FILE_HIDDEN;
726 if(fuAttrFlags & FILE_ATTRIBUTE_SYSTEM_W)
727 fileAttr |= FILE_SYSTEM;
728 if(fuAttrFlags & FILE_ATTRIBUTE_READONLY_W)
729 fileAttr |= FILE_READONLY;
730 // TODO: FILE_ATTRIBUTE_TEMPORARY_W
731
732 switch(fuCreate)
733 {
734 case CREATE_NEW_W:
735 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
736 break;
737 case CREATE_ALWAYS_W:
738 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
739 break;
740 case OPEN_EXISTING_W:
741 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
742 break;
743 case OPEN_ALWAYS_W:
744 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
745 break;
746 case TRUNCATE_EXISTING_W:
747 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
748 break;
749 }
750
751 if(fuAttrFlags & FILE_FLAG_WRITE_THROUGH_W) openMode |= OPEN_FLAGS_WRITE_THROUGH;
752 if(fuAttrFlags & FILE_FLAG_NO_BUFFERING_W) openMode |= OPEN_FLAGS_NO_CACHE;
753 if(fuAttrFlags & FILE_FLAG_RANDOM_ACCESS_W) openMode |= OPEN_FLAGS_RANDOM;
754 if(fuAttrFlags & FILE_FLAG_SEQUENTIAL_SCAN_W) openMode |= OPEN_FLAGS_SEQUENTIAL;
755 // TODO: FILE_FLAG_BACKUP_SEMANTICS_W
756 // FILE_FLAG_POSIX_SEMANTICS_W are not supported
757
758 if(fuShare == 0)
759 openMode |= OPEN_SHARE_DENYREADWRITE;
760 else
761 if(fuShare == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
762 openMode |= OPEN_SHARE_DENYNONE;
763 else
764 if(fuShare & FILE_SHARE_READ_W)
765 openMode |= OPEN_SHARE_DENYWRITE;
766 else
767 if(fuShare & FILE_SHARE_WRITE_W)
768 openMode |= OPEN_SHARE_DENYREAD;
769
770 if(fuAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
771 openMode |= OPEN_ACCESS_READWRITE;
772 else
773 if(fuAccess & GENERIC_READ_W)
774 openMode |= OPEN_ACCESS_READONLY;
775 else
776 if(fuAccess & GENERIC_WRITE_W)
777 openMode |= OPEN_ACCESS_WRITEONLY;
778
779 int retry = 0;
780 while(retry < 2)
781 {
782 rc = DosOpen((PSZ)lpszFile,
783 &hFile,
784 &actionTaken,
785 fileSize,
786 fileAttr,
787 openFlag,
788 openMode,
789 NULL);
790 if(rc == ERROR_TOO_MANY_OPEN_FILES)
791 {
792 ULONG CurMaxFH;
793 LONG ReqCount = 32;
794
795 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
796 if(rc) {
797 dprintf(("DosSetRelMaxFH returned %d", rc));
798 SetLastError(ERROR_TOO_MANY_OPEN_FILES_W);
799 return INVALID_HANDLE_VALUE_W;
800 }
801 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
802 }
803 else break;
804 retry++;
805 }
806
807 if(rc)
808 {
809 SetLastError(error2WinError(rc));
810 return INVALID_HANDLE_VALUE_W;
811 }
812 SetLastError(ERROR_SUCCESS_W);
813 return hFile;
814}
815//******************************************************************************
816//******************************************************************************
817DWORD OSLibDosOpenFile(CHAR *lpszFile, UINT fuMode)
818{
819 ULONG actionTaken = 0;
820 ULONG fileSize = 0;
821 ULONG fileAttr = FILE_NORMAL;
822 ULONG openFlag = 0;
823 ULONG openMode = 0;
824 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;
825 HFILE hFile;
826
827 if(!(fuMode & (OF_CREATE_W | OF_READWRITE_W | OF_WRITE_W)))
828 {
829 openMode |= OPEN_ACCESS_READONLY;
830 openFlag |= OPEN_ACTION_OPEN_IF_EXISTS;
831 }
832 else
833 {
834 if(fuMode & OF_CREATE_W) {
835 openFlag |= OPEN_ACTION_CREATE_IF_NEW |
836 OPEN_ACTION_REPLACE_IF_EXISTS;
837 }
838 else openFlag |= OPEN_ACTION_OPEN_IF_EXISTS; //180575
839
840 if(fuMode & OF_READWRITE_W)
841 openMode |= OPEN_ACCESS_READWRITE;
842 else
843 if(fuMode & OF_WRITE_W)
844 openMode |= OPEN_ACCESS_WRITEONLY;
845 else
846 if(fuMode & OF_CREATE_W)
847 openMode |= OPEN_ACCESS_READWRITE;
848 }
849
850 if((fuMode & OF_SHARE_DENY_WRITE_W) ||
851 !(fuMode & (OF_SHARE_DENY_READ_W | OF_SHARE_DENY_NONE_W | OF_SHARE_EXCLUSIVE_W)))
852 openMode |= OPEN_SHARE_DENYWRITE;
853 else
854 if (fuMode & OF_SHARE_DENY_NONE_W)
855 openMode |= OPEN_SHARE_DENYNONE;
856 else
857 if (fuMode & OF_SHARE_DENY_READ_W)
858 openMode |= OPEN_SHARE_DENYREAD;
859 else
860 if (fuMode & OF_SHARE_EXCLUSIVE_W)
861 openMode |= OPEN_SHARE_DENYREADWRITE;
862
863 rc = DosOpen((PSZ)lpszFile,
864 &hFile,
865 &actionTaken,
866 fileSize,
867 fileAttr,
868 openFlag,
869 openMode,
870 NULL);
871
872 if(rc != NO_ERROR)
873 {
874 if(fuMode & OF_EXIST_W)
875 {
876 if(rc == ERROR_OPEN_FAILED || rc == ERROR_FILE_NOT_FOUND)
877 {
878 SetLastError(ERROR_FILE_NOT_FOUND_W);
879 return HFILE_ERROR_W;
880 }
881 }
882 if((rc == ERROR_OPEN_FAILED) && (openFlag & OPEN_ACTION_OPEN_IF_EXISTS))
883 {
884 SetLastError(ERROR_FILE_NOT_FOUND_W);
885 }
886 else SetLastError(error2WinError(rc));
887
888 return HFILE_ERROR_W;
889 }
890 SetLastError(ERROR_SUCCESS_W);
891 return hFile;
892}
893//******************************************************************************
894//******************************************************************************
895BOOL OSLibDosLockFile(DWORD hFile, DWORD dwFlags,
896 DWORD OffsetLow, DWORD OffsetHigh,
897 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
898 LPOVERLAPPED lpOverlapped)
899{
900 APIRET rc;
901
902 // Set 5 secs timeout for locking file and no other can access this
903 // file region
904
905 if(lpOverlapped) {//TODO:
906 dprintf(("OSLibDosLockFile: overlapped lock not yet implemented!!"));
907 }
908 //TODO: Locking region crossing end of file is permitted. Works in OS/2??
909 if(f64BitIO)
910 {
911 FILELOCKL lockRangeL;
912
913 lockRangeL.lOffset.ulLo = OffsetLow;
914 lockRangeL.lOffset.ulHi = OffsetHigh;
915 lockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
916 lockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
917
918 rc = OdinDosSetFileLocksL(hFile, NULL, &lockRangeL,
919 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
920 }
921 else
922 {
923 FILELOCK lockRange = { OffsetLow, nNumberOfBytesToLockLow };
924
925 rc = DosSetFileLocks(hFile, NULL, &lockRange,
926 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
927 }
928 if(rc) {
929 SetLastError(error2WinError(rc));
930 return FALSE;
931 }
932 SetLastError(ERROR_SUCCESS_W);
933 return TRUE;
934}
935//******************************************************************************
936//******************************************************************************
937BOOL OSLibDosUnlockFile(DWORD hFile, DWORD OffsetLow, DWORD OffsetHigh,
938 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
939 LPOVERLAPPED lpOverlapped)
940{
941 APIRET rc;
942
943 // Set 5 secs timeout for unlocking file and no other can access this
944 // file region
945
946 if(lpOverlapped) {//TODO:
947 dprintf(("OSLibDosUnlockFile: overlapped unlock not yet implemented!!"));
948 }
949 if(f64BitIO)
950 {
951 FILELOCKL unlockRangeL;
952
953 unlockRangeL.lOffset.ulLo = OffsetLow;
954 unlockRangeL.lOffset.ulHi = OffsetHigh;
955 unlockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
956 unlockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
957
958 rc = OdinDosSetFileLocksL(hFile, &unlockRangeL, NULL, 5000, 0);
959 }
960 else
961 {
962 FILELOCK unlockRange = { OffsetLow, nNumberOfBytesToLockLow };
963
964 rc = DosSetFileLocks(hFile, &unlockRange, NULL, 5000, 0);
965 }
966 if(rc) {
967 SetLastError(error2WinError(rc));
968 return FALSE;
969 }
970 SetLastError(ERROR_SUCCESS_W);
971 return TRUE;
972}
973//******************************************************************************
974//******************************************************************************
975BOOL OSLibDosFlushFileBuffers(DWORD hFile)
976{
977 APIRET rc;
978
979 rc = DosResetBuffer(hFile);
980 SetLastError(error2WinError(rc));
981 return (rc == NO_ERROR);
982}
983//******************************************************************************
984//******************************************************************************
985DWORD OSLibDosGetFileSize(DWORD hFile, LPDWORD lpdwFileSizeHigh)
986{
987 APIRET rc;
988 ULONG sizeLow;
989
990 if(f64BitIO)
991 {
992 FILESTATUS3L fsts3ConfigInfoL = {{0}};
993 ULONG ulBufSize = sizeof(FILESTATUS3L);
994
995 rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &fsts3ConfigInfoL, ulBufSize);
996 if(lpdwFileSizeHigh) {
997 *lpdwFileSizeHigh = fsts3ConfigInfoL.cbFile.ulHi;
998 }
999 sizeLow = fsts3ConfigInfoL.cbFile.ulLo;
1000 }
1001 else
1002 {
1003 FILESTATUS3 fsts3ConfigInfo = {{0}};
1004 ULONG ulBufSize = sizeof(FILESTATUS3);
1005
1006 if(lpdwFileSizeHigh) {
1007 *lpdwFileSizeHigh = 0;
1008 }
1009 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
1010 sizeLow = fsts3ConfigInfo.cbFile;
1011 }
1012 if(rc) {
1013 SetLastError(error2WinError(rc));
1014 return -1;
1015 }
1016 SetLastError(ERROR_SUCCESS_W);
1017 return sizeLow;
1018}
1019//******************************************************************************
1020//******************************************************************************
1021DWORD OSLibDosSetFilePointer(DWORD hFile, DWORD OffsetLow, DWORD *OffsetHigh, DWORD method)
1022{
1023 LONGLONG offsetL;
1024 LONGLONG newoffsetL;
1025 APIRET rc;
1026 DWORD newoffset;
1027
1028 switch(method) {
1029 case FILE_BEGIN_W:
1030 method = FILE_BEGIN;
1031 break;
1032
1033 case FILE_CURRENT_W:
1034 method = FILE_CURRENT;
1035 break;
1036
1037 case FILE_END_W:
1038 method = FILE_END;
1039 break;
1040 }
1041 if(f64BitIO) {
1042 offsetL.ulLo = OffsetLow;
1043 offsetL.ulHi = (OffsetHigh) ? *OffsetHigh : 0;
1044 rc = OdinDosSetFilePtrL(hFile, offsetL, method, &newoffsetL);
1045 if(OffsetHigh) {
1046 *OffsetHigh = newoffsetL.ulHi;
1047 }
1048 newoffset = newoffsetL.ulLo;
1049 }
1050 else rc = DosSetFilePtr(hFile, OffsetLow, method, &newoffset);
1051 if(rc) {
1052 SetLastError(error2WinError(rc));
1053 return -1;
1054 }
1055 SetLastError(ERROR_SUCCESS_W);
1056 return newoffset;
1057}
1058//******************************************************************************
1059//******************************************************************************
1060BOOL OSLibDosSetEndOfFile(DWORD hFile)
1061{
1062 ULONG newFilePos;
1063 LONGLONG FilePosL = {0,0};
1064 LONGLONG newFilePosL;
1065 APIRET rc;
1066
1067 if(f64BitIO) {
1068 rc = OdinDosSetFilePtrL(hFile, FilePosL, FILE_CURRENT, &newFilePosL);
1069 if(rc == 0) {
1070 rc = OdinDosSetFileSizeL(hFile, newFilePosL);
1071 }
1072 }
1073 else {
1074 rc = DosSetFilePtr(hFile, 0, FILE_CURRENT, &newFilePos);
1075 if(rc == 0) {
1076 rc = DosSetFileSize(hFile, newFilePos);
1077 }
1078 }
1079 if(rc) {
1080 SetLastError(error2WinError(rc));
1081 return FALSE;
1082 }
1083 SetLastError(ERROR_SUCCESS_W);
1084 return TRUE;
1085}
1086//******************************************************************************
1087//******************************************************************************
1088BOOL OSLibDosGetFileInformationByHandle(DWORD hFile, BY_HANDLE_FILE_INFORMATION* pInfo)
1089{
1090 APIRET rc;
1091
1092 if(f64BitIO)
1093 {
1094 FILESTATUS4L statusL = { 0 };
1095
1096 rc = DosQueryFileInfo(hFile,
1097 FIL_QUERYEASIZEL,
1098 &statusL,
1099 sizeof(statusL));
1100 if(rc == NO_ERROR)
1101 {
1102 pInfo->dwFileAttributes = 0;
1103 if(!(statusL.attrFile & NOT_NORMAL))
1104 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1105 if(statusL.attrFile & FILE_READONLY)
1106 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1107 if(statusL.attrFile & FILE_HIDDEN)
1108 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1109 if(statusL.attrFile & FILE_SYSTEM)
1110 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1111 if(statusL.attrFile & FILE_DIRECTORY)
1112 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1113 if(statusL.attrFile & FILE_ARCHIVED)
1114 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1115
1116 pmDateTimeToFileTime(&statusL.fdateCreation,
1117 &statusL.ftimeCreation,
1118 &pInfo->ftCreationTime);
1119 pmDateTimeToFileTime(&statusL.fdateLastAccess,
1120 &statusL.ftimeLastAccess,
1121 &pInfo->ftLastAccessTime);
1122 pmDateTimeToFileTime(&statusL.fdateLastWrite,
1123 &statusL.ftimeLastWrite,
1124 &pInfo->ftLastWriteTime);
1125
1126 pInfo->nFileSizeHigh = statusL.cbFile.ulHi;
1127 pInfo->nFileSizeLow = statusL.cbFile.ulLo;
1128 pInfo->dwVolumeSerialNumber = 0; //todo
1129 pInfo->nNumberOfLinks = 1;
1130 pInfo->nFileIndexHigh = 0;
1131 pInfo->nFileIndexLow = 0;
1132 }
1133 }
1134 else
1135 {
1136 FILESTATUS4 status = { 0 };
1137
1138 rc = DosQueryFileInfo(hFile,
1139 FIL_QUERYEASIZE,
1140 &status,
1141 sizeof(status));
1142 if(rc == NO_ERROR)
1143 {
1144 pInfo->dwFileAttributes = 0;
1145 if(!(status.attrFile & NOT_NORMAL))
1146 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1147 if(status.attrFile & FILE_READONLY)
1148 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1149 if(status.attrFile & FILE_HIDDEN)
1150 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1151 if(status.attrFile & FILE_SYSTEM)
1152 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1153 if(status.attrFile & FILE_DIRECTORY)
1154 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1155 if(status.attrFile & FILE_ARCHIVED)
1156 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1157
1158 pmDateTimeToFileTime(&status.fdateCreation,
1159 &status.ftimeCreation,
1160 &pInfo->ftCreationTime);
1161 pmDateTimeToFileTime(&status.fdateLastAccess,
1162 &status.ftimeLastAccess,
1163 &pInfo->ftLastAccessTime);
1164 pmDateTimeToFileTime(&status.fdateLastWrite,
1165 &status.ftimeLastWrite,
1166 &pInfo->ftLastWriteTime);
1167
1168 pInfo->nFileSizeHigh = 0;
1169 pInfo->nFileSizeLow = status.cbFile;
1170 pInfo->dwVolumeSerialNumber = 0; //todo
1171 pInfo->nNumberOfLinks = 1;
1172 pInfo->nFileIndexHigh = 0;
1173 pInfo->nFileIndexLow = 0;
1174 }
1175 }
1176 if(rc) {
1177 SetLastError(error2WinError(rc));
1178 return FALSE;
1179 }
1180 SetLastError(ERROR_SUCCESS_W);
1181 return TRUE;
1182}
1183//******************************************************************************
1184//******************************************************************************
1185BOOL OSLibDosSetFileTime(DWORD hFile, WORD creationdate, WORD creationtime,
1186 WORD lastaccessdate, WORD lastaccesstime,
1187 WORD lastwritedate, WORD lastwritetime)
1188{
1189 FILESTATUS3 fileInfo;
1190 APIRET rc;
1191
1192 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1193
1194 if(rc == NO_ERROR)
1195 {
1196 if(creationdate && creationtime) {
1197 fileInfo.fdateCreation = *(FDATE *)&creationdate;
1198 fileInfo.ftimeCreation = *(FTIME *)&creationtime;
1199 }
1200 if(lastaccessdate && lastaccesstime) {
1201 fileInfo.fdateLastAccess = *(FDATE *)&lastaccessdate;
1202 fileInfo.ftimeLastAccess = *(FTIME *)&lastaccesstime;
1203 }
1204 if(lastwritedate && lastwritetime) {
1205 fileInfo.fdateLastWrite = *(FDATE *)&lastwritedate;
1206 fileInfo.ftimeLastWrite = *(FTIME *)&lastwritetime;
1207 }
1208
1209 rc = DosSetFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1210 }
1211
1212 if(rc)
1213 {
1214 SetLastError(error2WinError(rc));
1215 return FALSE;
1216 }
1217 SetLastError(ERROR_SUCCESS_W);
1218 return TRUE;
1219}
1220//******************************************************************************
1221//******************************************************************************
1222BOOL OSLibDosGetFileTime(DWORD hFile, WORD *creationdate, WORD *creationtime,
1223 WORD *lastaccessdate, WORD *lastaccesstime,
1224 WORD *lastwritedate, WORD *lastwritetime)
1225{
1226 FILESTATUS3 fileInfo;
1227 APIRET rc;
1228
1229 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1230
1231 if(rc == NO_ERROR)
1232 {
1233 *creationdate = *(WORD *)&fileInfo.fdateCreation;
1234 *creationtime = *(WORD *)&fileInfo.ftimeCreation;
1235 *lastaccessdate = *(WORD *)&fileInfo.fdateLastAccess;
1236 *lastaccesstime = *(WORD *)&fileInfo.ftimeLastAccess;
1237 *lastwritedate = *(WORD *)&fileInfo.fdateLastWrite;
1238 *lastwritetime = *(WORD *)&fileInfo.ftimeLastWrite;
1239 }
1240
1241 if(rc)
1242 {
1243 SetLastError(error2WinError(rc));
1244 return FALSE;
1245 }
1246 SetLastError(ERROR_SUCCESS_W);
1247 return TRUE;
1248}
1249//******************************************************************************
1250//******************************************************************************
1251DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
1252{
1253 DWORD newoffset;
1254 APIRET rc;
1255
1256
1257 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
1258 if(rc) {
1259 dprintf(("DosSetFilePtr Error rc:%d", rc));
1260 return -1;
1261 }
1262 else return newoffset;
1263}
1264//******************************************************************************
1265//******************************************************************************
1266DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
1267{
1268 *hNew = -1;
1269 return DosDupHandle(hFile, hNew);
1270}
1271//******************************************************************************
1272//******************************************************************************
1273void OSLibDosDisableHardError(BOOL fTurnOff)
1274{
1275 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
1276}
1277//******************************************************************************
1278//Returns time spent in kernel & user mode in milliseconds
1279//******************************************************************************
1280BOOL OSLibDosQueryProcTimes(DWORD procid, ULONG *kerneltime, ULONG *usertime)
1281{
1282 APIRET rc;
1283 char *buf;
1284 ULONG size;
1285 ULONG nrthreads = 4;
1286
1287tryagain:
1288 size = sizeof(QTOPLEVEL)+sizeof(QGLOBAL)+sizeof(QPROCESS) + nrthreads*sizeof(QTHREAD);
1289 buf = (char *)malloc(size);
1290 rc = DosQuerySysState(0x1, RESERVED, procid, RESERVED, (PCHAR)buf, size);
1291
1292 if(rc) {
1293 free(buf);
1294 if(rc == ERROR_BUFFER_OVERFLOW) {
1295 nrthreads += 4;
1296 goto tryagain;
1297 }
1298 return FALSE;
1299 }
1300 PQTOPLEVEL top = (PQTOPLEVEL)buf;
1301
1302 *kerneltime = 0;
1303 *usertime = 0;
1304 for(int i=0;i<top->procdata->threadcnt;i++) {
1305 *kerneltime += top->procdata->threads[i].systime;
1306 *usertime += top->procdata->threads[i].usertime;
1307 }
1308 free(buf);
1309 return TRUE;
1310}
1311//******************************************************************************
1312//******************************************************************************
1313// TODO: implement SecurityAttributes parameter
1314DWORD OSLibDosCreateNamedPipe(LPCTSTR lpName,
1315 DWORD dwOpenMode,
1316 DWORD dwPipeMode,
1317 DWORD nMaxInstances,
1318 DWORD nOutBufferSize,
1319 DWORD nInBufferSize,
1320 DWORD nDefaultTimeOut,
1321 void* lpSecurityAttributes)
1322{ DWORD dwOS2Mode = 0;
1323 DWORD dwOS2PipeMode = 0;
1324 LPSTR lpOS2Name;
1325 DWORD hPipe;
1326 DWORD rc;
1327
1328 if (dwOpenMode & PIPE_ACCESS_DUPLEX_W)
1329 dwOS2Mode |= NP_ACCESS_DUPLEX;
1330 else
1331 if (dwOpenMode & PIPE_ACCESS_INBOUND_W)
1332 dwOS2Mode |= NP_ACCESS_INBOUND;
1333 else
1334 if (dwOpenMode & PIPE_ACCESS_OUTBOUND_W)
1335 dwOS2Mode |= NP_ACCESS_OUTBOUND;
1336 // TODO:
1337 // if(dwOpenMode & FILE_FLAG_OVERLAPPED)
1338 // if(dwOpenMode & WRITE_DAC)
1339 // if(dwOpenMode & WRITE_OWNER)
1340 // if(dwOpenMode & ACCESS_SYSTEM_SECURITY)
1341 if(dwOpenMode & FILE_FLAG_WRITE_THROUGH_W)
1342 dwOS2Mode |= NP_WRITEBEHIND; // FIXME: I'm not sure!
1343
1344 if (dwPipeMode & PIPE_WAIT_W)
1345 dwOS2PipeMode |= NP_WAIT;
1346 if (dwPipeMode & PIPE_NOWAIT_W)
1347 dwOS2PipeMode |= NP_NOWAIT;
1348 if (dwPipeMode & PIPE_READMODE_BYTE_W)
1349 dwOS2PipeMode |= NP_READMODE_BYTE;
1350 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
1351 dwOS2PipeMode |= NP_READMODE_MESSAGE;
1352 if (dwPipeMode & PIPE_TYPE_BYTE_W)
1353 dwOS2PipeMode |= NP_TYPE_BYTE;
1354 if (dwPipeMode & PIPE_TYPE_MESSAGE_W)
1355 dwOS2PipeMode |= NP_TYPE_MESSAGE;
1356
1357 if (nMaxInstances>0xff)
1358 {
1359 SetLastError(ERROR_INVALID_PARAMETER_W); // ERROR_INVALID_PARAMETER
1360 return -1; // INVALID_HANDLE_VALUE
1361 }
1362 dwOS2PipeMode |= nMaxInstances;
1363
1364 if (strstr(lpName,"\\\\."))
1365 {
1366 // If pipe is created on the local machine
1367 // we must delete string \\. because
1368 // in Windows named pipes scheme is a \\.\PIPE\pipename
1369 // but in OS/2 only \PIPE\pipename
1370 lpOS2Name = (LPSTR)lpName + 3;
1371 }
1372 else lpOS2Name = (LPSTR)lpName;
1373
1374 dprintf(("DosCreateNPipe(%s,%x,%x,%x,%x,%x)",lpOS2Name,dwOS2Mode,dwOS2PipeMode,nInBufferSize,nOutBufferSize,nDefaultTimeOut));
1375 rc=DosCreateNPipe(lpOS2Name,
1376 &hPipe,
1377 dwOS2Mode,
1378 dwOS2PipeMode,
1379 nInBufferSize,
1380 nInBufferSize,
1381 nDefaultTimeOut); // Timeouts must be tested!
1382
1383 dprintf(("DosCreateNPipe rc=%d",rc));
1384 if (rc)
1385 {
1386 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
1387 return -1; // INVALID_HANDLE_VALUE
1388 }
1389 return hPipe;
1390}
1391
1392//******************************************************************************
1393//******************************************************************************
1394// TODO: implement lpOverlapped parameter!
1395BOOL OSLibDosConnectNamedPipe(DWORD hNamedPipe, LPOVERLAPPED lpOverlapped)
1396{
1397 DWORD rc;
1398
1399 rc=DosConnectNPipe(hNamedPipe);
1400 dprintf(("DosConnectNPipe rc=%d",rc));
1401
1402 if (!rc) return (TRUE);
1403 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1404
1405 return (FALSE);
1406}
1407
1408//******************************************************************************
1409//******************************************************************************
1410BOOL OSLibDosCallNamedPipe( LPCTSTR lpNamedPipeName,
1411 LPVOID lpInBuffer,
1412 DWORD nInBufferSize,
1413 LPVOID lpOutBuffer,
1414 DWORD nOutBufferSize,
1415 LPDWORD lpBytesRead,
1416 DWORD nTimeOut )
1417{
1418 LPSTR lpOS2Name;
1419 DWORD rc;
1420
1421 if (strstr(lpNamedPipeName,"\\\\."))
1422 {
1423 // If pipe is created on the local machine
1424 // we must delete string \\. because
1425 // in Windows named pipes scheme is a \\.\PIPE\pipename
1426 // but in OS/2 only \PIPE\pipename
1427 lpOS2Name = (LPSTR)lpNamedPipeName + 3;
1428 }
1429 else lpOS2Name = (LPSTR)lpNamedPipeName;
1430
1431 rc=DosCallNPipe(lpOS2Name,
1432 lpInBuffer,
1433 nInBufferSize,
1434 lpOutBuffer,
1435 nOutBufferSize,
1436 lpBytesRead,
1437 nTimeOut );
1438
1439
1440 if (!rc) return (TRUE);
1441 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1442
1443 return (FALSE);
1444}
1445
1446//******************************************************************************
1447//******************************************************************************
1448BOOL OSLibDosTransactNamedPipe( DWORD hNamedPipe,
1449 LPVOID lpInBuffer,
1450 DWORD nInBufferSize,
1451 LPVOID lpOutBuffer,
1452 DWORD nOutBufferSize,
1453 LPDWORD lpBytesRead,
1454 LPOVERLAPPED lpOverlapped)
1455{
1456 DWORD rc;
1457
1458 rc=DosTransactNPipe(hNamedPipe,
1459 lpOutBuffer,
1460 nOutBufferSize,
1461 lpInBuffer,
1462 nInBufferSize,
1463 lpBytesRead);
1464
1465 dprintf(("DosTransactNPipe returned rc=%d");)
1466 if (!rc) return (TRUE);
1467 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1468
1469 return (FALSE);
1470}
1471
1472//******************************************************************************
1473//******************************************************************************
1474BOOL OSLibDosPeekNamedPipe(DWORD hPipe,
1475 LPVOID lpvBuffer,
1476 DWORD cbBuffer,
1477 LPDWORD lpcbRead,
1478 LPDWORD lpcbAvail,
1479 LPDWORD lpcbMessage)
1480{
1481 DWORD rc;
1482 AVAILDATA availData ={0};
1483 ULONG ulDummy;
1484
1485 rc=DosPeekNPipe(hPipe,lpvBuffer,cbBuffer,lpcbRead,&availData,&ulDummy);
1486
1487 dprintf(("DosPeekNPipe returned rc=%d",rc));
1488
1489 if (!rc)
1490 {
1491 *lpcbAvail = availData.cbpipe;
1492 *lpcbMessage = availData.cbmessage;
1493 return (TRUE);
1494 }
1495 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1496
1497 return (FALSE);
1498}
1499//******************************************************************************
1500//******************************************************************************
1501BOOL OSLibDosDisconnectNamedPipe(DWORD hPipe)
1502{
1503 DWORD rc;
1504
1505 rc=DosDisConnectNPipe(hPipe);
1506
1507 dprintf(("DosDisConnectNPipe returned rc=%d",rc));
1508
1509 if (!rc) return TRUE;
1510 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1511
1512 return (FALSE);
1513}
1514//******************************************************************************
1515//******************************************************************************
1516BOOL OSLibDosWaitNamedPipe(LPCSTR lpszNamedPipeName,
1517 DWORD dwTimeout)
1518{
1519 LPSTR lpOS2Name;
1520 DWORD rc;
1521
1522 if (strstr(lpszNamedPipeName,"\\\\."))
1523 {
1524 // If pipe is created on the local machine
1525 // we must delete string \\. because
1526 // in Windows named pipes scheme is a \\.\PIPE\pipename
1527 // but in OS/2 only \PIPE\pipename
1528 lpOS2Name = (LPSTR)lpszNamedPipeName + 3;
1529 }
1530 else lpOS2Name = (LPSTR)lpszNamedPipeName;
1531
1532 rc=DosWaitNPipe(lpOS2Name,dwTimeout);
1533
1534 dprintf(("DosWaitNPipe returned rc=%d",rc));
1535
1536 if (!rc) return TRUE;
1537 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1538
1539 return (FALSE);
1540}
1541//******************************************************************************
1542//******************************************************************************
1543BOOL isRoot(CHAR* name)
1544{
1545 if (name[1] == ':')
1546 {
1547 //local name (x:\)
1548 return (name[2] == 0) || !strchr(&name[3],'\\');
1549 } else if (name[0] == '\\')
1550 {
1551 //UNC name (\\resource\drive\)
1552 CHAR *drive,*dir;
1553
1554 drive = strchr(&name[2],'\\');
1555 if (!drive) return FALSE;
1556 dir = strchr(&drive[1],'\\');
1557 if (!dir) return TRUE;
1558 return !strchr(&dir[1],'\\');
1559 } else return FALSE; //unknown
1560}
1561//******************************************************************************
1562//******************************************************************************
1563inline CHAR system2DOSCharacter(CHAR ch)
1564{
1565 switch(ch)
1566 {
1567 case ' ':
1568 case '.':
1569 case '~':
1570 return '_';
1571
1572 default:
1573 return toupper(ch);
1574 }
1575}
1576
1577VOID long2ShortName(CHAR* longName,CHAR* shortName)
1578{
1579 INT x;
1580 CHAR *source = longName,*dest = shortName,*ext = strrchr(longName,'.');
1581
1582 if ((strcmp(longName,".") == 0) || (strcmp(longName,"..") == 0))
1583 {
1584 strcpy(shortName,longName);
1585 return;
1586 }
1587
1588 //CB: quick and dirty, real FILE~12.EXT is too slow
1589
1590 //8 character file name
1591 for (x = 0;x < 8;x++)
1592 {
1593 if ((source == ext) || (source[0] == 0)) break;
1594 dest[0] = system2DOSCharacter(source[0]);
1595 source++;
1596 dest++;
1597 }
1598
1599 if (source[0] == 0)
1600 {
1601 dest[0] = 0;
1602 return;
1603 }
1604
1605 if (source != ext)
1606 {
1607 //longName > 8 characters, insert ~1
1608 shortName[6] = '~';
1609 shortName[7] = '1';
1610 }
1611
1612 if (ext)
1613 {
1614 //add extension, 3 characters
1615 dest[0] = ext[0];
1616 dest++;
1617 ext++;
1618 for (x = 0;x < 3;x++)
1619 {
1620 if (ext[0] == 0) break;
1621 dest[0] = system2DOSCharacter(ext[0]);
1622 ext++;
1623 dest++;
1624 }
1625 }
1626 dest[0] = 0;
1627}
1628//******************************************************************************
1629//******************************************************************************
1630VOID translateFileResults(FILESTATUS3 *pResult,LPWIN32_FIND_DATAA pFind,CHAR* achName)
1631{
1632 CHAR* name;
1633
1634 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1635
1636 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1637 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1638 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1639
1640 pFind->nFileSizeHigh = 0; //CB: fixme
1641 pFind->nFileSizeLow = pResult->cbFile;
1642 name = strrchr(achName,'\\');
1643 if (name)
1644 {
1645 name++;
1646 strcpy(pFind->cFileName,name);
1647 } else pFind->cFileName[0] = 0;
1648 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1649}
1650
1651VOID translateFindResults(FILEFINDBUF3 *pResult,LPWIN32_FIND_DATAA pFind)
1652{
1653 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1654
1655 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1656 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1657 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1658
1659 pFind->nFileSizeHigh = 0; //CB: fixme
1660 pFind->nFileSizeLow = pResult->cbFile;
1661 strcpy(pFind->cFileName,pResult->achName);
1662 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1663}
1664//******************************************************************************
1665//******************************************************************************
1666DWORD OSLibDosFindFirst(LPCSTR lpFileName,WIN32_FIND_DATAA* lpFindFileData)
1667{
1668 HDIR hDir = -1;
1669 ULONG attrs;
1670 FILEFINDBUF3 result;
1671 ULONG searchCount = 1;
1672
1673 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1674 result.achName[0] = 0;
1675
1676 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1677 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,&result,sizeof(result),&searchCount,FIL_STANDARD);
1678 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1679
1680 //check root: skip "." and ".." (HPFS, not on FAT)
1681 //check in OSLibDosFindNext not necessary: "." and ".." are the first two entries
1682 if ((rc == 0) && isRoot((LPSTR)lpFileName))
1683 {
1684 while ((strcmp(result.achName,".") == 0) || (strcmp(result.achName,"..") == 0))
1685 {
1686 result.achName[0] = 0;
1687 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1688 searchCount = 1;
1689 APIRET rc = DosFindNext(hDir,&result,sizeof(result),&searchCount);
1690 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1691 if (rc)
1692 {
1693 DosFindClose(hDir);
1694 SetLastError(error2WinError(rc));
1695
1696 return INVALID_HANDLE_VALUE_W;
1697 }
1698 }
1699 }
1700 if(rc) {
1701 DosFindClose(hDir);
1702 SetLastError(error2WinError(rc));
1703 return INVALID_HANDLE_VALUE_W;
1704 }
1705 translateFindResults(&result,lpFindFileData);
1706 return hDir;
1707}
1708//******************************************************************************
1709// NOTE: returns "." and ".." in root
1710//******************************************************************************
1711DWORD OSLibDosFindFirstMulti(LPCSTR lpFileName,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1712{
1713 HDIR hDir = -1;
1714 ULONG attrs;
1715 FILEFINDBUF3 *result,*data;
1716 ULONG searchCount = *count;
1717
1718 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1719 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1720
1721 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1722 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,result,searchCount*sizeof(FILEFINDBUF3),&searchCount,FIL_STANDARD);
1723 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1724 if (rc)
1725 {
1726 free(result);
1727 *count = 0;
1728 SetLastError(error2WinError(rc));
1729
1730 return INVALID_HANDLE_VALUE_W;
1731 }
1732
1733 data = result;
1734 for (int x = 0;x < searchCount;x++)
1735 {
1736 translateFindResults(data,&lpFindFileData[x]);
1737 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1738 }
1739 free(result);
1740 *count = searchCount;
1741
1742 return hDir;
1743}
1744//******************************************************************************
1745//******************************************************************************
1746BOOL OSLibDosFindNext(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData)
1747{
1748 FILEFINDBUF3 result;
1749 ULONG searchCount = 1;
1750
1751 APIRET rc = DosFindNext((HDIR)hFindFile,&result,sizeof(result),&searchCount);
1752 if (rc)
1753 {
1754 SetLastError(error2WinError(rc));
1755
1756 return FALSE;
1757 }
1758
1759 translateFindResults(&result,lpFindFileData);
1760
1761 return TRUE;
1762}
1763//******************************************************************************
1764//******************************************************************************
1765BOOL OSLibDosFindNextMulti(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1766{
1767 FILEFINDBUF3 *result,*data;
1768 ULONG searchCount = *count;
1769
1770 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1771 APIRET rc = DosFindNext((HDIR)hFindFile,result,searchCount*sizeof(FILEFINDBUF3),&searchCount);
1772 if (rc)
1773 {
1774 free(result);
1775 *count = 0;
1776 SetLastError(error2WinError(rc));
1777
1778 return FALSE;
1779 }
1780
1781 data = result;
1782 for (int x = 0;x < searchCount;x++)
1783 {
1784 translateFindResults(data,&lpFindFileData[x]);
1785 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1786 }
1787 free(result);
1788 *count = searchCount;
1789
1790 return TRUE;
1791}
1792//******************************************************************************
1793//******************************************************************************
1794BOOL OSLibDosFindClose(DWORD hFindFile)
1795{
1796 APIRET rc = DosFindClose((HDIR)hFindFile);
1797 if (rc)
1798 {
1799 SetLastError(error2WinError(rc));
1800
1801 return FALSE;
1802 }
1803
1804 return TRUE;
1805}
1806//******************************************************************************
1807#define FSATTACH_SIZE 256
1808//******************************************************************************
1809DWORD OSLibDosQueryVolumeFS(int drive, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
1810{
1811 PFSQBUFFER2 fsinfo = (PFSQBUFFER2) alloca(FSATTACH_SIZE);
1812 ULONG cb = FSATTACH_SIZE;
1813 char drv[3] = "A:";
1814 char *fsname;
1815 APIRET rc;
1816
1817 if(lpFileSystemNameBuffer == NULL) {
1818 DebugInt3();
1819 return ERROR_INVALID_PARAMETER_W;
1820 }
1821 drv[0] = (char)('A' + drive - 1);
1822
1823 DosError(FERR_DISABLEHARDERR);
1824 rc = DosQueryFSAttach(drv, 1, FSAIL_QUERYNAME, fsinfo, &cb);
1825 DosError(FERR_ENABLEHARDERR);
1826
1827 switch(rc) {
1828 case ERROR_INVALID_DRIVE:
1829 return ERROR_INVALID_DRIVE_W;
1830 case ERROR_NO_VOLUME_LABEL:
1831 return ERROR_NO_VOLUME_LABEL_W;
1832 case NO_ERROR:
1833 break;
1834 default:
1835 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1836 }
1837
1838 fsname = (char *)&fsinfo->szName[0] + fsinfo->cbName + 1;
1839 if(strlen(fsname) < nFileSystemNameSize) {
1840 strcpy(lpFileSystemNameBuffer, fsname);
1841 }
1842 else return ERROR_BUFFER_OVERFLOW_W;
1843 return 0;
1844}
1845//******************************************************************************
1846typedef struct _FSINFOBUF
1847{
1848 ULONG ulVolser; /* Volume serial number */
1849 VOLUMELABEL vol; /* Volume lable */
1850} FSINFOBUF;
1851//******************************************************************************
1852DWORD OSLibDosQueryVolumeSerialAndName(int drive, LPDWORD lpVolumeSerialNumber,
1853 LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
1854{
1855 FSINFOBUF fsi;
1856 APIRET rc;
1857
1858 DosError(FERR_DISABLEHARDERR);
1859 rc = DosQueryFSInfo(drive, FSIL_VOLSER, &fsi, sizeof(fsi));
1860 DosError(FERR_ENABLEHARDERR);
1861
1862 switch(rc) {
1863 case ERROR_INVALID_DRIVE:
1864 return ERROR_INVALID_DRIVE_W;
1865 case ERROR_NO_VOLUME_LABEL:
1866 return ERROR_NO_VOLUME_LABEL_W;
1867 case NO_ERROR:
1868 break;
1869 default:
1870 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1871 }
1872
1873 if(lpVolumeSerialNumber) {
1874 *lpVolumeSerialNumber = fsi.ulVolser;
1875 }
1876 if(lpVolumeNameBuffer)
1877 {
1878 if(nVolumeNameSize > fsi.vol.cch) {
1879 strcpy(lpVolumeNameBuffer, (PCHAR)fsi.vol.szVolLabel);
1880 }
1881 else return ERROR_BUFFER_OVERFLOW_W;
1882 }
1883
1884 return ERROR_SUCCESS_W;
1885}
1886//******************************************************************************
1887//******************************************************************************
Note: See TracBrowser for help on using the repository browser.