#define NDEBUG
#include <debug.h>
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+
/* FUNCTIONS *****************************************************************/
static DRIVER_CANCEL NpfsListeningCancelRoutine;
DPRINT("NpfsConnectPipe()\n");
+ /* Fail, if the CCB is not a pipe CCB */
+ if (Ccb->Type != CCB_PIPE)
+ {
+ DPRINT("Not a pipe\n");
+ return STATUS_ILLEGAL_FUNCTION;
+ }
+
+ /* Fail, if the CCB is not a server end CCB */
+ if (Ccb->PipeEnd != FILE_PIPE_SERVER_END)
+ {
+ DPRINT("Not the server end\n");
+ return STATUS_ILLEGAL_FUNCTION;
+ }
+
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeResetEvent(&Ccb->ConnectEvent);
DPRINT("NpfsDisconnectPipe()\n");
+ /* Fail, if the CCB is not a pipe CCB */
+ if (Ccb->Type != CCB_PIPE)
+ {
+ DPRINT("Not a pipe\n");
+ return STATUS_ILLEGAL_FUNCTION;
+ }
+
+ /* Fail, if the CCB is not a server end CCB */
+ if (Ccb->PipeEnd != FILE_PIPE_SERVER_END)
+ {
+ DPRINT("Not the server end\n");
+ return STATUS_ILLEGAL_FUNCTION;
+ }
+
Fcb = Ccb->Fcb;
KeLockMutex(&Fcb->CcbListLock);
return Status;
}
-
static NTSTATUS
NpfsWaitPipe(PIRP Irp,
PNPFS_CCB Ccb)
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", Fcb);
+ 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");
+
+ 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;
+ }
+
+ Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
+ UserRequest,
+ KernelMode,
+ TRUE,
+ TimeOut);
+
+ DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
+
+ return Status;
+}
+
+NTSTATUS
+NpfsWaitPipe2(PIRP Irp,
+ PNPFS_CCB Ccb)
+{
+ PLIST_ENTRY current_entry;
+ PNPFS_FCB Fcb;
+ PNPFS_CCB ServerCcb;
+ 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;
+
+ /* Calculate the pipe name length and allocate the buffer */
+ PipeName.Length = WaitPipe->NameLength + sizeof(WCHAR);
+ PipeName.MaximumLength = PipeName.Length + sizeof(WCHAR);
+ PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ PipeName.MaximumLength,
+ TAG_NPFS_NAMEBLOCK);
+ if (PipeName.Buffer == NULL)
+ {
+ DPRINT1("Could not allocate memory for the pipe name!\n");
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
+ PipeName.Buffer[0] = L'\\';
+ RtlCopyMemory(&PipeName.Buffer[1],
+ &WaitPipe->Name[0],
+ WaitPipe->NameLength);
+ PipeName.Buffer[PipeName.Length / sizeof(WCHAR)] = 0;
+
+ DPRINT("Waiting for Pipe %wZ\n", &PipeName);
+
+ /* Get the VCB */
+ Vcb = Ccb->Fcb->Vcb;
+
+ /* Lock the pipe list */
+ KeLockMutex(&Vcb->PipeListLock);
+
+ /* File a pipe with the given name */
+ Fcb = NpfsFindPipe(Vcb,
+ &PipeName);
+
+ /* Unlock the pipe list */
+ KeUnlockMutex(&Vcb->PipeListLock);
+
+ /* Release the pipe name buffer */
+ ExFreePoolWithTag(PipeName.Buffer, TAG_NPFS_NAMEBLOCK);
+
+ /* Fail if not pipe was found */
+ if (Fcb == NULL)
+ {
+ DPRINT("No pipe found!\n", Fcb);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ 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;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;