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

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

Rewrite of PE loader code, EB's fixes + VirtualProtect bugfix

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