#define NDEBUG
#include <debug.h>
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+
/* FUNCTIONS *****************************************************************/
static DRIVER_CANCEL NpfsListeningCancelRoutine;
KeLockMutex(&Ccb->Fcb->CcbListLock);
- IoMarkIrpPending(Irp);
- InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
-
IoAcquireCancelSpinLock(&oldIrql);
if (!Irp->Cancel)
{
+ Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
+ IoMarkIrpPending(Irp);
+ InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
(void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
IoReleaseCancelSpinLock(oldIrql);
KeUnlockMutex(&Ccb->Fcb->CcbListLock);
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
NTSTATUS Status;
+ KPROCESSOR_MODE WaitMode;
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);
IoStack = IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
Flags = FileObject->Flags;
+ WaitMode = Irp->RequestorMode;
/* search for a listening client fcb */
KeLockMutex(&Fcb->CcbListLock);
/* no listening client fcb found */
DPRINT("No listening client fcb found -- waiting for client\n");
- Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
-
Status = NpfsAddListeningServerInstance(Irp, Ccb);
KeUnlockMutex(&Fcb->CcbListLock);
- if (Flags & FO_SYNCHRONOUS_IO)
+ if ((Status == STATUS_PENDING) && (Flags & FO_SYNCHRONOUS_IO))
{
KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
- Irp->RequestorMode,
- FALSE,
+ WaitMode,
+ (Flags & FO_ALERTABLE_IO) != 0,
NULL);
}
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);
{
RemoveEntryList(Entry);
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
- Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
+ Complete = (NULL != IoSetCancelRoutine(Irp, NULL));
break;
}
Entry = Entry->Flink;
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", 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");
+ 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
+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;
- UNICODE_STRING PipeName;
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 = ExAllocatePool(NonPagedPool, PipeName.MaximumLength);
+ PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ PipeName.MaximumLength,
+ TAG_NPFS_NAMEBLOCK);
if (PipeName.Buffer == NULL)
{
DPRINT1("Could not allocate memory for the pipe name!\n");
KeUnlockMutex(&Vcb->PipeListLock);
/* Release the pipe name buffer */
- ExFreePool(PipeName.Buffer);
+ ExFreePoolWithTag(PipeName.Buffer, TAG_NPFS_NAMEBLOCK);
/* Fail if not pipe was found */
if (Fcb == NULL)
}
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;
{
/* found a listening server CCB */
DPRINT("Listening server CCB found -- connecting\n");
-
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
+ NpfsDereferenceFcb(Fcb);
+#endif
return STATUS_SUCCESS;
}
TimeOut = WaitPipe->Timeout;
else
TimeOut = Fcb->TimeOut;
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
+ NpfsDereferenceFcb(Fcb);
+#endif
/* Wait for one */
Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
UserRequest,
- KernelMode,
- FALSE,
+ 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);
ULONG OutputBufferLength;
ULONG ReturnLength = 0;
PFILE_PIPE_PEEK_BUFFER Reply;
- PNPFS_FCB Fcb;
+ //PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
NTSTATUS Status;
ULONG MessageCount = 0;
DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
/* Validate parameters */
- if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
+ if (OutputBufferLength < FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))
{
DPRINT1("Buffer too small\n");
return STATUS_INVALID_PARAMETER;
}
Ccb = IoStack->FileObject->FsContext2;
- Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
- Fcb = Ccb->Fcb;
+ Reply = Irp->AssociatedIrp.SystemBuffer;
+ //Fcb = Ccb->Fcb;
Reply->NamedPipeState = Ccb->PipeState;
{
DPRINT("Byte Stream Mode\n");
Reply->MessageLength = Ccb->ReadDataAvailable;
- DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
+ DPRINT("Reply->MessageLength %lu\n", Reply->MessageLength);
MessageCount = 1;
- if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
+ if (OutputBufferLength >= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[Ccb->ReadDataAvailable]))
{
+ RtlCopyMemory(Reply->Data, BufferPtr, Ccb->ReadDataAvailable);
ReturnLength = Ccb->ReadDataAvailable;
- memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
}
}
else
{
DPRINT("Message Mode\n");
- ReadDataAvailable=Ccb->ReadDataAvailable;
+ ReadDataAvailable = Ccb->ReadDataAvailable;
if (ReadDataAvailable > 0)
{
- memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
+ RtlCopyMemory(&Reply->MessageLength,
+ BufferPtr,
+ sizeof(Reply->MessageLength));
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
{
- memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
+ RtlCopyMemory(&MessageLength, BufferPtr, sizeof(MessageLength));
ASSERT(MessageLength > 0);
- DPRINT("MessageLength = %lu\n",MessageLength);
+ DPRINT("MessageLength = %lu\n", MessageLength);
ReadDataAvailable -= MessageLength;
MessageCount++;
/* If its the first message, copy the Message if the size of buffer is large enough */
- if (MessageCount==1)
+ if (MessageCount == 1)
{
- if ((Reply->Data[0])
- && (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
+ if (OutputBufferLength >= FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[MessageLength]))
{
- memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
+ RtlCopyMemory(Reply->Data,
+ (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)),
+ MessageLength);
ReturnLength = MessageLength;
}
}
- BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
+ BufferPtr = (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength) + MessageLength);
DPRINT("BufferPtr = %x\n", BufferPtr);
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
}
Reply->NumberOfMessages = MessageCount;
- Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
+ Irp->IoStatus.Information = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[ReturnLength]);
Irp->IoStatus.Status = STATUS_SUCCESS;
Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- PNPFS_VCB Vcb;
+ //PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
+ //Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;