From 2300542dbc5904dd06f6b71ffa47935841cb9883 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 9 Nov 2005 04:32:44 +0000 Subject: [PATCH] - Fix PeekNamedPipe. Now only 14 winetests fail for pipetest. - Cleanup DisconnectNamedPipe and fix a small bug in it. svn path=/trunk/; revision=19088 --- reactos/lib/kernel32/file/npipe.c | 176 +++++++++++++++--------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/reactos/lib/kernel32/file/npipe.c b/reactos/lib/kernel32/file/npipe.c index 70480021481..1ba72cfa5c8 100644 --- a/reactos/lib/kernel32/file/npipe.c +++ b/reactos/lib/kernel32/file/npipe.c @@ -760,43 +760,42 @@ CallNamedPipeW(LPCWSTR lpNamedPipeName, /* * @implemented */ -BOOL STDCALL +BOOL +WINAPI DisconnectNamedPipe(HANDLE hNamedPipe) { - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; - Status = NtFsControlFile(hNamedPipe, - NULL, - NULL, - NULL, - &Iosb, - FSCTL_PIPE_DISCONNECT, - NULL, - 0, - NULL, - 0); - if (Status == STATUS_PENDING) + /* Send the FSCTL to the driver */ + Status = NtFsControlFile(hNamedPipe, + NULL, + NULL, + NULL, + &Iosb, + FSCTL_PIPE_DISCONNECT, + NULL, + 0, + NULL, + 0); + if (Status == STATUS_PENDING) { - Status = NtWaitForSingleObject(hNamedPipe, - FALSE, - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return(FALSE); - } + /* Wait on NPFS to finish and get updated status */ + Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL); + if (NT_SUCCESS(Status)) Status = Iosb.Status; } - if (!NT_SUCCESS(Status)) + /* Check for error */ + if (!NT_SUCCESS(Status)) { - SetLastErrorByStatus(Status); - return(FALSE); - } - return(TRUE); + /* Fail */ + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; } - /* * @unimplemented */ @@ -989,91 +988,92 @@ GetNamedPipeInfo(HANDLE hNamedPipe, return(TRUE); } - /* * @implemented */ -BOOL STDCALL +BOOL +WINAPI PeekNamedPipe(HANDLE hNamedPipe, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesRead, - LPDWORD lpTotalBytesAvail, - LPDWORD lpBytesLeftThisMessage) + LPVOID lpBuffer, + DWORD nBufferSize, + LPDWORD lpBytesRead, + LPDWORD lpTotalBytesAvail, + LPDWORD lpBytesLeftThisMessage) { - PFILE_PIPE_PEEK_BUFFER Buffer; - IO_STATUS_BLOCK Iosb; - ULONG BufferSize; - NTSTATUS Status; + PFILE_PIPE_PEEK_BUFFER Buffer; + IO_STATUS_BLOCK Iosb; + ULONG BufferSize; + NTSTATUS Status; - BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER); - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - BufferSize); - - Status = NtFsControlFile(hNamedPipe, - NULL, - NULL, - NULL, - &Iosb, - FSCTL_PIPE_PEEK, - NULL, - 0, - Buffer, - BufferSize); - if (Status == STATUS_PENDING) - { - Status = NtWaitForSingleObject(hNamedPipe, - FALSE, - NULL); - if (NT_SUCCESS(Status)) - Status = Iosb.Status; - } + /* Calculate the buffer space that we'll need and allocate it */ + BufferSize = nBufferSize + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]); + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); - if (Status == STATUS_BUFFER_OVERFLOW) + /* Tell the driver to seek */ + Status = NtFsControlFile(hNamedPipe, + NULL, + NULL, + NULL, + &Iosb, + FSCTL_PIPE_PEEK, + NULL, + 0, + Buffer, + BufferSize); + if (Status == STATUS_PENDING) { - Status = STATUS_SUCCESS; + /* Wait for npfs to be done, and update the status */ + Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL); + if (NT_SUCCESS(Status)) Status = Iosb.Status; } - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), - 0, - Buffer); - SetLastErrorByStatus(Status); - return(FALSE); - } + /* Overflow is success for us */ + if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_SUCCESS; - if (lpTotalBytesAvail != NULL) + /* If we failed */ + if (!NT_SUCCESS(Status)) { - *lpTotalBytesAvail = Buffer->ReadDataAvailable; + /* Free the buffer and return failure */ + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + SetLastErrorByStatus(Status); + return FALSE; } - if (lpBytesRead != NULL) + /* Check if caller requested bytes available */ + if (lpTotalBytesAvail) *lpTotalBytesAvail = Buffer->ReadDataAvailable; + + /* Check if caller requested bytes read */ + if (lpBytesRead) { - *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER); + /* Calculate the bytes returned, minus our structure overhead */ + *lpBytesRead = (ULONG)(Iosb.Information - + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])); } - if (lpBytesLeftThisMessage != NULL) + /* Check if caller requested bytes left */ + if (lpBytesLeftThisMessage) { - *lpBytesLeftThisMessage = Buffer->MessageLength - - (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)); + /* Calculate total minus what we returned and our structure overhead */ + *lpBytesLeftThisMessage = Buffer->MessageLength - + (ULONG)(Iosb.Information - + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])); } - if (lpBuffer != NULL) + /* Check if the caller wanted to see the actual data */ + if (lpBuffer) { - memcpy(lpBuffer, Buffer->Data, - min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER))); + /* Give him what he wants */ + RtlCopyMemory(lpBuffer, + Buffer->Data, + Iosb.Information - + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])); } - RtlFreeHeap(RtlGetProcessHeap(), - 0, - Buffer); - - return(TRUE); + /* Free the buffer and return success */ + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + return TRUE; } - /* * @implemented */ -- 2.17.1