From 76c3fa745145a94205e532f518faf1f5ccfa7fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 4 Nov 2005 19:31:47 +0000 Subject: [PATCH] Revert 18883 and 18912, as they break named pipes (These changes were correct per se, but another problem surfaced: see http://www.reactos.org/archives/public/ros-dev/2005-November/005958.html) svn path=/trunk/; revision=19002 --- reactos/drivers/fs/np/create.c | 102 ++++++++++++++++++------------ reactos/lib/kernel32/file/npipe.c | 92 +++++++++++++++++---------- reactos/lib/kernel32/file/pipe.c | 9 +-- 3 files changed, 122 insertions(+), 81 deletions(-) diff --git a/reactos/drivers/fs/np/create.c b/reactos/drivers/fs/np/create.c index 34e44a9151b..773abf7150a 100644 --- a/reactos/drivers/fs/np/create.c +++ b/reactos/drivers/fs/np/create.c @@ -113,6 +113,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, PNPFS_FCB ClientFcb; PNPFS_FCB ServerFcb = NULL; PNPFS_DEVICE_EXTENSION DeviceExt; + BOOLEAN SpecialAccess; DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); @@ -124,6 +125,12 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, Irp->IoStatus.Information = 0; + SpecialAccess = ((IoStack->Parameters.CreatePipe.ShareAccess & 3) == 3); + if (SpecialAccess) + { + DPRINT("NpfsCreate() open client end for special use!\n"); + } + /* * Step 1. Find the pipe we're trying to open. */ @@ -165,7 +172,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, ClientFcb->Pipe = Pipe; ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END; ClientFcb->OtherSide = NULL; - ClientFcb->PipeState = FILE_PIPE_DISCONNECTED_STATE; + ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE; InitializeListHead(&ClientFcb->ReadRequestListHead); DPRINT("Fcb: %x\n", ClientFcb); @@ -204,56 +211,67 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, * Step 3. Search for listening server FCB. */ - /* - * WARNING: Point of no return! Once we get the server FCB it's - * possible that we completed a wait request and so we have to - * complete even this request. - */ - - ServerFcb = NpfsFindListeningServerInstance(Pipe); - if (ServerFcb == NULL) + if (!SpecialAccess) { - PLIST_ENTRY CurrentEntry; - PNPFS_FCB Fcb; - /* - * If no waiting server FCB was found then try to pick - * one of the listing server FCB on the pipe. - */ - - CurrentEntry = Pipe->ServerFcbListHead.Flink; - while (CurrentEntry != &Pipe->ServerFcbListHead) - { - Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, FcbListEntry); - if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE) - { - ServerFcb = Fcb; - break; - } - CurrentEntry = CurrentEntry->Flink; - } - - /* - * No one is listening to me?! I'm so lonely... :( + * WARNING: Point of no return! Once we get the server FCB it's + * possible that we completed a wait request and so we have to + * complete even this request. */ + ServerFcb = NpfsFindListeningServerInstance(Pipe); if (ServerFcb == NULL) { - /* Not found, bail out with error for FILE_OPEN requests. */ - DPRINT("No listening server fcb found!\n"); - if (ClientFcb->Data) - ExFreePool(ClientFcb->Data); - KeUnlockMutex(&Pipe->FcbListLock); - Irp->IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_PIPE_NOT_AVAILABLE; + PLIST_ENTRY CurrentEntry; + PNPFS_FCB Fcb; + + /* + * If no waiting server FCB was found then try to pick + * one of the listing server FCB on the pipe. + */ + + CurrentEntry = Pipe->ServerFcbListHead.Flink; + while (CurrentEntry != &Pipe->ServerFcbListHead) + { + Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, FcbListEntry); + if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE) + { + ServerFcb = Fcb; + break; + } + CurrentEntry = CurrentEntry->Flink; + } + + /* + * No one is listening to me?! I'm so lonely... :( + */ + + if (ServerFcb == NULL) + { + /* Not found, bail out with error for FILE_OPEN requests. */ + DPRINT("No listening server fcb found!\n"); + if (ClientFcb->Data) + ExFreePool(ClientFcb->Data); + KeUnlockMutex(&Pipe->FcbListLock); + Irp->IoStatus.Status = STATUS_PIPE_BUSY; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_PIPE_BUSY; + } + } + else + { + /* Signal the server thread and remove it from the waiter list */ + /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */ + NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb); } } - else + else if (IsListEmpty(&Pipe->ServerFcbListHead)) { - /* Signal the server thread and remove it from the waiter list */ - /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */ - NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb); + DPRINT("No server fcb found!\n"); + KeUnlockMutex(&Pipe->FcbListLock); + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; } /* diff --git a/reactos/lib/kernel32/file/npipe.c b/reactos/lib/kernel32/file/npipe.c index d464992c8f5..fa8338e2cf6 100644 --- a/reactos/lib/kernel32/file/npipe.c +++ b/reactos/lib/kernel32/file/npipe.c @@ -15,12 +15,6 @@ #define NDEBUG #include "../include/debug.h" -/* FIXME - defined in ntifs.h */ -#if !defined(FILE_PIPE_BYTE_STREAM_TYPE) && !defined(FILE_PIPE_MESSAGE_TYPE) -#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000 -#define FILE_PIPE_MESSAGE_TYPE 0x00000001 -#endif - /* FUNCTIONS ****************************************************************/ /* @@ -78,6 +72,7 @@ CreateNamedPipeW(LPCWSTR lpName, HANDLE PipeHandle; ACCESS_MASK DesiredAccess; ULONG CreateOptions; + ULONG CreateDisposition; ULONG WriteModeMessage; ULONG ReadModeMessage; ULONG NonBlocking; @@ -85,12 +80,6 @@ CreateNamedPipeW(LPCWSTR lpName, ULONG ShareAccess, Attributes; LARGE_INTEGER DefaultTimeOut; PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; - - if (nMaxInstances == 0 || nMaxInstances > PIPE_UNLIMITED_INSTANCES) - { - SetLastError(ERROR_INVALID_PARAMETER); - return INVALID_HANDLE_VALUE; - } Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName, &NamedPipeName, @@ -119,40 +108,77 @@ CreateNamedPipeW(LPCWSTR lpName, NULL, SecurityDescriptor); - DesiredAccess = SYNCHRONIZE | (dwOpenMode & (WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY)); + DesiredAccess = 0; ShareAccess = 0; + CreateDisposition = FILE_OPEN_IF; CreateOptions = 0; - if (dwOpenMode & FILE_FLAG_WRITE_THROUGH) - CreateOptions |= FILE_WRITE_THROUGH; + { + CreateOptions = CreateOptions | FILE_WRITE_THROUGH; + } if (!(dwOpenMode & FILE_FLAG_OVERLAPPED)) - CreateOptions |= FILE_SYNCHRONOUS_IO_NONALERT; - - if (dwOpenMode & PIPE_ACCESS_INBOUND) { - ShareAccess |= FILE_SHARE_WRITE; - DesiredAccess |= GENERIC_READ; + CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_NONALERT; } - if (dwOpenMode & PIPE_ACCESS_OUTBOUND) + if (dwOpenMode & PIPE_ACCESS_DUPLEX) { - ShareAccess |= FILE_SHARE_READ; - DesiredAccess |= GENERIC_WRITE; + CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX; + DesiredAccess |= (FILE_GENERIC_READ | FILE_GENERIC_WRITE); + } + else if (dwOpenMode & PIPE_ACCESS_INBOUND) + { + CreateOptions = CreateOptions | FILE_PIPE_INBOUND; + DesiredAccess |= FILE_GENERIC_READ; + } + else if (dwOpenMode & PIPE_ACCESS_OUTBOUND) + { + CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND; + DesiredAccess |= FILE_GENERIC_WRITE; } - if (dwPipeMode & PIPE_TYPE_MESSAGE) - WriteModeMessage = FILE_PIPE_MESSAGE_TYPE; + if (dwPipeMode & PIPE_TYPE_BYTE) + { + WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE; + } + else if (dwPipeMode & PIPE_TYPE_MESSAGE) + { + WriteModeMessage = FILE_PIPE_MESSAGE_MODE; + } else - WriteModeMessage = FILE_PIPE_BYTE_STREAM_TYPE; + { + WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE; + } - if (dwPipeMode & PIPE_READMODE_MESSAGE) - ReadModeMessage = FILE_PIPE_MESSAGE_MODE; + if (dwPipeMode & PIPE_READMODE_BYTE) + { + ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE; + } + else if (dwPipeMode & PIPE_READMODE_MESSAGE) + { + ReadModeMessage = FILE_PIPE_MESSAGE_MODE; + } else - ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE; + { + ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE; + } - if (dwPipeMode & PIPE_NOWAIT) - NonBlocking = FILE_PIPE_COMPLETE_OPERATION; + if (dwPipeMode & PIPE_WAIT) + { + NonBlocking = FILE_PIPE_QUEUE_OPERATION; + } + else if (dwPipeMode & PIPE_NOWAIT) + { + NonBlocking = FILE_PIPE_COMPLETE_OPERATION; + } else - NonBlocking = FILE_PIPE_QUEUE_OPERATION; + { + NonBlocking = FILE_PIPE_QUEUE_OPERATION; + } + + if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES) + { + nMaxInstances = 0xFFFFFFFF; + } DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000LL; @@ -161,7 +187,7 @@ CreateNamedPipeW(LPCWSTR lpName, &ObjectAttributes, &Iosb, ShareAccess, - FILE_OPEN_IF, + CreateDisposition, CreateOptions, WriteModeMessage, ReadModeMessage, diff --git a/reactos/lib/kernel32/file/pipe.c b/reactos/lib/kernel32/file/pipe.c index efabbd28808..f5e65d505ac 100644 --- a/reactos/lib/kernel32/file/pipe.c +++ b/reactos/lib/kernel32/file/pipe.c @@ -59,9 +59,6 @@ BOOL STDCALL CreatePipe(PHANDLE hReadPipe, Attributes |= OBJ_INHERIT; } - /* use default buffer size if desired */ - if (nSize == 0) nSize = 0x1000; - InitializeObjectAttributes(&ObjectAttributes, &PipeName, Attributes, @@ -69,7 +66,7 @@ BOOL STDCALL CreatePipe(PHANDLE hReadPipe, SecurityDescriptor); Status = NtCreateNamedPipeFile(&ReadPipeHandle, - FILE_GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + FILE_GENERIC_READ, &ObjectAttributes, &StatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -89,10 +86,10 @@ BOOL STDCALL CreatePipe(PHANDLE hReadPipe, } Status = NtOpenFile(&WritePipeHandle, - FILE_GENERIC_WRITE | SYNCHRONIZE, + FILE_GENERIC_WRITE, &ObjectAttributes, &StatusBlock, - FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) {