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

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

some bugfixes + GetVolumeInformation rewrite

File size: 40.5 KB
Line 
1/* $Id: oslibdos.cpp,v 1.28 2000-05-23 18:45:12 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
35//******************************************************************************
36// translate OS/2 error codes to Windows codes
37// NOTE: add all codes you need, list is not complete!
38//******************************************************************************
39DWORD error2WinError(APIRET rc,DWORD defaultCode = ERROR_NOT_ENOUGH_MEMORY_W)
40{
41 switch (rc)
42 {
43 case NO_ERROR: //0
44 return ERROR_SUCCESS_W;
45
46 case ERROR_FILE_NOT_FOUND: //2
47 return ERROR_FILE_NOT_FOUND_W;
48
49 case ERROR_PATH_NOT_FOUND: //3
50 return ERROR_PATH_NOT_FOUND_W;
51
52 case ERROR_ACCESS_DENIED: //5
53 return ERROR_ACCESS_DENIED_W;
54
55 case ERROR_INVALID_HANDLE: //6
56 return ERROR_INVALID_HANDLE_W;
57
58 case ERROR_NOT_ENOUGH_MEMORY: //8
59 return ERROR_NOT_ENOUGH_MEMORY_W;
60
61 case ERROR_BAD_FORMAT: //11
62 return ERROR_BAD_FORMAT_W;
63
64 case ERROR_NO_MORE_FILES: //18
65 return ERROR_NO_MORE_FILES_W;
66
67 case ERROR_NOT_DOS_DISK: //26
68 return ERROR_NOT_DOS_DISK_W;
69
70 case ERROR_OUT_OF_STRUCTURES: //84
71 return ERROR_OUT_OF_STRUCTURES_W;
72
73 case ERROR_INVALID_PARAMETER: //87
74 return ERROR_INVALID_PARAMETER_W;
75
76 case ERROR_INTERRUPT: //95
77 return ERROR_INVALID_AT_INTERRUPT_TIME_W; //CB: right???
78
79 case ERROR_DRIVE_LOCKED: //108
80 return ERROR_DRIVE_LOCKED_W;
81
82 case ERROR_BROKEN_PIPE: //109
83 return ERROR_BROKEN_PIPE_W;
84
85 case ERROR_BUFFER_OVERFLOW: //111
86 return ERROR_BUFFER_OVERFLOW_W;
87
88 case ERROR_NO_MORE_SEARCH_HANDLES: //113
89 return ERROR_NO_MORE_SEARCH_HANDLES_W;
90
91 case ERROR_SEM_TIMEOUT: //121
92 return ERROR_SEM_TIMEOUT_W;
93
94 case ERROR_DISCARDED: //157
95 return ERROR_DISCARDED_W;
96
97 case ERROR_FILENAME_EXCED_RANGE: //206
98 return ERROR_FILENAME_EXCED_RANGE_W;
99
100 case ERROR_META_EXPANSION_TOO_LONG: //208
101 return ERROR_META_EXPANSION_TOO_LONG_W;
102
103 case ERROR_BAD_PIPE: //230
104 return ERROR_BAD_PIPE_W;
105
106 case ERROR_PIPE_BUSY: //231
107 return ERROR_PIPE_BUSY_W;
108
109 case ERROR_PIPE_NOT_CONNECTED: //233
110 return ERROR_PIPE_NOT_CONNECTED_W;
111
112 case ERROR_MORE_DATA: //234
113 return ERROR_MORE_DATA_W;
114
115 case ERROR_INVALID_EA_NAME: //254
116 return ERROR_INVALID_EA_NAME_W;
117
118 case ERROR_EA_LIST_INCONSISTENT: //255
119 return ERROR_EA_LIST_INCONSISTENT_W;
120
121 case ERROR_EAS_DIDNT_FIT: //275
122 return ERROR_EAS_DIDNT_FIT;
123
124 default:
125 return defaultCode;
126 }
127}
128//******************************************************************************
129//TODO: Assumes entire memory range has the same protection flags!
130//TODO: Check if this works for code aliases...
131//******************************************************************************
132DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
133{
134 DWORD rc;
135 DWORD attr;
136 DWORD size = cb;
137
138 cb = (cb-1) & ~0xfff;
139 cb+= PAGE_SIZE;
140
141 rc = DosQueryMem(pb, &size, &attr);
142 if(rc) {
143 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
144 return rc;
145 }
146 size = (size-1) & ~0xfff;
147 size+= PAGE_SIZE;
148 if(size != cb) {
149 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
150 //ignore this and continue return 5;
151 attr = fl; //just use original protection flags (NOT CORRECT)
152 }
153 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
154 if(attr != fl) {
155 rc = DosSetMem(pb, size, fl);
156 if(rc) {
157 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
158 attr = fl;
159 //just continue for now
160 //return rc;
161 }
162 }
163 rc = DosAliasMem(pb, cb, ppbAlias, 2);
164 if(rc) {
165 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
166 return rc;
167 }
168 if(attr != fl) {
169 rc = DosSetMem(pb, size, attr);
170 if(rc) {
171 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
172 return rc;
173 }
174 }
175 return 0;
176}
177//******************************************************************************
178//NT returns addresses aligned at 64k, so we do too.
179//******************************************************************************
180DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags)
181{
182 LPVOID memaddr;
183 DWORD offset;
184 APIRET rc;
185
186 rc = DosAllocMem(&memaddr, size, PAG_READ | flAllocMem);
187 if(rc) {
188 return rc;
189 }
190 DosEnterCritSec();
191 DosFreeMem(memaddr);
192 offset = (DWORD)memaddr & 0xFFFF;
193 if(offset) {
194 DosAllocMem(&memaddr, 64*1024 - offset, PAG_READ | flAllocMem);
195 }
196 rc = DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
197 DosExitCritSec();
198 if((DWORD)*lplpMemAddr & 0xFFFF) {//still not at 64k boundary?
199 DosFreeMem(*lplpMemAddr);
200 rc = OSLibDosAllocMem(lplpMemAddr, size, flags);
201 }
202 if(offset) {
203 DosFreeMem(memaddr);
204 }
205
206 return rc;
207}
208//******************************************************************************
209//******************************************************************************
210DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
211{
212 return DosFreeMem(lpMemAddr);
213}
214//******************************************************************************
215//NOTE: If name == NULL, allocated gettable unnamed shared memory
216//******************************************************************************
217DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
218{
219 APIRET rc;
220 char *sharedmemname = NULL;
221
222 if(name) {
223 sharedmemname = (char *)malloc(strlen(name) + 16);
224 strcpy(sharedmemname, "\\SHAREMEM\\");
225 strcat(sharedmemname, name);
226 }
227 else flags |= OBJ_GETTABLE;
228
229 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
230 if(name) {
231 free(sharedmemname);
232 }
233 return rc;
234}
235//******************************************************************************
236//NOTE: If name == NULL, assume gettable unnamed shared memory
237//******************************************************************************
238DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
239{
240 APIRET rc;
241 char *sharedmemname = NULL;
242
243 if(name) {
244 sharedmemname = (char *)malloc(strlen(name) + 16);
245 strcpy(sharedmemname, "\\SHAREMEM\\");
246 strcat(sharedmemname, name);
247 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
248 if(name) {
249 free(sharedmemname);
250 }
251 }
252 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
253
254 return rc;
255}
256//******************************************************************************
257//******************************************************************************
258DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
259{
260 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
261}
262//******************************************************************************
263//******************************************************************************
264DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
265{
266 APIRET rc;
267
268 rc = DosSetMem(lpMemAddr, size, flags);
269 switch(rc) {
270 case ERROR_INVALID_ADDRESS:
271 return OSLIB_ERROR_INVALID_ADDRESS;
272 case ERROR_ACCESS_DENIED:
273 return OSLIB_ERROR_ACCESS_DENIED;
274 default:
275 return rc;
276 }
277}
278//******************************************************************************
279//******************************************************************************
280DWORD OSLibDosOpen(char *lpszFileName, DWORD flags)
281{
282 APIRET rc;
283 HFILE hFile;
284 ULONG ulAction;
285 DWORD os2flags = OPEN_FLAGS_NOINHERIT;
286
287
288 if(flags & OSLIB_ACCESS_READONLY)
289 os2flags |= OPEN_ACCESS_READONLY;
290 else
291 if(flags & OSLIB_ACCESS_READWRITE)
292 os2flags |= OPEN_ACCESS_READWRITE;
293
294 if(flags & OSLIB_ACCESS_SHAREDENYNONE)
295 os2flags |= OPEN_SHARE_DENYNONE;
296 else
297 if(flags & OSLIB_ACCESS_SHAREDENYREAD)
298 os2flags |= OPEN_SHARE_DENYREAD;
299 else
300 if(flags & OSLIB_ACCESS_SHAREDENYWRITE)
301 os2flags |= OPEN_SHARE_DENYWRITE;
302
303tryopen:
304 rc = DosOpen(lpszFileName, /* File path name */
305 &hFile, /* File handle */
306 &ulAction, /* Action taken */
307 0L, /* File primary allocation */
308 0L, /* File attribute */
309 OPEN_ACTION_FAIL_IF_NEW |
310 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
311 os2flags,
312 0L); /* No extended attribute */
313
314 if(rc) {
315 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
316 ULONG CurMaxFH;
317 LONG ReqCount = 32;
318
319 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
320 if(rc) {
321 dprintf(("DosSetRelMaxFH returned %d", rc));
322 return 0;
323 }
324 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
325 goto tryopen;
326 }
327 return 0;
328 }
329 else return hFile;
330}
331//******************************************************************************
332//******************************************************************************
333DWORD OSLibDosClose(DWORD hFile)
334{
335 return DosClose(hFile);
336}
337//******************************************************************************
338//******************************************************************************
339DWORD OSLibDosChangeMaxFileHandles()
340{
341 ULONG CurMaxFH;
342 LONG ReqCount = 0;
343 APIRET rc;
344
345 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
346 if(rc) {
347 dprintf(("DosSetRelMaxFH returned %d", rc));
348 return rc;
349 }
350 if(ReqCount + ODIN_INCREMENT_MAX_FILEHANDLES > CurMaxFH) {
351 ReqCount = CurMaxFH + ODIN_INCREMENT_MAX_FILEHANDLES;
352 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
353 if(rc) {
354 dprintf(("DosSetRelMaxFH returned %d", rc));
355 return rc;
356 }
357 }
358 return 0;
359}
360//******************************************************************************
361//******************************************************************************
362DWORD OSLibDosSetInitialMaxFileHandles(DWORD maxhandles)
363{
364 ULONG CurMaxFH;
365 LONG ReqCount = 0;
366 APIRET rc;
367
368 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
369 if(rc) {
370 dprintf(("DosSetRelMaxFH returned %d", rc));
371 return rc;
372 }
373 if(CurMaxFH < maxhandles) {
374 rc = DosSetMaxFH(maxhandles);
375 if(rc) {
376 dprintf(("DosSetMaxFH returned %d", rc));
377 return rc;
378 }
379 }
380 return 0;
381}
382//******************************************************************************
383//******************************************************************************
384DWORD OSLibDosRead(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesRead)
385{
386 return DosRead(hFile, lpBuffer, size, nrBytesRead);
387}
388//******************************************************************************
389//******************************************************************************
390DWORD OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten)
391{
392 return DosWrite(hFile, lpBuffer, size, nrBytesWritten);
393}
394//******************************************************************************
395//******************************************************************************
396DWORD OSLibDosSetFilePtr(DWORD hFile, DWORD offset, DWORD method)
397{
398 DWORD os2method;
399 DWORD newoffset;
400 APIRET rc;
401
402 switch(method) {
403 case OSLIB_SETPTR_FILE_CURRENT:
404 os2method = FILE_CURRENT;
405 break;
406 case OSLIB_SETPTR_FILE_BEGIN:
407 os2method = FILE_BEGIN ;
408 break;
409 case OSLIB_SETPTR_FILE_END:
410 os2method = FILE_END;
411 break;
412 default:
413 return OSLIB_ERROR_INVALID_PARAMETER;
414 }
415 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
416 if(rc) {
417 return -1;
418 }
419 else return newoffset;
420}
421//******************************************************************************
422//******************************************************************************
423DWORD OSLibDosDelete(char *lpszFileName)
424{
425 return DosDelete(lpszFileName);
426}
427//******************************************************************************
428//******************************************************************************
429BOOL pmDateTimeToFileTime(FDATE *pDate,FTIME *pTime,FILETIME *pFT)
430{
431 USHORT dosTime, dosDate;
432
433 dosTime = *(USHORT*)pTime;
434 dosDate = *(USHORT*)pDate;
435
436 return DosDateTimeToFileTime(dosDate,dosTime,pFT);
437}
438//******************************************************************************
439//******************************************************************************
440#define NOT_NORMAL (FILE_ATTRIBUTE_READONLY_W | \
441 FILE_ATTRIBUTE_HIDDEN_W | \
442 FILE_ATTRIBUTE_SYSTEM_W | \
443 FILE_ATTRIBUTE_ARCHIVE_W)
444
445inline DWORD pm2WinFileAttributes(DWORD attrFile)
446{
447 DWORD res = 0;
448
449 if (!(attrFile & NOT_NORMAL))
450 res |= FILE_ATTRIBUTE_NORMAL_W;
451 if (attrFile & FILE_READONLY)
452 res |= FILE_ATTRIBUTE_READONLY_W;
453 if (attrFile & FILE_HIDDEN)
454 res |= FILE_ATTRIBUTE_HIDDEN_W;
455 if (attrFile & FILE_SYSTEM)
456 res |= FILE_ATTRIBUTE_SYSTEM_W;
457 if (attrFile & FILE_DIRECTORY)
458 res |= FILE_ATTRIBUTE_DIRECTORY_W;
459 if (attrFile & FILE_ARCHIVED)
460 res |= FILE_ATTRIBUTE_ARCHIVE_W;
461
462 //CB: not used: FILE_ATTRIBUTE_COMPRESSED_W
463
464 return res;
465}
466//******************************************************************************
467//******************************************************************************
468BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
469 ULONG ulDummy,
470 PVOID pBuffer)
471{
472 APIRET rc; /* API return code */
473 FILESTATUS3 fs3; /* file information structure */
474 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
475
476 // Note: we only handle standard "GetFileExInfoStandard" requests
477 rc = DosQueryPathInfo(pszName, /* query the file information */
478 FIL_STANDARD,
479 &fs3,
480 sizeof(fs3));
481 if (rc != NO_ERROR) /* check for errors */
482 return FALSE; /* raise error condition */
483
484 // convert structure
485 lpFad->dwFileAttributes = pm2WinFileAttributes(fs3.attrFile);
486 pmDateTimeToFileTime(&fs3.fdateCreation, &fs3.ftimeCreation, &lpFad->ftCreationTime);
487 pmDateTimeToFileTime(&fs3.fdateLastAccess, &fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
488 pmDateTimeToFileTime(&fs3.fdateLastWrite, &fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
489
490 /* @@@PH we might add Aurora support ...
491 lpFad->nFileSizeHigh = info.nFileSizeHigh;
492 */
493 lpFad->nFileSizeHigh = 0;
494 lpFad->nFileSizeLow = fs3.cbFile;
495
496 return TRUE;
497}
498//******************************************************************************
499DWORD WIN32API GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD );
500//******************************************************************************
501DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
502 DWORD length_fullname)
503{
504 switch(cmd) {
505 case OSLIB_SEARCHDIR:
506 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
507 name, full_name, length_fullname) != 0) {
508 return 0;
509 }
510 return strlen(full_name);
511
512
513 case OSLIB_SEARCHCURDIR:
514 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
515 name, full_name, length_fullname) != 0) {
516 return 0;
517 }
518 return strlen(full_name);
519
520 case OSLIB_SEARCHFILE:
521 {
522 FILESTATUS3 fileinfo;
523
524 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
525 return 0;
526 }
527 strncpy(full_name, name, length_fullname);
528 return strlen(full_name);
529 }
530
531 case OSLIB_SEARCHENV:
532 {
533 LPSTR envstring;
534 int envsize;
535 CHAR szResult[CCHMAXPATH];
536
537 envsize = GetEnvironmentVariableA(path, NULL, 0);
538 envstring = (LPSTR)malloc(envsize+1);
539 GetEnvironmentVariableA(path, envstring, envsize);
540 if(DosSearchPath(SEARCH_IGNORENETERRS, envstring,
541 name, szResult, sizeof(szResult)) != 0) {
542 free(envstring);
543 return 0;
544 }
545 free(envstring);
546 strcpy(full_name, szResult);
547 return strlen(full_name);
548 }
549 }
550 return 0;
551}
552//******************************************************************************
553//******************************************************************************
554DWORD OSLibDosCreate(CHAR *lpFileName,
555 DWORD dwAccess,
556 DWORD dwShare,
557 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
558 DWORD dwCreation,
559 DWORD dwFlags,
560 HANDLE hTemplate,
561 DWORD *dwFile)
562{
563 APIRET rc;
564 HFILE hFile;
565 ULONG ulAction=0;
566 DWORD os2Attrib=0;
567 DWORD os2Flags = 0; //OPEN_FLAGS_NOINHERIT;
568 DWORD os2Open=0;
569
570 if(dwAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
571 os2Flags |= OPEN_ACCESS_READWRITE;
572 else if(dwAccess & GENERIC_WRITE_W)
573 os2Flags |= OPEN_ACCESS_WRITEONLY;
574 else if(dwAccess & GENERIC_READ_W)
575 os2Flags |= OPEN_ACCESS_READONLY;
576
577 if(dwShare == 0)
578 os2Flags |= OPEN_SHARE_DENYREADWRITE;
579 else if(dwShare == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
580 os2Flags |= OPEN_SHARE_DENYNONE;
581 else if(dwShare & FILE_SHARE_READ_W)
582 os2Flags |= OPEN_SHARE_DENYWRITE;
583 else if(dwShare & FILE_SHARE_WRITE_W)
584 os2Flags |= OPEN_SHARE_DENYREAD;
585
586 if(dwCreation == CREATE_NEW_W)
587 os2Open = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
588 else if(dwCreation == CREATE_ALWAYS_W)
589 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
590 else if(dwCreation == OPEN_EXISTING_W)
591 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
592 else if(dwCreation == OPEN_ALWAYS_W)
593 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
594 else if(dwCreation == TRUNCATE_EXISTING_W)
595 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS;// |OPEN_ACTION_FAIL_IF_NEW;
596
597 if(dwFlags & FILE_ATTRIBUTE_READONLY_W)
598 os2Attrib |= FILE_READONLY;
599 if(dwFlags & FILE_ATTRIBUTE_HIDDEN_W)
600 os2Attrib |= FILE_HIDDEN;
601 if(dwFlags & FILE_ATTRIBUTE_SYSTEM_W)
602 os2Attrib |= FILE_SYSTEM;
603 if(dwFlags & FILE_ATTRIBUTE_DIRECTORY_W)
604 os2Attrib |= FILE_DIRECTORY;
605 if(dwFlags & FILE_ATTRIBUTE_ARCHIVE_W)
606 os2Attrib |= FILE_ARCHIVED;
607 if(dwFlags & FILE_ATTRIBUTE_NORMAL_W)
608 os2Attrib |= FILE_NORMAL;
609
610 if(dwFlags & FILE_FLAG_WRITE_THROUGH_W)
611 os2Flags |= OPEN_FLAGS_WRITE_THROUGH;
612 if(dwFlags & FILE_FLAG_NO_BUFFERING_W)
613 os2Flags |= OPEN_FLAGS_NO_CACHE;
614 if(dwFlags & FILE_FLAG_RANDOM_ACCESS_W)
615 os2Flags |= OPEN_FLAGS_RANDOM;
616 if(dwFlags & FILE_FLAG_SEQUENTIAL_SCAN_W)
617 os2Flags |= OPEN_FLAGS_SEQUENTIAL;
618
619 // TODO:
620 // if(dwFlags & FILE_FLAG_OVERLAPPED_W)
621 // if(dwFlags & FILE_FLAG_DELETE_ON_CLOSE_W
622
623 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
624 os2Attrib, os2Open, os2Flags, 0);
625
626 if(rc)
627 {
628 // TODO: TEST TEST
629 dprintf(("DosOpen Error rc:%d, try without GENERIC_WRITE_W", rc));
630 if(dwAccess & GENERIC_WRITE_W)
631 os2Flags &= ~(OPEN_ACCESS_READWRITE | OPEN_ACCESS_WRITEONLY);
632 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
633 os2Attrib, os2Open, os2Flags, 0);
634 if(rc)
635 {
636 dprintf(("DosOpen Error rc:%d os2Attrib:%X os2Open:%X os2Flags:%X",
637 rc, os2Attrib, os2Open, os2Flags));
638 hFile = -1;
639 }
640 }
641
642 *dwFile = hFile;
643 return rc;
644}
645//******************************************************************************
646//(without changing file pointer)
647//******************************************************************************
648DWORD OSLibDosGetFileSize(DWORD hFile)
649{
650 FILESTATUS3 fsts3ConfigInfo = {{0}};
651 ULONG ulBufSize = sizeof(FILESTATUS3);
652
653 DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
654 return fsts3ConfigInfo.cbFile;
655}
656//******************************************************************************
657//******************************************************************************
658DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
659{
660 DWORD newoffset;
661 APIRET rc;
662
663
664 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
665 if(rc) {
666 dprintf(("DosSetFilePtr Error rc:%d", rc));
667 return -1;
668 }
669 else return newoffset;
670}
671//******************************************************************************
672//(FlushBuffer)
673//******************************************************************************
674DWORD OSLibDosResetBuffer(DWORD hFile)
675{
676 return DosResetBuffer(hFile);
677}
678//******************************************************************************
679//******************************************************************************
680DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
681{
682 *hNew = -1;
683 return DosDupHandle(hFile, hNew);
684}
685//******************************************************************************
686//******************************************************************************
687void OSLibDosDisableHardError(BOOL fTurnOff)
688{
689 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
690}
691//******************************************************************************
692//Returns time spent in kernel & user mode in milliseconds
693//******************************************************************************
694BOOL OSLibDosQueryProcTimes(DWORD procid, ULONG *kerneltime, ULONG *usertime)
695{
696 APIRET rc;
697 char *buf;
698 ULONG size;
699 ULONG nrthreads = 4;
700
701tryagain:
702 size = sizeof(QTOPLEVEL)+sizeof(QGLOBAL)+sizeof(QPROCESS) + nrthreads*sizeof(QTHREAD);
703 buf = (char *)malloc(size);
704 rc = DosQuerySysState(0x1, RESERVED, procid, RESERVED, (PCHAR)buf, size);
705
706 if(rc) {
707 free(buf);
708 if(rc == ERROR_BUFFER_OVERFLOW) {
709 nrthreads += 4;
710 goto tryagain;
711 }
712 return FALSE;
713 }
714 PQTOPLEVEL top = (PQTOPLEVEL)buf;
715
716 *kerneltime = 0;
717 *usertime = 0;
718 for(int i=0;i<top->procdata->threadcnt;i++) {
719 *kerneltime += top->procdata->threads[i].systime;
720 *usertime += top->procdata->threads[i].usertime;
721 }
722 free(buf);
723 return TRUE;
724}
725//******************************************************************************
726//******************************************************************************
727// TODO: implement SecurityAttributes parameter
728DWORD OSLibDosCreateNamedPipe(LPCTSTR lpName,
729 DWORD dwOpenMode,
730 DWORD dwPipeMode,
731 DWORD nMaxInstances,
732 DWORD nOutBufferSize,
733 DWORD nInBufferSize,
734 DWORD nDefaultTimeOut,
735 void* lpSecurityAttributes)
736{ DWORD dwOS2Mode = 0;
737 DWORD dwOS2PipeMode = 0;
738 LPSTR lpOS2Name;
739 DWORD hPipe;
740 DWORD rc;
741
742 if (dwOpenMode & PIPE_ACCESS_DUPLEX_W)
743 dwOS2Mode |= NP_ACCESS_DUPLEX;
744 else
745 if (dwOpenMode & PIPE_ACCESS_INBOUND_W)
746 dwOS2Mode |= NP_ACCESS_INBOUND;
747 else
748 if (dwOpenMode & PIPE_ACCESS_OUTBOUND_W)
749 dwOS2Mode |= NP_ACCESS_OUTBOUND;
750 // TODO:
751 // if(dwOpenMode & FILE_FLAG_OVERLAPPED)
752 // if(dwOpenMode & WRITE_DAC)
753 // if(dwOpenMode & WRITE_OWNER)
754 // if(dwOpenMode & ACCESS_SYSTEM_SECURITY)
755 if(dwOpenMode & FILE_FLAG_WRITE_THROUGH_W)
756 dwOS2Mode |= NP_WRITEBEHIND; // FIXME: I'm not sure!
757
758 if (dwPipeMode & PIPE_WAIT_W)
759 dwOS2PipeMode |= NP_WAIT;
760 if (dwPipeMode & PIPE_NOWAIT_W)
761 dwOS2PipeMode |= NP_NOWAIT;
762 if (dwPipeMode & PIPE_READMODE_BYTE_W)
763 dwOS2PipeMode |= NP_READMODE_BYTE;
764 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
765 dwOS2PipeMode |= NP_READMODE_MESSAGE;
766 if (dwPipeMode & PIPE_TYPE_BYTE_W)
767 dwOS2PipeMode |= NP_TYPE_BYTE;
768 if (dwPipeMode & PIPE_TYPE_MESSAGE_W)
769 dwOS2PipeMode |= NP_TYPE_MESSAGE;
770
771 if (nMaxInstances>0xff)
772 {
773 SetLastError(ERROR_INVALID_PARAMETER_W); // ERROR_INVALID_PARAMETER
774 return -1; // INVALID_HANDLE_VALUE
775 }
776 dwOS2PipeMode |= nMaxInstances;
777
778 if (strstr(lpName,"\\\\."))
779 {
780 // If pipe is created on the local machine
781 // we must delete string \\. because
782 // in Windows named pipes scheme is a \\.\PIPE\pipename
783 // but in OS/2 only \PIPE\pipename
784 lpOS2Name = (LPSTR)lpName + 3;
785 }
786 else lpOS2Name = (LPSTR)lpName;
787
788 dprintf(("DosCreateNPipe(%s,%x,%x,%x,%x,%x)",lpOS2Name,dwOS2Mode,dwOS2PipeMode,nInBufferSize,nOutBufferSize,nDefaultTimeOut));
789 rc=DosCreateNPipe(lpOS2Name,
790 &hPipe,
791 dwOS2Mode,
792 dwOS2PipeMode,
793 nInBufferSize,
794 nInBufferSize,
795 nDefaultTimeOut); // Timeouts must be tested!
796
797 dprintf(("DosCreateNPipe rc=%d",rc));
798 if (rc)
799 {
800 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
801 return -1; // INVALID_HANDLE_VALUE
802 }
803 return hPipe;
804}
805
806//******************************************************************************
807//******************************************************************************
808// TODO: implement lpOverlapped parameter!
809BOOL OSLibDosConnectNamedPipe(DWORD hNamedPipe, LPOVERLAPPED lpOverlapped)
810{
811 DWORD rc;
812
813 rc=DosConnectNPipe(hNamedPipe);
814 dprintf(("DosConnectNPipe rc=%d",rc));
815
816 if (!rc) return (TRUE);
817 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
818
819 return (FALSE);
820}
821
822//******************************************************************************
823//******************************************************************************
824BOOL OSLibDosCallNamedPipe( LPCTSTR lpNamedPipeName,
825 LPVOID lpInBuffer,
826 DWORD nInBufferSize,
827 LPVOID lpOutBuffer,
828 DWORD nOutBufferSize,
829 LPDWORD lpBytesRead,
830 DWORD nTimeOut )
831{
832 LPSTR lpOS2Name;
833 DWORD rc;
834
835 if (strstr(lpNamedPipeName,"\\\\."))
836 {
837 // If pipe is created on the local machine
838 // we must delete string \\. because
839 // in Windows named pipes scheme is a \\.\PIPE\pipename
840 // but in OS/2 only \PIPE\pipename
841 lpOS2Name = (LPSTR)lpNamedPipeName + 3;
842 }
843 else lpOS2Name = (LPSTR)lpNamedPipeName;
844
845 rc=DosCallNPipe(lpOS2Name,
846 lpInBuffer,
847 nInBufferSize,
848 lpOutBuffer,
849 nOutBufferSize,
850 lpBytesRead,
851 nTimeOut );
852
853
854 if (!rc) return (TRUE);
855 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
856
857 return (FALSE);
858}
859
860//******************************************************************************
861//******************************************************************************
862BOOL OSLibDosTransactNamedPipe( DWORD hNamedPipe,
863 LPVOID lpInBuffer,
864 DWORD nInBufferSize,
865 LPVOID lpOutBuffer,
866 DWORD nOutBufferSize,
867 LPDWORD lpBytesRead,
868 LPOVERLAPPED lpOverlapped)
869{
870 DWORD rc;
871
872 rc=DosTransactNPipe(hNamedPipe,
873 lpOutBuffer,
874 nOutBufferSize,
875 lpInBuffer,
876 nInBufferSize,
877 lpBytesRead);
878
879 dprintf(("DosTransactNPipe returned rc=%d");)
880 if (!rc) return (TRUE);
881 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
882
883 return (FALSE);
884}
885
886//******************************************************************************
887//******************************************************************************
888BOOL OSLibDosPeekNamedPipe(DWORD hPipe,
889 LPVOID lpvBuffer,
890 DWORD cbBuffer,
891 LPDWORD lpcbRead,
892 LPDWORD lpcbAvail,
893 LPDWORD lpcbMessage)
894{
895 DWORD rc;
896 AVAILDATA availData ={0};
897 ULONG ulDummy;
898
899 rc=DosPeekNPipe(hPipe,lpvBuffer,cbBuffer,lpcbRead,&availData,&ulDummy);
900
901 dprintf(("DosPeekNPipe returned rc=%d",rc));
902
903 if (!rc)
904 {
905 *lpcbAvail = availData.cbpipe;
906 *lpcbMessage = availData.cbmessage;
907 return (TRUE);
908 }
909 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
910
911 return (FALSE);
912}
913//******************************************************************************
914//******************************************************************************
915BOOL OSLibDosDisconnectNamedPipe(DWORD hPipe)
916{
917 DWORD rc;
918
919 rc=DosDisConnectNPipe(hPipe);
920
921 dprintf(("DosDisConnectNPipe returned rc=%d",rc));
922
923 if (!rc) return TRUE;
924 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
925
926 return (FALSE);
927}
928//******************************************************************************
929//******************************************************************************
930BOOL OSLibDosWaitNamedPipe(LPCSTR lpszNamedPipeName,
931 DWORD dwTimeout)
932{
933 LPSTR lpOS2Name;
934 DWORD rc;
935
936 if (strstr(lpszNamedPipeName,"\\\\."))
937 {
938 // If pipe is created on the local machine
939 // we must delete string \\. because
940 // in Windows named pipes scheme is a \\.\PIPE\pipename
941 // but in OS/2 only \PIPE\pipename
942 lpOS2Name = (LPSTR)lpszNamedPipeName + 3;
943 }
944 else lpOS2Name = (LPSTR)lpszNamedPipeName;
945
946 rc=DosWaitNPipe(lpOS2Name,dwTimeout);
947
948 dprintf(("DosWaitNPipe returned rc=%d",rc));
949
950 if (!rc) return TRUE;
951 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
952
953 return (FALSE);
954}
955//******************************************************************************
956//******************************************************************************
957BOOL isRoot(CHAR* name)
958{
959 if (name[1] == ':')
960 {
961 //local name (x:\)
962 return (name[2] == 0) || !strchr(&name[3],'\\');
963 } else if (name[0] == '\\')
964 {
965 //UNC name (\\resource\drive\)
966 CHAR *drive,*dir;
967
968 drive = strchr(&name[2],'\\');
969 if (!drive) return FALSE;
970 dir = strchr(&drive[1],'\\');
971 if (!dir) return TRUE;
972 return !strchr(&dir[1],'\\');
973 } else return FALSE; //unknown
974}
975//******************************************************************************
976//******************************************************************************
977inline CHAR system2DOSCharacter(CHAR ch)
978{
979 switch(ch)
980 {
981 case ' ':
982 case '.':
983 case '~':
984 return '_';
985
986 default:
987 return toupper(ch);
988 }
989}
990
991VOID long2ShortName(CHAR* longName,CHAR* shortName)
992{
993 INT x;
994 CHAR *source = longName,*dest = shortName,*ext = strrchr(longName,'.');
995
996 if ((strcmp(longName,".") == 0) || (strcmp(longName,"..") == 0))
997 {
998 strcpy(shortName,longName);
999 return;
1000 }
1001
1002 //CB: quick and dirty, real FILE~12.EXT is too slow
1003
1004 //8 character file name
1005 for (x = 0;x < 8;x++)
1006 {
1007 if ((source == ext) || (source[0] == 0)) break;
1008 dest[0] = system2DOSCharacter(source[0]);
1009 source++;
1010 dest++;
1011 }
1012
1013 if (source[0] == 0)
1014 {
1015 dest[0] = 0;
1016 return;
1017 }
1018
1019 if (source != ext)
1020 {
1021 //longName > 8 characters, insert ~1
1022 shortName[6] = '~';
1023 shortName[7] = '1';
1024 }
1025
1026 if (ext)
1027 {
1028 //add extension, 3 characters
1029 dest[0] = ext[0];
1030 dest++;
1031 ext++;
1032 for (x = 0;x < 3;x++)
1033 {
1034 if (ext[0] == 0) break;
1035 dest[0] = system2DOSCharacter(ext[0]);
1036 ext++;
1037 dest++;
1038 }
1039 }
1040 dest[0] = 0;
1041}
1042//******************************************************************************
1043//******************************************************************************
1044VOID translateFileResults(FILESTATUS3 *pResult,LPWIN32_FIND_DATAA pFind,CHAR* achName)
1045{
1046 CHAR* name;
1047
1048 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1049
1050 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1051 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1052 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1053
1054 pFind->nFileSizeHigh = 0; //CB: fixme
1055 pFind->nFileSizeLow = pResult->cbFile;
1056 name = strrchr(achName,'\\');
1057 if (name)
1058 {
1059 name++;
1060 strcpy(pFind->cFileName,name);
1061 } else pFind->cFileName[0] = 0;
1062 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1063}
1064
1065VOID translateFindResults(FILEFINDBUF3 *pResult,LPWIN32_FIND_DATAA pFind)
1066{
1067 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
1068
1069 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
1070 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
1071 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
1072
1073 pFind->nFileSizeHigh = 0; //CB: fixme
1074 pFind->nFileSizeLow = pResult->cbFile;
1075 strcpy(pFind->cFileName,pResult->achName);
1076 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
1077}
1078//******************************************************************************
1079//******************************************************************************
1080DWORD OSLibDosFindFirst(LPCSTR lpFileName,WIN32_FIND_DATAA* lpFindFileData)
1081{
1082 HDIR hDir = -1;
1083 ULONG attrs;
1084 FILEFINDBUF3 result;
1085 ULONG searchCount = 1;
1086
1087 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1088 result.achName[0] = 0;
1089
1090 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1091 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,&result,sizeof(result),&searchCount,FIL_STANDARD);
1092 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1093
1094 //check root: skip "." and ".." (HPFS, not on FAT)
1095 //check in OSLibDosFindNext not necessary: "." and ".." are the first two entries
1096 if ((rc == 0) && isRoot((LPSTR)lpFileName))
1097 {
1098 while ((strcmp(result.achName,".") == 0) || (strcmp(result.achName,"..") == 0))
1099 {
1100 result.achName[0] = 0;
1101 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1102 searchCount = 1;
1103 APIRET rc = DosFindNext(hDir,&result,sizeof(result),&searchCount);
1104 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1105 if (rc)
1106 {
1107 DosFindClose(hDir);
1108 SetLastError(error2WinError(rc));
1109
1110 return INVALID_HANDLE_VALUE_W;
1111 }
1112 }
1113 }
1114 if(rc) {
1115 DosFindClose(hDir);
1116 SetLastError(error2WinError(rc));
1117 return INVALID_HANDLE_VALUE_W;
1118 }
1119 translateFindResults(&result,lpFindFileData);
1120 return hDir;
1121}
1122//******************************************************************************
1123// NOTE: returns "." and ".." in root
1124//******************************************************************************
1125DWORD OSLibDosFindFirstMulti(LPCSTR lpFileName,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1126{
1127 HDIR hDir = -1;
1128 ULONG attrs;
1129 FILEFINDBUF3 *result,*data;
1130 ULONG searchCount = *count;
1131
1132 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
1133 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1134
1135 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
1136 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,result,searchCount*sizeof(FILEFINDBUF3),&searchCount,FIL_STANDARD);
1137 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
1138 if (rc)
1139 {
1140 free(result);
1141 *count = 0;
1142 SetLastError(error2WinError(rc));
1143
1144 return INVALID_HANDLE_VALUE_W;
1145 }
1146
1147 data = result;
1148 for (int x = 0;x < searchCount;x++)
1149 {
1150 translateFindResults(data,&lpFindFileData[x]);
1151 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1152 }
1153 free(result);
1154 *count = searchCount;
1155
1156 return hDir;
1157}
1158//******************************************************************************
1159//******************************************************************************
1160BOOL OSLibDosFindNext(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData)
1161{
1162 FILEFINDBUF3 result;
1163 ULONG searchCount = 1;
1164
1165 APIRET rc = DosFindNext((HDIR)hFindFile,&result,sizeof(result),&searchCount);
1166 if (rc)
1167 {
1168 SetLastError(error2WinError(rc));
1169
1170 return FALSE;
1171 }
1172
1173 translateFindResults(&result,lpFindFileData);
1174
1175 return TRUE;
1176}
1177//******************************************************************************
1178//******************************************************************************
1179BOOL OSLibDosFindNextMulti(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
1180{
1181 FILEFINDBUF3 *result,*data;
1182 ULONG searchCount = *count;
1183
1184 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
1185 APIRET rc = DosFindNext((HDIR)hFindFile,result,searchCount*sizeof(FILEFINDBUF3),&searchCount);
1186 if (rc)
1187 {
1188 free(result);
1189 *count = 0;
1190 SetLastError(error2WinError(rc));
1191
1192 return FALSE;
1193 }
1194
1195 data = result;
1196 for (int x = 0;x < searchCount;x++)
1197 {
1198 translateFindResults(data,&lpFindFileData[x]);
1199 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
1200 }
1201 free(result);
1202 *count = searchCount;
1203
1204 return TRUE;
1205}
1206//******************************************************************************
1207//******************************************************************************
1208BOOL OSLibDosFindClose(DWORD hFindFile)
1209{
1210 APIRET rc = DosFindClose((HDIR)hFindFile);
1211 if (rc)
1212 {
1213 SetLastError(error2WinError(rc));
1214
1215 return FALSE;
1216 }
1217
1218 return TRUE;
1219}
1220//******************************************************************************
1221#define FSATTACH_SIZE 256
1222//******************************************************************************
1223DWORD OSLibDosQueryVolumeFS(int drive, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
1224{
1225 PFSQBUFFER2 fsinfo = (PFSQBUFFER2) alloca(FSATTACH_SIZE);
1226 ULONG cb = FSATTACH_SIZE;
1227 char drv[3] = "A:";
1228 char *fsname;
1229 APIRET rc;
1230
1231 if(lpFileSystemNameBuffer == NULL) {
1232 DebugInt3();
1233 return ERROR_INVALID_PARAMETER_W;
1234 }
1235 drv[0] = (char)('A' + drive - 1);
1236
1237 DosError(FERR_DISABLEHARDERR);
1238 rc = DosQueryFSAttach(drv, 1, FSAIL_QUERYNAME, fsinfo, &cb);
1239 DosError(FERR_ENABLEHARDERR);
1240
1241 switch(rc) {
1242 case ERROR_INVALID_DRIVE:
1243 return ERROR_INVALID_DRIVE_W;
1244 case ERROR_NO_VOLUME_LABEL:
1245 return ERROR_NO_VOLUME_LABEL_W;
1246 case NO_ERROR:
1247 break;
1248 default:
1249 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1250 }
1251
1252 fsname = (char *)&fsinfo->szName[0] + fsinfo->cbName + 1;
1253 if(strlen(fsname) < nFileSystemNameSize) {
1254 strcpy(lpFileSystemNameBuffer, fsname);
1255 }
1256 else return ERROR_BUFFER_OVERFLOW_W;
1257 return 0;
1258}
1259//******************************************************************************
1260typedef struct _FSINFOBUF
1261{
1262 ULONG ulVolser; /* Volume serial number */
1263 VOLUMELABEL vol; /* Volume lable */
1264} FSINFOBUF;
1265//******************************************************************************
1266DWORD OSLibDosQueryVolumeSerialAndName(int drive, LPDWORD lpVolumeSerialNumber,
1267 LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
1268{
1269 FSINFOBUF fsi;
1270 APIRET rc;
1271
1272 DosError(FERR_DISABLEHARDERR);
1273 rc = DosQueryFSInfo(drive, FSIL_VOLSER, &fsi, sizeof(fsi));
1274 DosError(FERR_ENABLEHARDERR);
1275
1276 switch(rc) {
1277 case ERROR_INVALID_DRIVE:
1278 return ERROR_INVALID_DRIVE_W;
1279 case ERROR_NO_VOLUME_LABEL:
1280 return ERROR_NO_VOLUME_LABEL_W;
1281 case NO_ERROR:
1282 break;
1283 default:
1284 return ERROR_NOT_ENOUGH_MEMORY; //whatever
1285 }
1286
1287 if(lpVolumeSerialNumber) {
1288 *lpVolumeSerialNumber = fsi.ulVolser;
1289 }
1290 if(lpVolumeNameBuffer)
1291 {
1292 if(nVolumeNameSize > fsi.vol.cch) {
1293 strcpy(lpVolumeNameBuffer, (PCHAR)fsi.vol.szVolLabel);
1294 }
1295 else return ERROR_BUFFER_OVERFLOW_W;
1296 }
1297
1298 return ERROR_SUCCESS_W;
1299}
1300//******************************************************************************
1301//******************************************************************************
Note: See TracBrowser for help on using the repository browser.