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

Last change on this file since 21302 was 21302, checked in by ydario, 16 years ago

Kernel32 updates.

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