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

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

Search path for executables when they can't be found in the current directory.

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