source: trunk/src/kernel32/hmnpipe.cpp@ 9660

Last change on this file since 9660 was 9660, checked in by sandervl, 23 years ago

changes for inheritance (check security structure); workaround for PeekNamedPipe with unnamed pipes; support input/output redirection for child processes

File size: 17.8 KB
Line 
1/* $Id: hmnpipe.cpp,v 1.10 2003-01-10 15:19:53 sandervl Exp $ */
2/*
3 * Project Odin Software License can be found in LICENSE.TXT
4 *
5 * Win32 Named Pipes device access class
6 *
7 * Copyright 2000 Przemyslaw Dobrowolski <dobrawka@asua.org.pl>
8 *
9 * TODO: OVERLAPPED results!!!!
10 *
11 * PD: All my work for Odin I dedicate to my deceased mother.
12 *
13 */
14#include <odin.h>
15#include <os2win.h>
16#include <misc.h>
17#include "HMDevice.h"
18#include "HMFile.h"
19#include "HMNPipe.h"
20#include "oslibdos.h"
21#include <string.h>
22
23#define DBG_LOCALLOG DBG_hmnpipe
24#include "dbglocal.h"
25
26#undef DEBUG_LOCAL
27//#define DEBUG_LOCAL
28
29#ifdef DEBUG_LOCAL
30# define dprintfl(a) dprintf(a)
31#else
32inline void ignore_dprintf(...){}
33# define dprintfl(a) ignore_dprintf(a)
34#endif
35
36/*****************************************************************************
37 Register PIPE device class
38 *****************************************************************************/
39HMDeviceNamedPipeClass::HMDeviceNamedPipeClass(LPCSTR lpDeviceName) : HMDeviceFileClass(lpDeviceName)
40{
41 HMDeviceRegisterEx("\\\\.\\PIPE", this, NULL);
42}
43/*****************************************************************************
44 * Name : HMDeviceNamedPipeClass::FindDevice
45 * Purpose : Checks if lpDeviceName belongs to this device class
46 * Parameters: LPCSTR lpClassDevName
47 * LPCSTR lpDeviceName
48 * int namelength
49 * Variables :
50 * Result :
51 * Remark :
52 * Status :
53 *
54 * Author : SvL
55 *****************************************************************************/
56BOOL HMDeviceNamedPipeClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
57{
58 if(lstrncmpiA("\\\\.\\PIPE\\", lpDeviceName, 9) == 0) {
59 return TRUE;
60 }
61 return FALSE;
62}
63//******************************************************************************
64//******************************************************************************
65BOOL HMDeviceNamedPipeClass::PeekNamedPipe(PHMHANDLEDATA pHMHandleData,
66 LPVOID lpvBuffer,
67 DWORD cbBuffer,
68 LPDWORD lpcbRead,
69 LPDWORD lpcbAvail,
70 LPDWORD lpcbMessage)
71{
72 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::PeekNamedPipe %s(%08x)\n",
73 lpHMDeviceName, pHMHandleData));
74
75 return OSLibDosPeekNamedPipe(pHMHandleData->hHMHandle,
76 lpvBuffer,
77 cbBuffer,
78 lpcbRead,
79 lpcbAvail,
80 lpcbMessage);
81}
82
83//******************************************************************************
84//******************************************************************************
85DWORD HMDeviceNamedPipeClass::CreateNamedPipe(PHMHANDLEDATA pHMHandleData,
86 LPCTSTR lpName,
87 DWORD dwOpenMode,
88 DWORD dwPipeMode,
89 DWORD nMaxInstances,
90 DWORD nOutBufferSize,
91 DWORD nInBufferSize,
92 DWORD nDefaultTimeOut,
93 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
94{
95 pHMHandleData->dwInternalType = HMTYPE_PIPE;
96
97 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::CreateNamedPipe %s\n",
98 lpName));
99
100
101 pHMHandleData->hHMHandle = OSLibDosCreateNamedPipe( lpName,
102 dwOpenMode,
103 dwPipeMode,
104 nMaxInstances,
105 nOutBufferSize,
106 nInBufferSize,
107 nDefaultTimeOut,
108 lpSecurityAttributes );
109
110
111 return (pHMHandleData->hHMHandle);
112}
113/*****************************************************************************
114 * Name : DWORD HMDeviceNamedPipeClass::CreateFile
115 * Purpose : this is called from the handle manager if a CreateFile() is
116 * performed on a handle
117 * Parameters: LPCSTR lpFileName name of the file / device
118 * PHMHANDLEDATA pHMHandleData data of the NEW handle
119 * PVOID lpSecurityAttributes ignored
120 * PHMHANDLEDATA pHMHandleDataTemplate data of the template handle
121 * Variables :
122 * Result :
123 * Remark :
124 * Status : NO_ERROR - API succeeded
125 * other - what is to be set in SetLastError
126 *
127 * Author : SvL
128 *****************************************************************************/
129
130DWORD HMDeviceNamedPipeClass::CreateFile (LPCSTR lpFileName,
131 PHMHANDLEDATA pHMHandleData,
132 PVOID lpSecurityAttributes,
133 PHMHANDLEDATA pHMHandleDataTemplate)
134{
135 pHMHandleData->hHMHandle = OSLibDosOpenPipe(lpFileName,
136 pHMHandleData->dwAccess,
137 pHMHandleData->dwShare,
138 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
139 pHMHandleData->dwCreation,
140 pHMHandleData->dwFlags);
141 if(pHMHandleData->hHMHandle == -1) {
142 return GetLastError();
143 }
144 return ERROR_SUCCESS;
145}
146
147/*****************************************************************************
148 * Name : DWORD HMDeviceFileClass::GetFileType
149 * Purpose : determine the handle type
150 * Parameters: PHMHANDLEDATA pHMHandleData
151 * Variables :
152 * Result : API returncode
153 * Remark :
154 * Status :
155 *
156 * Author : SvL
157 *****************************************************************************/
158
159DWORD HMDeviceNamedPipeClass::GetFileType(PHMHANDLEDATA pHMHandleData)
160{
161 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::GetFileType %s(%08x)\n",
162 lpHMDeviceName,
163 pHMHandleData));
164
165 return FILE_TYPE_PIPE;
166}
167
168/*****************************************************************************
169 * Name : DWORD HMDeviceNamedPipeClass::CloseHandle
170 * Purpose : close the handle
171 * Parameters: PHMHANDLEDATA pHMHandleData
172 * Variables :
173 * Result : API returncode
174 * Remark :
175 * Status :
176 *
177 * Author : SvL
178 *****************************************************************************/
179
180BOOL HMDeviceNamedPipeClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
181{
182 dprintf(("KERNEL32: HMDeviceNamedPipeClass::CloseHandle(%08x)", pHMHandleData->hHMHandle));
183
184 OSLibDosDisconnectNamedPipe(pHMHandleData->hHMHandle);
185 return OSLibDosClose(pHMHandleData->hHMHandle);
186}
187//******************************************************************************
188//******************************************************************************
189BOOL HMDeviceNamedPipeClass::CreatePipe(PHMHANDLEDATA pHMHandleDataRead,
190 PHMHANDLEDATA pHMHandleDataWrite,
191 LPSECURITY_ATTRIBUTES lpsa,
192 DWORD cbPipe)
193{
194 pHMHandleDataRead->dwInternalType = HMTYPE_PIPE;
195 pHMHandleDataWrite->dwInternalType = HMTYPE_PIPE;
196
197 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::CreatePipe"));
198
199 if(!OSLibDosCreatePipe(&pHMHandleDataRead->hHMHandle,
200 &pHMHandleDataWrite->hHMHandle,
201 lpsa,
202 cbPipe))
203 {
204 return TRUE;
205 }
206 else
207 return FALSE;
208}
209//******************************************************************************
210//******************************************************************************
211BOOL HMDeviceNamedPipeClass::ConnectNamedPipe( PHMHANDLEDATA pHMHandleData,
212 LPOVERLAPPED lpOverlapped)
213{
214 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::ConnectNamedPipe %s(%08x) [%08x]\n",
215 lpHMDeviceName, pHMHandleData,lpOverlapped));
216
217 return OSLibDosConnectNamedPipe(pHMHandleData->hHMHandle,lpOverlapped);
218}
219
220//******************************************************************************
221//******************************************************************************
222BOOL HMDeviceNamedPipeClass::DisconnectNamedPipe(PHMHANDLEDATA pHMHandleData)
223{
224 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::DisconnectNamedPipe %s(%08x)\n",
225 lpHMDeviceName, pHMHandleData));
226
227 return OSLibDosDisconnectNamedPipe(pHMHandleData->hHMHandle);
228}
229
230//******************************************************************************
231//******************************************************************************
232BOOL HMDeviceNamedPipeClass::GetNamedPipeHandleState(PHMHANDLEDATA pHMHandleData,
233 LPDWORD lpState,
234 LPDWORD lpCurInstances,
235 LPDWORD lpMaxCollectionCount,
236 LPDWORD lpCollectDataTimeout,
237 LPTSTR lpUserName,
238 DWORD nMaxUserNameSize)
239{
240 dprintf(("KERNEL32: HMDeviceNamedPipeClass::GetNamedPipeHandleStateA (%s) (%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) NIY\n",
241 lpHMDeviceName,
242 lpState,
243 lpCurInstances,
244 lpMaxCollectionCount,
245 lpCollectDataTimeout,
246 lpUserName,
247 nMaxUserNameSize));
248
249 return (FALSE);
250}
251
252//******************************************************************************
253//******************************************************************************
254BOOL HMDeviceNamedPipeClass::GetNamedPipeInfo(PHMHANDLEDATA pHMHandleData,
255 LPDWORD lpFlags,
256 LPDWORD lpOutBufferSize,
257 LPDWORD lpInBufferSize,
258 LPDWORD lpMaxInstances)
259{
260
261 dprintf(("KERNEL32: HMDeviceNamedPipeClass::GetNamedPipeInfo (%s) (%08xh,%08xh,%08xh,%08xh) NIY\n",
262 lpHMDeviceName,
263 lpFlags,
264 lpOutBufferSize,
265 lpInBufferSize,
266 lpMaxInstances));
267
268 return (FALSE);
269}
270//******************************************************************************
271//******************************************************************************
272DWORD HMDeviceNamedPipeClass::TransactNamedPipe(PHMHANDLEDATA pHMHandleData,
273 LPVOID lpvWriteBuf,
274 DWORD cbWriteBuf,
275 LPVOID lpvReadBuf,
276 DWORD cbReadBuf,
277 LPDWORD lpcbRead,
278 LPOVERLAPPED lpo)
279{
280
281 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::TransactNamedPipe %s(%08x) - [%08x,%08x,%08x,%08x,%08x,%08x]\n",
282 lpHMDeviceName, pHMHandleData,lpvWriteBuf,cbWriteBuf,lpvReadBuf,cbReadBuf,lpcbRead,lpo));
283
284 return(OSLibDosTransactNamedPipe( pHMHandleData->hHMHandle,
285 lpvWriteBuf,
286 cbWriteBuf,
287 lpvReadBuf,
288 cbReadBuf,
289 lpcbRead,
290 lpo));
291}
292//******************************************************************************
293//******************************************************************************
294BOOL HMDeviceNamedPipeClass::SetNamedPipeHandleState(PHMHANDLEDATA pHMHandleData,
295 LPDWORD lpdwMode,
296 LPDWORD lpcbMaxCollect,
297 LPDWORD lpdwCollectDataTimeout)
298{
299 BOOL ret;
300
301 dprintf(("KERNEL32: HMDeviceNamedPipeClass::SetNamedPipeInfo (%s) (%08xh,%08xh,%08xh)",
302 lpdwMode,lpcbMaxCollect,lpdwCollectDataTimeout));
303
304 if(lpdwMode) {
305 ret = OSLibSetNamedPipeState(pHMHandleData->hHMHandle, *lpdwMode);
306 }
307 if(lpcbMaxCollect || lpdwCollectDataTimeout) {
308 dprintf(("WARNING: Not supported -> lpcbMaxCollect & lpdwCollectDataTimeout"));
309 }
310 return ret;
311}
312//******************************************************************************
313//******************************************************************************
314BOOL HMDeviceNamedPipeClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
315 LPOVERLAPPED arg2,
316 LPDWORD arg3,
317 BOOL arg4)
318{
319 return (FALSE);
320}
321/*****************************************************************************
322 * Name : BOOL HMDeviceNamedPipeClass::ReadFile
323 * Purpose : read data from handle / device
324 * Parameters: PHMHANDLEDATA pHMHandleData,
325 * LPCVOID lpBuffer,
326 * DWORD nNumberOfBytesToRead,
327 * LPDWORD lpNumberOfBytesRead,
328 * LPOVERLAPPED lpOverlapped
329 * Variables :
330 * Result : Boolean
331 * Remark :
332 * Status :
333 *
334 * Author : SvL
335 *****************************************************************************/
336
337BOOL HMDeviceNamedPipeClass::ReadFile(PHMHANDLEDATA pHMHandleData,
338 LPCVOID lpBuffer,
339 DWORD nNumberOfBytesToRead,
340 LPDWORD lpNumberOfBytesRead,
341 LPOVERLAPPED lpOverlapped,
342 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
343{
344 DWORD bytesread;
345 BOOL bRC;
346
347 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
348 lpHMDeviceName,
349 pHMHandleData,
350 lpBuffer,
351 nNumberOfBytesToRead,
352 lpNumberOfBytesRead,
353 lpOverlapped));
354
355 //This pointer can to be NULL
356 if(lpNumberOfBytesRead)
357 *lpNumberOfBytesRead = 0;
358 else
359 lpNumberOfBytesRead = &bytesread;
360
361 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
362 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
363 SetLastError(ERROR_INVALID_PARAMETER);
364 return FALSE;
365 }
366 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
367 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
368 }
369 if(lpCompletionRoutine) {
370 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
371 }
372
373 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
374 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
375 }
376
377 bRC = HMDeviceFileClass::ReadFile(pHMHandleData,
378 lpBuffer,
379 nNumberOfBytesToRead,
380 lpNumberOfBytesRead,
381 lpOverlapped, lpCompletionRoutine);
382
383 dprintf(("KERNEL32: HMDeviceNamedPipeClass::ReadFile returned %08xh; bytes read %d",
384 bRC, *lpNumberOfBytesRead));
385
386 return bRC;
387}
388
389
390/*****************************************************************************
391 * Name : BOOL HMDeviceNamedPipeClass::WriteFile
392 * Purpose : write data to handle / device
393 * Parameters: PHMHANDLEDATA pHMHandleData,
394 * LPCVOID lpBuffer,
395 * DWORD nNumberOfBytesToWrite,
396 * LPDWORD lpNumberOfBytesWritten,
397 * LPOVERLAPPED lpOverlapped
398 * Variables :
399 * Result : Boolean
400 * Remark :
401 * Status :
402 *
403 * Author : SvL
404 *****************************************************************************/
405
406BOOL HMDeviceNamedPipeClass::WriteFile(PHMHANDLEDATA pHMHandleData,
407 LPCVOID lpBuffer,
408 DWORD nNumberOfBytesToWrite,
409 LPDWORD lpNumberOfBytesWritten,
410 LPOVERLAPPED lpOverlapped,
411 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
412{
413 DWORD byteswritten;
414 BOOL bRC;
415
416 dprintfl(("KERNEL32: HMDeviceNamedPipeClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
417 lpHMDeviceName,
418 pHMHandleData,
419 lpBuffer,
420 nNumberOfBytesToWrite,
421 lpNumberOfBytesWritten,
422 lpOverlapped));
423
424 //This pointer can to be NULL
425 if(lpNumberOfBytesWritten)
426 *lpNumberOfBytesWritten = 0;
427 else
428 lpNumberOfBytesWritten = &byteswritten;
429
430 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
431 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
432 SetLastError(ERROR_INVALID_PARAMETER);
433 return FALSE;
434 }
435 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
436 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
437 }
438
439 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
440 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
441 }
442 bRC = HMDeviceFileClass::WriteFile(pHMHandleData,
443 lpBuffer,
444 nNumberOfBytesToWrite,
445 lpNumberOfBytesWritten,
446 lpOverlapped, lpCompletionRoutine);
447
448 dprintf(("KERNEL32: HMDeviceNamedPipeClass::WriteFile returned %08xh; bytes written %d",
449 bRC, *lpNumberOfBytesWritten));
450
451 return bRC;
452}
453//******************************************************************************
454//******************************************************************************
Note: See TracBrowser for help on using the repository browser.