mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 04:20:46 +00:00
- fixed TransactNamedPipe to properly wait on completion for synchronous operations
- prevent completion port notification by not passing an APC context to the kernel when the low-order bit of the event handle is set (for asynchronous operations) svn path=/trunk/; revision=15051
This commit is contained in:
parent
bb1d3b119b
commit
b62466eed1
1 changed files with 82 additions and 53 deletions
|
@ -892,64 +892,93 @@ PeekNamedPipe(HANDLE hNamedPipe,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
TransactNamedPipe(HANDLE hNamedPipe,
|
TransactNamedPipe(IN HANDLE hNamedPipe,
|
||||||
LPVOID lpInBuffer,
|
IN LPVOID lpInBuffer,
|
||||||
DWORD nInBufferSize,
|
IN DWORD nInBufferSize,
|
||||||
LPVOID lpOutBuffer,
|
OUT LPVOID lpOutBuffer,
|
||||||
DWORD nOutBufferSize,
|
IN DWORD nOutBufferSize,
|
||||||
LPDWORD lpBytesRead,
|
OUT LPDWORD lpBytesRead OPTIONAL,
|
||||||
LPOVERLAPPED lpOverlapped)
|
IN LPOVERLAPPED lpOverlapped OPTIONAL)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
NTSTATUS Status;
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if (lpOverlapped == NULL)
|
if (lpBytesRead != NULL)
|
||||||
{
|
{
|
||||||
Status = NtFsControlFile(hNamedPipe,
|
*lpBytesRead = 0;
|
||||||
NULL,
|
}
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
FSCTL_PIPE_TRANSCEIVE,
|
|
||||||
lpInBuffer,
|
|
||||||
nInBufferSize,
|
|
||||||
lpOutBuffer,
|
|
||||||
nOutBufferSize);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
NtWaitForSingleObject(hNamedPipe,
|
|
||||||
0,
|
|
||||||
FALSE);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
*lpBytesRead = IoStatusBlock.Information;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lpOverlapped->Internal = STATUS_PENDING;
|
|
||||||
|
|
||||||
Status = NtFsControlFile(hNamedPipe,
|
if (lpOverlapped != NULL)
|
||||||
lpOverlapped->hEvent,
|
{
|
||||||
NULL,
|
PVOID ApcContext;
|
||||||
NULL,
|
|
||||||
(PIO_STATUS_BLOCK)lpOverlapped,
|
|
||||||
FSCTL_PIPE_TRANSCEIVE,
|
|
||||||
lpInBuffer,
|
|
||||||
nInBufferSize,
|
|
||||||
lpOutBuffer,
|
|
||||||
nOutBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
|
||||||
{
|
lpOverlapped->Internal = STATUS_PENDING;
|
||||||
SetLastErrorByStatus(Status);
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(TRUE);
|
Status = NtFsControlFile(hNamedPipe,
|
||||||
|
lpOverlapped->hEvent,
|
||||||
|
NULL,
|
||||||
|
ApcContext,
|
||||||
|
(PIO_STATUS_BLOCK)lpOverlapped,
|
||||||
|
FSCTL_PIPE_TRANSCEIVE,
|
||||||
|
lpInBuffer,
|
||||||
|
nInBufferSize,
|
||||||
|
lpOutBuffer,
|
||||||
|
nOutBufferSize);
|
||||||
|
|
||||||
|
/* return FALSE in case of failure and pending operations! */
|
||||||
|
if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpBytesRead != NULL)
|
||||||
|
{
|
||||||
|
*lpBytesRead = lpOverlapped->InternalHigh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK Iosb;
|
||||||
|
|
||||||
|
Status = NtFsControlFile(hNamedPipe,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&Iosb,
|
||||||
|
FSCTL_PIPE_TRANSCEIVE,
|
||||||
|
lpInBuffer,
|
||||||
|
nInBufferSize,
|
||||||
|
lpOutBuffer,
|
||||||
|
nOutBufferSize);
|
||||||
|
|
||||||
|
/* wait in case operation is pending */
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
Status = NtWaitForSingleObject(hNamedPipe,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = Iosb.Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
|
||||||
|
check that case either and crashes (only after the operation
|
||||||
|
completed) */
|
||||||
|
*lpBytesRead = Iosb.Information;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue