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

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

Allow executable api exports

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