Author: akhaldi
Date: Sun Sep 1 10:16:29 2013
New Revision: 59934
URL:
http://svn.reactos.org/svn/reactos?rev=59934&view=rev
Log:
[NPFS/KERNEL32]
* Back out r59915 for a moment so we can use Patchbot.
Modified:
trunk/reactos/dll/win32/kernel32/client/file/npipe.c
trunk/reactos/drivers/filesystems/npfs/create.c
trunk/reactos/drivers/filesystems/npfs/fsctrl.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/npipe.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/npipe.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/npipe.c [iso-8859-1] Sun Sep 1 10:16:29
2013
@@ -13,6 +13,8 @@
#define NDEBUG
#include <debug.h>
DEBUG_CHANNEL(kernel32file);
+
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
/* GLOBALS ********************************************************************/
@@ -362,6 +364,17 @@
return r;
}
+
+/*
+ * When NPFS will work properly, use this code instead. It is compatible with
+ * Microsoft's NPFS.SYS. The main difference is that:
+ * - This code actually respects the timeout instead of ignoring it!
+ * - This code validates and creates the proper names for both UNC and local pipes
+ * - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or
+ * \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the
+ * FILE_PIPE_WAIT_FOR_BUFFER structure.
+ */
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
/*
* @implemented
*/
@@ -546,6 +559,96 @@
/* Success */
return TRUE;
}
+#else
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+WaitNamedPipeW(LPCWSTR lpNamedPipeName,
+ DWORD nTimeOut)
+{
+ UNICODE_STRING NamedPipeName;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
+ HANDLE FileHandle;
+ IO_STATUS_BLOCK Iosb;
+
+ if (RtlDosPathNameToNtPathName_U(lpNamedPipeName,
+ &NamedPipeName,
+ NULL,
+ NULL) == FALSE)
+ {
+ return FALSE;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NamedPipeName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&FileHandle,
+ FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ RtlFreeUnicodeString(&NamedPipeName);
+ return FALSE;
+ }
+
+ /* Check what timeout we got */
+ if (nTimeOut == NMPWAIT_WAIT_FOREVER)
+ {
+ /* Don't use a timeout */
+ WaitPipe.TimeoutSpecified = FALSE;
+ }
+ else
+ {
+ /* Check if default */
+ if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT)
+ {
+ /* Set it to 0 */
+ WaitPipe.Timeout.LowPart = 0;
+ WaitPipe.Timeout.HighPart = 0;
+ }
+ else
+ {
+ /* Convert to NT format */
+ WaitPipe.Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
+ }
+
+ /* In both cases, we do have a timeout */
+ WaitPipe.TimeoutSpecified = TRUE;
+ }
+
+ Status = NtFsControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ FSCTL_PIPE_WAIT,
+ &WaitPipe,
+ sizeof(WaitPipe),
+ NULL,
+ 0);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ RtlFreeUnicodeString(&NamedPipeName);
+ return FALSE;
+ }
+
+ RtlFreeUnicodeString(&NamedPipeName);
+ return TRUE;
+}
+#endif
+
/*
* @implemented
Modified: trunk/reactos/drivers/filesystems/npfs/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/c…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/create.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/create.c [iso-8859-1] Sun Sep 1 10:16:29 2013
@@ -12,6 +12,8 @@
#define NDEBUG
#include <debug.h>
+
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
/* FUNCTIONS *****************************************************************/
@@ -249,6 +251,10 @@
PNPFS_CCB ServerCcb = NULL;
PNPFS_VCB Vcb;
NTSTATUS Status;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ ACCESS_MASK DesiredAccess;
+ BOOLEAN SpecialAccess;
+#endif
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
@@ -257,11 +263,22 @@
FileObject = IoStack->FileObject;
RelatedFileObject = FileObject->RelatedFileObject;
FileName = &FileObject->FileName;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+#endif
DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName);
Irp->IoStatus.Information = 0;
+
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ SpecialAccess = ((DesiredAccess & SPECIFIC_RIGHTS_ALL) == FILE_READ_ATTRIBUTES);
+ if (SpecialAccess)
+ {
+ DPRINT("NpfsCreate() open client end for special use!\n");
+ }
+#endif
DPRINT("FileName->Length: %hu RelatedFileObject: %p\n",
FileName->Length, RelatedFileObject);
@@ -336,7 +353,11 @@
ClientCcb->FileObject = FileObject;
ClientCcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
ClientCcb->PipeEnd = FILE_PIPE_CLIENT_END;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+#else
ClientCcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+#endif
InitializeListHead(&ClientCcb->ReadRequestListHead);
DPRINT("CCB: %p\n", ClientCcb);
@@ -377,62 +398,85 @@
/*
* Step 3. Search for listening server CCB.
*/
- /*
- * WARNING: Point of no return! Once we get the server CCB it's
- * possible that we completed a wait request and so we have to
- * complete even this request.
- */
-
- ServerCcb = NpfsFindListeningServerInstance(Fcb);
- if (ServerCcb == NULL)
- {
- PLIST_ENTRY CurrentEntry;
- PNPFS_CCB Ccb;
-
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ if (!SpecialAccess)
+ {
+#endif
/*
- * If no waiting server CCB was found then try to pick
- * one of the listing server CCB on the pipe.
+ * WARNING: Point of no return! Once we get the server CCB it's
+ * possible that we completed a wait request and so we have to
+ * complete even this request.
*/
- CurrentEntry = Fcb->ServerCcbListHead.Flink;
- while (CurrentEntry != &Fcb->ServerCcbListHead)
- {
- Ccb = CONTAINING_RECORD(CurrentEntry, NPFS_CCB, CcbListEntry);
- if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
+ ServerCcb = NpfsFindListeningServerInstance(Fcb);
+ if (ServerCcb == NULL)
+ {
+ PLIST_ENTRY CurrentEntry;
+ PNPFS_CCB Ccb;
+
+ /*
+ * If no waiting server CCB was found then try to pick
+ * one of the listing server CCB on the pipe.
+ */
+
+ CurrentEntry = Fcb->ServerCcbListHead.Flink;
+ while (CurrentEntry != &Fcb->ServerCcbListHead)
{
- ServerCcb = Ccb;
- break;
+ Ccb = CONTAINING_RECORD(CurrentEntry, NPFS_CCB, CcbListEntry);
+ if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ ServerCcb = Ccb;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
}
- CurrentEntry = CurrentEntry->Flink;
- }
-
- /*
- * No one is listening to me?! I'm so lonely... :(
- */
-
- if (ServerCcb == NULL)
- {
- /* Not found, bail out with error for FILE_OPEN requests. */
- DPRINT("No listening server CCB found!\n");
- if (ClientCcb->Data)
+
+ /*
+ * No one is listening to me?! I'm so lonely... :(
+ */
+
+ if (ServerCcb == NULL)
{
- ExFreePoolWithTag(ClientCcb->Data, TAG_NPFS_CCB_DATA);
+ /* Not found, bail out with error for FILE_OPEN requests. */
+ DPRINT("No listening server CCB found!\n");
+ if (ClientCcb->Data)
+ {
+ ExFreePoolWithTag(ClientCcb->Data, TAG_NPFS_CCB_DATA);
+ }
+
+ NpfsDereferenceCcb(ClientCcb);
+ KeUnlockMutex(&Fcb->CcbListLock);
+ NpfsDereferenceFcb(Fcb);
+ Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
-
- NpfsDereferenceCcb(ClientCcb);
- KeUnlockMutex(&Fcb->CcbListLock);
- NpfsDereferenceFcb(Fcb);
- Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
- }
- else
- {
- /* Signal the server thread and remove it from the waiter list */
- /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
- NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
- }
+ }
+ else
+ {
+ /* Signal the server thread and remove it from the waiter list */
+ /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
+ NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
+ }
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ }
+ else if (IsListEmpty(&Fcb->ServerCcbListHead))
+ {
+ DPRINT("No server fcb found!\n");
+
+ if (ClientCcb->Data)
+ {
+ ExFreePoolWithTag(ClientCcb->Data, TAG_NPFS_CCB_DATA);
+ }
+
+ NpfsDereferenceCcb(ClientCcb);
+ KeUnlockMutex(&Fcb->CcbListLock);
+ NpfsDereferenceFcb(Fcb);
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+#endif
/*
* Step 4. Add the client CCB to a list and connect it if possible.
Modified: trunk/reactos/drivers/filesystems/npfs/fsctrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] Sun Sep 1 10:16:29 2013
@@ -14,6 +14,8 @@
#define NDEBUG
#include <debug.h>
+
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
/* FUNCTIONS *****************************************************************/
@@ -317,8 +319,108 @@
return Status;
}
+static NTSTATUS
+NpfsWaitPipe(PIRP Irp,
+ PNPFS_CCB Ccb)
+{
+ PLIST_ENTRY current_entry;
+ PNPFS_FCB Fcb;
+ PNPFS_CCB ServerCcb;
+ PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
+ PLARGE_INTEGER TimeOut;
+ NTSTATUS Status;
+ PEXTENDED_IO_STACK_LOCATION IoStack;
+ PFILE_OBJECT FileObject;
+ PNPFS_VCB Vcb;
+
+ IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
+ ASSERT(IoStack);
+ FileObject = IoStack->FileObject;
+ ASSERT(FileObject);
+
+ DPRINT("Waiting on Pipe %wZ\n", &FileObject->FileName);
+
+ WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+
+ ASSERT(Ccb->Fcb);
+ ASSERT(Ccb->Fcb->Vcb);
+
+ /* Get the VCB */
+ Vcb = Ccb->Fcb->Vcb;
+
+ /* Lock the pipe list */
+ KeLockMutex(&Vcb->PipeListLock);
+
+ /* File a pipe with the given name */
+ Fcb = NpfsFindPipe(Vcb,
+ &FileObject->FileName);
+
+ /* Unlock the pipe list */
+ KeUnlockMutex(&Vcb->PipeListLock);
+
+ /* Fail if not pipe was found */
+ if (Fcb == NULL)
+ {
+ DPRINT("No pipe found!\n");
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* search for listening server */
+ current_entry = Fcb->ServerCcbListHead.Flink;
+ while (current_entry != &Fcb->ServerCcbListHead)
+ {
+ ServerCcb = CONTAINING_RECORD(current_entry,
+ NPFS_CCB,
+ CcbListEntry);
+
+ if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ /* found a listening server CCB */
+ DPRINT("Listening server CCB found -- connecting\n");
+ NpfsDereferenceFcb(Fcb);
+ return STATUS_SUCCESS;
+ }
+
+ current_entry = current_entry->Flink;
+ }
+
+ /* No listening server fcb found, so wait for one */
+
+ /* If a timeout specified */
+ if (WaitPipe->TimeoutSpecified)
+ {
+ /* NMPWAIT_USE_DEFAULT_WAIT = 0 */
+ if (WaitPipe->Timeout.QuadPart == 0)
+ {
+ TimeOut = &Fcb->TimeOut;
+ }
+ else
+ {
+ TimeOut = &WaitPipe->Timeout;
+ }
+ }
+ else
+ {
+ /* Wait forever */
+ TimeOut = NULL;
+ }
+ NpfsDereferenceFcb(Fcb);
+
+ Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
+ UserRequest,
+ Irp->RequestorMode,
+ (Ccb->FileObject->Flags & FO_ALERTABLE_IO)
!= 0,
+ TimeOut);
+ if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status ==
STATUS_ALERTED))
+ Status = STATUS_CANCELLED;
+
+ DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
+
+ return Status;
+}
+
NTSTATUS
-NpfsWaitPipe(PIRP Irp,
+NpfsWaitPipe2(PIRP Irp,
PNPFS_CCB Ccb)
{
PLIST_ENTRY current_entry;
@@ -327,12 +429,16 @@
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
LARGE_INTEGER TimeOut;
NTSTATUS Status;
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
PNPFS_VCB Vcb;
UNICODE_STRING PipeName;
+#endif
+
DPRINT("NpfsWaitPipe\n");
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
/* Fail, if the CCB does not represent the root directory */
if (Ccb->Type != CCB_DIRECTORY)
return STATUS_ILLEGAL_FUNCTION;
@@ -382,6 +488,15 @@
}
DPRINT("Fcb %p\n", Fcb);
+#else
+ Fcb = Ccb->Fcb;
+
+ if (Ccb->PipeState != 0)
+ {
+ DPRINT("Pipe is not in passive (waiting) state!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+#endif
/* search for listening server */
current_entry = Fcb->ServerCcbListHead.Flink;
@@ -395,7 +510,9 @@
{
/* found a listening server CCB */
DPRINT("Listening server CCB found -- connecting\n");
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
NpfsDereferenceFcb(Fcb);
+#endif
return STATUS_SUCCESS;
}
@@ -409,8 +526,9 @@
TimeOut = WaitPipe->Timeout;
else
TimeOut = Fcb->TimeOut;
-
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
NpfsDereferenceFcb(Fcb);
+#endif
/* Wait for one */
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,