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

Last change on this file since 6094 was 6094, checked in by sandervl, 24 years ago

rewrote CreateDirectory

File size: 81.4 KB
Line 
1/* $Id: oslibdos.cpp,v 1.71 2001-06-24 16:40:44 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 * Copyright 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#define INCL_BASE
15#define INCL_DOSEXCEPTIONS
16#define INCL_DOSMEMMGR
17#define INCL_DOSPROCESS
18#define INCL_DOSFILEMGR
19#define INCL_DOSERRORS
20#define INCL_DOSDEVIOCTL
21#define INCL_NPIPES
22#include <os2wrap.h> //Odin32 OS/2 api wrappers
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <ctype.h>
27#include <win32api.h>
28#include <winconst.h>
29#include <win\winioctl.h>
30#include <misc.h>
31#include "initterm.h"
32#include "oslibdos.h"
33#include "dosqss.h"
34#include "win32k.h"
35
36#define DBG_LOCALLOG DBG_oslibdos
37#include "dbglocal.h"
38
39static PROC_DosSetFileSizeL DosSetFileSizeLProc = 0;
40static PROC_DosSetFilePtrL DosSetFilePtrLProc = 0;
41static PROC_DosSetFileLocksL DosSetFileLocksLProc = 0;
42static BOOL f64BitIO = FALSE;
43//******************************************************************************
44//******************************************************************************
45void OSLibInitWSeBFileIO()
46{
47 HMODULE hDoscalls;
48
49 if(DosQueryModuleHandle("DOSCALLS", &hDoscalls) != NO_ERROR) {
50 return;
51 }
52 if(DosQueryProcAddr(hDoscalls, 989, NULL, (PFN *)&DosSetFileSizeLProc) != NO_ERROR) {
53 return;
54 }
55 if(DosQueryProcAddr(hDoscalls, 988, NULL, (PFN *)&DosSetFilePtrLProc) != NO_ERROR) {
56 return;
57 }
58 if(DosQueryProcAddr(hDoscalls, 986, NULL, (PFN *)&DosSetFileLocksLProc) != NO_ERROR) {
59 return;
60 }
61 f64BitIO = TRUE;
62}
63//******************************************************************************
64//******************************************************************************
65APIRET OdinDosSetFileSizeL(HFILE hFile, LONGLONG cbSize)
66{
67 APIRET yyrc;
68 USHORT sel = RestoreOS2FS();
69
70 yyrc = DosSetFileSizeLProc(hFile, cbSize);
71 SetFS(sel);
72
73 return yyrc;
74}
75//******************************************************************************
76//******************************************************************************
77APIRET OdinDosSetFilePtrL(HFILE hFile, LONGLONG ib, ULONG method, PLONGLONG ibActual)
78{
79 APIRET yyrc;
80 USHORT sel = RestoreOS2FS();
81
82 yyrc = DosSetFilePtrLProc(hFile, ib, method, ibActual);
83 SetFS(sel);
84
85 return yyrc;
86}
87//******************************************************************************
88//******************************************************************************
89APIRET OdinDosSetFileLocksL(HFILE hFile, PFILELOCKL pflUnlock, PFILELOCKL pflLock,
90 ULONG timeout, ULONG flags)
91{
92 APIRET yyrc;
93 USHORT sel = RestoreOS2FS();
94
95 yyrc = DosSetFileLocksLProc(hFile, pflUnlock, pflLock, timeout, flags);
96 SetFS(sel);
97
98 return yyrc;
99}
100//******************************************************************************
101// translate OS/2 error codes to Windows codes
102// NOTE: add all codes you need, list is not complete!
103//******************************************************************************
104DWORD error2WinError(APIRET rc,DWORD defaultCode)
105{
106 switch (rc)
107 {
108 case NO_ERROR: //0
109 return ERROR_SUCCESS_W;
110
111 case ERROR_INVALID_FUNCTION: //1
112 return ERROR_INVALID_FUNCTION_W;
113
114 case ERROR_FILE_NOT_FOUND: //2
115 return ERROR_FILE_NOT_FOUND_W;
116
117 case ERROR_PATH_NOT_FOUND: //3
118 return ERROR_PATH_NOT_FOUND_W;
119
120 case ERROR_TOO_MANY_OPEN_FILES: //4
121 return ERROR_TOO_MANY_OPEN_FILES_W;
122
123 case ERROR_ACCESS_DENIED: //5
124 return ERROR_ACCESS_DENIED_W;
125
126 case ERROR_INVALID_HANDLE: //6
127 return ERROR_INVALID_HANDLE_W;
128
129 case ERROR_NOT_ENOUGH_MEMORY: //8
130 return ERROR_NOT_ENOUGH_MEMORY_W;
131
132 case ERROR_BAD_FORMAT: //11
133 return ERROR_BAD_FORMAT_W;
134
135 case ERROR_INVALID_ACCESS: //12
136 return ERROR_INVALID_ACCESS_W;
137
138 case ERROR_NO_MORE_FILES: //18
139 return ERROR_NO_MORE_FILES_W;
140
141 case ERROR_WRITE_PROTECT: //19
142 return ERROR_WRITE_PROTECT_W;
143
144 case ERROR_NOT_READY: //21
145 return ERROR_NOT_READY_W;
146
147 case ERROR_NOT_DOS_DISK: //26
148 return ERROR_NOT_DOS_DISK_W;
149
150 case ERROR_WRITE_FAULT: //29
151 return ERROR_WRITE_FAULT_W;
152
153 case ERROR_GEN_FAILURE: //31
154 return ERROR_GEN_FAILURE_W;
155
156 case ERROR_SHARING_VIOLATION: //32
157 return ERROR_SHARING_VIOLATION_W;
158
159 case ERROR_LOCK_VIOLATION: //32
160 return ERROR_LOCK_VIOLATION_W;
161
162 case ERROR_SHARING_BUFFER_EXCEEDED: //36
163 return ERROR_SHARING_BUFFER_EXCEEDED_W;
164
165 case ERROR_CANNOT_MAKE: //82
166 return ERROR_CANNOT_MAKE_W;
167
168 case ERROR_OUT_OF_STRUCTURES: //84
169 return ERROR_OUT_OF_STRUCTURES_W;
170
171 case ERROR_INVALID_PARAMETER: //87
172 return ERROR_INVALID_PARAMETER_W;
173
174 case ERROR_INTERRUPT: //95
175 return ERROR_INVALID_AT_INTERRUPT_TIME_W; //CB: right???
176
177 case ERROR_DEVICE_IN_USE: //99
178 return ERROR_DEVICE_IN_USE_W;
179
180 case ERROR_TOO_MANY_SEMAPHORES: //100
181 return ERROR_TOO_MANY_SEMAPHORES_W;
182
183 case ERROR_DRIVE_LOCKED: //108
184 return ERROR_DRIVE_LOCKED_W;
185
186 case ERROR_BROKEN_PIPE: //109
187 return ERROR_BROKEN_PIPE_W;
188
189 case ERROR_OPEN_FAILED: //110
190 return ERROR_OPEN_FAILED_W;
191
192 case ERROR_BUFFER_OVERFLOW: //111
193 return ERROR_BUFFER_OVERFLOW_W;
194
195 case ERROR_DISK_FULL: //112
196 return ERROR_DISK_FULL_W;
197
198 case ERROR_NO_MORE_SEARCH_HANDLES: //113
199 return ERROR_NO_MORE_SEARCH_HANDLES_W;
200
201 case ERROR_SEM_TIMEOUT: //121
202 return ERROR_SEM_TIMEOUT_W;
203
204 case ERROR_INVALID_NAME:
205 return ERROR_INVALID_NAME_W;
206
207 case ERROR_DIRECT_ACCESS_HANDLE: //130
208 return ERROR_DIRECT_ACCESS_HANDLE_W;
209
210 case ERROR_NEGATIVE_SEEK: //131
211 return ERROR_NEGATIVE_SEEK;
212
213 case ERROR_SEEK_ON_DEVICE: //132
214 return ERROR_SEEK_ON_DEVICE_W;
215
216 case ERROR_DISCARDED: //157
217 return ERROR_DISCARDED_W;
218
219 case ERROR_FILENAME_EXCED_RANGE: //206
220 return ERROR_FILENAME_EXCED_RANGE_W;
221
222 case ERROR_META_EXPANSION_TOO_LONG: //208
223 return ERROR_META_EXPANSION_TOO_LONG_W;
224
225 case ERROR_BAD_PIPE: //230
226 return ERROR_BAD_PIPE_W;
227
228 case ERROR_PIPE_BUSY: //231
229 return ERROR_PIPE_BUSY_W;
230
231 case ERROR_NO_DATA: //232
232 return ERROR_NO_DATA_W;
233
234 case ERROR_PIPE_NOT_CONNECTED: //233
235 return ERROR_PIPE_NOT_CONNECTED_W;
236
237 case ERROR_MORE_DATA: //234
238 return ERROR_MORE_DATA_W;
239
240 case ERROR_INVALID_EA_NAME: //254
241 return ERROR_INVALID_EA_NAME_W;
242
243 case ERROR_EA_LIST_INCONSISTENT: //255
244 return ERROR_EA_LIST_INCONSISTENT_W;
245
246 case ERROR_EAS_DIDNT_FIT: //275
247 return ERROR_EAS_DIDNT_FIT;
248
249 default:
250 dprintf(("WARNING: error2WinError: error %d not included!!!!", rc));
251 return defaultCode;
252 }
253}
254//******************************************************************************
255//TODO: Assumes entire memory range has the same protection flags!
256//TODO: Check if this works for code aliases...
257//******************************************************************************
258DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
259{
260 DWORD rc;
261 DWORD attr;
262 DWORD size = cb;
263
264 cb = (cb-1) & ~0xfff;
265 cb+= PAGE_SIZE;
266
267 rc = DosQueryMem(pb, &size, &attr);
268 if(rc) {
269 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
270 return rc;
271 }
272 size = (size-1) & ~0xfff;
273 size+= PAGE_SIZE;
274 if(size != cb) {
275 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
276 //ignore this and continue return 5;
277 attr = fl; //just use original protection flags (NOT CORRECT)
278 }
279 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
280 if(attr != fl) {
281 rc = DosSetMem(pb, size, fl);
282 if(rc) {
283 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
284 attr = fl;
285 //just continue for now
286 //return rc;
287 }
288 }
289 rc = DosAliasMem(pb, cb, ppbAlias, 2);
290 if(rc) {
291 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
292 return rc;
293 }
294 if(attr != fl) {
295 rc = DosSetMem(pb, size, attr);
296 if(rc) {
297 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
298 return rc;
299 }
300 }
301 return 0;
302}
303//******************************************************************************
304//NT returns addresses aligned at 64k, so we do too.
305//******************************************************************************
306// tries to retrieve an aligned block recursivly
307APIRET OdinAlignMemR(LPVOID *lpMemAddr, DWORD size, DWORD offset, DWORD flags)
308{
309 LPVOID memaddr;
310 APIRET rc, rc2;
311
312 DosEnterCritSec();
313 DosFreeMem(*lpMemAddr);
314 rc2 = DosAllocMem(&memaddr, 64 * 1024 - offset, PAG_READ | flAllocMem);
315 rc = DosAllocMem(lpMemAddr, size, flags | flAllocMem);
316 DosExitCritSec();
317
318 dprintf2(("OdinAlignMem: DosAllocMem returned %d, %d and pointers %x, %x for size %x and offset %x", rc, rc2, *lpMemAddr, memaddr, size, offset ));
319
320 if(rc2) {
321 // giving up - return as received
322 return rc;
323 }
324
325 if(rc) {
326 // seems to be out of memory
327 DosFreeMem(memaddr);
328 return rc;
329 }
330
331 if((DWORD) *lpMemAddr & 0xFFFF)
332 rc = OdinAlignMemR(lpMemAddr, size, (DWORD) *lpMemAddr & 0xFFFF, flags);
333
334 DosFreeMem(memaddr);
335 return rc;
336}
337//******************************************************************************
338//******************************************************************************
339DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD cbSize, DWORD flFlags)
340{
341 PVOID pvMemAddr;
342 DWORD offset;
343 APIRET rc;
344
345 /*
346 * Let's try use the exteneded DosAllocMem API of Win32k.sys.
347 */
348 if (libWin32kInstalled())
349 {
350 rc = DosAllocMemEx(lplpMemAddr, cbSize, flFlags | flAllocMem | OBJ_ALIGN64K);
351 if (rc != ERROR_NOT_SUPPORTED) /* This call was stubbed until recently. */
352 return rc;
353 }
354
355 /*
356 * If no or old Win32k fall back to old method.
357 */
358
359 rc = DosAllocMem(&pvMemAddr, cbSize, flFlags | flAllocMem);
360 if(rc) {
361 return rc;
362 }
363
364 // already 64k aligned ?
365 if((DWORD) pvMemAddr & 0xFFFF)
366 rc = OdinAlignMemR(&pvMemAddr, cbSize, (DWORD) pvMemAddr & 0xFFFF, flFlags);
367
368 if(!rc)
369 *lplpMemAddr = pvMemAddr;
370
371 return rc;
372}
373//******************************************************************************
374//******************************************************************************
375DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
376{
377 return DosFreeMem(lpMemAddr);
378}
379//******************************************************************************
380//NOTE: If name == NULL, allocated gettable unnamed shared memory
381//OS/2 returns error 123 (invalid name) if the shared memory name includes
382//colons. We need to replace them with underscores.
383//******************************************************************************
384DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
385{
386 APIRET rc;
387 char *sharedmemname = NULL, *tmp;
388
389 if(name) {
390 sharedmemname = (char *)malloc(strlen(name) + 16);
391 strcpy(sharedmemname, "\\SHAREMEM\\");
392 strcat(sharedmemname, name);
393 }
394 else flags |= OBJ_GETTABLE;
395
396 //SvL: Colons are unacceptable in shared memory names (for whatever reason)
397 tmp = sharedmemname;
398 while(*tmp != 0) {
399 if(*tmp == ':') {
400 *tmp = '_';
401 }
402 tmp++;
403 }
404
405 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
406 if(name) {
407 free(sharedmemname);
408 }
409 return rc;
410}
411//******************************************************************************
412//NOTE: If name == NULL, assume gettable unnamed shared memory
413//******************************************************************************
414DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
415{
416 APIRET rc;
417 char *sharedmemname = NULL, *tmp;
418
419 if(name) {
420 sharedmemname = (char *)malloc(strlen(name) + 16);
421 strcpy(sharedmemname, "\\SHAREMEM\\");
422 strcat(sharedmemname, name);
423
424 //SvL: Colons are unacceptable in shared memory names (for whatever reason)
425 tmp = sharedmemname;
426 while(*tmp != 0) {
427 if(*tmp == ':') {
428 *tmp = '_';
429 }
430 tmp++;
431 }
432 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
433 if(name) {
434 free(sharedmemname);
435 }
436 }
437 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
438
439 return rc;
440}
441//******************************************************************************
442//******************************************************************************
443DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
444{
445 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
446}
447//******************************************************************************
448//******************************************************************************
449DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
450{
451 APIRET rc;
452
453 rc = DosSetMem(lpMemAddr, size, flags);
454 switch(rc) {
455 case ERROR_INVALID_ADDRESS:
456 return OSLIB_ERROR_INVALID_ADDRESS;
457 case ERROR_ACCESS_DENIED:
458 return OSLIB_ERROR_ACCESS_DENIED;
459 default:
460 return rc;
461 }
462}
463//******************************************************************************
464//******************************************************************************
465DWORD OSLibDosOpen(char *lpszFileName, DWORD flags)
466{
467 APIRET rc;
468 HFILE hFile;
469 ULONG ulAction;
470 DWORD os2flags = OPEN_FLAGS_NOINHERIT;
471
472
473 if(flags & OSLIB_ACCESS_READONLY)
474 os2flags |= OPEN_ACCESS_READONLY;
475 else
476 if(flags & OSLIB_ACCESS_READWRITE)
477 os2flags |= OPEN_ACCESS_READWRITE;
478
479 if(flags & OSLIB_ACCESS_SHAREDENYNONE)
480 os2flags |= OPEN_SHARE_DENYNONE;
481 else
482 if(flags & OSLIB_ACCESS_SHAREDENYREAD)
483 os2flags |= OPEN_SHARE_DENYREAD;
484 else
485 if(flags & OSLIB_ACCESS_SHAREDENYWRITE)
486 os2flags |= OPEN_SHARE_DENYWRITE;
487
488tryopen:
489 rc = DosOpen(lpszFileName, /* File path name */
490 &hFile, /* File handle */
491 &ulAction, /* Action taken */
492 0L, /* File primary allocation */
493 0L, /* File attribute */
494 OPEN_ACTION_FAIL_IF_NEW |
495 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
496 os2flags,
497 0L); /* No extended attribute */
498
499 if(rc) {
500 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
501 ULONG CurMaxFH;
502 LONG ReqCount = 32;
503
504 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
505 if(rc) {
506 dprintf(("DosSetRelMaxFH returned %d", rc));
507 return 0;
508 }
509 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
510 goto tryopen;
511 }
512 return 0;
513 }
514 else return hFile;
515}
516//******************************************************************************
517//******************************************************************************
518BOOL OSLibDosClose(DWORD hFile)
519{
520 APIRET rc;
521
522 rc = DosClose(hFile);
523 SetLastError(error2WinError(rc));
524 return (rc == NO_ERROR);
525}
526//******************************************************************************
527//******************************************************************************
528BOOL OSLibDosCopyFile(LPCSTR lpszOldFile, LPCSTR lpszNewFile, BOOL fFailIfExist)
529{
530 APIRET rc;
531
532 rc = DosCopy((PSZ)lpszOldFile, (PSZ)lpszNewFile, fFailIfExist ? 0: DCPY_EXISTING);
533 SetLastError(error2WinError(rc));
534 return (rc == NO_ERROR);
535}
536//******************************************************************************
537//******************************************************************************
538BOOL OSLibDosMoveFile(LPCSTR lpszOldFile, LPCSTR lpszNewFile)
539{
540 APIRET rc;
541
542 rc = DosMove((PSZ)lpszOldFile, (PSZ)lpszNewFile);
543 SetLastError(error2WinError(rc));
544 return (rc == NO_ERROR);
545}
546//******************************************************************************
547//******************************************************************************
548BOOL OSLibDosRemoveDir(LPCSTR lpszDir)
549{
550 APIRET rc;
551
552 rc = DosDeleteDir((PSZ)lpszDir);
553 SetLastError(error2WinError(rc));
554 return (rc == NO_ERROR);
555}
556//******************************************************************************
557//******************************************************************************
558BOOL OSLibDosCreateDirectory(LPCSTR lpszDir)
559{
560 APIRET rc;
561
562 rc = DosCreateDir((PSZ)lpszDir, NULL);
563 SetLastError(error2WinError(rc));
564 return (rc == NO_ERROR);
565}
566//******************************************************************************
567//******************************************************************************
568DWORD OSLibDosChangeMaxFileHandles()
569{
570 ULONG CurMaxFH;
571 LONG ReqCount = 0;
572 APIRET rc;
573
574 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
575 if(rc) {
576 dprintf(("DosSetRelMaxFH returned %d", rc));
577 return rc;
578 }
579 if(ReqCount + ODIN_INCREMENT_MAX_FILEHANDLES > CurMaxFH) {
580 ReqCount = CurMaxFH + ODIN_INCREMENT_MAX_FILEHANDLES;
581 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
582 if(rc) {
583 dprintf(("DosSetRelMaxFH returned %d", rc));
584 return rc;
585 }
586 }
587 return 0;
588}
589//******************************************************************************
590//******************************************************************************
591DWORD OSLibDosSetInitialMaxFileHandles(DWORD maxhandles)
592{
593 ULONG CurMaxFH;
594 LONG ReqCount = 0;
595 APIRET rc;
596
597 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
598 if(rc) {
599 dprintf(("DosSetRelMaxFH returned %d", rc));
600 return rc;
601 }
602 if(CurMaxFH < maxhandles) {
603 rc = DosSetMaxFH(maxhandles);
604 if(rc) {
605 dprintf(("DosSetMaxFH returned %d", rc));
606 return rc;
607 }
608 }
609 return 0;
610}
611//******************************************************************************
612//******************************************************************************
613BOOL OSLibDosRead(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesRead)
614{
615 APIRET rc;
616
617 rc = DosRead(hFile, lpBuffer, size, nrBytesRead);
618 SetLastError(error2WinError(rc));
619 return (rc == NO_ERROR);
620}
621//******************************************************************************
622//******************************************************************************
623BOOL OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten)
624{
625 APIRET rc;
626
627 rc = DosWrite(hFile, lpBuffer, size, nrBytesWritten);
628 SetLastError(error2WinError(rc));
629 return (rc == NO_ERROR);
630}
631//******************************************************************************
632//******************************************************************************
633DWORD OSLibDosSetFilePtr(DWORD hFile, DWORD offset, DWORD method)
634{
635 DWORD os2method;
636 DWORD newoffset;
637 APIRET rc;
638
639 switch(method)
640 {
641 case OSLIB_SETPTR_FILE_CURRENT:
642 os2method = FILE_CURRENT;
643 break;
644 case OSLIB_SETPTR_FILE_BEGIN:
645 os2method = FILE_BEGIN ;
646 break;
647 case OSLIB_SETPTR_FILE_END:
648 os2method = FILE_END;
649 break;
650 default:
651 return OSLIB_ERROR_INVALID_PARAMETER;
652 }
653
654 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
655 if(rc)
656 {
657 SetLastError(error2WinError(rc));
658 return -1;
659 }
660 else return newoffset;
661}
662//******************************************************************************
663//******************************************************************************
664BOOL OSLibDosDelete(char *lpszFileName)
665{
666 APIRET rc;
667
668 rc = DosDelete(lpszFileName);
669 if(rc) {
670 SetLastError(error2WinError(rc));
671 return FALSE;
672 }
673 return TRUE;
674}
675//******************************************************************************
676//******************************************************************************
677BOOL pmDateTimeToFileTime(FDATE *pDate,FTIME *pTime,FILETIME *pFT)
678{
679 register USHORT dosTime, dosDate;
680
681 dosTime = *(USHORT*)pTime;
682 dosDate = *(USHORT*)pDate;
683
684 // PH: probably replace with faster implementation than calling Open32
685 // through the external interface!
686 return DosDateTimeToFileTime(dosDate,dosTime,pFT);
687}
688//******************************************************************************
689//******************************************************************************
690#define NOT_NORMAL (FILE_ATTRIBUTE_READONLY_W | \
691 FILE_ATTRIBUTE_HIDDEN_W | \
692 FILE_ATTRIBUTE_SYSTEM_W | \
693 FILE_ATTRIBUTE_ARCHIVE_W)
694
695inline DWORD pm2WinFileAttributes(DWORD attrFile)
696{
697 DWORD res = 0;
698
699 if (!(attrFile & NOT_NORMAL))
700 res |= FILE_ATTRIBUTE_NORMAL_W;
701 if (attrFile & FILE_READONLY)
702 res |= FILE_ATTRIBUTE_READONLY_W;
703 if (attrFile & FILE_HIDDEN)
704 res |= FILE_ATTRIBUTE_HIDDEN_W;
705 if (attrFile & FILE_SYSTEM)
706 res |= FILE_ATTRIBUTE_SYSTEM_W;
707 if (attrFile & FILE_DIRECTORY)
708 res |= FILE_ATTRIBUTE_DIRECTORY_W;
709 if (attrFile & FILE_ARCHIVED)
710 res |= FILE_ATTRIBUTE_ARCHIVE_W;
711
712 //CB: not used: FILE_ATTRIBUTE_COMPRESSED_W
713 //PH: NT server will serve appropriate sizes for compressed files
714 // over network. So if realSize < allocatedSize, the file must
715 // be compressed.
716
717 return res;
718}
719//******************************************************************************
720//******************************************************************************
721BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
722 ULONG ulDummy,
723 PVOID pBuffer)
724{
725 APIRET rc; /* API return code */
726 FILESTATUS3 fs3; /* file information structure */
727 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
728
729 // Note: we only handle standard "GetFileExInfoStandard" requests
730 rc = DosQueryPathInfo(pszName, /* query the file information */
731 FIL_STANDARD,
732 &fs3,
733 sizeof(fs3));
734 if (rc != NO_ERROR) /* check for errors */
735 return FALSE; /* raise error condition */
736
737 // convert structure
738 lpFad->dwFileAttributes = pm2WinFileAttributes(fs3.attrFile);
739 pmDateTimeToFileTime(&fs3.fdateCreation, &fs3.ftimeCreation, &lpFad->ftCreationTime);
740 pmDateTimeToFileTime(&fs3.fdateLastAccess, &fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
741 pmDateTimeToFileTime(&fs3.fdateLastWrite, &fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
742
743 /* @@@PH we might add Aurora support ...
744 lpFad->nFileSizeHigh = info.nFileSizeHigh;
745 */
746 lpFad->nFileSizeHigh = 0;
747 lpFad->nFileSizeLow = fs3.cbFile;
748
749 return TRUE;
750}
751//******************************************************************************
752DWORD WIN32API GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD );
753//******************************************************************************
754DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
755 DWORD length_fullname)
756{
757 switch(cmd) {
758 case OSLIB_SEARCHDIR:
759 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
760 name, full_name, length_fullname) != 0) {
761 return 0;
762 }
763 return strlen(full_name);
764
765
766 case OSLIB_SEARCHCURDIR:
767 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
768 name, full_name, length_fullname) != 0) {
769 return 0;
770 }
771 return strlen(full_name);
772
773 case OSLIB_SEARCHFILE:
774 {
775 FILESTATUS3 fileinfo;
776
777 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
778 return 0;
779 }
780 strncpy(full_name, name, length_fullname);
781 full_name[length_fullname-1] = 0;
782 return strlen(full_name);
783 }
784
785 case OSLIB_SEARCHENV:
786 {
787 LPSTR envstring;
788 int envsize;
789 CHAR szResult[CCHMAXPATH];
790
791 envsize = GetEnvironmentVariableA(path, NULL, 0);
792 envstring = (LPSTR)malloc(envsize+1);
793 GetEnvironmentVariableA(path, envstring, envsize);
794 if(DosSearchPath(SEARCH_IGNORENETERRS, envstring,
795 name, szResult, sizeof(szResult)) != 0) {
796 free(envstring);
797 return 0;
798 }
799 free(envstring);
800 strcpy(full_name, szResult);
801 return strlen(full_name);
802 }
803 }
804 return 0;
805}
806//******************************************************************************
807//******************************************************************************
808DWORD OSLibDosQueryPathInfo(CHAR *pszPathName,
809 ULONG ulInfoLevel,
810 PVOID pInfoBuf,
811 ULONG cbInfoBuf)
812{
813 APIRET rc = DosQueryPathInfo( pszPathName, ulInfoLevel,
814 pInfoBuf, cbInfoBuf );
815
816 if(rc == ERROR_TOO_MANY_OPEN_FILES)
817 {
818 LONG reqCount = 2;
819 ULONG maxFiles;
820
821 if(DosSetRelMaxFH(&reqCount, &maxFiles) == NO_ERROR)
822 rc = DosQueryPathInfo(pszPathName, ulInfoLevel,
823 pInfoBuf, cbInfoBuf );
824 }
825 return rc;
826}
827//******************************************************************************
828//******************************************************************************
829DWORD OSLibDosCreateFile(CHAR *lpszFile,
830 DWORD fuAccess,
831 DWORD fuShare,
832 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
833 DWORD fuCreate,
834 DWORD fuAttrFlags,
835 HANDLE hTemplateFile)
836{
837 HFILE hFile;
838 ULONG actionTaken = 0;
839 ULONG fileSize = 0;
840 ULONG fileAttr = FILE_NORMAL;
841 ULONG openFlag = 0;
842 ULONG openMode = 0;
843 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;;
844
845 //TODO: lpSecurityAttributes (inheritance)
846
847 if(fuAttrFlags & FILE_ATTRIBUTE_ARCHIVE_W)
848 fileAttr |= FILE_ARCHIVED;
849 if(fuAttrFlags & FILE_ATTRIBUTE_HIDDEN_W)
850 fileAttr |= FILE_HIDDEN;
851 if(fuAttrFlags & FILE_ATTRIBUTE_SYSTEM_W)
852 fileAttr |= FILE_SYSTEM;
853 if(fuAttrFlags & FILE_ATTRIBUTE_READONLY_W)
854 fileAttr |= FILE_READONLY;
855 // TODO: FILE_ATTRIBUTE_TEMPORARY_W
856
857 switch(fuCreate)
858 {
859 case CREATE_NEW_W:
860 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
861 break;
862 case CREATE_ALWAYS_W:
863 /* kso 2000-11-26: Not sure if OPEN_ACTION_REPLACE_IF_EXISTS is correct here! It is correct according to
864 * MSDN, but not according to "The Win32 API SuperBible". Anyway I haven't got time to check it out in
865 * NT now.
866 * The problem is that OPEN_ACTION_REPLACE_IF_EXISTS requires write access. It failes with
867 * rc = ERROR_ACCESS_DENIED (5). Quick fix, use OPEN_IF_EXIST if readonly access.
868 */
869 if (fuAccess & GENERIC_WRITE_W)
870 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
871 else
872 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
873 break;
874 case OPEN_EXISTING_W:
875 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
876 break;
877 case OPEN_ALWAYS_W:
878 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
879 break;
880 case TRUNCATE_EXISTING_W:
881 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
882 break;
883 }
884
885 if(fuAttrFlags & FILE_FLAG_WRITE_THROUGH_W) openMode |= OPEN_FLAGS_WRITE_THROUGH;
886 if(fuAttrFlags & FILE_FLAG_NO_BUFFERING_W) openMode |= OPEN_FLAGS_NO_CACHE;
887 if(fuAttrFlags & FILE_FLAG_RANDOM_ACCESS_W) openMode |= OPEN_FLAGS_RANDOM;
888 if(fuAttrFlags & FILE_FLAG_SEQUENTIAL_SCAN_W) openMode |= OPEN_FLAGS_SEQUENTIAL;
889 // TODO: FILE_FLAG_BACKUP_SEMANTICS_W
890 // FILE_FLAG_POSIX_SEMANTICS_W are not supported
891
892 //TODO: FILE_SHARE_DELETE
893 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == 0 )
894 openMode |= OPEN_SHARE_DENYREADWRITE;
895 else
896 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
897 openMode |= OPEN_SHARE_DENYNONE;
898 else
899 if(fuShare & FILE_SHARE_READ_W)
900 openMode |= OPEN_SHARE_DENYWRITE;
901 else
902 if(fuShare & FILE_SHARE_WRITE_W)
903 openMode |= OPEN_SHARE_DENYREAD;
904
905 if(fuAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
906 openMode |= OPEN_ACCESS_READWRITE;
907 else
908 if(fuAccess & GENERIC_READ_W)
909 openMode |= OPEN_ACCESS_READONLY;
910 else
911 if(fuAccess & GENERIC_WRITE_W)
912 openMode |= OPEN_ACCESS_WRITEONLY;
913
914#if 0
915 //SvL: Not true; verified in NT! (also messed up access of files on
916 // readonly volumes)
917 // CreateFile with OPEN_ALWAYS & GENERIC_READ on non-existing file
918 // -> creates 0 size file, WriteFile is not allowed
919 // Same in OS/2.
920 /* if creating a file, access cannot be readonly! */
921 if (openFlag & OPEN_ACTION_CREATE_IF_NEW &&
922 (!(openMode & OPEN_ACCESS_READWRITE) &&
923 !(openMode & OPEN_ACCESS_WRITEONLY))) {
924 openMode |= OPEN_ACCESS_READWRITE;
925 }
926#endif
927
928 if(strlen(lpszFile) == 2 && lpszFile[1] == ':') {
929 //app tries to open physical disk
930 openMode |= OPEN_FLAGS_DASD;
931 }
932 int retry = 0;
933 while (retry < 3)
934 {
935 dprintf(("DosOpen %s openFlag=%x openMode=%x", lpszFile, openFlag, openMode));
936 rc = DosOpen((PSZ)lpszFile,
937 &hFile,
938 &actionTaken,
939 fileSize,
940 fileAttr,
941 openFlag,
942 openMode,
943 NULL);
944 if (rc == ERROR_TOO_MANY_OPEN_FILES)
945 {
946 ULONG CurMaxFH;
947 LONG ReqCount = 32;
948
949 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
950 if(rc) {
951 dprintf(("DosSetRelMaxFH returned %d", rc));
952 SetLastError(ERROR_TOO_MANY_OPEN_FILES_W);
953 return INVALID_HANDLE_VALUE_W;
954 }
955 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
956 }
957 #if 0
958 else if (rc == ERROR_ACCESS_DENIED && (openFlag & OPEN_ACTION_REPLACE_IF_EXISTS))
959 { /* kso: I have great problems with the REPLACE not working
960 * So, I guess this emulation may help...
961 * This problem exist on WS4eB SMP FP1 and Warp4 FP14/Kernel 14059 at least.
962 */
963 rc = DosOpen((PSZ)lpszFile,
964 &hFile,
965 &actionTaken,
966 fileSize,
967 fileAttr,
968 (openFlag & ~OPEN_ACTION_REPLACE_IF_EXISTS) | OPEN_ACTION_OPEN_IF_EXISTS,
969 openMode,
970 NULL);
971 if (rc == NO_ERROR)
972 {
973 rc = DosSetFileSize(hFile, 0);
974 if (!rc && fileSize > 0)
975 rc = DosSetFileSize(hFile, fileSize);
976 if (rc)
977 {
978 DosClose(hFile);
979 hFile = NULLHANDLE;
980
981 if (rc != ERROR_TOO_MANY_OPEN_FILES)
982 break;
983 }
984 else break;
985 }
986 }
987 #endif
988 else break;
989 retry++;
990 }
991
992 if(rc)
993 {
994 // @@@AH 2001-06-02 Win2k SP2 returns error 2 in this case
995 int winError = error2WinError(rc);
996 if (winError == ERROR_OPEN_FAILED_W)
997 winError = ERROR_FILE_NOT_FOUND_W;
998 SetLastError(winError);
999 return INVALID_HANDLE_VALUE_W;
1000 }
1001 SetLastError(ERROR_SUCCESS_W);
1002 return hFile;
1003}
1004//******************************************************************************
1005//******************************************************************************
1006DWORD OSLibDosOpenFile(CHAR *lpszFile, UINT fuMode)
1007{
1008 ULONG actionTaken = 0;
1009 ULONG fileSize = 0;
1010 ULONG fileAttr = FILE_NORMAL;
1011 ULONG openFlag = 0;
1012 ULONG openMode = 0;
1013 APIRET rc = ERROR_NOT_ENOUGH_MEMORY;
1014 HFILE hFile;
1015
1016 if(!(fuMode & (OF_CREATE_W | OF_READWRITE_W | OF_WRITE_W)))
1017 {
1018 openMode |= OPEN_ACCESS_READONLY;
1019 openFlag |= OPEN_ACTION_OPEN_IF_EXISTS;
1020 }
1021 else
1022 {
1023 if(fuMode & OF_CREATE_W) {
1024 openFlag |= OPEN_ACTION_CREATE_IF_NEW |
1025 OPEN_ACTION_REPLACE_IF_EXISTS;
1026 }
1027 else openFlag |= OPEN_ACTION_OPEN_IF_EXISTS;
1028
1029 if(fuMode & OF_READWRITE_W)
1030 openMode |= OPEN_ACCESS_READWRITE;
1031 else
1032 if(fuMode & OF_WRITE_W)
1033 openMode |= OPEN_ACCESS_WRITEONLY;
1034 else
1035 if(fuMode & OF_CREATE_W)
1036 openMode |= OPEN_ACCESS_READWRITE;
1037 }
1038
1039 if((fuMode & OF_SHARE_DENY_WRITE_W) ||
1040 !(fuMode & (OF_SHARE_DENY_READ_W | OF_SHARE_DENY_NONE_W | OF_SHARE_EXCLUSIVE_W)))
1041 openMode |= OPEN_SHARE_DENYWRITE;
1042 else
1043 if (fuMode & OF_SHARE_DENY_NONE_W)
1044 openMode |= OPEN_SHARE_DENYNONE;
1045 else
1046 if (fuMode & OF_SHARE_DENY_READ_W)
1047 openMode |= OPEN_SHARE_DENYREAD;
1048 else
1049 if (fuMode & OF_SHARE_EXCLUSIVE_W)
1050 openMode |= OPEN_SHARE_DENYREADWRITE;
1051
1052 rc = DosOpen((PSZ)lpszFile,
1053 &hFile,
1054 &actionTaken,
1055 fileSize,
1056 fileAttr,
1057 openFlag,
1058 openMode,
1059 NULL);
1060
1061 if(rc != NO_ERROR)
1062 {
1063 if(fuMode & OF_EXIST_W)
1064 {
1065 if(rc == ERROR_OPEN_FAILED || rc == ERROR_FILE_NOT_FOUND)
1066 {
1067 SetLastError(ERROR_FILE_NOT_FOUND_W);
1068 return HFILE_ERROR_W;
1069 }
1070 }
1071 if((rc == ERROR_OPEN_FAILED) && (openFlag & OPEN_ACTION_OPEN_IF_EXISTS))
1072 {
1073 SetLastError(ERROR_FILE_NOT_FOUND_W);
1074 }
1075 else SetLastError(error2WinError(rc));
1076
1077 return HFILE_ERROR_W;
1078 }
1079 SetLastError(ERROR_SUCCESS_W);
1080 return hFile;
1081}
1082//******************************************************************************
1083//******************************************************************************
1084BOOL OSLibDosLockFile(DWORD hFile, DWORD dwFlags,
1085 DWORD OffsetLow, DWORD OffsetHigh,
1086 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
1087 LPOVERLAPPED lpOverlapped)
1088{
1089 APIRET rc;
1090
1091 // Set 5 secs timeout for locking file and no other can access this
1092 // file region
1093
1094 if(lpOverlapped) {//TODO:
1095 dprintf(("OSLibDosLockFile: overlapped lock not yet implemented!!"));
1096 }
1097 //TODO: Locking region crossing end of file is permitted. Works in OS/2??
1098 if(f64BitIO)
1099 {
1100 FILELOCKL lockRangeL;
1101
1102 lockRangeL.lOffset.ulLo = OffsetLow;
1103 lockRangeL.lOffset.ulHi = OffsetHigh;
1104 lockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
1105 lockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
1106
1107 rc = OdinDosSetFileLocksL(hFile, NULL, &lockRangeL,
1108 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
1109 //SvL: 64 bits values are only supported by JFS
1110 // Try the 32 bits DosSetFileLocks if it fails
1111 // (TODO: should check the partition type instead)
1112 if(rc == ERROR_INVALID_PARAMETER && (OffsetHigh || nNumberOfBytesToLockHigh)) {
1113 goto oldlock;
1114 }
1115 }
1116 else
1117 {
1118oldlock:
1119 FILELOCK lockRange = { OffsetLow, nNumberOfBytesToLockLow };
1120
1121 rc = DosSetFileLocks(hFile, NULL, &lockRange,
1122 (dwFlags & LOCKFILE_FAIL_IMMEDIATELY_W) ? 0 : 5000, 0);
1123 }
1124 if(rc) {
1125 SetLastError(error2WinError(rc));
1126 return FALSE;
1127 }
1128 SetLastError(ERROR_SUCCESS_W);
1129 return TRUE;
1130}
1131//******************************************************************************
1132//******************************************************************************
1133BOOL OSLibDosUnlockFile(DWORD hFile, DWORD OffsetLow, DWORD OffsetHigh,
1134 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
1135 LPOVERLAPPED lpOverlapped)
1136{
1137 APIRET rc;
1138
1139 // Set 5 secs timeout for unlocking file and no other can access this
1140 // file region
1141
1142 if(lpOverlapped) {//TODO:
1143 dprintf(("OSLibDosUnlockFile: overlapped unlock not yet implemented!!"));
1144 }
1145 if(f64BitIO)
1146 {
1147 FILELOCKL unlockRangeL;
1148
1149 unlockRangeL.lOffset.ulLo = OffsetLow;
1150 unlockRangeL.lOffset.ulHi = OffsetHigh;
1151 unlockRangeL.lRange.ulLo = nNumberOfBytesToLockLow;
1152 unlockRangeL.lRange.ulHi = nNumberOfBytesToLockHigh;
1153
1154 rc = OdinDosSetFileLocksL(hFile, &unlockRangeL, NULL, 5000, 0);
1155 //SvL: 64 bits values are only supported by JFS
1156 // Try the 32 bits DosSetFileLocks if it fails
1157 // (TODO: should check the partition type instead)
1158 if(rc == ERROR_INVALID_PARAMETER && (OffsetHigh || nNumberOfBytesToLockHigh)) {
1159 goto oldlock;
1160 }
1161 }
1162 else
1163 {
1164oldlock:
1165 FILELOCK unlockRange = { OffsetLow, nNumberOfBytesToLockLow };
1166
1167 rc = DosSetFileLocks(hFile, &unlockRange, NULL, 5000, 0);
1168 }
1169 if(rc) {
1170 SetLastError(error2WinError(rc));
1171 return FALSE;
1172 }
1173 SetLastError(ERROR_SUCCESS_W);
1174 return TRUE;
1175}
1176//******************************************************************************
1177//******************************************************************************
1178BOOL OSLibDosFlushFileBuffers(DWORD hFile)
1179{
1180 APIRET rc;
1181
1182 rc = DosResetBuffer(hFile);
1183 SetLastError(error2WinError(rc));
1184 return (rc == NO_ERROR);
1185}
1186//******************************************************************************
1187//******************************************************************************
1188DWORD OSLibDosGetFileSize(DWORD hFile, LPDWORD lpdwFileSizeHigh)
1189{
1190 APIRET rc;
1191 ULONG sizeLow;
1192
1193 if(f64BitIO)
1194 {
1195 FILESTATUS3L fsts3ConfigInfoL = {{0}};
1196 ULONG ulBufSize = sizeof(FILESTATUS3L);
1197
1198 rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &fsts3ConfigInfoL, ulBufSize);
1199 if(lpdwFileSizeHigh) {
1200 *lpdwFileSizeHigh = fsts3ConfigInfoL.cbFile.ulHi;
1201 }
1202 sizeLow = fsts3ConfigInfoL.cbFile.ulLo;
1203 }
1204 else
1205 {
1206 FILESTATUS3 fsts3ConfigInfo = {{0}};
1207 ULONG ulBufSize = sizeof(FILESTATUS3);
1208
1209 if(lpdwFileSizeHigh) {
1210 *lpdwFileSizeHigh = 0;
1211 }
1212 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
1213 sizeLow = fsts3ConfigInfo.cbFile;
1214 }
1215 if(rc) {
1216 SetLastError(error2WinError(rc));
1217 return -1;
1218 }
1219 SetLastError(ERROR_SUCCESS_W);
1220 return sizeLow;
1221}
1222//******************************************************************************
1223//******************************************************************************
1224DWORD OSLibDosSetFilePointer(DWORD hFile, DWORD OffsetLow, DWORD *OffsetHigh, DWORD method)
1225{
1226 LONGLONG offsetL;
1227 LONGLONG newoffsetL;
1228 APIRET rc;
1229 DWORD newoffset;
1230
1231 switch(method)
1232 {
1233 case FILE_BEGIN_W:
1234 method = FILE_BEGIN;
1235 break;
1236
1237 case FILE_CURRENT_W:
1238 method = FILE_CURRENT;
1239 break;
1240
1241 case FILE_END_W:
1242 method = FILE_END;
1243 break;
1244 }
1245
1246 // PH Note: for a negative 32-bit seek, the OS/2 64-bit version
1247 // needs to be skipped.
1248 if( (f64BitIO) && (OffsetHigh) )
1249 {
1250 offsetL.ulLo = OffsetLow;
1251 offsetL.ulHi = (OffsetHigh) ? *OffsetHigh : 0;
1252 rc = OdinDosSetFilePtrL(hFile, offsetL, method, &newoffsetL);
1253 if(OffsetHigh) {
1254 *OffsetHigh = newoffsetL.ulHi;
1255 }
1256 newoffset = newoffsetL.ulLo;
1257 }
1258 else rc = DosSetFilePtr(hFile, OffsetLow, method, &newoffset);
1259
1260 if(rc)
1261 {
1262 SetLastError(error2WinError(rc));
1263 return -1;
1264 }
1265 SetLastError(ERROR_SUCCESS_W);
1266 return newoffset;
1267}
1268//******************************************************************************
1269//******************************************************************************
1270BOOL OSLibDosSetEndOfFile(DWORD hFile)
1271{
1272 ULONG newFilePos;
1273 LONGLONG FilePosL = {0,0};
1274 LONGLONG newFilePosL;
1275 APIRET rc;
1276
1277 if(f64BitIO) {
1278 rc = OdinDosSetFilePtrL(hFile, FilePosL, FILE_CURRENT, &newFilePosL);
1279 if(rc == 0) {
1280 rc = OdinDosSetFileSizeL(hFile, newFilePosL);
1281 }
1282 }
1283 else {
1284 rc = DosSetFilePtr(hFile, 0, FILE_CURRENT, &newFilePos);
1285 if(rc == 0) {
1286 rc = DosSetFileSize(hFile, newFilePos);
1287 }
1288 }
1289 if(rc) {
1290 SetLastError(error2WinError(rc));
1291 return FALSE;
1292 }
1293 SetLastError(ERROR_SUCCESS_W);
1294 return TRUE;
1295}
1296//******************************************************************************
1297//******************************************************************************
1298BOOL OSLibDosGetFileInformationByHandle(DWORD hFile, BY_HANDLE_FILE_INFORMATION* pInfo)
1299{
1300 APIRET rc;
1301
1302 if(f64BitIO)
1303 {
1304 FILESTATUS4L statusL = { 0 };
1305
1306 rc = DosQueryFileInfo(hFile, FIL_QUERYEASIZEL,
1307 &statusL, sizeof(statusL));
1308 if(rc == NO_ERROR)
1309 {
1310 pInfo->dwFileAttributes = 0;
1311 if(!(statusL.attrFile & NOT_NORMAL))
1312 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1313 if(statusL.attrFile & FILE_READONLY)
1314 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1315 if(statusL.attrFile & FILE_HIDDEN)
1316 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1317 if(statusL.attrFile & FILE_SYSTEM)
1318 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1319 if(statusL.attrFile & FILE_DIRECTORY)
1320 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1321 if(statusL.attrFile & FILE_ARCHIVED)
1322 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1323
1324 pmDateTimeToFileTime(&statusL.fdateCreation,
1325 &statusL.ftimeCreation,
1326 &pInfo->ftCreationTime);
1327 pmDateTimeToFileTime(&statusL.fdateLastAccess,
1328 &statusL.ftimeLastAccess,
1329 &pInfo->ftLastAccessTime);
1330 pmDateTimeToFileTime(&statusL.fdateLastWrite,
1331 &statusL.ftimeLastWrite,
1332 &pInfo->ftLastWriteTime);
1333
1334 pInfo->nFileSizeHigh = statusL.cbFile.ulHi;
1335 pInfo->nFileSizeLow = statusL.cbFile.ulLo;
1336 pInfo->dwVolumeSerialNumber = 0; //todo
1337 pInfo->nNumberOfLinks = 1;
1338 pInfo->nFileIndexHigh = 0;
1339 pInfo->nFileIndexLow = 0;
1340 }
1341 }
1342 else
1343 {
1344 FILESTATUS4 status = { 0 };
1345
1346 rc = DosQueryFileInfo(hFile, FIL_QUERYEASIZE, &status,
1347 sizeof(status));
1348 if(rc == NO_ERROR)
1349 {
1350 pInfo->dwFileAttributes = 0;
1351 if(!(status.attrFile & NOT_NORMAL))
1352 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL_W;
1353 if(status.attrFile & FILE_READONLY)
1354 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_READONLY_W;
1355 if(status.attrFile & FILE_HIDDEN)
1356 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN_W;
1357 if(status.attrFile & FILE_SYSTEM)
1358 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_SYSTEM_W;
1359 if(status.attrFile & FILE_DIRECTORY)
1360 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY_W;
1361 if(status.attrFile & FILE_ARCHIVED)
1362 pInfo->dwFileAttributes |= FILE_ATTRIBUTE_ARCHIVE_W;
1363
1364 pmDateTimeToFileTime(&status.fdateCreation,
1365 &status.ftimeCreation,
1366 &pInfo->ftCreationTime);
1367 pmDateTimeToFileTime(&status.fdateLastAccess,
1368 &status.ftimeLastAccess,
1369 &pInfo->ftLastAccessTime);
1370 pmDateTimeToFileTime(&status.fdateLastWrite,
1371 &status.ftimeLastWrite,
1372 &pInfo->ftLastWriteTime);
1373
1374 pInfo->nFileSizeHigh = 0;
1375 pInfo->nFileSizeLow = status.cbFile;
1376 pInfo->dwVolumeSerialNumber = 0; //todo
1377 pInfo->nNumberOfLinks = 1;
1378 pInfo->nFileIndexHigh = 0;
1379 pInfo->nFileIndexLow = 0;
1380 }
1381 }
1382 if(rc) {
1383 SetLastError(error2WinError(rc));
1384 return FALSE;
1385 }
1386 SetLastError(ERROR_SUCCESS_W);
1387 return TRUE;
1388}
1389//******************************************************************************
1390//******************************************************************************
1391BOOL OSLibDosSetFileTime(DWORD hFile, WORD creationdate, WORD creationtime,
1392 WORD lastaccessdate, WORD lastaccesstime,
1393 WORD lastwritedate, WORD lastwritetime)
1394{
1395 FILESTATUS3 fileInfo;
1396 APIRET rc;
1397
1398 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1399
1400 if(rc == NO_ERROR)
1401 {
1402 if(creationdate && creationtime) {
1403 fileInfo.fdateCreation = *(FDATE *)&creationdate;
1404 fileInfo.ftimeCreation = *(FTIME *)&creationtime;
1405 }
1406 if(lastaccessdate && lastaccesstime) {
1407 fileInfo.fdateLastAccess = *(FDATE *)&lastaccessdate;
1408 fileInfo.ftimeLastAccess = *(FTIME *)&lastaccesstime;
1409 }
1410 if(lastwritedate && lastwritetime) {
1411 fileInfo.fdateLastWrite = *(FDATE *)&lastwritedate;
1412 fileInfo.ftimeLastWrite = *(FTIME *)&lastwritetime;
1413 }
1414
1415 rc = DosSetFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1416 }
1417
1418 if(rc)
1419 {
1420 SetLastError(error2WinError(rc));
1421 return FALSE;
1422 }
1423 SetLastError(ERROR_SUCCESS_W);
1424 return TRUE;
1425}
1426//******************************************************************************
1427//******************************************************************************
1428BOOL OSLibDosGetFileTime(DWORD hFile, WORD *creationdate, WORD *creationtime,
1429 WORD *lastaccessdate, WORD *lastaccesstime,
1430 WORD *lastwritedate, WORD *lastwritetime)
1431{
1432 FILESTATUS3 fileInfo;
1433 APIRET rc;
1434
1435 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fileInfo, sizeof(fileInfo));
1436
1437 if(rc == NO_ERROR)
1438 {
1439 *creationdate = *(WORD *)&fileInfo.fdateCreation;
1440 *creationtime = *(WORD *)&fileInfo.ftimeCreation;
1441 *lastaccessdate = *(WORD *)&fileInfo.fdateLastAccess;
1442 *lastaccesstime = *(WORD *)&fileInfo.ftimeLastAccess;
1443 *lastwritedate = *(WORD *)&fileInfo.fdateLastWrite;
1444 *lastwritetime = *(WORD *)&fileInfo.ftimeLastWrite;
1445 }
1446
1447 if(rc)
1448 {
1449 SetLastError(error2WinError(rc));
1450 return FALSE;
1451 }
1452 SetLastError(ERROR_SUCCESS_W);
1453 return TRUE;
1454}
1455//******************************************************************************
1456//******************************************************************************
1457DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
1458{
1459 DWORD newoffset;
1460 APIRET rc;
1461
1462
1463 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
1464 if(rc) {
1465 dprintf(("DosSetFilePtr Error rc:%d", rc));
1466 return -1;
1467 }
1468 else return newoffset;
1469}
1470//******************************************************************************
1471//******************************************************************************
1472DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
1473{
1474 *hNew = -1;
1475 return DosDupHandle(hFile, hNew);
1476}
1477//******************************************************************************
1478//******************************************************************************
1479void OSLibDosDisableHardError(BOOL fTurnOff)
1480{
1481 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
1482}
1483//******************************************************************************
1484//Returns time spent in kernel & user mode in milliseconds
1485//******************************************************************************
1486BOOL OSLibDosQueryProcTimes(DWORD procid, ULONG *kerneltime, ULONG *usertime)
1487{
1488 APIRET rc;
1489 char *buf;
1490 ULONG size;
1491 ULONG nrthreads = 4;
1492
1493tryagain:
1494 size = sizeof(QTOPLEVEL)+sizeof(QGLOBAL)+sizeof(QPROCESS) + nrthreads*sizeof(QTHREAD);
1495 buf = (char *)malloc(size);
1496 rc = DosQuerySysState(0x1, RESERVED, procid, RESERVED, (PCHAR)buf, size);
1497
1498 if(rc) {
1499 free(buf);
1500 if(rc == ERROR_BUFFER_OVERFLOW) {
1501 nrthreads += 4;
1502 goto tryagain;
1503 }
1504 return FALSE;
1505 }
1506 PQTOPLEVEL top = (PQTOPLEVEL)buf;
1507
1508 *kerneltime = 0;
1509 *usertime = 0;
1510 for(int i=0;i<top->procdata->threadcnt;i++) {
1511 *kerneltime += top->procdata->threads[i].systime;
1512 *usertime += top->procdata->threads[i].usertime;
1513 }
1514 free(buf);
1515 return TRUE;
1516}
1517//******************************************************************************
1518//******************************************************************************
1519// TODO: implement SecurityAttributes parameter
1520DWORD OSLibDosCreateNamedPipe(LPCTSTR lpName,
1521 DWORD dwOpenMode,
1522 DWORD dwPipeMode,
1523 DWORD nMaxInstances,
1524 DWORD nOutBufferSize,
1525 DWORD nInBufferSize,
1526 DWORD nDefaultTimeOut,
1527 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
1528{ DWORD dwOS2Mode = 0;
1529 DWORD dwOS2PipeMode = 0;
1530 LPSTR lpOS2Name;
1531 DWORD hPipe;
1532 DWORD rc, ulAction;
1533
1534 if (dwOpenMode & PIPE_ACCESS_DUPLEX_W)
1535 dwOS2Mode |= NP_ACCESS_DUPLEX;
1536 else
1537 if (dwOpenMode & PIPE_ACCESS_INBOUND_W)
1538 dwOS2Mode |= NP_ACCESS_INBOUND;
1539 else
1540 if (dwOpenMode & PIPE_ACCESS_OUTBOUND_W)
1541 dwOS2Mode |= NP_ACCESS_OUTBOUND;
1542 // TODO:
1543 // if(dwOpenMode & FILE_FLAG_OVERLAPPED)
1544 // if(dwOpenMode & WRITE_DAC)
1545 // if(dwOpenMode & WRITE_OWNER)
1546 // if(dwOpenMode & ACCESS_SYSTEM_SECURITY)
1547 if(dwOpenMode & FILE_FLAG_WRITE_THROUGH_W)
1548 dwOS2Mode |= NP_WRITEBEHIND; // FIXME: I'm not sure!
1549
1550 if (dwPipeMode & PIPE_WAIT_W)
1551 dwOS2PipeMode |= NP_WAIT;
1552 if (dwPipeMode & PIPE_NOWAIT_W)
1553 dwOS2PipeMode |= NP_NOWAIT;
1554 if (dwPipeMode & PIPE_READMODE_BYTE_W)
1555 dwOS2PipeMode |= NP_READMODE_BYTE;
1556 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
1557 dwOS2PipeMode |= NP_READMODE_MESSAGE;
1558 if (dwPipeMode & PIPE_TYPE_BYTE_W)
1559 dwOS2PipeMode |= NP_TYPE_BYTE;
1560 if (dwPipeMode & PIPE_TYPE_MESSAGE_W)
1561 dwOS2PipeMode |= NP_TYPE_MESSAGE;
1562
1563 if (nMaxInstances>0xff)
1564 {
1565 SetLastError(ERROR_INVALID_PARAMETER_W); // ERROR_INVALID_PARAMETER
1566 return -1; // INVALID_HANDLE_VALUE
1567 }
1568 dwOS2PipeMode |= nMaxInstances;
1569
1570 if (strstr(lpName,"\\\\."))
1571 {
1572 // If pipe is created on the local machine
1573 // we must delete string \\. because
1574 // in Windows named pipes scheme is a \\.\PIPE\pipename
1575 // but in OS/2 only \PIPE\pipename
1576 lpOS2Name = (LPSTR)lpName + 3;
1577 }
1578 else lpOS2Name = (LPSTR)lpName;
1579
1580 dprintf(("DosCreateNPipe(%s,%x,%x,%x,%x,%x)",lpOS2Name,dwOS2Mode,dwOS2PipeMode,nInBufferSize,nOutBufferSize,nDefaultTimeOut));
1581
1582 //if the windows app tries to open another instance of an existing pipe, then
1583 //we must use DosOpen here. So first try DosOpen, if that fails then we can
1584 //create the named pipe
1585 rc = DosOpen(lpOS2Name, &hPipe, &ulAction, 0, FILE_NORMAL, FILE_OPEN,
1586 ((dwOpenMode & PIPE_ACCESS_INBOUND_W) ? OPEN_ACCESS_READWRITE : OPEN_ACCESS_READONLY) |
1587 OPEN_SHARE_DENYNONE, NULL);
1588
1589 if(rc == NO_ERROR) {
1590 dprintf(("Opening of existing named pipe succeeded"));
1591 return hPipe;
1592 }
1593
1594 rc=DosCreateNPipe(lpOS2Name,
1595 &hPipe,
1596 dwOS2Mode,
1597 dwOS2PipeMode,
1598 nInBufferSize,
1599 nInBufferSize,
1600 nDefaultTimeOut); // Timeouts must be tested!
1601
1602 dprintf(("DosCreateNPipe rc=%d",rc));
1603 if (rc)
1604 {
1605 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
1606 return -1; // INVALID_HANDLE_VALUE
1607 }
1608 return hPipe;
1609}
1610//******************************************************************************
1611//******************************************************************************
1612BOOL OSLibSetNamedPipeState(DWORD hNamedPipe, DWORD dwPipeMode)
1613{
1614 ULONG dwOS2PipeMode = 0;
1615 APIRET rc;
1616
1617 if (dwPipeMode & PIPE_WAIT_W)
1618 dwOS2PipeMode |= NP_WAIT;
1619 if (dwPipeMode & PIPE_NOWAIT_W)
1620 dwOS2PipeMode |= NP_NOWAIT;
1621 if (dwPipeMode & PIPE_READMODE_BYTE_W)
1622 dwOS2PipeMode |= NP_READMODE_BYTE;
1623 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
1624 dwOS2PipeMode |= NP_READMODE_MESSAGE;
1625
1626 rc = DosSetNPHState(hNamedPipe, dwOS2PipeMode);
1627 if(rc) {
1628 SetLastError(error2WinError(rc, ERROR_INVALID_PARAMETER_W));
1629 return FALSE;
1630 }
1631 return TRUE;
1632}
1633//******************************************************************************
1634//******************************************************************************
1635DWORD OSLibDosOpenPipe(LPCTSTR lpName,
1636 DWORD fuAccess,
1637 DWORD fuShare,
1638 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1639 DWORD fuCreate,
1640 DWORD fuAttrFlags)
1641{
1642 LPSTR lpOS2Name;
1643 ULONG hPipe;
1644 ULONG rc, ulAction;
1645 ULONG openFlag = 0;
1646 ULONG openMode = 0;
1647
1648
1649 switch(fuCreate)
1650 {
1651 case CREATE_NEW_W:
1652 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
1653 break;
1654 case CREATE_ALWAYS_W:
1655 /* kso 2000-11-26: Not sure if OPEN_ACTION_REPLACE_IF_EXISTS is correct here! It is correct according to
1656 * MSDN, but not according to "The Win32 API SuperBible". Anyway I haven't got time to check it out in
1657 * NT now.
1658 * The problem is that OPEN_ACTION_REPLACE_IF_EXISTS requires write access. It failes with
1659 * rc = ERROR_ACCESS_DENIED (5). Quick fix, use OPEN_IF_EXIST if readonly access.
1660 */
1661 if (fuAccess & GENERIC_WRITE_W)
1662 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
1663 else
1664 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
1665 break;
1666 case OPEN_EXISTING_W:
1667 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
1668 break;
1669 case OPEN_ALWAYS_W:
1670 openFlag |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
1671 break;
1672 case TRUNCATE_EXISTING_W:
1673 openFlag |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
1674 break;
1675 }
1676
1677 if(fuAttrFlags & FILE_FLAG_WRITE_THROUGH_W) openMode |= OPEN_FLAGS_WRITE_THROUGH;
1678 if(fuAttrFlags & FILE_FLAG_NO_BUFFERING_W) openMode |= OPEN_FLAGS_NO_CACHE;
1679 if(fuAttrFlags & FILE_FLAG_RANDOM_ACCESS_W) openMode |= OPEN_FLAGS_RANDOM;
1680 if(fuAttrFlags & FILE_FLAG_SEQUENTIAL_SCAN_W) openMode |= OPEN_FLAGS_SEQUENTIAL;
1681 // TODO: FILE_FLAG_BACKUP_SEMANTICS_W
1682 // FILE_FLAG_POSIX_SEMANTICS_W are not supported
1683
1684 //TODO: FILE_SHARE_DELETE
1685 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == 0 )
1686 openMode |= OPEN_SHARE_DENYREADWRITE;
1687 else
1688 if((fuShare & (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W)) == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
1689 openMode |= OPEN_SHARE_DENYNONE;
1690 else
1691 if(fuShare & FILE_SHARE_READ_W)
1692 openMode |= OPEN_SHARE_DENYWRITE;
1693 else
1694 if(fuShare & FILE_SHARE_WRITE_W)
1695 openMode |= OPEN_SHARE_DENYREAD;
1696
1697 if(fuAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
1698 openMode |= OPEN_ACCESS_READWRITE;
1699 else
1700 if(fuAccess & GENERIC_READ_W)
1701 openMode |= OPEN_ACCESS_READONLY;
1702 else
1703 if(fuAccess & GENERIC_WRITE_W)
1704 openMode |= OPEN_ACCESS_WRITEONLY;
1705
1706 if (strstr(lpName,"\\\\."))
1707 {
1708 // If pipe is created on the local machine
1709 // we must delete string \\. because
1710 // in Windows named pipes scheme is a \\.\PIPE\pipename
1711 // but in OS/2 only \PIPE\pipename
1712 lpOS2Name = (LPSTR)lpName + 3;
1713 }
1714 else lpOS2Name = (LPSTR)lpName;
1715
1716 rc = DosOpen(lpOS2Name, &hPipe, &ulAction, 0, 0,
1717 openFlag, openMode, NULL);
1718
1719 if(rc == NO_ERROR) {
1720 dprintf(("Opening of existing named pipe succeeded"));
1721 return hPipe;
1722 }
1723
1724 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
1725 return -1; // INVALID_HANDLE_VALUE
1726}
1727
1728//******************************************************************************
1729//******************************************************************************
1730// TODO: implement lpOverlapped parameter!
1731BOOL OSLibDosConnectNamedPipe(DWORD hNamedPipe, LPOVERLAPPED lpOverlapped)
1732{
1733 DWORD rc;
1734
1735 rc=DosConnectNPipe(hNamedPipe);
1736 dprintf(("DosConnectNPipe rc=%d",rc));
1737
1738 if (!rc) return (TRUE);
1739 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1740
1741 return (FALSE);
1742}
1743
1744//******************************************************************************
1745//******************************************************************************
1746BOOL OSLibDosCallNamedPipe( LPCTSTR lpNamedPipeName,
1747 LPVOID lpInBuffer,
1748 DWORD nInBufferSize,
1749 LPVOID lpOutBuffer,
1750 DWORD nOutBufferSize,
1751 LPDWORD lpBytesRead,
1752 DWORD nTimeOut )
1753{
1754 LPSTR lpOS2Name;
1755 DWORD rc;
1756
1757 if (strstr(lpNamedPipeName,"\\\\."))
1758 {
1759 // If pipe is created on the local machine
1760 // we must delete string \\. because
1761 // in Windows named pipes scheme is a \\.\PIPE\pipename
1762 // but in OS/2 only \PIPE\pipename
1763 lpOS2Name = (LPSTR)lpNamedPipeName + 3;
1764 }
1765 else lpOS2Name = (LPSTR)lpNamedPipeName;
1766
1767 rc=DosCallNPipe(lpOS2Name,
1768 lpInBuffer,
1769 nInBufferSize,
1770 lpOutBuffer,
1771 nOutBufferSize,
1772 lpBytesRead,
1773 nTimeOut );
1774
1775
1776 if (!rc) return (TRUE);
1777 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1778
1779 return (FALSE);
1780}
1781
1782//******************************************************************************
1783//******************************************************************************
1784BOOL OSLibDosTransactNamedPipe( DWORD hNamedPipe,
1785 LPVOID lpInBuffer,
1786 DWORD nInBufferSize,
1787 LPVOID lpOutBuffer,
1788 DWORD nOutBufferSize,
1789 LPDWORD lpBytesRead,
1790 LPOVERLAPPED lpOverlapped)
1791{
1792 DWORD rc;
1793
1794 rc=DosTransactNPipe(hNamedPipe,
1795 lpOutBuffer,
1796 nOutBufferSize,
1797 lpInBuffer,
1798 nInBufferSize,
1799 lpBytesRead);
1800
1801 dprintf(("DosTransactNPipe returned rc=%d");)
1802 if (!rc) return (TRUE);
1803 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1804
1805 return (FALSE);
1806}
1807
1808//******************************************************************************
1809//******************************************************************************
1810BOOL OSLibDosPeekNamedPipe(DWORD hPipe,
1811 LPVOID lpvBuffer,
1812 DWORD cbBuffer,
1813 LPDWORD lpcbRead,
1814 LPDWORD lpcbAvail,
1815 LPDWORD lpcbMessage)
1816{
1817 DWORD rc;
1818 AVAILDATA availData ={0};
1819 ULONG ulDummy;
1820
1821 rc=DosPeekNPipe(hPipe,lpvBuffer,cbBuffer,lpcbRead,&availData,&ulDummy);
1822
1823 dprintf(("DosPeekNPipe returned rc=%d",rc));
1824
1825 if (!rc)
1826 {
1827 *lpcbAvail = availData.cbpipe;
1828 *lpcbMessage = availData.cbmessage;
1829 return (TRUE);
1830 }
1831 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1832
1833 return (FALSE);
1834}
1835//******************************************************************************
1836//******************************************************************************
1837BOOL OSLibDosDisconnectNamedPipe(DWORD hPipe)
1838{
1839 DWORD rc;
1840
1841 rc=DosDisConnectNPipe(hPipe);
1842
1843 dprintf(("DosDisConnectNPipe returned rc=%d",rc));
1844
1845 if (!rc) return TRUE;
1846 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1847
1848 return (FALSE);
1849}
1850//******************************************************************************
1851//******************************************************************************
1852BOOL OSLibDosWaitNamedPipe(LPCSTR lpszNamedPipeName,
1853 DWORD dwTimeout)
1854{
1855 LPSTR lpOS2Name;
1856 DWORD rc;
1857
1858 if (strstr(lpszNamedPipeName,"\\\\."))
1859 {
1860 // If pipe is created on the local machine
1861 // we must delete string \\. because
1862 // in Windows named pipes scheme is a \\.\PIPE\pipename
1863 // but in OS/2 only \PIPE\pipename
1864 lpOS2Name = (LPSTR)lpszNamedPipeName + 3;
1865 }
1866 else lpOS2Name = (LPSTR)lpszNamedPipeName;
1867
1868 rc=DosWaitNPipe(lpOS2Name,dwTimeout);
1869
1870 dprintf(("DosWaitNPipe returned rc=%d",rc));
1871
1872 if (!rc) return TRUE;
1873 SetLastError(error2WinError(rc,ERROR_PIPE_NOT_CONNECTED_W));
1874
1875 return (FALSE);
1876}
1877//******************************************************************************
1878//******************************************************************************
1879BOOL isRoot(CHAR* name)
1880{
1881 if (name[1] == ':')
1882 {
1883 //local name (x:\)
1884 return (name[2] == 0) || !strchr(&name[3],'\\');
1885 } else if (name[0] == '\\')
1886 {
1887 //UNC name (\\resource\drive\)
1888 CHAR *drive,*dir;
1889
1890 drive = strchr(&name[2],'\\');
1891 if (!drive) return FALSE;
1892 dir = strchr(&drive[1],'\\');
1893 if (!dir) return TRUE;
1894 return !strchr(&dir[1],'\\');
1895 } else return FALSE; //unknown
1896}
1897//******************************************************************************
1898//******************************************************************************
1899inline CHAR system2DOSCharacter(CHAR ch)
1900{
1901 switch(ch)
1902 {
1903 case ' ':
1904 case '.':
1905 case '~':
1906 return '_';
1907
1908 default:
1909 return toupper(ch);
1910 }
1911}
1912
1913// TODO: not finished nor correct!!!!
1914VOID long2ShortName(CHAR* longName, CHAR* shortName)
1915{
1916 // check for uplink / root: "." and ".."
1917 if (longName[0] == '.')
1918 {
1919 // if ((strcmp(longName,".") == 0) || (strcmp(longName,"..") == 0))
1920 if (longName[1] == 0) // "."
1921 {
1922 shortName[0] = '.';
1923 shortName[1] = 0;
1924 return;
1925 }
1926
1927 if (longName[1] == '.' && longName[2] == 0) // ".."
1928 {
1929 shortName[0] = '.';
1930 shortName[1] = '.';
1931 shortName[2] = 0;
1932 return;
1933 }
1934 }
1935 else
1936 // check for empty name
1937 if(longName[0] == 0)
1938 {
1939 shortName[0] = 0;
1940 return;
1941 }
1942
1943 INT x;
1944 CHAR *source = longName;
1945
1946 // Test if longName is 8:3 compliant and simply copy
1947 // the filename.
1948 BOOL flag83 = TRUE;
1949
1950 // verify forbidden characters
1951 for (x = 0;
1952 (x < 8) &&
1953 (flag83 == TRUE);
1954 x++)
1955 {
1956 switch (*source)
1957 {
1958 case '.': // a period will cause the loop to abort!
1959 x=1000;
1960 break;
1961
1962 case '/': case '?':
1963 case '*': case ':':
1964 case '\\': case '"':
1965 case ' ':
1966 flag83 = FALSE;
1967 break;
1968 default:
1969 source++;
1970 break;
1971 }
1972 }
1973
1974 // verify we're on a period now
1975 if (flag83 == TRUE)
1976 if (*source != '.')
1977 flag83 = FALSE;
1978 else source++;
1979
1980 // verify extension
1981 if (flag83 == TRUE)
1982 for (INT y = 0;
1983 (y < 3) && (flag83 == TRUE);
1984 y++)
1985 {
1986 switch (*source)
1987 {
1988 case '/': case '?':
1989 case '*': case ':':
1990 case '\\': case '"':
1991 case ' ': case '.':
1992 flag83 = FALSE;
1993 break;
1994 }
1995 source++;
1996 }
1997
1998 // verify we're at the end of the string now
1999 if (flag83 == TRUE)
2000 if (*source != 0)
2001 flag83 = FALSE;
2002
2003 // OK, done
2004 if (flag83 == TRUE)
2005 {
2006 // we might not alter any character here, since
2007 // an app opening a specific file with an 8:3 "alias",
2008 // would surely fail.
2009 strcpy(shortName, longName);
2010
2011 return; // Done
2012 }
2013
2014
2015 // @@@PH
2016 shortName[0] = 0; // this function is disabled anyway ...
2017 return;
2018
2019 CHAR *dest = shortName;
2020 CHAR *ext = strrchr(longName,'.');
2021
2022 //CB: quick and dirty, real FILE~12.EXT is too slow
2023 //PH: We'd have to count the number of non-8:3-compliant files
2024 // within a directory. Or simpler: the number of files within
2025 // the current directory.
2026
2027 //8 character file name
2028 for (x = 0;x < 8;x++)
2029 {
2030 if ((source == ext) || (source[0] == 0)) break;
2031 dest[0] = system2DOSCharacter(source[0]);
2032 source++;
2033 dest++;
2034 }
2035
2036 if (source[0] == 0)
2037 {
2038 dest[0] = 0;
2039 return;
2040 }
2041
2042 if (source != ext)
2043 {
2044 //longName > 8 characters, insert ~1
2045 shortName[6] = '~';
2046 shortName[7] = '1';
2047 }
2048
2049 if (ext)
2050 {
2051 //add extension, 3 characters
2052 dest[0] = ext[0];
2053 dest++;
2054 ext++;
2055 for (x = 0;x < 3;x++)
2056 {
2057 if (ext[0] == 0) break;
2058 dest[0] = system2DOSCharacter(ext[0]);
2059 ext++;
2060 dest++;
2061 }
2062 }
2063 dest[0] = 0;
2064}
2065//******************************************************************************
2066//******************************************************************************
2067VOID translateFileResults(FILESTATUS3 *pResult,LPWIN32_FIND_DATAA pFind,CHAR* achName)
2068{
2069 CHAR* name;
2070
2071 pFind->dwReserved0 = pFind->dwReserved1 = 0;
2072 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
2073
2074 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
2075 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
2076 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
2077
2078 pFind->nFileSizeHigh = 0; //CB: fixme
2079 pFind->nFileSizeLow = pResult->cbFile;
2080 name = strrchr(achName,'\\');
2081 if (name)
2082 {
2083 name++;
2084 strcpy(pFind->cFileName,name);
2085 }
2086 else
2087 pFind->cFileName[0] = 0;
2088
2089 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
2090}
2091
2092VOID translateFindResults(FILEFINDBUF3 *pResult,LPWIN32_FIND_DATAA pFind)
2093{
2094 pFind->dwFileAttributes = pm2WinFileAttributes(pResult->attrFile);
2095 pFind->dwReserved0 = pFind->dwReserved1 = 0;
2096
2097 pmDateTimeToFileTime(&pResult->fdateCreation,&pResult->ftimeCreation,&pFind->ftCreationTime);
2098 pmDateTimeToFileTime(&pResult->fdateLastAccess,&pResult->ftimeLastAccess,&pFind->ftLastAccessTime);
2099 pmDateTimeToFileTime(&pResult->fdateLastWrite,&pResult->ftimeLastWrite,&pFind->ftLastWriteTime);
2100
2101 pFind->nFileSizeHigh = 0; //CB: fixme
2102 pFind->nFileSizeLow = pResult->cbFile;
2103 strcpy(pFind->cFileName,pResult->achName);
2104 long2ShortName(pFind->cFileName,pFind->cAlternateFileName);
2105}
2106//******************************************************************************
2107//******************************************************************************
2108DWORD OSLibDosFindFirst(LPCSTR lpFileName,WIN32_FIND_DATAA* lpFindFileData)
2109{
2110 HDIR hDir = -1;
2111 ULONG attrs;
2112 FILEFINDBUF3 result;
2113 ULONG searchCount = 1;
2114
2115 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
2116 result.achName[0] = 0;
2117
2118 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
2119 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,&result,sizeof(result),&searchCount,FIL_STANDARD);
2120 //PH: DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
2121
2122 //check root: skip "." and ".." (HPFS, not on FAT)
2123 //check in OSLibDosFindNext not necessary: "." and ".." are the first two entries
2124 if ((rc == 0) && isRoot((LPSTR)lpFileName))
2125 {
2126 while ((strcmp(result.achName,".") == 0) ||
2127 (strcmp(result.achName,"..") == 0))
2128 {
2129 result.achName[0] = 0;
2130 //PH: DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
2131 searchCount = 1;
2132 APIRET rc = DosFindNext(hDir,&result,sizeof(result),&searchCount);
2133 //PH: DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
2134 if (rc)
2135 {
2136 DosFindClose(hDir);
2137 SetLastError(error2WinError(rc));
2138
2139 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
2140 return INVALID_HANDLE_VALUE_W;
2141 }
2142 }
2143 }
2144
2145 // enable i/o kernel exceptions again
2146 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
2147
2148 if(rc)
2149 {
2150 DosFindClose(hDir);
2151 SetLastError(error2WinError(rc));
2152 return INVALID_HANDLE_VALUE_W;
2153 }
2154 translateFindResults(&result,lpFindFileData);
2155 SetLastError(ERROR_SUCCESS_W);
2156 return hDir;
2157}
2158//******************************************************************************
2159// NOTE: returns "." and ".." in root
2160//******************************************************************************
2161DWORD OSLibDosFindFirstMulti(LPCSTR lpFileName,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
2162{
2163 HDIR hDir = -1;
2164 ULONG attrs;
2165 FILEFINDBUF3 *result,*data;
2166 ULONG searchCount = *count;
2167
2168 attrs = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED;
2169 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
2170
2171 DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
2172 APIRET rc = DosFindFirst((PSZ)lpFileName,&hDir,attrs,result,searchCount*sizeof(FILEFINDBUF3),&searchCount,FIL_STANDARD);
2173 DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
2174 if (rc)
2175 {
2176 free(result);
2177 *count = 0;
2178 SetLastError(error2WinError(rc));
2179
2180 return INVALID_HANDLE_VALUE_W;
2181 }
2182
2183 data = result;
2184 for (int x = 0;x < searchCount;x++)
2185 {
2186 translateFindResults(data,&lpFindFileData[x]);
2187 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
2188 }
2189 free(result);
2190 *count = searchCount;
2191
2192 SetLastError(ERROR_SUCCESS_W);
2193 return hDir;
2194}
2195//******************************************************************************
2196//******************************************************************************
2197BOOL OSLibDosFindNext(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData)
2198{
2199 FILEFINDBUF3 result;
2200 ULONG searchCount = 1;
2201
2202 APIRET rc = DosFindNext((HDIR)hFindFile,&result,sizeof(result),&searchCount);
2203 if (rc)
2204 {
2205 SetLastError(error2WinError(rc));
2206
2207 return FALSE;
2208 }
2209
2210 translateFindResults(&result,lpFindFileData);
2211 SetLastError(ERROR_SUCCESS_W);
2212 return TRUE;
2213}
2214//******************************************************************************
2215//******************************************************************************
2216BOOL OSLibDosFindNextMulti(DWORD hFindFile,WIN32_FIND_DATAA *lpFindFileData,DWORD *count)
2217{
2218 FILEFINDBUF3 *result,*data;
2219 ULONG searchCount = *count;
2220
2221 result = (FILEFINDBUF3*)malloc(searchCount*sizeof(FILEFINDBUF3));
2222 APIRET rc = DosFindNext((HDIR)hFindFile,result,searchCount*sizeof(FILEFINDBUF3),&searchCount);
2223 if (rc)
2224 {
2225 free(result);
2226 *count = 0;
2227 SetLastError(error2WinError(rc));
2228
2229 return FALSE;
2230 }
2231
2232 data = result;
2233 for (int x = 0;x < searchCount;x++)
2234 {
2235 translateFindResults(data,&lpFindFileData[x]);
2236 data = (FILEFINDBUF3*)(((DWORD)data)+data->oNextEntryOffset);
2237 }
2238 free(result);
2239 *count = searchCount;
2240
2241 SetLastError(ERROR_SUCCESS_W);
2242 return TRUE;
2243}
2244//******************************************************************************
2245//******************************************************************************
2246BOOL OSLibDosFindClose(DWORD hFindFile)
2247{
2248 APIRET rc = DosFindClose((HDIR)hFindFile);
2249 if (rc)
2250 {
2251 SetLastError(error2WinError(rc));
2252 return FALSE;
2253 }
2254
2255 SetLastError(ERROR_SUCCESS_W);
2256 return TRUE;
2257}
2258//******************************************************************************
2259#define FSATTACH_SIZE 256
2260//******************************************************************************
2261DWORD OSLibDosQueryVolumeFS(int drive, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
2262{
2263 PFSQBUFFER2 fsinfo = (PFSQBUFFER2) alloca(FSATTACH_SIZE);
2264 ULONG cb = FSATTACH_SIZE;
2265 char drv[3] = "A:";
2266 char *fsname;
2267 APIRET rc;
2268
2269 if(lpFileSystemNameBuffer == NULL) {
2270 DebugInt3();
2271 return ERROR_INVALID_PARAMETER_W;
2272 }
2273 drv[0] = (char)('A' + drive - 1);
2274
2275 DosError(FERR_DISABLEHARDERR);
2276 rc = DosQueryFSAttach(drv, 1, FSAIL_QUERYNAME, fsinfo, &cb);
2277 DosError(FERR_ENABLEHARDERR);
2278
2279 switch(rc) {
2280 case ERROR_INVALID_DRIVE:
2281 return ERROR_INVALID_DRIVE_W;
2282 case ERROR_NO_VOLUME_LABEL:
2283 return ERROR_NO_VOLUME_LABEL_W;
2284 case NO_ERROR:
2285 break;
2286 default:
2287 return ERROR_NOT_ENOUGH_MEMORY; //whatever
2288 }
2289
2290 fsname = (char *)&fsinfo->szName[0] + fsinfo->cbName + 1;
2291
2292 /* @@@PH 2000/08/10 CMD.EXE querys with nFileSystemNameSize == 0
2293 * however does NOT expect to receive an error.
2294 */
2295 strncpy(lpFileSystemNameBuffer,
2296 fsname,
2297 nFileSystemNameSize);
2298 /*
2299 if(strlen(fsname) < nFileSystemNameSize) {
2300 strcpy(lpFileSystemNameBuffer, fsname);
2301 }
2302 else return ERROR_BUFFER_OVERFLOW_W;
2303 */
2304 return 0;
2305}
2306//******************************************************************************
2307typedef struct _FSINFOBUF
2308{
2309 ULONG ulVolser; /* Volume serial number */
2310 VOLUMELABEL vol; /* Volume lable */
2311} FSINFOBUF;
2312//******************************************************************************
2313DWORD OSLibDosQueryVolumeSerialAndName(int drive, LPDWORD lpVolumeSerialNumber,
2314 LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
2315{
2316 FSINFOBUF fsi;
2317 APIRET rc;
2318
2319 DosError(FERR_DISABLEHARDERR);
2320 rc = DosQueryFSInfo(drive, FSIL_VOLSER, &fsi, sizeof(fsi));
2321 DosError(FERR_ENABLEHARDERR);
2322
2323 switch(rc) {
2324 case ERROR_INVALID_DRIVE:
2325 return ERROR_INVALID_DRIVE_W;
2326 case ERROR_NO_VOLUME_LABEL:
2327 return ERROR_NO_VOLUME_LABEL_W;
2328 case NO_ERROR:
2329 break;
2330 default:
2331 return ERROR_NOT_ENOUGH_MEMORY; //whatever
2332 }
2333
2334 if(lpVolumeSerialNumber) {
2335 *lpVolumeSerialNumber = fsi.ulVolser;
2336 }
2337 if(lpVolumeNameBuffer)
2338 {
2339 if(nVolumeNameSize > fsi.vol.cch) {
2340 strcpy(lpVolumeNameBuffer, (PCHAR)fsi.vol.szVolLabel);
2341 }
2342 else return ERROR_BUFFER_OVERFLOW_W;
2343 }
2344
2345 return ERROR_SUCCESS_W;
2346}
2347//******************************************************************************
2348//******************************************************************************
2349BOOL OSLibGetDiskFreeSpace(LPSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
2350 LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters,
2351 LPDWORD lpTotalNumberOfClusters)
2352{
2353 ULONG diskNum;
2354 FSALLOCATE fsAlloc;
2355 APIRET rc;
2356
2357 if(lpRootPathName == 0)
2358 diskNum = 0;
2359 else
2360 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z' )
2361 diskNum = *lpRootPathName - 'A' + 1;
2362 else
2363 if('a' <= *lpRootPathName && *lpRootPathName <= 'z' )
2364 diskNum = *lpRootPathName - 'a' + 1;
2365 else
2366 diskNum = 0;
2367
2368 DosError(FERR_DISABLEHARDERR);
2369 rc = DosQueryFSInfo(diskNum, FSIL_ALLOC, &fsAlloc, sizeof(fsAlloc));
2370 DosError(FERR_ENABLEHARDERR);
2371
2372 if(rc == 0)
2373 {
2374 *lpSectorsPerCluster = fsAlloc.cSectorUnit;
2375 *lpBytesPerSector = fsAlloc.cbSector;
2376 *lpNumberOfFreeClusters = fsAlloc.cUnitAvail;
2377 *lpTotalNumberOfClusters = fsAlloc.cUnit;
2378 SetLastError(ERROR_SUCCESS_W);
2379 return TRUE;
2380 }
2381 SetLastError(error2WinError(rc));
2382 return FALSE;
2383}
2384//******************************************************************************
2385//******************************************************************************
2386BOOL OSLibDosGetDiskGeometry(HANDLE hDisk, DWORD cDisk, PVOID pdiskgeom)
2387{
2388 PDISK_GEOMETRY pGeom = (PDISK_GEOMETRY)pdiskgeom;
2389 BYTE param[2] = {0, 0};
2390 ULONG parsize = 2;
2391 BIOSPARAMETERBLOCK bpb;
2392 ULONG datasize = sizeof(bpb);
2393 APIRET rc;
2394
2395 param[1] = cDisk - 'A';
2396 rc = DosDevIOCtl((hDisk) ? hDisk : -1, IOCTL_DISK, DSK_GETDEVICEPARAMS, param, 2, &parsize, &bpb, sizeof(bpb), &datasize);
2397 if(rc == 0)
2398 {
2399 pGeom->SectorsPerTrack = bpb.usSectorsPerTrack;
2400 pGeom->BytesPerSector = bpb.usBytesPerSector;
2401 pGeom->TracksPerCylinder = 80; //TODO:!!!!!
2402 pGeom->Cylinders.u.LowPart = bpb.cCylinders;
2403 pGeom->Cylinders.u.HighPart = 0;
2404 switch(bpb.bDeviceType) {
2405 case DEVTYPE_48TPI:
2406 pGeom->MediaType = F5_360_512; //?????
2407 break;
2408 case DEVTYPE_96TPI:
2409 pGeom->MediaType = F5_1Pt2_512; //?????
2410 break;
2411 case DEVTYPE_35:
2412 pGeom->MediaType = F3_720_512;
2413 break;
2414 case DEVTYPE_8SD:
2415 case DEVTYPE_8DD:
2416 pGeom->MediaType = RemovableMedia;
2417 break;
2418 case DEVTYPE_FIXED:
2419 pGeom->MediaType = FixedMedia;
2420 break;
2421 case DEVTYPE_TAPE:
2422 pGeom->MediaType = RemovableMedia;
2423 break;
2424 case DEVTYPE_UNKNOWN: //others, include 1.44 3.5 inch disk drive
2425 pGeom->MediaType = F3_1Pt44_512;
2426 break;
2427 case 8: //RW optical disk
2428 pGeom->MediaType = RemovableMedia;
2429 break;
2430 case 9: //2.88 3.5 inch disk
2431 pGeom->MediaType = F3_2Pt88_512;
2432 break;
2433 }
2434 SetLastError(ERROR_SUCCESS_W);
2435 return TRUE;
2436 }
2437 SetLastError(error2WinError(rc));
2438 return FALSE;
2439}
2440//******************************************************************************
2441//Returns bit map where with the mapping of the logical drives
2442//******************************************************************************
2443ULONG OSLibGetLogicalDrives()
2444{
2445 ULONG ulDriveNum = 0; /* Drive number (A=1, B=2, C=3, ...) */
2446 ULONG ulDriveMap = 0; /* Mapping of valid drives */
2447 APIRET rc;
2448
2449 rc = DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
2450 if(rc) {
2451 DebugInt3();
2452 SetLastError(error2WinError(rc));
2453 return 0;
2454 }
2455 return ulDriveMap;
2456}
2457//******************************************************************************
2458//******************************************************************************
2459ULONG OSLibDosQueryCurrentDisk()
2460
2461{
2462 ULONG ulDriveNum = 0; /* Drive number (A=1, B=2, C=3, ...) */
2463 ULONG ulDriveMap = 0; /* Mapping of valid drives */
2464 APIRET rc;
2465
2466 rc = DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
2467 if(rc) {
2468 DebugInt3();
2469 SetLastError(error2WinError(rc));
2470 return 0;
2471 }
2472 return ulDriveNum;
2473}
2474//******************************************************************************
2475//******************************************************************************
2476BOOL OSLibDosCreatePipe(PHANDLE phfRead,
2477 PHANDLE phfWrite,
2478 LPSECURITY_ATTRIBUTES lpsa,
2479 DWORD dwSize)
2480{
2481 APIRET rc;
2482
2483 dprintf(("DosCreatePipe(%08xh,%08xh,%08xh)\n",
2484 phfRead,
2485 phfWrite,
2486 dwSize));
2487
2488 // select default buffer size
2489 if (dwSize == 0)
2490 dwSize = 4096;
2491
2492 rc = DosCreatePipe(phfRead,
2493 phfWrite,
2494 dwSize);
2495 dprintf(("DosCreatePipe rc=%d",rc));
2496 if (rc)
2497 {
2498 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER_W));
2499 return -1; // INVALID_HANDLE_VALUE
2500 }
2501 SetLastError(ERROR_SUCCESS_W);
2502 return NO_ERROR;
2503}
2504//******************************************************************************
2505//******************************************************************************
2506DWORD OSLibDosDevIOCtl( DWORD hFile, DWORD dwCat, DWORD dwFunc,
2507 PVOID pParm, DWORD dwParmMaxLen, DWORD *pdwParmLen,
2508 PVOID pData, DWORD dwDataMaxLen, DWORD *pdwDataLen)
2509{
2510 APIRET rc;
2511
2512 rc = DosDevIOCtl( (HFILE)hFile, dwCat, dwFunc,
2513 pParm, dwParmMaxLen, pdwParmLen,
2514 pData, dwDataMaxLen, pdwDataLen);
2515
2516 SetLastError(error2WinError(rc,ERROR_INVALID_HANDLE));
2517 return (DWORD)rc;
2518}
2519
2520/**
2521 * Pure wrapper for DosQueryModulName which returns the OS/2 returncode.
2522 * @returns Returncode from DosQueryModuleName.
2523 * @param hModule Handle of the module which name we query.
2524 * @param cchName Length of the output name buffer.
2525 * @param pszname Pointer to the output name buffer.
2526 * @status Completely implemented.
2527 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
2528 */
2529ULONG OSLibDosQueryModuleName(ULONG hModule, int cchName, char *pszName)
2530{
2531 return DosQueryModuleName(hModule, cchName, pszName);
2532}
2533
2534
2535HINSTANCE OSLibDosLoadModule(LPSTR szModName)
2536{
2537 APIRET rc;
2538 HMODULE hModule = NULLHANDLE;
2539 char name[ CCHMAXPATH ];
2540
2541 rc = DosLoadModule(name, CCHMAXPATH, szModName, &hModule);
2542 if(rc) {
2543 SetLastError(error2WinError(rc,ERROR_FILE_NOT_FOUND));
2544 return 0;
2545 }
2546 SetLastError(ERROR_SUCCESS_W);
2547 return hModule;
2548}
2549//******************************************************************************
2550//******************************************************************************
2551void OSLibDosFreeModule(HINSTANCE hinst)
2552{
2553 DosFreeModule(hinst);
2554}
2555//******************************************************************************
2556//******************************************************************************
2557ULONG OSLibDosQuerySysInfo(ULONG iStart, ULONG iLast, PVOID pBuf, ULONG cbBuf)
2558{
2559 APIRET rc;
2560
2561 rc = DosQuerySysInfo(iStart, iLast, pBuf, cbBuf);
2562 SetLastError(error2WinError(rc,ERROR_INVALID_HANDLE));
2563 return rc;
2564}
2565//******************************************************************************
2566//returned length is number of characters required or used for current dir
2567//*excluding* terminator
2568//******************************************************************************
2569ULONG OSLibDosQueryDir(DWORD length, LPSTR lpszCurDir)
2570{
2571 ULONG drivemap, currentdisk, len;
2572 char *lpszCurDriveAndDir = lpszCurDir +3;
2573 APIRET rc;
2574
2575 len = (length > 3) ? length - 3 : 0;
2576
2577 rc = DosQueryCurrentDir(0, lpszCurDriveAndDir, &len);
2578 if(rc != ERROR_BUFFER_OVERFLOW)
2579 {
2580 if(rc)
2581 {
2582 SetLastError(error2WinError(rc,ERROR_INVALID_PARAMETER));
2583 return 0;
2584 }
2585 len = strlen(lpszCurDriveAndDir) + 3;
2586
2587 // Dir returned by DosQueryCurDir doesn't include drive, so add it
2588 DosQueryCurrentDisk(&currentdisk, &drivemap);
2589
2590 if(isupper(lpszCurDir[3])) {
2591 lpszCurDir[0] = (char)('A' - 1 + currentdisk);
2592 }
2593 else lpszCurDir[0] = (char)('a' - 1 + currentdisk);
2594
2595 lpszCurDir[1] = ':';
2596 lpszCurDir[2] = '\\';
2597 }
2598 else len += 3; // + 3 since DosQueryCurDir doesn't include drive
2599
2600 SetLastError(ERROR_SUCCESS_W);
2601 return len;
2602}
2603//******************************************************************************
2604//******************************************************************************
Note: See TracBrowser for help on using the repository browser.