- Fix PeekNamedPipe. Now only 14 winetests fail for pipetest.

- Cleanup DisconnectNamedPipe and fix a small bug in it.

svn path=/trunk/; revision=19088
This commit is contained in:
Alex Ionescu 2005-11-09 04:32:44 +00:00
parent 85f0828a18
commit 2300542dbc

View file

@ -760,43 +760,42 @@ CallNamedPipeW(LPCWSTR lpNamedPipeName,
/* /*
* @implemented * @implemented
*/ */
BOOL STDCALL BOOL
WINAPI
DisconnectNamedPipe(HANDLE hNamedPipe) DisconnectNamedPipe(HANDLE hNamedPipe)
{ {
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
Status = NtFsControlFile(hNamedPipe, /* Send the FSCTL to the driver */
NULL, Status = NtFsControlFile(hNamedPipe,
NULL, NULL,
NULL, NULL,
&Iosb, NULL,
FSCTL_PIPE_DISCONNECT, &Iosb,
NULL, FSCTL_PIPE_DISCONNECT,
0, NULL,
NULL, 0,
0); NULL,
if (Status == STATUS_PENDING) 0);
if (Status == STATUS_PENDING)
{ {
Status = NtWaitForSingleObject(hNamedPipe, /* Wait on NPFS to finish and get updated status */
FALSE, Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
NULL); if (NT_SUCCESS(Status)) Status = Iosb.Status;
if (!NT_SUCCESS(Status)) }
{
SetLastErrorByStatus(Status); /* Check for error */
return(FALSE); if (!NT_SUCCESS(Status))
{
/* Fail */
SetLastErrorByStatus(Status);
return FALSE;
} }
}
if (!NT_SUCCESS(Status)) return TRUE;
{
SetLastErrorByStatus(Status);
return(FALSE);
}
return(TRUE);
} }
/* /*
* @unimplemented * @unimplemented
*/ */
@ -989,91 +988,92 @@ GetNamedPipeInfo(HANDLE hNamedPipe,
return(TRUE); return(TRUE);
} }
/* /*
* @implemented * @implemented
*/ */
BOOL STDCALL BOOL
WINAPI
PeekNamedPipe(HANDLE hNamedPipe, PeekNamedPipe(HANDLE hNamedPipe,
LPVOID lpBuffer, LPVOID lpBuffer,
DWORD nBufferSize, DWORD nBufferSize,
LPDWORD lpBytesRead, LPDWORD lpBytesRead,
LPDWORD lpTotalBytesAvail, LPDWORD lpTotalBytesAvail,
LPDWORD lpBytesLeftThisMessage) LPDWORD lpBytesLeftThisMessage)
{ {
PFILE_PIPE_PEEK_BUFFER Buffer; PFILE_PIPE_PEEK_BUFFER Buffer;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
ULONG BufferSize; ULONG BufferSize;
NTSTATUS Status; NTSTATUS Status;
BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER); /* Calculate the buffer space that we'll need and allocate it */
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), BufferSize = nBufferSize + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
0, Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
BufferSize);
Status = NtFsControlFile(hNamedPipe, /* Tell the driver to seek */
NULL, Status = NtFsControlFile(hNamedPipe,
NULL, NULL,
NULL, NULL,
&Iosb, NULL,
FSCTL_PIPE_PEEK, &Iosb,
NULL, FSCTL_PIPE_PEEK,
0, NULL,
Buffer, 0,
BufferSize); Buffer,
if (Status == STATUS_PENDING) BufferSize);
if (Status == STATUS_PENDING)
{ {
Status = NtWaitForSingleObject(hNamedPipe, /* Wait for npfs to be done, and update the status */
FALSE, Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
NULL); if (NT_SUCCESS(Status)) Status = Iosb.Status;
if (NT_SUCCESS(Status))
Status = Iosb.Status;
} }
if (Status == STATUS_BUFFER_OVERFLOW) /* Overflow is success for us */
if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_SUCCESS;
/* If we failed */
if (!NT_SUCCESS(Status))
{ {
Status = STATUS_SUCCESS; /* Free the buffer and return failure */
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
SetLastErrorByStatus(Status);
return FALSE;
} }
if (!NT_SUCCESS(Status)) /* Check if caller requested bytes available */
if (lpTotalBytesAvail) *lpTotalBytesAvail = Buffer->ReadDataAvailable;
/* Check if caller requested bytes read */
if (lpBytesRead)
{ {
RtlFreeHeap(RtlGetProcessHeap(), /* Calculate the bytes returned, minus our structure overhead */
0, *lpBytesRead = (ULONG)(Iosb.Information -
Buffer); FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
SetLastErrorByStatus(Status);
return(FALSE);
} }
if (lpTotalBytesAvail != NULL) /* Check if caller requested bytes left */
if (lpBytesLeftThisMessage)
{ {
*lpTotalBytesAvail = Buffer->ReadDataAvailable; /* 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 (lpBytesRead != NULL) /* Check if the caller wanted to see the actual data */
if (lpBuffer)
{ {
*lpBytesRead = 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]));
} }
if (lpBytesLeftThisMessage != NULL) /* Free the buffer and return success */
{ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
*lpBytesLeftThisMessage = Buffer->MessageLength - return TRUE;
(Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
}
if (lpBuffer != NULL)
{
memcpy(lpBuffer, Buffer->Data,
min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
}
RtlFreeHeap(RtlGetProcessHeap(),
0,
Buffer);
return(TRUE);
} }
/* /*
* @implemented * @implemented
*/ */