{
PIO_STACK_LOCATION IoStack;
NODE_TYPE_CODE Type;
- ULONG InputLength;
+ ULONG OutputLength;
ULONG NamedPipeEnd;
PNP_CCB Ccb;
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
- InputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
+ OutputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (!Type)
return STATUS_PIPE_DISCONNECTED;
}
- if ((Type != NPFS_NTC_CCB) && (InputLength < sizeof(*PeekBuffer)))
+ if ((Type != NPFS_NTC_CCB) &&
+ (OutputLength < FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data)))
{
return STATUS_INVALID_PARAMETER;
}
PeekBuffer->NumberOfMessages = 0;
PeekBuffer->MessageLength = 0;
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
- BytesPeeked = sizeof(*PeekBuffer);
+ BytesPeeked = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data);
if (DataQueue->QueueState == WriteEntries)
{
PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
}
- if (InputLength == sizeof(*PeekBuffer))
+
+ if (OutputLength == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data))
{
Status = PeekBuffer->ReadDataAvailable ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
}
TRUE,
FALSE,
PeekBuffer->Data,
- InputLength - sizeof(*PeekBuffer),
+ OutputLength - FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data),
Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE,
Ccb,
List);
Status = IoStatus.Status;
- BytesPeeked = IoStatus.Information + sizeof(*PeekBuffer);
+ BytesPeeked += IoStatus.Information;
}
}
else
NODE_TYPE_CODE NodeTypeCode;
PLIST_ENTRY NextEntry;
PNP_FCB Fcb;
+ PWCHAR OriginalBuffer;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
- InLength = IoStack->Parameters.DeviceIoControl.InputBufferLength;
+ InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
SourceString.Buffer = NULL;
- if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
+ if (NpDecodeFileObject(IoStack->FileObject,
+ NULL,
+ &Ccb,
+ &NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
{
Status = STATUS_ILLEGAL_FUNCTION;
goto Quickie;
}
NameLength = Buffer->NameLength;
- if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength))
+ if ((NameLength > (0xFFFF - sizeof(UNICODE_NULL))) ||
+ ((NameLength + FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name)) > InLength))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
- SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, NPFS_WRITE_BLOCK_TAG);
+ SourceString.Buffer = ExAllocatePoolWithTag(PagedPool,
+ SourceString.Length,
+ NPFS_WRITE_BLOCK_TAG);
if (!SourceString.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
RtlCopyMemory(&SourceString.Buffer[1], Buffer->Name, Buffer->NameLength);
Status = STATUS_SUCCESS;
+ OriginalBuffer = SourceString.Buffer;
//Status = NpTranslateAlias(&SourceString);
if (!NT_SUCCESS(Status)) goto Quickie;
if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
}
- if (NextEntry == &Fcb->CcbList)
+ if (NextEntry != &Fcb->CcbList)
{
Status = STATUS_SUCCESS;
}
Status = NpAddWaiter(&NpVcb->WaitQueue,
Fcb->Timeout,
Irp,
- &SourceString);
+ OriginalBuffer == SourceString.Buffer ?
+ NULL : &SourceString);
}
Quickie:
if (WaitEntry)
{
- ObfDereferenceObject(WaitEntry->FileObject);
+ ObDereferenceObject(WaitEntry->FileObject);
ExFreePool(WaitEntry);
}
PNP_WAIT_QUEUE_ENTRY WaitEntry = Context;
OldIrql = KfAcquireSpinLock(&WaitEntry->WaitQueue->WaitLock);
+
Irp = WaitEntry->Irp;
if (Irp)
{
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
if (!IoSetCancelRoutine(Irp, NULL))
{
Irp->Tail.Overlay.DriverContext[1] = NULL;
Irp = NULL;
}
}
+
KfReleaseSpinLock(&WaitEntry->WaitQueue->WaitLock, OldIrql);
+
if (Irp)
{
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
}
- ObfDereferenceObject(WaitEntry->FileObject);
+
+ ObDereferenceObject(WaitEntry->FileObject);
ExFreePool(WaitEntry);
}
NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN PUNICODE_STRING PipeName,
IN NTSTATUS Status,
- IN PLIST_ENTRY ListEntry)
+ IN PLIST_ENTRY List)
{
UNICODE_STRING DestinationString;
KIRQL OldIrql;
PWCHAR Buffer;
+ PLIST_ENTRY NextEntry;
+ PNP_WAIT_QUEUE_ENTRY WaitEntry, Linkage;
+ PIRP WaitIrp;
+ PFILE_PIPE_WAIT_FOR_BUFFER WaitBuffer;
+ ULONG i, NameLength;
- Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length, NPFS_WAIT_BLOCK_TAG);
+ Linkage = NULL;
+
+ Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ PipeName->Length,
+ NPFS_WAIT_BLOCK_TAG);
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length);
OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
- ASSERT(IsListEmpty(&WaitQueue->WaitList) == TRUE);
+ for (NextEntry = WaitQueue->WaitList.Flink;
+ NextEntry != &WaitQueue->WaitList;
+ NextEntry = NextEntry->Flink)
+ {
+ WaitIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
+ WaitEntry = WaitIrp->Tail.Overlay.DriverContext[1];
+
+ if (WaitEntry->AliasName.Length)
+ {
+ ASSERT(FALSE);
+ if (DestinationString.Length == WaitEntry->AliasName.Length)
+ {
+ if (RtlCompareMemory(WaitEntry->AliasName.Buffer,
+ DestinationString.Buffer,
+ DestinationString.Length) ==
+ DestinationString.Length)
+ {
+CancelWait:
+ RemoveEntryList(&WaitIrp->Tail.Overlay.ListEntry);
+ if (KeCancelTimer(&WaitEntry->Timer))
+ {
+ WaitEntry->WaitQueue = (PNP_WAIT_QUEUE)Linkage;
+ Linkage = WaitEntry;
+ }
+ else
+ {
+ WaitEntry->Irp = NULL;
+ WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
+ }
+
+ if (IoSetCancelRoutine(WaitIrp, NULL))
+ {
+ WaitIrp->IoStatus.Information = 0;
+ WaitIrp->IoStatus.Status = Status;
+ InsertTailList(List, &WaitIrp->Tail.Overlay.ListEntry);
+ }
+ else
+ {
+ WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ WaitBuffer = WaitIrp->AssociatedIrp.SystemBuffer;
+
+ if (WaitBuffer->NameLength + sizeof(WCHAR) == DestinationString.Length)
+ {
+ NameLength = WaitBuffer->NameLength / sizeof(WCHAR);
+ for (i = 0; i < NameLength; i++)
+ {
+ if (WaitBuffer->Name[i] != DestinationString.Buffer[i + 1]) break;
+ }
+
+ if (i >= NameLength) goto CancelWait;
+ }
+ }
+ }
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
+
ExFreePool(DestinationString.Buffer);
+
+ while (Linkage)
+ {
+ WaitEntry = Linkage;
+ Linkage = (PNP_WAIT_QUEUE_ENTRY)Linkage->WaitQueue;
+ ObDereferenceObject(WaitEntry->FileObject);
+ ExFreePool(WaitEntry);
+ }
+
return STATUS_SUCCESS;
}
NTAPI
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN LARGE_INTEGER WaitTime,
- IN PIRP Irp,
- IN PUNICODE_STRING Name)
+ IN PIRP Irp,
+ IN PUNICODE_STRING AliasName)
{
PIO_STACK_LOCATION IoStack;
KIRQL OldIrql;
IoStack = IoGetCurrentIrpStackLocation(Irp);
- WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), NPFS_WRITE_BLOCK_TAG);
- if (WaitEntry)
+ WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool,
+ sizeof(*WaitEntry),
+ NPFS_WRITE_BLOCK_TAG);
+ if (!WaitEntry)
{
- KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
- KeInitializeTimer(&WaitEntry->Timer);
-
- if (Name)
- {
- WaitEntry->String = *Name;
- }
- else
- {
- WaitEntry->String.Length = 0;
- WaitEntry->String.Buffer = 0;
- }
-
- WaitEntry->WaitQueue = WaitQueue;
- WaitEntry->Irp = Irp;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
- if (WaitBuffer->TimeoutSpecified)
- {
- DueTime = WaitBuffer->Timeout;
- }
- else
- {
- DueTime = WaitTime;
- }
+ KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
+ KeInitializeTimer(&WaitEntry->Timer);
- for (i = 0; i < WaitBuffer->NameLength / sizeof(WCHAR); i++)
- {
- WaitBuffer->Name[i] = RtlUpcaseUnicodeChar(WaitBuffer->Name[i]);
- }
+ if (AliasName)
+ {
+ WaitEntry->AliasName = *AliasName;
+ }
+ else
+ {
+ WaitEntry->AliasName.Length = 0;
+ WaitEntry->AliasName.Buffer = NULL;
+ }
- Irp->Tail.Overlay.DriverContext[0] = WaitQueue;
- Irp->Tail.Overlay.DriverContext[1] = WaitEntry;
- OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
+ WaitEntry->WaitQueue = WaitQueue;
+ WaitEntry->Irp = Irp;
- IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
+ WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+ if (WaitBuffer->TimeoutSpecified)
+ {
+ DueTime = WaitBuffer->Timeout;
+ }
+ else
+ {
+ DueTime = WaitTime;
+ }
- if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
- {
- Status = STATUS_CANCELLED;
- }
- else
- {
- InsertTailList(&WaitQueue->WaitList, &Irp->Tail.Overlay.ListEntry);
+ for (i = 0; i < WaitBuffer->NameLength / sizeof(WCHAR); i++)
+ {
+ WaitBuffer->Name[i] = RtlUpcaseUnicodeChar(WaitBuffer->Name[i]);
+ }
- IoMarkIrpPending(Irp);
- Status = STATUS_PENDING;
+ Irp->Tail.Overlay.DriverContext[0] = WaitQueue;
+ Irp->Tail.Overlay.DriverContext[1] = WaitEntry;
- WaitEntry->FileObject = IoStack->FileObject;
- ObfReferenceObject(WaitEntry->FileObject);
+ OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
- KeSetTimer(&WaitEntry->Timer, DueTime, &WaitEntry->Dpc);
- WaitEntry = NULL;
+ IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
- }
- KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
- if (WaitEntry) ExFreePool(WaitEntry);
+ if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
+ {
+ Status = STATUS_CANCELLED;
}
else
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ InsertTailList(&WaitQueue->WaitList, &Irp->Tail.Overlay.ListEntry);
+
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+
+ WaitEntry->FileObject = IoStack->FileObject;
+ ObReferenceObject(WaitEntry->FileObject);
+
+ KeSetTimer(&WaitEntry->Timer, DueTime, &WaitEntry->Dpc);
+ WaitEntry = NULL;
+
}
+
+ KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
+ if (WaitEntry) ExFreePool(WaitEntry);
+
return Status;
}