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

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

SetLastError calling convention bugs fixed

File size: 28.9 KB
Line 
1/* $Id: oslibdos.cpp,v 1.20 2000-02-23 01:06:58 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 *
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#define INCL_NPIPES
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <win32type.h>
23#include <winconst.h>
24#include <misc.h>
25#include "initterm.h"
26#include "oslibdos.h"
27#include "dosqss.h"
28
29#define DBG_LOCALLOG DBG_oslibdos
30#include "dbglocal.h"
31
32/***********************************
33 * PH: fixups for missing os2win.h *
34 ***********************************/
35
36void _System _O32_SetLastError(ULONG ulError);
37
38APIRET APIENTRY DosAliasMem(PVOID pb, ULONG cb, PPVOID ppbAlias, ULONG fl);
39
40//******************************************************************************
41//TODO: Assumes entire memory range has the same protection flags!
42//TODO: Check if this works for code aliases...
43//******************************************************************************
44DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
45{
46 DWORD rc;
47 DWORD attr;
48 DWORD size = cb;
49
50 cb = (cb-1) & ~0xfff;
51 cb+= PAGE_SIZE;
52
53 rc = DosQueryMem(pb, &size, &attr);
54 if(rc) {
55 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
56 return rc;
57 }
58 size = (size-1) & ~0xfff;
59 size+= PAGE_SIZE;
60 if(size != cb) {
61 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
62 //ignore this and continue return 5;
63 attr = fl; //just use original protection flags (NOT CORRECT)
64 }
65 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
66 if(attr != fl) {
67 rc = DosSetMem(pb, size, fl);
68 if(rc) {
69 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
70 attr = fl;
71 //just continue for now
72 //return rc;
73 }
74 }
75 rc = DosAliasMem(pb, cb, ppbAlias, 2);
76 if(rc) {
77 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
78 return rc;
79 }
80 if(attr != fl) {
81 rc = DosSetMem(pb, size, attr);
82 if(rc) {
83 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
84 return rc;
85 }
86 }
87 return 0;
88}
89//******************************************************************************
90//NT returns addresses aligned at 64k, so we do too.
91//******************************************************************************
92DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags)
93{
94 LPVOID memaddr;
95 DWORD offset;
96 APIRET rc;
97
98 rc = DosAllocMem(&memaddr, size, PAG_READ | flAllocMem);
99 if(rc) {
100 return rc;
101 }
102 DosEnterCritSec();
103 DosFreeMem(memaddr);
104 offset = (DWORD)memaddr & 0xFFFF;
105 if(offset) {
106 DosAllocMem(&memaddr, 64*1024 - offset, PAG_READ | flAllocMem);
107 }
108 rc = DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
109 DosExitCritSec();
110 if((DWORD)*lplpMemAddr & 0xFFFF) {//still not at 64k boundary?
111 DosFreeMem(*lplpMemAddr);
112 rc = OSLibDosAllocMem(lplpMemAddr, size, flags);
113 }
114 if(offset) {
115 DosFreeMem(memaddr);
116 }
117
118 return rc;
119}
120//******************************************************************************
121//******************************************************************************
122DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
123{
124 return DosFreeMem(lpMemAddr);
125}
126//******************************************************************************
127//NOTE: If name == NULL, allocated gettable unnamed shared memory
128//******************************************************************************
129DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
130{
131 APIRET rc;
132 char *sharedmemname = NULL;
133
134 if(name) {
135 sharedmemname = (char *)malloc(strlen(name) + 16);
136 strcpy(sharedmemname, "\\SHAREMEM\\");
137 strcat(sharedmemname, name);
138 }
139 else flags |= OBJ_GETTABLE;
140
141 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
142 if(name) {
143 free(sharedmemname);
144 }
145 return rc;
146}
147//******************************************************************************
148//NOTE: If name == NULL, assume gettable unnamed shared memory
149//******************************************************************************
150DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
151{
152 APIRET rc;
153 char *sharedmemname = NULL;
154
155 if(name) {
156 sharedmemname = (char *)malloc(strlen(name) + 16);
157 strcpy(sharedmemname, "\\SHAREMEM\\");
158 strcat(sharedmemname, name);
159 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
160 if(name) {
161 free(sharedmemname);
162 }
163 }
164 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
165
166 return rc;
167}
168//******************************************************************************
169//******************************************************************************
170DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
171{
172 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
173}
174//******************************************************************************
175//******************************************************************************
176DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
177{
178 APIRET rc;
179
180 rc = DosSetMem(lpMemAddr, size, flags);
181 switch(rc) {
182 case ERROR_INVALID_ADDRESS:
183 return OSLIB_ERROR_INVALID_ADDRESS;
184 case ERROR_ACCESS_DENIED:
185 return OSLIB_ERROR_ACCESS_DENIED;
186 default:
187 return rc;
188 }
189}
190//******************************************************************************
191//******************************************************************************
192DWORD OSLibDosOpen(char *lpszFileName, DWORD flags)
193{
194 APIRET rc;
195 HFILE hFile;
196 ULONG ulAction;
197 DWORD os2flags = OPEN_FLAGS_NOINHERIT;
198
199
200 if(flags & OSLIB_ACCESS_READONLY)
201 os2flags |= OPEN_ACCESS_READONLY;
202 else
203 if(flags & OSLIB_ACCESS_READWRITE)
204 os2flags |= OPEN_ACCESS_READWRITE;
205
206 if(flags & OSLIB_ACCESS_SHAREDENYNONE)
207 os2flags |= OPEN_SHARE_DENYNONE;
208 else
209 if(flags & OSLIB_ACCESS_SHAREDENYREAD)
210 os2flags |= OPEN_SHARE_DENYREAD;
211 else
212 if(flags & OSLIB_ACCESS_SHAREDENYWRITE)
213 os2flags |= OPEN_SHARE_DENYWRITE;
214
215tryopen:
216 rc = DosOpen(lpszFileName, /* File path name */
217 &hFile, /* File handle */
218 &ulAction, /* Action taken */
219 0L, /* File primary allocation */
220 0L, /* File attribute */
221 OPEN_ACTION_FAIL_IF_NEW |
222 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
223 os2flags,
224 0L); /* No extended attribute */
225
226 if(rc) {
227 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
228 ULONG CurMaxFH;
229 LONG ReqCount = 32;
230
231 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
232 if(rc) {
233 dprintf(("DosSetRelMaxFH returned %d", rc));
234 return 0;
235 }
236 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
237 goto tryopen;
238 }
239 return 0;
240 }
241 else return hFile;
242}
243//******************************************************************************
244//******************************************************************************
245DWORD OSLibDosClose(DWORD hFile)
246{
247 return DosClose(hFile);
248}
249//******************************************************************************
250//******************************************************************************
251DWORD OSLibDosRead(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesRead)
252{
253 return DosRead(hFile, lpBuffer, size, nrBytesRead);
254}
255//******************************************************************************
256//******************************************************************************
257DWORD OSLibDosWrite(DWORD hFile, LPVOID lpBuffer, DWORD size, DWORD *nrBytesWritten)
258{
259 return DosWrite(hFile, lpBuffer, size, nrBytesWritten);
260}
261//******************************************************************************
262//******************************************************************************
263DWORD OSLibDosSetFilePtr(DWORD hFile, DWORD offset, DWORD method)
264{
265 DWORD os2method;
266 DWORD newoffset;
267 APIRET rc;
268
269 switch(method) {
270 case OSLIB_SETPTR_FILE_CURRENT:
271 os2method = FILE_CURRENT;
272 break;
273 case OSLIB_SETPTR_FILE_BEGIN:
274 os2method = FILE_BEGIN ;
275 break;
276 case OSLIB_SETPTR_FILE_END:
277 os2method = FILE_END;
278 break;
279 default:
280 return OSLIB_ERROR_INVALID_PARAMETER;
281 }
282 rc = DosSetFilePtr(hFile, offset, os2method, &newoffset);
283 if(rc) {
284 return -1;
285 }
286 else return newoffset;
287}
288//******************************************************************************
289//******************************************************************************
290//@@@PH Note: this routine is nothing but a QUICK'N'DIRTY HACK!
291//@@@PH this function should be implemented accordingly to NTDLL's
292// RtlSecondsSince1980ToTime
293// RtlTimeToSecondsSince1980
294static void iFDATEFTIME2FILETIME(FDATE fdOS2, FTIME ftOS2, LPFILETIME pftWin32)
295{
296 float f;
297 #define facSECOND 2 // as encoded in OS/2
298 #define facMINUTE 60
299 #define facHOUR 3600
300 #define facDAY 86400
301 #define facMONTH facDAY * 30 // cough, cough :)
302 #define facYEAR facDAY * 365
303
304 /* pftWin32 is 100ns based from 01.01.1601 00:00:00 */
305 f = (fdOS2.year + 379) * facYEAR // 1980 - 1601
306 + (fdOS2.month - 0 ) * facMONTH
307 + (fdOS2.day - 1 ) * facDAY
308 + (ftOS2.hours ) * facHOUR
309 + (ftOS2.minutes ) * facMINUTE
310 + (ftOS2.twosecs ) * facSECOND;
311
312 f *= 10000; // convert to 100ns base
313 pftWin32->dwHighDateTime = (f / (float)(0xffffffff) );
314 pftWin32->dwLowDateTime = (f - (float)((float)pftWin32->dwHighDateTime *
315 (float)0xffffffff) );
316}
317
318BOOL OSLibDosGetFileAttributesEx(PSZ pszName,
319 ULONG ulDummy,
320 PVOID pBuffer)
321{
322 APIRET rc; /* API return code */
323 FILESTATUS3 fs3; /* file information structure */
324 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) pBuffer;
325
326 // Note: we only handle standard "GetFileExInfoStandard" requests
327 rc = DosQueryPathInfo(pszName, /* query the file information */
328 FIL_STANDARD,
329 &fs3,
330 sizeof(fs3));
331 if (rc != NO_ERROR) /* check for errors */
332 return FALSE; /* raise error condition */
333
334 // convert structure
335 lpFad->dwFileAttributes = fs3.attrFile; // directly interchangeable
336 iFDATEFTIME2FILETIME(fs3.fdateCreation, fs3.ftimeCreation, &lpFad->ftCreationTime);
337 iFDATEFTIME2FILETIME(fs3.fdateLastAccess, fs3.ftimeLastAccess, &lpFad->ftLastAccessTime);
338 iFDATEFTIME2FILETIME(fs3.fdateLastWrite, fs3.ftimeLastWrite, &lpFad->ftLastWriteTime);
339
340 /* @@@PH we might add Aurora support ...
341 lpFad->nFileSizeHigh = info.nFileSizeHigh;
342 */
343 lpFad->nFileSizeHigh = 0;
344 lpFad->nFileSizeLow = fs3.cbFile;
345
346 return TRUE;
347}
348//******************************************************************************
349DWORD WIN32API GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD );
350//******************************************************************************
351DWORD OSLibDosSearchPath(DWORD cmd, char *path, char *name, char *full_name,
352 DWORD length_fullname)
353{
354 switch(cmd) {
355 case OSLIB_SEARCHDIR:
356 if(DosSearchPath(SEARCH_IGNORENETERRS, path,
357 name, full_name, length_fullname) != 0) {
358 return 0;
359 }
360 return strlen(full_name);
361
362
363 case OSLIB_SEARCHCURDIR:
364 if(DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_CUR_DIRECTORY, path,
365 name, full_name, length_fullname) != 0) {
366 return 0;
367 }
368 return strlen(full_name);
369
370 case OSLIB_SEARCHFILE:
371 {
372 FILESTATUS3 fileinfo;
373
374 if(DosQueryPathInfo(name, FIL_STANDARD, &fileinfo, sizeof(fileinfo)) != 0) {
375 return 0;
376 }
377 strncpy(full_name, name, length_fullname);
378 return strlen(full_name);
379 }
380
381 case OSLIB_SEARCHENV:
382 {
383 LPSTR envstring;
384 int envsize;
385 CHAR szResult[CCHMAXPATH];
386
387 envsize = GetEnvironmentVariableA(path, NULL, 0);
388 envstring = (LPSTR)malloc(envsize+1);
389 GetEnvironmentVariableA(path, envstring, envsize);
390 if(DosSearchPath(SEARCH_IGNORENETERRS, envstring,
391 name, szResult, sizeof(szResult)) != 0) {
392 free(envstring);
393 return 0;
394 }
395 free(envstring);
396 strcpy(full_name, szResult);
397 return strlen(full_name);
398 }
399 }
400 return 0;
401}
402//******************************************************************************
403//******************************************************************************
404DWORD OSLibDosCreate(CHAR *lpFileName,
405 DWORD dwAccess,
406 DWORD dwShare,
407 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
408 DWORD dwCreation,
409 DWORD dwFlags,
410 HANDLE hTemplate,
411 DWORD *dwFile)
412{
413 APIRET rc;
414 HFILE hFile;
415 ULONG ulAction=0;
416 DWORD os2Attrib=0;
417 DWORD os2Flags = 0; //OPEN_FLAGS_NOINHERIT;
418 DWORD os2Open=0;
419
420 if(dwAccess == (GENERIC_READ_W | GENERIC_WRITE_W))
421 os2Flags |= OPEN_ACCESS_READWRITE;
422 else if(dwAccess & GENERIC_WRITE_W)
423 os2Flags |= OPEN_ACCESS_WRITEONLY;
424 else if(dwAccess & GENERIC_READ_W)
425 os2Flags |= OPEN_ACCESS_READONLY;
426
427 if(dwShare == 0)
428 os2Flags |= OPEN_SHARE_DENYREADWRITE;
429 else if(dwShare == (FILE_SHARE_READ_W | FILE_SHARE_WRITE_W))
430 os2Flags |= OPEN_SHARE_DENYNONE;
431 else if(dwShare & FILE_SHARE_READ_W)
432 os2Flags |= OPEN_SHARE_DENYWRITE;
433 else if(dwShare & FILE_SHARE_WRITE_W)
434 os2Flags |= OPEN_SHARE_DENYREAD;
435
436 if(dwCreation == CREATE_NEW_W)
437 os2Open = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
438 else if(dwCreation == CREATE_ALWAYS_W)
439 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
440 else if(dwCreation == OPEN_EXISTING_W)
441 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
442 else if(dwCreation == OPEN_ALWAYS_W)
443 os2Open = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
444 else if(dwCreation == TRUNCATE_EXISTING_W)
445 os2Open = OPEN_ACTION_REPLACE_IF_EXISTS;// |OPEN_ACTION_FAIL_IF_NEW;
446
447 if(dwFlags & FILE_ATTRIBUTE_READONLY_W)
448 os2Attrib |= FILE_READONLY;
449 if(dwFlags & FILE_ATTRIBUTE_HIDDEN_W)
450 os2Attrib |= FILE_HIDDEN;
451 if(dwFlags & FILE_ATTRIBUTE_SYSTEM_W)
452 os2Attrib |= FILE_SYSTEM;
453 if(dwFlags & FILE_ATTRIBUTE_DIRECTORY_W)
454 os2Attrib |= FILE_DIRECTORY;
455 if(dwFlags & FILE_ATTRIBUTE_ARCHIVE_W)
456 os2Attrib |= FILE_ARCHIVED;
457 if(dwFlags & FILE_ATTRIBUTE_NORMAL_W)
458 os2Attrib |= FILE_NORMAL;
459
460 if(dwFlags & FILE_FLAG_WRITE_THROUGH_W)
461 os2Flags |= OPEN_FLAGS_WRITE_THROUGH;
462 if(dwFlags & FILE_FLAG_NO_BUFFERING_W)
463 os2Flags |= OPEN_FLAGS_NO_CACHE;
464 if(dwFlags & FILE_FLAG_RANDOM_ACCESS_W)
465 os2Flags |= OPEN_FLAGS_RANDOM;
466 if(dwFlags & FILE_FLAG_SEQUENTIAL_SCAN_W)
467 os2Flags |= OPEN_FLAGS_SEQUENTIAL;
468
469 // TODO:
470 // if(dwFlags & FILE_FLAG_OVERLAPPED_W)
471 // if(dwFlags & FILE_FLAG_DELETE_ON_CLOSE_W
472
473 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
474 os2Attrib, os2Open, os2Flags, 0);
475
476 if(rc)
477 {
478 // TODO: TEST TEST
479 dprintf(("DosOpen Error rc:%d, try without GENERIC_WRITE_W", rc));
480 if(dwAccess & GENERIC_WRITE_W)
481 os2Flags &= ~(OPEN_ACCESS_READWRITE | OPEN_ACCESS_WRITEONLY);
482 rc = DosOpen(lpFileName, &hFile, &ulAction, 0,
483 os2Attrib, os2Open, os2Flags, 0);
484 if(rc)
485 {
486 dprintf(("DosOpen Error rc:%d os2Attrib:%X os2Open:%X os2Flags:%X",
487 rc, os2Attrib, os2Open, os2Flags));
488 hFile = -1;
489 }
490 }
491
492 *dwFile = hFile;
493 return rc;
494}
495//******************************************************************************
496//(without changing file pointer)
497//******************************************************************************
498DWORD OSLibDosGetFileSize(DWORD hFile)
499{
500 FILESTATUS3 fsts3ConfigInfo = {{0}};
501 ULONG ulBufSize = sizeof(FILESTATUS3);
502
503 DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
504 return fsts3ConfigInfo.cbFile;
505}
506//******************************************************************************
507//******************************************************************************
508DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method)
509{
510 DWORD newoffset;
511 APIRET rc;
512
513
514 rc = DosSetFilePtr(hFile, offset, method, &newoffset);
515 if(rc) {
516 dprintf(("DosSetFilePtr Error rc:%d", rc));
517 return -1;
518 }
519 else return newoffset;
520}
521//******************************************************************************
522//(FlushBuffer)
523//******************************************************************************
524DWORD OSLibDosResetBuffer(DWORD hFile)
525{
526 return DosResetBuffer(hFile);
527}
528//******************************************************************************
529//******************************************************************************
530DWORD OSLibDosDupHandle(DWORD hFile, DWORD *hNew)
531{
532 *hNew = -1;
533 return DosDupHandle(hFile, hNew);
534}
535//******************************************************************************
536//******************************************************************************
537void OSLibDosDisableHardError(BOOL fTurnOff)
538{
539 DosError((fTurnOff) ? FERR_DISABLEHARDERR : FERR_ENABLEHARDERR);
540}
541//******************************************************************************
542//Returns time spent in kernel & user mode in milliseconds
543//******************************************************************************
544BOOL OSLibDosQueryProcTimes(DWORD procid, ULONG *kerneltime, ULONG *usertime)
545{
546 APIRET rc;
547 char *buf;
548 ULONG size;
549 ULONG nrthreads = 4;
550
551tryagain:
552 size = sizeof(QTOPLEVEL)+sizeof(QGLOBAL)+sizeof(QPROCESS) + nrthreads*sizeof(QTHREAD);
553 buf = (char *)malloc(size);
554 rc = DosQuerySysState(0x1, RESERVED, procid, RESERVED, (PCHAR)buf, size);
555
556 if(rc) {
557 free(buf);
558 if(rc == ERROR_BUFFER_OVERFLOW) {
559 nrthreads += 4;
560 goto tryagain;
561 }
562 return FALSE;
563 }
564 PQTOPLEVEL top = (PQTOPLEVEL)buf;
565
566 *kerneltime = 0;
567 *usertime = 0;
568 for(int i=0;i<top->procdata->threadcnt;i++) {
569 *kerneltime += top->procdata->threads[i].systime;
570 *usertime += top->procdata->threads[i].usertime;
571 }
572 free(buf);
573 return TRUE;
574}
575//******************************************************************************
576//******************************************************************************
577// TODO: implement SecurityAttributes parameter
578DWORD OSLibDosCreateNamedPipe(LPCTSTR lpName,
579 DWORD dwOpenMode,
580 DWORD dwPipeMode,
581 DWORD nMaxInstances,
582 DWORD nOutBufferSize,
583 DWORD nInBufferSize,
584 DWORD nDefaultTimeOut,
585 void* lpSecurityAttributes)
586{ DWORD dwOS2Mode = 0;
587 DWORD dwOS2PipeMode = 0;
588 LPSTR lpOS2Name;
589 DWORD hPipe;
590 DWORD rc;
591
592 if (dwOpenMode & PIPE_ACCESS_DUPLEX_W)
593 dwOS2Mode |= NP_ACCESS_DUPLEX;
594 else
595 if (dwOpenMode & PIPE_ACCESS_INBOUND_W)
596 dwOS2Mode |= NP_ACCESS_INBOUND;
597 else
598 if (dwOpenMode & PIPE_ACCESS_OUTBOUND_W)
599 dwOS2Mode |= NP_ACCESS_OUTBOUND;
600 // TODO:
601 // if(dwOpenMode & FILE_FLAG_OVERLAPPED)
602 // if(dwOpenMode & WRITE_DAC)
603 // if(dwOpenMode & WRITE_OWNER)
604 // if(dwOpenMode & ACCESS_SYSTEM_SECURITY)
605 if(dwOpenMode & FILE_FLAG_WRITE_THROUGH_W)
606 dwOS2Mode |= NP_WRITEBEHIND; // FIXME: I'm not sure!
607
608 if (dwPipeMode & PIPE_WAIT_W)
609 dwOS2PipeMode |= NP_WAIT;
610 if (dwPipeMode & PIPE_NOWAIT_W)
611 dwOS2PipeMode |= NP_NOWAIT;
612 if (dwPipeMode & PIPE_READMODE_BYTE_W)
613 dwOS2PipeMode |= NP_READMODE_BYTE;
614 if (dwPipeMode & PIPE_READMODE_MESSAGE_W)
615 dwOS2PipeMode |= NP_READMODE_MESSAGE;
616 if (dwPipeMode & PIPE_TYPE_BYTE_W)
617 dwOS2PipeMode |= NP_TYPE_BYTE;
618 if (dwPipeMode & PIPE_TYPE_MESSAGE_W)
619 dwOS2PipeMode |= NP_TYPE_MESSAGE;
620
621 if (nMaxInstances>0xff)
622 {
623 _O32_SetLastError(87); // ERROR_INVALID_PARAMETER
624 return -1; // INVALID_HANDLE_VALUE
625 }
626 dwOS2PipeMode |= nMaxInstances;
627
628 if (strstr(lpName,"\\\\."))
629 {
630 // If pipe is created on the local machine
631 // we must delete string \\. because
632 // in Windows named pipes scheme is a \\.\PIPE\pipename
633 // but in OS/2 only \PIPE\pipename
634 lpOS2Name = (LPSTR)lpName + 3;
635 }
636 else lpOS2Name = (LPSTR)lpName;
637
638 dprintf(("DosCreateNPipe(%s,%x,%x,%x,%x,%x)",lpOS2Name,dwOS2Mode,dwOS2PipeMode,nInBufferSize,nOutBufferSize,nDefaultTimeOut));
639 rc=DosCreateNPipe(lpOS2Name,
640 &hPipe,
641 dwOS2Mode,
642 dwOS2PipeMode,
643 nInBufferSize,
644 nInBufferSize,
645 nDefaultTimeOut); // Timeouts must be tested!
646
647 dprintf(("DosCreateNPipe rc=%d",rc));
648 if (rc)
649 {
650 if ( rc == ERROR_PIPE_BUSY ) _O32_SetLastError(ERROR_PIPE_BUSY_W);
651 else
652 if ( rc == ERROR_PATH_NOT_FOUND ) _O32_SetLastError(ERROR_PATH_NOT_FOUND_W);
653 else
654 if ( rc == ERROR_NOT_ENOUGH_MEMORY ) _O32_SetLastError(ERROR_NOT_ENOUGH_MEMORY_W);
655 else
656 if ( rc == ERROR_INVALID_PARAMETER ) _O32_SetLastError(ERROR_INVALID_PARAMETER_W);
657 else
658 if ( rc == ERROR_OUT_OF_STRUCTURES ) _O32_SetLastError(ERROR_OUT_OF_STRUCTURES_W);
659 else
660 // Unknown error
661 _O32_SetLastError(ERROR_INVALID_PARAMETER_W); // fixme!
662 return -1; // INVALID_HANDLE_VALUE
663 }
664 return hPipe;
665}
666
667//******************************************************************************
668//******************************************************************************
669// TODO: implement lpOverlapped parameter!
670BOOL OSLibDosConnectNamedPipe(DWORD hNamedPipe, LPOVERLAPPED lpOverlapped)
671{
672 DWORD rc;
673
674 rc=DosConnectNPipe(hNamedPipe);
675 dprintf(("DosConnectNPipe rc=%d",rc));
676
677 if (!rc) return (TRUE);
678 else
679 if (rc==ERROR_BROKEN_PIPE) _O32_SetLastError(ERROR_BROKEN_PIPE_W);
680 else
681 if (rc==ERROR_BAD_PIPE) _O32_SetLastError(ERROR_BAD_PIPE_W);
682 else
683 if (rc==ERROR_PIPE_NOT_CONNECTED) _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
684 else
685 // TODO: Implemnt this using Windows Errors
686 // if (rc==ERROR_INTERRUPT)
687 _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
688
689 return (FALSE);
690}
691
692//******************************************************************************
693//******************************************************************************
694BOOL OSLibDosCallNamedPipe( LPCTSTR lpNamedPipeName,
695 LPVOID lpInBuffer,
696 DWORD nInBufferSize,
697 LPVOID lpOutBuffer,
698 DWORD nOutBufferSize,
699 LPDWORD lpBytesRead,
700 DWORD nTimeOut )
701{
702 LPSTR lpOS2Name;
703 DWORD rc;
704
705 if (strstr(lpNamedPipeName,"\\\\."))
706 {
707 // If pipe is created on the local machine
708 // we must delete string \\. because
709 // in Windows named pipes scheme is a \\.\PIPE\pipename
710 // but in OS/2 only \PIPE\pipename
711 lpOS2Name = (LPSTR)lpNamedPipeName + 3;
712 }
713 else lpOS2Name = (LPSTR)lpNamedPipeName;
714
715 rc=DosCallNPipe(lpOS2Name,
716 lpInBuffer,
717 nInBufferSize,
718 lpOutBuffer,
719 nOutBufferSize,
720 lpBytesRead,
721 nTimeOut );
722
723
724 if (!rc) return (TRUE);
725 else
726 if ( rc==ERROR_FILE_NOT_FOUND ) _O32_SetLastError(ERROR_FILE_NOT_FOUND_W);
727 else
728 if ( rc==ERROR_PATH_NOT_FOUND ) _O32_SetLastError(ERROR_PATH_NOT_FOUND_W);
729 else
730 if ( rc==ERROR_ACCESS_DENIED ) _O32_SetLastError(ERROR_ACCESS_DENIED_W);
731 else
732 if ( rc==ERROR_MORE_DATA ) _O32_SetLastError(ERROR_MORE_DATA_W);
733 else
734 if ( rc==ERROR_PIPE_BUSY ) _O32_SetLastError(ERROR_PIPE_BUSY_W);
735 else
736 if ( rc==ERROR_BAD_FORMAT ) _O32_SetLastError(ERROR_BAD_FORMAT_W);
737 else
738 if ( rc==ERROR_BROKEN_PIPE ) _O32_SetLastError(ERROR_BROKEN_PIPE_W);
739 else
740 if ( rc==ERROR_BAD_PIPE ) _O32_SetLastError(ERROR_BAD_PIPE_W);
741 else
742 if ( rc==ERROR_PIPE_NOT_CONNECTED ) _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
743 else
744 // TODO: Implemnt this using Windows Errors
745 // if (rc==ERROR_INTERRUPT)
746 _O32_SetLastError(233);
747
748 return (FALSE);
749}
750
751//******************************************************************************
752//******************************************************************************
753BOOL OSLibDosTransactNamedPipe( DWORD hNamedPipe,
754 LPVOID lpInBuffer,
755 DWORD nInBufferSize,
756 LPVOID lpOutBuffer,
757 DWORD nOutBufferSize,
758 LPDWORD lpBytesRead,
759 LPOVERLAPPED lpOverlapped)
760{
761 DWORD rc;
762
763 rc=DosTransactNPipe(hNamedPipe,
764 lpOutBuffer,
765 nOutBufferSize,
766 lpInBuffer,
767 nInBufferSize,
768 lpBytesRead);
769
770 dprintf(("DosTransactNPipe returned rc=%d");)
771 if (!rc) return (TRUE);
772 else
773 if ( rc==ERROR_ACCESS_DENIED ) _O32_SetLastError(ERROR_ACCESS_DENIED_W);
774 else
775 if ( rc==ERROR_MORE_DATA ) _O32_SetLastError(ERROR_MORE_DATA_W);
776 else
777 if ( rc==ERROR_PIPE_BUSY ) _O32_SetLastError(ERROR_PIPE_BUSY_W);
778 else
779 if ( rc==ERROR_BAD_FORMAT ) _O32_SetLastError(ERROR_BAD_FORMAT_W);
780 else
781 if ( rc==ERROR_BROKEN_PIPE ) _O32_SetLastError(ERROR_BROKEN_PIPE_W);
782 else
783 if ( rc==ERROR_BAD_PIPE ) _O32_SetLastError(ERROR_BAD_PIPE_W);
784 else
785 if ( rc==ERROR_PIPE_NOT_CONNECTED ) _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
786 else
787 // Unknown error
788 _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
789
790 return (FALSE);
791}
792
793//******************************************************************************
794//******************************************************************************
795BOOL OSLibDosPeekNamedPipe(DWORD hPipe,
796 LPVOID lpvBuffer,
797 DWORD cbBuffer,
798 LPDWORD lpcbRead,
799 LPDWORD lpcbAvail,
800 LPDWORD lpcbMessage)
801{
802 DWORD rc;
803 AVAILDATA availData ={0};
804 ULONG ulDummy;
805
806 rc=DosPeekNPipe(hPipe,lpvBuffer,cbBuffer,lpcbRead,&availData,&ulDummy);
807
808 dprintf(("DosPeekNPipe returned rc=%d",rc));
809
810 if (!rc)
811 {
812 *lpcbAvail = availData.cbpipe;
813 *lpcbMessage = availData.cbmessage;
814 return (TRUE);
815 }
816 else
817 if ( rc==ERROR_ACCESS_DENIED ) _O32_SetLastError(ERROR_ACCESS_DENIED_W);
818 else
819 if ( rc==ERROR_PIPE_BUSY ) _O32_SetLastError(ERROR_PIPE_BUSY_W);
820 else
821 if ( rc==ERROR_BAD_PIPE ) _O32_SetLastError(ERROR_BAD_PIPE_W);
822 else
823 if ( rc==ERROR_PIPE_NOT_CONNECTED ) _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
824 else
825 // Unknown error
826 _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
827
828 return (FALSE);
829}
830//******************************************************************************
831//******************************************************************************
832BOOL OSLibDosDisconnectNamedPipe(DWORD hPipe)
833{
834 DWORD rc;
835
836 rc=DosDisConnectNPipe(hPipe);
837
838 dprintf(("DosDisConnectNPipe returned rc=%d",rc));
839
840 if (!rc) return TRUE;
841 else
842 if ( rc==ERROR_BROKEN_PIPE ) _O32_SetLastError(ERROR_BROKEN_PIPE_W);
843 else
844 if ( rc==ERROR_BAD_PIPE ) _O32_SetLastError(ERROR_BAD_PIPE_W);
845 else
846 // Unknown error
847 _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W); // Maybe another?
848
849 return (FALSE);
850}
851//******************************************************************************
852//******************************************************************************
853BOOL OSLibDosWaitNamedPipe(LPCSTR lpszNamedPipeName,
854 DWORD dwTimeout)
855{
856 LPSTR lpOS2Name;
857 DWORD rc;
858
859 if (strstr(lpszNamedPipeName,"\\\\."))
860 {
861 // If pipe is created on the local machine
862 // we must delete string \\. because
863 // in Windows named pipes scheme is a \\.\PIPE\pipename
864 // but in OS/2 only \PIPE\pipename
865 lpOS2Name = (LPSTR)lpszNamedPipeName + 3;
866 }
867 else lpOS2Name = (LPSTR)lpszNamedPipeName;
868
869 rc=DosWaitNPipe(lpOS2Name,dwTimeout);
870
871 dprintf(("DosWaitNPipe returned rc=%d",rc));
872
873 if (!rc) return TRUE;
874 else
875 if ( rc == ERROR_PATH_NOT_FOUND ) _O32_SetLastError(ERROR_PATH_NOT_FOUND_W);
876 else
877 if ( rc==ERROR_BAD_PIPE ) _O32_SetLastError(ERROR_BAD_PIPE_W);
878 else
879 if ( rc == ERROR_PIPE_BUSY ) _O32_SetLastError(ERROR_PIPE_BUSY_W);
880 else
881 if ( rc == ERROR_SEM_TIMEOUT_W ) _O32_SetLastError(ERROR_SEM_TIMEOUT_W);
882 else
883 // TODO: Implemnt this using Windows Errors
884 // if (rc==ERROR_INTERRUPT)
885 _O32_SetLastError(ERROR_PIPE_NOT_CONNECTED_W);
886
887 return (FALSE);
888}
Note: See TracBrowser for help on using the repository browser.