APIRET os2APIENTRY DosCreatePipe(PHFILE phfRead, PHFILE phfWrite, ULONG cb) { if(phfRead==0 || phfWrite==0) return 87; //invalid parameter ntFILE *ntFileR=new ntFILE; if(!ntFileR) return 8; //not enough memory ntFILE *ntFileW=new ntFILE; if(!ntFileW) { delete ntFileR; return 8; //not enough memory } int idxR=FileTable.findAndLockFree(); if(idxR==-1) { delete ntFileR; delete ntFileW; return 4; //too many open files } int idxW=FileTable.findAndLockFree(); if(idxW==-1) { delete ntFileR; delete ntFileW; FileTable.unlock(idxR); return 4; //too many open files } HANDLE hReadPipe,hWritePipe; SECURITY_ATTRIBUTES sa; memset(&sa,0,sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; //os/2 pipes are by default inherited, nt pipes isn't if(CreatePipe(&hReadPipe,&hWritePipe,&sa,(DWORD)cb)) { ntFileR->ntFileHandle = hReadPipe; ntFileR->mode = OPEN_ACCESS_READONLY; ntFileW->ntFileHandle = hWritePipe; ntFileW->mode = OPEN_ACCESS_WRITEONLY; FileTable[idxR] = ntFileR; FileTable[idxW] = ntFileW; FileTable.unlock(idxR); FileTable.unlock(idxW); *phfRead = (os2HFILE)idxR; *phfWrite = (os2HFILE)idxW; return 0; } else { FileTable.unlock(idxR); FileTable.unlock(idxW); delete ntFileR; delete ntFileW; return (APIRET)GetLastError(); } }
APIRET os2APIENTRY DosDupHandle(os2HFILE hFile, PHFILE pHfile) { int srcIdx = (int)hFile; FileTable.lock(srcIdx); if(!FileTable[srcIdx]) { FileTable.unlock(srcIdx); return 1; //FixMe } int dstIdx; if(*pHfile==(os2HFILE)-1) { dstIdx = FileTable.findAndLockFree(); if(dstIdx==-1) { FileTable.unlock(srcIdx); return 4; //too many open files } } else { dstIdx = (int)*pHfile; FileTable.lock(dstIdx); } if(srcIdx==dstIdx) { //no-op FileTable.unlock(srcIdx); return 0; } if(FileTable[dstIdx]) { CloseHandle(FileTable[dstIdx]->ntFileHandle); delete FileTable[dstIdx]; FileTable[dstIdx] = 0; } APIRET rc; HANDLE target; if(DuplicateHandle(GetCurrentProcess(), FileTable[srcIdx]->ntFileHandle, GetCurrentProcess(), &target, 0, TRUE, DUPLICATE_SAME_ACCESS )) { rc = 0; FileTable[dstIdx] = new ntFILE; FileTable[dstIdx]->ntFileHandle = target; FileTable[dstIdx]->mode = FileTable[srcIdx]->mode; if(dstIdx==0) SetStdHandle(STD_INPUT_HANDLE,target); else if(dstIdx==1) SetStdHandle(STD_OUTPUT_HANDLE,target); else if(dstIdx==2) SetStdHandle(STD_ERROR_HANDLE,target); } else rc = 6; //invalid handle FileTable.unlock(srcIdx); FileTable.unlock(dstIdx); return rc; }
APIRET os2APIENTRY DosOpen(PCSZ pszFileName, PHFILE pHf, PULONG pulAction, ULONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2) { int idx=FileTable.findAndLockFree(); if(idx==-1) return 4; //too many open files ntFILE *ntFile=new ntFILE; if(!ntFile) return 8; //not enough memory if(peaop2) return 282; //eas not supported char szName[MAX_PATH]; DWORD fdwAccess; DWORD fdwShareMode; LPSECURITY_ATTRIBUTES lpsa; DWORD fdwCreate; DWORD fdwAttrsAndFlags; HANDLE hTemplateFile; //szName, FixMe: named pipe namespace strcpy(szName,pszFileName); //fdwAcess if((fsOpenMode&0x7)==OPEN_ACCESS_READONLY) fdwAccess = GENERIC_READ; else if((fsOpenMode&0x7)==OPEN_ACCESS_WRITEONLY) fdwAccess = GENERIC_WRITE; else if((fsOpenMode&0x7)==OPEN_ACCESS_READWRITE) fdwAccess = GENERIC_READ|GENERIC_WRITE; else return 87; //invalid parameter //fdwShareMode if((fsOpenMode&0x70)==OPEN_SHARE_DENYREADWRITE) fdwShareMode = 0; else if((fsOpenMode&0x70)==OPEN_SHARE_DENYWRITE) fdwShareMode = FILE_SHARE_READ; else if((fsOpenMode&0x70)==OPEN_SHARE_DENYREAD) fdwShareMode = FILE_SHARE_WRITE; else if((fsOpenMode&0x70)==OPEN_SHARE_DENYNONE) fdwShareMode = FILE_SHARE_READ+FILE_SHARE_WRITE; else return 87; //invalid parameter //lpsa SECURITY_ATTRIBUTES sa; if((fsOpenMode&OPEN_FLAGS_NOINHERIT)) lpsa = 0; else { memset(&sa,0,sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; lpsa = &sa; } //fdwCreate switch(fsOpenFlags&0xff) { case OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_FAIL_IF_EXISTS: return 1; //FixMe case OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS: fdwCreate = OPEN_EXISTING; break; case OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_REPLACE_IF_EXISTS: fdwCreate = TRUNCATE_EXISTING; break; case OPEN_ACTION_CREATE_IF_NEW|OPEN_ACTION_FAIL_IF_EXISTS: fdwCreate = CREATE_NEW; break; case OPEN_ACTION_CREATE_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS: fdwCreate = OPEN_ALWAYS; break; case OPEN_ACTION_CREATE_IF_NEW|OPEN_ACTION_REPLACE_IF_EXISTS: fdwCreate = CREATE_ALWAYS; break; default: return 87; //invalid parameter, FixMe: is this legal under os/2? } //fdwAttrsAndFlags fdwAttrsAndFlags = 0; if(ulAttribute&FILE_ARCHIVED) fdwAttrsAndFlags |= FILE_ATTRIBUTE_ARCHIVE; if(ulAttribute&FILE_SYSTEM) fdwAttrsAndFlags |= FILE_ATTRIBUTE_SYSTEM; if(ulAttribute&FILE_HIDDEN) fdwAttrsAndFlags |= FILE_ATTRIBUTE_HIDDEN; if(ulAttribute&FILE_READONLY) fdwAttrsAndFlags |= FILE_ATTRIBUTE_READONLY; if(fsOpenMode&OPEN_FLAGS_WRITE_THROUGH) fdwAttrsAndFlags |= FILE_FLAG_WRITE_THROUGH; if(fsOpenMode&OPEN_FLAGS_NO_CACHE) fdwAttrsAndFlags |= FILE_FLAG_WRITE_THROUGH; if((fsOpenMode&0x700)==OPEN_FLAGS_SEQUENTIAL) fdwAttrsAndFlags |= FILE_FLAG_SEQUENTIAL_SCAN; if((fsOpenMode&0x700)==OPEN_FLAGS_RANDOM) fdwAttrsAndFlags |= FILE_FLAG_RANDOM_ACCESS; //hTemplateFile hTemplateFile = 0; HANDLE hf = CreateFile(szName, fdwAccess, fdwShareMode, lpsa, fdwCreate, fdwAttrsAndFlags, hTemplateFile); if(hf==INVALID_HANDLE_VALUE) return (APIRET)GetLastError(); //->pulAction if(fdwCreate==CREATE_ALWAYS || fdwCreate==OPEN_ALWAYS) { if(GetLastError()==183/*ERROR_ALREADY_EXIST*/) *pulAction = fdwCreate==CREATE_ALWAYS?FILE_CREATED:FILE_EXISTED; else *pulAction = FILE_CREATED; } else { *pulAction = FILE_EXISTED; } if((fsOpenFlags&0x0f)==OPEN_ACTION_REPLACE_IF_EXISTS) { //set file size SetFilePointer(hf,cbFile,0,0); SetEndOfFile(hf); //FixMe SetFilePointer(hf,0,0,0); } *pHf = (os2HFILE)idx; ntFile->ntFileHandle = hf; ntFile->mode = fsOpenMode; FileTable[idx] = ntFile; FileTable.unlock(idx); return 0; }