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

Last change on this file since 1914 was 1914, checked in by sandervl, 26 years ago

max open files fix + EB's mmap fix

File size: 18.0 KB
Line 
1/* $Id: oslibdos.cpp,v 1.11 1999-12-01 10:47:51 sandervl Exp $ */
2
3/*
4 * Wrappers for OS/2 Dos* API
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_BASE
13#define INCL_DOSEXCEPTIONS
14#define INCL_DOSMEMMGR
15#define INCL_DOSPROCESS
16#define INCL_DOSERRORS
17#include <os2wrap.h> //Odin32 OS/2 api wrappers
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21#include <win32type.h>
22#include <misc.h>
23#include "initterm.h"
24#include "oslibdos.h"
25
26APIRET APIENTRY DosAliasMem(PVOID pb, ULONG cb, PPVOID ppbAlias, ULONG fl);
27
28//******************************************************************************
29//TODO: Assumes entire memory range has the same protection flags!
30//TODO: Check if this works for code aliases...
31//******************************************************************************
32DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
33{
34 DWORD rc;
35 DWORD attr;
36 DWORD size = cb;
37
38 cb = (cb-1) & ~0xfff;
39 cb+= PAGE_SIZE;
40
41 rc = DosQueryMem(pb, &size, &attr);
42 if(rc) {
43 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
44 return rc;
45 }
46 size = (size-1) & ~0xfff;
47 size+= PAGE_SIZE;
48 if(size != cb) {
49 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
50 //ignore this and continue return 5;
51 attr = fl; //just use original protection flags (NOT CORRECT)
52 }
53 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
54 if(attr != fl) {
55 rc = DosSetMem(pb, size, fl);
56 if(rc) {
57 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
58 attr = fl;
59 //just continue for now
60 //return rc;
61 }
62 }
63 rc = DosAliasMem(pb, cb, ppbAlias, 2);
64 if(rc) {
65 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x return %d", pb, cb, rc));
66 return rc;
67 }
68 if(attr != fl) {
69 rc = DosSetMem(pb, size, attr);
70 if(rc) {
71 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
72 return rc;
73 }
74 }
75 return 0;
76}
77//******************************************************************************
78//NT returns addresses aligned at 64k, so we do too.
79//******************************************************************************
80DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags)
81{
82 LPVOID memaddr;
83 DWORD offset;
84 APIRET rc;
85
86 rc = DosAllocMem(&memaddr, size, PAG_READ | flAllocMem);
87 if(rc) {
88 return rc;
89 }
90 DosEnterCritSec();
91 DosFreeMem(memaddr);
92 offset = (DWORD)memaddr & 0xFFFF;
93 if(offset) {
94 DosAllocMem(&memaddr, 64*1024 - offset, PAG_READ | flAllocMem);
95 }
96 rc = DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
97 DosExitCritSec();
98 if((DWORD)*lplpMemAddr & 0xFFFF) {//still not at 64k boundary?
99 DosFreeMem(*lplpMemAddr);
100 rc = OSLibDosAllocMem(lplpMemAddr, size, flags);
101 }
102 if(offset) {
103 DosFreeMem(memaddr);
104 }
105
106 return rc;
107}
108//******************************************************************************
109//******************************************************************************
110DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
111{
112 return DosFreeMem(lpMemAddr);
113}
114//******************************************************************************
115//NOTE: If name == NULL, allocated gettable unnamed shared memory
116//******************************************************************************
117DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
118{
119 APIRET rc;
120 char *sharedmemname = NULL;
121
122 if(name) {
123 sharedmemname = (char *)malloc(strlen(name) + 16);
124 strcpy(sharedmemname, "\\SHAREMEM\\");
125 strcat(sharedmemname, name);
126 }
127 else flags |= OBJ_GETTABLE;
128
129 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
130 if(name) {
131 free(sharedmemname);
132 }
133 return rc;
134}
135//******************************************************************************
136//NOTE: If name == NULL, assume gettable unnamed shared memory
137//******************************************************************************
138DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
139{
140 APIRET rc;
141 char *sharedmemname = NULL;
142
143 if(name) {
144 sharedmemname = (char *)malloc(strlen(name) + 16);
145 strcpy(sharedmemname, "\\SHAREMEM\\");
146 strcat(sharedmemname, name);
147 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
148 if(name) {
149 free(sharedmemname);
150 }
151 }
152 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
153
154 return rc;
155}
156//******************************************************************************
157//******************************************************************************
158DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
159{
160 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
161}
162//******************************************************************************
163//******************************************************************************
164DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
165{
166 APIRET rc;
167
168 rc = DosSetMem(lpMemAddr, size, flags);
169 switch(rc) {
170 case ERROR_INVALID_ADDRESS:
171 return OSLIB_ERROR_INVALID_ADDRESS;
172 case ERROR_ACCESS_DENIED:
173 return OSLIB_ERROR_ACCESS_DENIED;
174 default:
175 return rc;
176 }
177}
178//******************************************************************************
179//******************************************************************************
180DWORD OSLibDosOpen(char *lpszFileName, DWORD flags)
181{
182 APIRET rc;
183 HFILE hFile;
184 ULONG ulAction;
185 DWORD os2flags = OPEN_FLAGS_NOINHERIT;
186
187
188 if(flags & OSLIB_ACCESS_READONLY)
189 os2flags |= OPEN_ACCESS_READONLY;
190 else
191 if(flags & OSLIB_ACCESS_READWRITE)
192 os2flags |= OPEN_ACCESS_READWRITE;
193
194 if(flags & OSLIB_ACCESS_SHAREDENYNONE)
195 os2flags |= OPEN_SHARE_DENYNONE;
196 else
197 if(flags & OSLIB_ACCESS_SHAREDENYREAD)
198 os2flags |= OPEN_SHARE_DENYREAD;
199 else
200 if(flags & OSLIB_ACCESS_SHAREDENYWRITE)
201 os2flags |= OPEN_SHARE_DENYWRITE;
202
203tryopen:
204 rc = DosOpen(lpszFileName, /* File path name */
205 &hFile, /* File handle */
206 &ulAction, /* Action taken */
207 0L, /* File primary allocation */
208 0L, /* File attribute */
209 OPEN_ACTION_FAIL_IF_NEW |
210 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
211 os2flags,
212 0L); /* No extended attribute */
213
214 if(rc) {
215 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
216 ULONG CurMaxFH;
217 LONG ReqCount = 32;
218
219 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
220 if(rc) {
221 dprintf(("DosSetRelMaxFH returned %d", rc));
222 return 0;
223 }
224 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
225 goto tryopen;
226 }
227 return 0;
228 }
229 else return hFile;
230}
231//******************************************************************************
232//******************************************************************************
233DWORD OSLibDosClose(DWORD hFile)
234{
235 return DosClose(hFile);
236}
237//******************************************************************************
238//******************************************************************************
239DWORD OSLibDosRead(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesRead)
240{
241 return DosRead(hFile, lpBuffer, size, nrBytesRead);
242}
243//******************************************************************************
244//******************************************************************************
245DWORD OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten)
246{
247 return DosWrite(hFile, lpBuffer, size, nrBytesWritten);
248}
249//******************************************************************************
250//******************************************************************************
251DWORD OSLibDosSetFilePtr(DWORD hFile, DWORD offset, DWORD method)
252{
253 DWORD os2method;
254 DWORD newoffset;
255 APIRET rc;
256
257 switch(method) {
258 case OSLIB_SETPTR_FILE_CURRENT:
259 os2method = FILE_CURRENT;
260 break;
261 case OSLIB_SETPTR_FILE_BEGIN:
262 os2method = FILE_BEGIN ;
263 break;
264 case OSLIB_SETPTR_FILE_END:
265 os2method = FILE_END;
266 break;
267 default:
268 return OSLIB_ERROR_INVALID_PARAMETER;
269 }
270 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
271 if(rc) {
272 return -1;
273 }
274 else return newoffset;
275}
276//******************************************************************************
277//******************************************************************************
278//@@@PH Note: this routine is nothing but a QUICK'N'DIRTY HACK!
279//@@@PH this function should be implemented accordingly to NTDLL's
280// RtlSecondsSince1980ToTime
281// RtlTimeToSecondsSince1980
282static void iFDATEFTIME2FILETIME(FDATE fdOS2, FTIME ftOS2, LPFILETIME pftWin32)
283{
284 float f;
285 #define facSECOND 2 // as encoded in OS/2
286 #define facMINUTE 60
287 #define facHOUR 3600
288 #define facDAY 86400
289 #define facMONTH facDAY * 30 // cough, cough :)
290 #define facYEAR facDAY * 365
291
292 /* pftWin32 is 100ns based from 01.01.1601 00:00:00 */
293 f = (fdOS2.year + 379) * facYEAR // 1980 - 1601
294 + (fdOS2.month - 0 ) * facMONTH
295 + (fdOS2.day - 1 ) * facDAY
296 + (ftOS2.hours ) * facHOUR
297 + (ftOS2.minutes ) * facMINUTE
298 + (ftOS2.twosecs ) * facSECOND;
299
300 f *= 10000; // convert to 100ns base
301 pftWin32->dwHighDateTime = (f / (float)(0xffffffff) );
302 pftWin32->dwLowDateTime = (f - (float)((float)pftWin32->dwHighDateTime *
303 (float)0xffffffff) );
304}
305
306BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
307 ULONG ulDummy,
308 PVOID pBuffer)
309{
310 APIRET rc; /* API return code */
311 FILESTATUS3 fs3; /* file information structure */
312 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
313
314 // Note: we only handle standard "GetFileExInfoStandard" requests
315 rc = DosQueryPathInfo(pszName, /* query the file information */
316 FIL_STANDARD,
317 &fs3,
318 sizeof(fs3));
319 if (rc != NO_ERROR) /* check for errors */
320 return FALSE; /* raise error condition */
321
322 // convert structure
323 lpFad->dwFileAttributes = fs3.attrFile; // directly interchangeable
324 iFDATEFTIME2FILETIME(fs3.fdateCreation, fs3.ftimeCreation, &lpFad->ftCreationTime);
325 iFDATEFTIME2FILETIME(fs3.fdateLastAccess, fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
326 iFDATEFTIME2FILETIME(fs3.fdateLastWrite, fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
327
328 /* @@@PH we might add Aurora support ...
329 lpFad->nFileSizeHigh = info.nFileSizeHigh;
330 */
331 lpFad->nFileSizeHigh = 0;
332 lpFad->nFileSizeLow = fs3.cbFile;
333
334 return TRUE;
335}
336//******************************************************************************
337//******************************************************************************
338DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
339 DWORD length_fullname)
340{
341 switch(cmd) {
342 case OSLIB_SEARCHDIR:
343 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
344 name, full_name, length_fullname) != 0) {
345 return 0;
346 }
347 return strlen(full_name);
348
349
350 case OSLIB_SEARCHCURDIR:
351 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
352 name, full_name, length_fullname) != 0) {
353 return 0;
354 }
355 return strlen(full_name);
356
357 case OSLIB_SEARCHFILE:
358 {
359 FILESTATUS3 fileinfo;
360
361 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
362 return 0;
363 }
364 strncpy(full_name, name, length_fullname);
365 return strlen(full_name);
366 }
367
368 case OSLIB_SEARCHENV:
369 {
370 char *env = getenv(path);
371 if(env == NULL)
372 return 0;
373
374 while(*env != '=') env++;
375 env++;
376 while(*env == ' ') env++;
377 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT, env,
378 name, full_name, length_fullname) != 0) {
379 return 0;
380 }
381 return strlen(full_name);
382 }
383 }
384 return 0;
385}
386//******************************************************************************
387//******************************************************************************
388DWORD OSLibDosCreate(CHAR *lpFileName,
389 DWORD dwAccess,
390 DWORD dwShare,
391 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
392 DWORD dwCreation,
393 DWORD dwFlags,
394 HANDLE hTemplate,
395 DWORD *dwFile)
396{
397 APIRET rc;
398 HFILE hFile;
399 ULONG ulAction=0;
400 DWORD os2Attrib=0;
401 DWORD os2Flags = 0; //OPEN_FLAGS_NOINHERIT;
402 DWORD os2Open=0;
403
404#define GENERIC_READ 0x80000000
405#define GENERIC_WRITE 0x40000000
406 if(dwAccess == (GENERIC_READ | GENERIC_WRITE))
407 os2Flags |= OPEN_ACCESS_READWRITE;
408 else if(dwAccess & GENERIC_WRITE)
409 os2Flags |= OPEN_ACCESS_WRITEONLY;
410 else if(dwAccess & GENERIC_READ)
411 os2Flags |= OPEN_ACCESS_READONLY;
412
413#define FILE_SHARE_READ 0x00000001L
414#define FILE_SHARE_WRITE 0x00000002L
415 if(dwShare == 0)
416 os2Flags |= OPEN_SHARE_DENYREADWRITE;
417 else if(dwShare == (FILE_SHARE_READ | FILE_SHARE_WRITE))
418 os2Flags |= OPEN_SHARE_DENYNONE;
419 else if(dwShare & FILE_SHARE_READ)
420 os2Flags |= OPEN_SHARE_DENYWRITE;
421 else if(dwShare & FILE_SHARE_WRITE)
422 os2Flags |= OPEN_SHARE_DENYREAD;
423
424#define CREATE_NEW 1
425#define CREATE_ALWAYS 2
426#define OPEN_EXISTING 3
427#define OPEN_ALWAYS 4
428#define TRUNCATE_EXISTING 5
429 if(dwCreation == CREATE_NEW)
430 os2Open = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
431 else if(dwCreation == CREATE_ALWAYS)
432 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
433 else if(dwCreation == OPEN_EXISTING)
434 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
435 else if(dwCreation == OPEN_ALWAYS)
436 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
437 else if(dwCreation == TRUNCATE_EXISTING)
438 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS;// |OPEN_ACTION_FAIL_IF_NEW;
439
440#define FILE_ATTRIBUTE_READONLY 0x00000001L
441#define FILE_ATTRIBUTE_HIDDEN 0x00000002L
442#define FILE_ATTRIBUTE_SYSTEM 0x00000004L
443#define FILE_ATTRIBUTE_DIRECTORY 0x00000010L
444#define FILE_ATTRIBUTE_ARCHIVE 0x00000020L
445#define FILE_ATTRIBUTE_NORMAL 0x00000080L
446#define FILE_ATTRIBUTE_TEMPORARY 0x00000100L
447 if(dwFlags & FILE_ATTRIBUTE_READONLY)
448 os2Attrib |= FILE_READONLY;
449 if(dwFlags & FILE_ATTRIBUTE_HIDDEN)
450 os2Attrib |= FILE_HIDDEN;
451 if(dwFlags & FILE_ATTRIBUTE_SYSTEM)
452 os2Attrib |= FILE_SYSTEM;
453 if(dwFlags & FILE_ATTRIBUTE_DIRECTORY)
454 os2Attrib |= FILE_DIRECTORY;
455 if(dwFlags & FILE_ATTRIBUTE_ARCHIVE)
456 os2Attrib |= FILE_ARCHIVED;
457 if(dwFlags & FILE_ATTRIBUTE_NORMAL)
458 os2Attrib |= FILE_NORMAL;
459
460#define FILE_FLAG_WRITE_THROUGH 0x80000000UL
461#define FILE_FLAG_OVERLAPPED 0x40000000L
462#define FILE_FLAG_NO_BUFFERING 0x20000000L
463#define FILE_FLAG_RANDOM_ACCESS 0x10000000L
464#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L
465#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L
466#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L
467#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L
468 if(dwFlags & FILE_FLAG_WRITE_THROUGH)
469 os2Flags |= OPEN_FLAGS_WRITE_THROUGH;
470 if(dwFlags & FILE_FLAG_NO_BUFFERING)
471 os2Flags |= OPEN_FLAGS_NO_CACHE;
472 if(dwFlags & FILE_FLAG_RANDOM_ACCESS)
473 os2Flags |= OPEN_FLAGS_RANDOM;
474 if(dwFlags & FILE_FLAG_SEQUENTIAL_SCAN)
475 os2Flags |= OPEN_FLAGS_SEQUENTIAL;
476
477 // TODO:
478 // if(dwFlags & FILE_FLAG_OVERLAPPED)
479 // if(dwFlags & FILE_FLAG_DELETE_ON_CLOSE
480
481 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
482 os2Attrib, os2Open, os2Flags, 0);
483
484 if(rc)
485 {
486 // TODO: TEST TEST
487 dprintf(("DosOpen Error rc:%d, try without GENERIC_WRITE", rc));
488 if(dwAccess & GENERIC_WRITE)
489 os2Flags &= ~(OPEN_ACCESS_READWRITE | OPEN_ACCESS_WRITEONLY);
490 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
491 os2Attrib, os2Open, os2Flags, 0);
492 if(rc)
493 {
494 dprintf(("DosOpen Error rc:%d os2Attrib:%X os2Open:%X os2Flags:%X",
495 rc, os2Attrib, os2Open, os2Flags));
496 hFile = -1;
497 }
498 }
499
500 *dwFile = hFile;
501 return rc;
502}
503//******************************************************************************
504//(without changing file pointer)
505//******************************************************************************
506DWORD OSLibDosGetFileSize(DWORD hFile)
507{
508 FILESTATUS3 fsts3ConfigInfo = {{0}};
509 ULONG ulBufSize = sizeof(FILESTATUS3);
510
511 DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
512 return fsts3ConfigInfo.cbFile;
513}
514//******************************************************************************
515//******************************************************************************
516DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
517{
518 DWORD newoffset;
519 APIRET rc;
520
521
522 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
523 if(rc) {
524 dprintf(("DosSetFilePtr Error rc:%d", rc));
525 return -1;
526 }
527 else return newoffset;
528}
529//******************************************************************************
530//(FlushBuffer)
531//******************************************************************************
532DWORD OSLibDosResetBuffer(DWORD hFile)
533{
534 return DosResetBuffer(hFile);
535}
536//******************************************************************************
537//******************************************************************************
538DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
539{
540 *hNew = -1;
541 return DosDupHandle(hFile, hNew);
542}
543//******************************************************************************
544//******************************************************************************
545void OSLibDosDisableHardError(BOOL fTurnOff)
546{
547 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
548}
549//******************************************************************************
550//******************************************************************************
Note: See TracBrowser for help on using the repository browser.