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

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

DIBSection changes, EB's file io additions, Jens Weissner's changes to several dlls

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