mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
For our 60000th commit, I bring you a complete rewrite of the Named Pipe File System. It is not yet "active", but I consider this to now be largely code complete and worthy of the prize (and I didn't want to delay other commiters any further). Once the code is reviewed, fixed, tested, and commented, it will replace our old and aging NPFS. This driver is cross-compatible with Windows Server 2003. It is expected to fix winetest incompatiblities, speed up performance, and reduce bizare RPC/SCM issues. This commit is dedicated to my best friend Rachel, who has not only always been there for me, but was also the motivating factor behind my return to my passion -- ReactOS :)
[NPFS-NEW]: Implement QueryVolume, QuerySecurity, SetSecurity. Everything but Directory Query, Fast I/O, and a few rare FSCTLs is implemented now. The former two will come in an upcoming commit. [NPFS-NEW]: Major cleanup in the way some member variables were being addressed. Reference them as array members based on the correct FILE_PIPE defines from now on. Also fix a lot of formatting issues. Fix a bunch of bugs that were found. Use FILE_PIPE_SERVER_END and FILE_PIPE_CLIENT_END intead of a BOOLEAN. Use TRUE/FALSE/STATUS_SUCCESS/NULL/etc when needed intead of 0/1. The code formatting can/should still be improved, but this was a big help. svn path=/trunk/; revision=60000
This commit is contained in:
parent
3dfdce74d8
commit
5492bdcde2
22 changed files with 1149 additions and 516 deletions
|
@ -13,8 +13,10 @@ list(APPEND SOURCE
|
|||
read.c
|
||||
readsup.c
|
||||
secursup.c
|
||||
seinfo.c
|
||||
statesup.c
|
||||
strucsup.c
|
||||
volinfo.c
|
||||
waitsup.c
|
||||
write.c
|
||||
writesup.c)
|
||||
|
|
|
@ -10,7 +10,7 @@ NpCommonCleanup(IN PDEVICE_OBJECT DeviceObject,
|
|||
LIST_ENTRY List;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PLIST_ENTRY ThisEntry, NextEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
|
@ -21,16 +21,16 @@ NpCommonCleanup(IN PDEVICE_OBJECT DeviceObject,
|
|||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB )
|
||||
&NamedPipeEnd);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ASSERT(Ccb->Fcb->ServerOpenCount != 0);
|
||||
--Ccb->Fcb->ServerOpenCount;
|
||||
}
|
||||
|
||||
NpSetClosingPipeState(Ccb, Irp, ServerSide, &List);
|
||||
NpSetClosingPipeState(Ccb, Irp, NamedPipeEnd, &List);
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
@ -62,7 +62,7 @@ NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
|
|
|
@ -10,7 +10,7 @@ NpCommonClose(IN PDEVICE_OBJECT DeviceObject,
|
|||
LIST_ENTRY List;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PLIST_ENTRY ThisEntry, NextEntry;
|
||||
PAGED_CODE();
|
||||
|
||||
|
@ -21,7 +21,7 @@ NpCommonClose(IN PDEVICE_OBJECT DeviceObject,
|
|||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
&NamedPipeEnd);
|
||||
if (NodeTypeCode == NPFS_NTC_ROOT_DCB)
|
||||
{
|
||||
--Fcb->CurrentInstances;
|
||||
|
|
|
@ -400,15 +400,15 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
&AccessState->GenerateOnClose);
|
||||
|
||||
SeUnlockSubjectContext(SubjectSecurityContext);
|
||||
if ( !AccessGranted ) return IoStatus;
|
||||
if (!AccessGranted) return IoStatus;
|
||||
|
||||
if ( Fcb->CurrentInstances >= Fcb->MaximumInstances )
|
||||
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
|
||||
{
|
||||
IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
if ( Disposition == FILE_CREATE )
|
||||
if (Disposition == FILE_CREATE)
|
||||
{
|
||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
return IoStatus;
|
||||
|
@ -428,7 +428,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
CheckShareAccess = FILE_SHARE_WRITE;
|
||||
}
|
||||
|
||||
if ( CheckShareAccess != ShareAccess )
|
||||
if (CheckShareAccess != ShareAccess)
|
||||
{
|
||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
return IoStatus;
|
||||
|
@ -456,7 +456,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
}
|
||||
|
||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
||||
Ccb->ServerFileObject = FileObject;
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
||||
|
||||
IoStatus.Status = STATUS_SUCCESS;
|
||||
|
@ -518,7 +518,7 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
|||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( !Parameters->NamedPipeType && Parameters->ReadMode == 1 )
|
||||
if (!Parameters->NamedPipeType && Parameters->ReadMode == 1)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quickie;
|
||||
|
@ -580,11 +580,11 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
|||
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
|
||||
|
||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
||||
Ccb->ServerFileObject = FileObject;
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||
|
||||
NpCheckForNotify(Dcb, 1, List);
|
||||
|
||||
IoStatus->Status = 0;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = 2;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
|
@ -638,7 +638,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT1("FileName %wZ\n", &FileObject->FileName);
|
||||
DPRINT1("FileName->Length: %hu RelatedFileObject: %p\n", FileName.Length, RelatedFileObject);
|
||||
|
||||
if ( RelatedFileObject )
|
||||
if (RelatedFileObject)
|
||||
{
|
||||
Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1);
|
||||
if (!(Fcb) ||
|
||||
|
@ -659,7 +659,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( FileName.Length <= 2u || *FileName.Buffer != '\\' )
|
||||
if (FileName.Length <= 2u || *FileName.Buffer != '\\')
|
||||
{
|
||||
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
||||
goto Quickie;
|
||||
|
@ -667,9 +667,9 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
Fcb = NpFindPrefix(&FileName, 1u, &Prefix);
|
||||
}
|
||||
|
||||
if ( Prefix.Length )
|
||||
if (Prefix.Length)
|
||||
{
|
||||
if (Fcb->NodeType == NPFS_NTC_ROOT_DCB )
|
||||
if (Fcb->NodeType == NPFS_NTC_ROOT_DCB)
|
||||
{
|
||||
IoStatus.Status = NpCreateNewNamedPipe((PNP_DCB)Fcb,
|
||||
FileObject,
|
||||
|
@ -692,7 +692,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
goto Quickie;
|
||||
}
|
||||
}
|
||||
if (Fcb->NodeType != NPFS_NTC_FCB )
|
||||
if (Fcb->NodeType != NPFS_NTC_FCB)
|
||||
{
|
||||
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
||||
goto Quickie;
|
||||
|
|
|
@ -45,7 +45,7 @@ NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
|
|||
NextEntry = DataQueue->Queue.Flink;
|
||||
while (NextEntry != &DataQueue->Queue)
|
||||
{
|
||||
if ( !QuotaLeft ) break;
|
||||
if (!QuotaLeft) break;
|
||||
|
||||
DataQueueEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, Irp);
|
||||
|
||||
|
@ -55,10 +55,10 @@ NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
|
|||
{
|
||||
DataLeft = DataQueueEntry->DataSize - ByteOffset;
|
||||
|
||||
if ( DataQueueEntry->QuotaInEntry < DataLeft )
|
||||
if (DataQueueEntry->QuotaInEntry < DataLeft)
|
||||
{
|
||||
NewQuotaLeft = DataLeft - DataQueueEntry->QuotaInEntry;
|
||||
if ( NewQuotaLeft > QuotaLeft ) NewQuotaLeft = QuotaLeft;
|
||||
if (NewQuotaLeft > QuotaLeft) NewQuotaLeft = QuotaLeft;
|
||||
|
||||
QuotaLeft -= NewQuotaLeft;
|
||||
DataQueueEntry->QuotaInEntry += NewQuotaLeft;
|
||||
|
@ -93,7 +93,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
|||
PNP_DATA_QUEUE_ENTRY QueueEntry;
|
||||
BOOLEAN HasWrites;
|
||||
|
||||
if ( DataQueue->QueueState == Empty)
|
||||
if (DataQueue->QueueState == Empty)
|
||||
{
|
||||
Irp = NULL;
|
||||
ASSERT(IsListEmpty(&DataQueue->Queue));
|
||||
|
@ -111,7 +111,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
|||
--DataQueue->EntriesInQueue;
|
||||
|
||||
HasWrites = 1;
|
||||
if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !QueueEntry->QuotaInEntry )
|
||||
if (!DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !QueueEntry->QuotaInEntry)
|
||||
{
|
||||
HasWrites = 0;
|
||||
}
|
||||
|
@ -134,12 +134,12 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
|||
|
||||
ExFreePool(QueueEntry);
|
||||
|
||||
if ( Flag )
|
||||
if (Flag)
|
||||
{
|
||||
NpGetNextRealDataQueueEntry(DataQueue, List);
|
||||
}
|
||||
|
||||
if ( HasWrites )
|
||||
if (HasWrites)
|
||||
{
|
||||
NpCompleteStalledWrites(DataQueue, List);
|
||||
}
|
||||
|
@ -168,10 +168,10 @@ NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
|||
DataEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, QueueEntry);
|
||||
|
||||
Type = DataEntry->DataEntryType;
|
||||
if ( Type == Buffered || Type == Unbuffered ) break;
|
||||
if (Type == Buffered || Type == Unbuffered) break;
|
||||
|
||||
Irp = NpRemoveDataQueueEntry(DataQueue, 0, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
|
@ -193,23 +193,23 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
BOOLEAN CompleteWrites, FirstEntry;
|
||||
PLIST_ENTRY NextEntry, ThisEntry;
|
||||
|
||||
if ( DeviceObject ) IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
if (DeviceObject) IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
InitializeListHead(&List);
|
||||
|
||||
DataQueue = (PNP_DATA_QUEUE)Irp->Tail.Overlay.DriverContext[2];
|
||||
ClientSecurityContext = NULL;
|
||||
|
||||
if ( DeviceObject )
|
||||
if (DeviceObject)
|
||||
{
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
}
|
||||
|
||||
DataEntry = (PNP_DATA_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[3];
|
||||
if ( DataEntry )
|
||||
if (DataEntry)
|
||||
{
|
||||
if (DataEntry->QueueEntry.Blink == &DataQueue->Queue )
|
||||
if (DataEntry->QueueEntry.Blink == &DataQueue->Queue)
|
||||
{
|
||||
DataQueue->ByteOffset = 0;
|
||||
FirstEntry = 1;
|
||||
|
@ -224,7 +224,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
ClientSecurityContext = DataEntry->ClientSecurityContext;
|
||||
|
||||
CompleteWrites = 1;
|
||||
if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !DataEntry->QuotaInEntry )
|
||||
if (!DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !DataEntry->QuotaInEntry)
|
||||
{
|
||||
CompleteWrites = 0;
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
DataQueue->QuotaUsed -= DataEntry->QuotaInEntry;
|
||||
--DataQueue->EntriesInQueue;
|
||||
|
||||
if (DataQueue->Queue.Flink == &DataQueue->Queue )
|
||||
if (DataQueue->Queue.Flink == &DataQueue->Queue)
|
||||
{
|
||||
DataQueue->QueueState = Empty;
|
||||
ASSERT(DataQueue->BytesInQueue == 0);
|
||||
|
@ -242,28 +242,28 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( FirstEntry )
|
||||
if (FirstEntry)
|
||||
{
|
||||
NpGetNextRealDataQueueEntry(DataQueue, &List);
|
||||
}
|
||||
if ( CompleteWrites )
|
||||
if (CompleteWrites)
|
||||
{
|
||||
NpCompleteStalledWrites(DataQueue, &List);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( DeviceObject )
|
||||
if (DeviceObject)
|
||||
{
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
}
|
||||
|
||||
if ( DataEntry ) ExFreePool(DataEntry);
|
||||
if (DataEntry) ExFreePool(DataEntry);
|
||||
|
||||
NpFreeClientSecurityContext(ClientSecurityContext);
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IofCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||
|
||||
NextEntry = List.Flink;
|
||||
while (NextEntry != &List)
|
||||
|
@ -278,7 +278,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PNP_DATA_QUEUE DataQueue,
|
||||
IN ULONG Who,
|
||||
|
@ -302,7 +302,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
|
||||
if ((Type != 2) && (Who == WriteEntries))
|
||||
{
|
||||
Status = NpGetClientSecurityContext(ServerSide,
|
||||
Status = NpGetClientSecurityContext(NamedPipeEnd,
|
||||
Ccb,
|
||||
Irp ? Irp->Tail.Overlay.Thread :
|
||||
PsGetCurrentThread(),
|
||||
|
@ -317,8 +317,8 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
case 3:
|
||||
|
||||
ASSERT(Irp != NULL);
|
||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*DataEntry), 'rFpN');
|
||||
if ( DataEntry )
|
||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*DataEntry), NPFS_DATA_ENTRY_TAG);
|
||||
if (DataEntry)
|
||||
{
|
||||
DataEntry->DataEntryType = Type;
|
||||
DataEntry->QuotaInEntry = 0;
|
||||
|
@ -336,10 +336,10 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
case Buffered:
|
||||
|
||||
EntrySize = sizeof(*DataEntry);
|
||||
if ( Who != Empty)
|
||||
if (Who != Empty)
|
||||
{
|
||||
EntrySize = DataSize + sizeof(*DataEntry);
|
||||
if ((DataSize + sizeof(*DataEntry)) < DataSize )
|
||||
if ((DataSize + sizeof(*DataEntry)) < DataSize)
|
||||
{
|
||||
NpFreeClientSecurityContext(ClientContext);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -347,7 +347,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
}
|
||||
|
||||
QuotaInEntry = DataSize - ByteOffset;
|
||||
if ( DataQueue->Quota - DataQueue->QuotaUsed < QuotaInEntry )
|
||||
if (DataQueue->Quota - DataQueue->QuotaUsed < QuotaInEntry)
|
||||
{
|
||||
QuotaInEntry = DataQueue->Quota - DataQueue->QuotaUsed;
|
||||
HasSpace = 1;
|
||||
|
@ -357,8 +357,8 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
HasSpace = 0;
|
||||
}
|
||||
|
||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, EntrySize, 'rFpN');
|
||||
if ( !DataEntry )
|
||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, EntrySize, NPFS_DATA_ENTRY_TAG);
|
||||
if (!DataEntry)
|
||||
{
|
||||
NpFreeClientSecurityContext(ClientContext);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -370,7 +370,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
DataEntry->ClientSecurityContext = ClientContext;
|
||||
DataEntry->DataSize = DataSize;
|
||||
|
||||
if ( Who == ReadEntries)
|
||||
if (Who == ReadEntries)
|
||||
{
|
||||
ASSERT(Irp);
|
||||
|
||||
|
@ -393,7 +393,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
}
|
||||
_SEH2_END;
|
||||
|
||||
if ( HasSpace && Irp )
|
||||
if (HasSpace && Irp)
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
}
|
||||
|
||||
ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState == Who));
|
||||
if ( DataQueue->QueueState == Empty )
|
||||
if (DataQueue->QueueState == Empty)
|
||||
{
|
||||
ASSERT(DataQueue->BytesInQueue == 0);
|
||||
ASSERT(DataQueue->EntriesInQueue == 0);
|
||||
|
@ -430,7 +430,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
DataQueue->QueueState = Who;
|
||||
DataQueue->BytesInQueue += DataEntry->DataSize;
|
||||
++DataQueue->EntriesInQueue;
|
||||
if ( ByteOffset )
|
||||
if (ByteOffset)
|
||||
{
|
||||
DataQueue->ByteOffset = ByteOffset;
|
||||
ASSERT(Who == WriteEntries);
|
||||
|
@ -440,7 +440,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
|
||||
InsertTailList(&DataQueue->Queue, &DataEntry->QueueEntry);
|
||||
|
||||
if ( Status == STATUS_PENDING )
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
Irp->Tail.Overlay.DriverContext[2] = DataQueue;
|
||||
|
@ -448,10 +448,10 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
|||
|
||||
IoSetCancelRoutine(Irp, NpCancelDataQueueIrp);
|
||||
|
||||
if ( Irp->Cancel )
|
||||
if (Irp->Cancel)
|
||||
{
|
||||
IoSetCancelRoutine(Irp, NULL);
|
||||
NpCancelDataQueueIrp(0, Irp);
|
||||
NpCancelDataQueueIrp(NULL, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,51 +14,43 @@ NTAPI
|
|||
NpSetPipeInfo(IN PNP_FCB Fcb,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PFILE_PIPE_INFORMATION Buffer,
|
||||
IN ULONG ServerSide,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||
ULONG CompletionMode;
|
||||
PAGED_CODE();
|
||||
|
||||
if ( Buffer->ReadMode == FILE_PIPE_MESSAGE_MODE && Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE )
|
||||
if (Buffer->ReadMode == FILE_PIPE_MESSAGE_MODE && Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( ServerSide )
|
||||
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
|
||||
{
|
||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xA04EFu, ServerSide, 0, 0);
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
CompletionMode = Ccb->ServerCompletionMode;
|
||||
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
|
||||
{
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xA04EFu, NamedPipeEnd, 0, 0);
|
||||
}
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
CompletionMode = Ccb->ClientCompletionMode;
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
|
||||
if ( Buffer->CompletionMode != FILE_PIPE_COMPLETE_OPERATION ||
|
||||
CompletionMode == FILE_PIPE_COMPLETE_OPERATION ||
|
||||
if (Buffer->CompletionMode != FILE_PIPE_COMPLETE_OPERATION ||
|
||||
Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION ||
|
||||
(ReadQueue->QueueState == ReadEntries &&
|
||||
WriteQueue->QueueState != WriteEntries ))
|
||||
WriteQueue->QueueState != WriteEntries))
|
||||
{
|
||||
if (ServerSide)
|
||||
{
|
||||
Ccb->ServerReadMode = Buffer->ReadMode & 0xFF;
|
||||
Ccb->ServerCompletionMode = Buffer->CompletionMode & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ccb->ClientReadMode = Buffer->ReadMode & 0xFF;
|
||||
Ccb->ClientCompletionMode = Buffer->CompletionMode & 0xFF;
|
||||
}
|
||||
Ccb->ReadMode[NamedPipeEnd] = Buffer->ReadMode & 0xFF;
|
||||
Ccb->CompletionMode[NamedPipeEnd] = Buffer->CompletionMode & 0xFF;
|
||||
|
||||
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
||||
Status = 0;
|
||||
NpCheckForNotify(Fcb->ParentDcb, FALSE, List);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,7 +72,7 @@ NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
PVOID Buffer;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
@ -88,18 +80,18 @@ NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if ( !NodeTypeCode ) return STATUS_PIPE_DISCONNECTED;
|
||||
if ( NodeTypeCode != NPFS_NTC_CCB ) return STATUS_INVALID_PARAMETER;
|
||||
&NamedPipeEnd);
|
||||
if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
|
||||
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
InfoClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if ( InfoClass == FileBasicInformation ) return NpSetBasicInfo(Ccb, Buffer);
|
||||
if (InfoClass == FileBasicInformation) return NpSetBasicInfo(Ccb, Buffer);
|
||||
|
||||
if ( InfoClass != FilePipeInformation ) return STATUS_INVALID_PARAMETER;
|
||||
if (InfoClass != FilePipeInformation) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
return NpSetPipeInfo(Fcb, Ccb, Buffer, ServerSide, List);
|
||||
return NpSetPipeInfo(Fcb, Ccb, Buffer, NamedPipeEnd, List);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -133,7 +125,7 @@ NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
|
@ -142,13 +134,322 @@ NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryBasicInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_BASIC_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
InfoBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryStandardInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length,
|
||||
IN ULONG NamedPipeEnd)
|
||||
{
|
||||
PNP_DATA_QUEUE DataQueue;
|
||||
PFILE_STANDARD_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
InfoBuffer->AllocationSize.LowPart = Ccb->DataQueue[FILE_PIPE_INBOUND].Quota +
|
||||
Ccb->DataQueue[FILE_PIPE_OUTBOUND].Quota;
|
||||
InfoBuffer->AllocationSize.HighPart = 0;
|
||||
|
||||
if (DataQueue->QueueState == WriteEntries)
|
||||
{
|
||||
InfoBuffer->EndOfFile.HighPart = 0;
|
||||
InfoBuffer->EndOfFile.LowPart = DataQueue->BytesInQueue -
|
||||
DataQueue->ByteOffset;
|
||||
}
|
||||
|
||||
InfoBuffer->Directory = FALSE;
|
||||
InfoBuffer->NumberOfLinks = 1;
|
||||
InfoBuffer->DeletePending = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryEaInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_EA_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryNameInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_NAME_INFORMATION InfoBuffer = Buffer;
|
||||
USHORT NameLength;
|
||||
NTSTATUS Status;
|
||||
PWCHAR Name;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
if (Ccb->NodeType == NPFS_NTC_ROOT_DCB_CCB)
|
||||
{
|
||||
NameLength = NpVcb->RootDcb->FullName.Length;
|
||||
Name = NpVcb->RootDcb->FullName.Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
NameLength = Ccb->Fcb->FullName.Length;
|
||||
Name = Ccb->Fcb->FullName.Buffer;
|
||||
}
|
||||
|
||||
if (*Length < NameLength)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
NameLength = *Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlCopyMemory(InfoBuffer->FileName, Name, NameLength);
|
||||
InfoBuffer->FileNameLength = NameLength;
|
||||
|
||||
*Length -= NameLength;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryInternalInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_INTERNAL_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryPositionInfo(IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length,
|
||||
IN ULONG NamedPipeEnd)
|
||||
{
|
||||
PNP_DATA_QUEUE DataQueue;
|
||||
PFILE_POSITION_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
if (DataQueue->QueueState == WriteEntries)
|
||||
{
|
||||
InfoBuffer->CurrentByteOffset.QuadPart = DataQueue->BytesInQueue -
|
||||
DataQueue->ByteOffset;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryPipeLocalInfo(IN PNP_FCB Fcb,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length,
|
||||
IN ULONG NamedPipeEnd)
|
||||
{
|
||||
PFILE_PIPE_LOCAL_INFORMATION InfoBuffer = Buffer;
|
||||
PNP_DATA_QUEUE InQueue, OutQueue;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
InQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
OutQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
|
||||
InfoBuffer->NamedPipeType = Fcb->NamedPipeType;
|
||||
InfoBuffer->NamedPipeConfiguration = Fcb->NamedPipeConfiguration;
|
||||
InfoBuffer->MaximumInstances = Fcb->MaximumInstances;
|
||||
InfoBuffer->CurrentInstances = Fcb->CurrentInstances;
|
||||
InfoBuffer->InboundQuota = InQueue->Quota;
|
||||
InfoBuffer->OutboundQuota = OutQueue->Quota;
|
||||
InfoBuffer->NamedPipeState = Ccb->NamedPipeState;
|
||||
InfoBuffer->NamedPipeEnd = NamedPipeEnd;
|
||||
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
if (InQueue->QueueState == WriteEntries)
|
||||
{
|
||||
InfoBuffer->ReadDataAvailable = InQueue->BytesInQueue - InQueue->ByteOffset;
|
||||
}
|
||||
InfoBuffer->WriteQuotaAvailable = OutQueue->QuotaUsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OutQueue->QueueState == WriteEntries)
|
||||
{
|
||||
InfoBuffer->ReadDataAvailable = OutQueue->BytesInQueue - OutQueue->ByteOffset;
|
||||
}
|
||||
InfoBuffer->WriteQuotaAvailable = InQueue->QuotaUsed;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryPipeInfo(IN PNP_FCB Fcb,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PVOID Buffer,
|
||||
IN OUT PULONG Length,
|
||||
IN ULONG NamedPipeEnd)
|
||||
{
|
||||
PFILE_PIPE_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
InfoBuffer->ReadMode = Ccb->ReadMode[NamedPipeEnd];
|
||||
InfoBuffer->CompletionMode = Ccb->CompletionMode[NamedPipeEnd];
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
FILE_INFORMATION_CLASS InfoClass;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
PFILE_ALL_INFORMATION AllInfo;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&NamedPipeEnd);
|
||||
if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
|
||||
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
Length = IoStack->Parameters.QueryFile.Length;
|
||||
InfoClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||
|
||||
if (NodeTypeCode != NPFS_NTC_CCB)
|
||||
{
|
||||
if (NodeTypeCode != NPFS_NTC_ROOT_DCB || InfoClass != FileNameInformation)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (InfoClass)
|
||||
{
|
||||
case FileNameInformation:
|
||||
Status = NpQueryNameInfo(Ccb, Buffer, &Length);
|
||||
break;
|
||||
|
||||
case FilePositionInformation:
|
||||
Status = NpQueryPositionInfo(Ccb, Buffer, &Length, NamedPipeEnd);
|
||||
break;
|
||||
|
||||
case FilePipeInformation:
|
||||
Status = NpQueryPipeInfo(Fcb, Ccb, Buffer, &Length, NamedPipeEnd);
|
||||
break;
|
||||
|
||||
case FilePipeLocalInformation:
|
||||
Status = NpQueryPipeLocalInfo(Fcb, Ccb, Buffer, &Length, NamedPipeEnd);
|
||||
break;
|
||||
|
||||
case FileBasicInformation:
|
||||
Status = NpQueryBasicInfo(Ccb, Buffer, &Length);
|
||||
break;
|
||||
|
||||
case FileStandardInformation:
|
||||
Status = NpQueryStandardInfo(Ccb, Buffer, &Length, NamedPipeEnd);
|
||||
break;
|
||||
|
||||
case FileInternalInformation:
|
||||
Status = NpQueryInternalInfo(Ccb, Buffer, &Length);
|
||||
break;
|
||||
|
||||
case FileAllInformation:
|
||||
|
||||
Length -= 12;
|
||||
AllInfo = (PFILE_ALL_INFORMATION)Buffer;
|
||||
NpQueryBasicInfo(Ccb, &AllInfo->BasicInformation, &Length);
|
||||
NpQueryStandardInfo(Ccb, &AllInfo->StandardInformation, &Length, NamedPipeEnd);
|
||||
NpQueryInternalInfo(Ccb, &AllInfo->InternalInformation, &Length);
|
||||
NpQueryEaInfo(Ccb, &AllInfo->EaInformation, &Length);
|
||||
NpQueryPositionInfo(Ccb, &AllInfo->PositionInformation, &Length, NamedPipeEnd);
|
||||
Length += 96;
|
||||
break;
|
||||
|
||||
case FileEaInformation:
|
||||
Status = NpQueryEaInfo(Ccb, Buffer, &Length);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = IoStack->Parameters.Read.Length - Length;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -167,7 +468,7 @@ NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
|
@ -176,3 +477,6 @@ NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// volinfo.c
|
||||
//
|
|
@ -5,7 +5,7 @@ NTAPI
|
|||
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||
OUT PVOID* PrimaryContext OPTIONAL,
|
||||
OUT PNP_CCB* Ccb,
|
||||
OUT PBOOLEAN ServerSide OPTIONAL)
|
||||
OUT PULONG NamedPipeEnd OPTIONAL)
|
||||
{
|
||||
ULONG_PTR Context;
|
||||
PNP_CCB Node;
|
||||
|
@ -14,7 +14,7 @@ NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
|||
Context = (ULONG_PTR)FileObject->FsContext;
|
||||
if ((Context) && (Context != 1))
|
||||
{
|
||||
if (ServerSide) *ServerSide = Context & 1;
|
||||
if (NamedPipeEnd) *NamedPipeEnd = Context & 1;
|
||||
|
||||
Node = (PVOID)(Context & ~1);
|
||||
|
||||
|
@ -47,7 +47,7 @@ NTAPI
|
|||
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
||||
IN PVOID PrimaryContext,
|
||||
IN PVOID Ccb,
|
||||
IN BOOLEAN ServerSide)
|
||||
IN ULONG NamedPipeEnd)
|
||||
{
|
||||
BOOLEAN FileIsPipe;
|
||||
PAGED_CODE();
|
||||
|
@ -57,7 +57,10 @@ NpSetFileObject(IN PFILE_OBJECT FileObject,
|
|||
if ((PrimaryContext) && (((PNP_CCB)PrimaryContext)->NodeType == NPFS_NTC_CCB))
|
||||
{
|
||||
FileIsPipe = TRUE;
|
||||
if (ServerSide) PrimaryContext = (PVOID)((ULONG_PTR)PrimaryContext | 1);
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
PrimaryContext = (PVOID) ((ULONG_PTR) PrimaryContext | 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
NTSTATUS Status;
|
||||
PNP_DATA_QUEUE FlushQueue;
|
||||
PAGED_CODE();
|
||||
|
@ -15,22 +15,27 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
|||
NodeTypeCode = NpDecodeFileObject(IoGetCurrentIrpStackLocation(Irp)->FileObject,
|
||||
NULL,
|
||||
&Ccb,
|
||||
&ServerSide);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB ) return STATUS_PIPE_DISCONNECTED;
|
||||
&NamedPipeEnd);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_PIPE_DISCONNECTED;
|
||||
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
//ms_exc.registration.TryLevel = 0;
|
||||
|
||||
FlushQueue = &Ccb->OutQueue;
|
||||
if ( ServerSide != 1 ) FlushQueue = &Ccb->InQueue;
|
||||
|
||||
if ( FlushQueue->QueueState == WriteEntries)
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
FlushQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
FlushQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
if (FlushQueue->QueueState == WriteEntries)
|
||||
{
|
||||
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||
Ccb,
|
||||
FlushQueue,
|
||||
1,
|
||||
2u,
|
||||
WriteEntries,
|
||||
2,
|
||||
0,
|
||||
Irp,
|
||||
NULL,
|
||||
|
@ -41,9 +46,7 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
|||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
|
|||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_CCB Ccb;
|
||||
NTSTATUS Status;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
|
@ -93,10 +93,10 @@ NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
|
||||
|
@ -125,7 +125,7 @@ NpListen(IN PDEVICE_OBJECT DeviceObject,
|
|||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_CCB Ccb;
|
||||
NTSTATUS Status;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
|
@ -134,10 +134,10 @@ NpListen(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||
{
|
||||
if ( ServerSide == 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||
|
||||
|
@ -169,7 +169,7 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
NODE_TYPE_CODE Type;
|
||||
ULONG InputLength;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_CCB Ccb;
|
||||
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
|
||||
PNP_DATA_QUEUE DataQueue;
|
||||
|
@ -181,8 +181,12 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
InputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (!Type) return STATUS_PIPE_DISCONNECTED;
|
||||
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
|
||||
if (!Type)
|
||||
{
|
||||
return STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
||||
if ((Type != NPFS_NTC_CCB) && (InputLength < sizeof(*PeekBuffer)))
|
||||
{
|
||||
|
@ -190,26 +194,28 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
PeekBuffer = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||
if ( ServerSide )
|
||||
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
|
||||
{
|
||||
if ( ServerSide != 1 )
|
||||
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
|
||||
{
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD02E5, ServerSide, 0, 0);
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD02E5, NamedPipeEnd, 0, 0);
|
||||
}
|
||||
DataQueue = &Ccb->InQueue;
|
||||
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->OutQueue;
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE )
|
||||
if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE )
|
||||
if (Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE)
|
||||
{
|
||||
return STATUS_INVALID_PIPE_STATE;
|
||||
}
|
||||
if ( DataQueue->QueueState != WriteEntries)
|
||||
|
||||
if (DataQueue->QueueState != WriteEntries)
|
||||
{
|
||||
return STATUS_PIPE_BROKEN;
|
||||
}
|
||||
|
@ -222,7 +228,7 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
|||
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
|
||||
BytesPeeked = sizeof(*PeekBuffer);
|
||||
|
||||
if ( DataQueue->QueueState == WriteEntries)
|
||||
if (DataQueue->QueueState == WriteEntries)
|
||||
{
|
||||
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
||||
NP_DATA_QUEUE_ENTRY,
|
||||
|
@ -230,14 +236,14 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
|||
ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
|
||||
|
||||
PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
|
||||
if ( Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
|
||||
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
|
||||
{
|
||||
PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
|
||||
PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
|
||||
}
|
||||
if ( InputLength == sizeof(*PeekBuffer) )
|
||||
if (InputLength == sizeof(*PeekBuffer))
|
||||
{
|
||||
Status = PeekBuffer->ReadDataAvailable != 0 ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
|
||||
Status = PeekBuffer->ReadDataAvailable ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -270,7 +276,7 @@ NpCompleteTransceiveIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if ( Irp->AssociatedIrp.SystemBuffer )
|
||||
if (Irp->AssociatedIrp.SystemBuffer)
|
||||
{
|
||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||
}
|
||||
|
@ -287,10 +293,10 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PVOID InBuffer, OutBuffer;
|
||||
ULONG InLength, OutLength, ReadMode, BytesWritten;
|
||||
ULONG InLength, OutLength, BytesWritten;
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PNP_CCB Ccb;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
|
@ -304,7 +310,7 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||
OutBuffer = Irp->UserBuffer;
|
||||
|
||||
if ( Irp->RequestorMode == UserMode)
|
||||
if (Irp->RequestorMode == UserMode)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -313,13 +319,13 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB )
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
if (NodeTypeCode != NPFS_NTC_CCB)
|
||||
{
|
||||
return STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
@ -327,39 +333,37 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
||||
|
||||
//ms_exc.registration.TryLevel = 1;
|
||||
if ( Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE )
|
||||
if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
Status = STATUS_INVALID_PIPE_STATE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( ServerSide )
|
||||
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
|
||||
{
|
||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD0538, ServerSide, 0, 0);
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
ReadMode = Ccb->ServerReadMode;
|
||||
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
|
||||
{
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD0538, NamedPipeEnd, 0, 0);
|
||||
}
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
ReadMode = Ccb->ClientReadMode;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||
|
||||
if (Ccb->Fcb->NamedPipeConfiguration != FILE_PIPE_FULL_DUPLEX ||
|
||||
ReadMode != FILE_PIPE_MESSAGE_MODE )
|
||||
Ccb->ReadMode[NamedPipeEnd] != FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
Status = STATUS_INVALID_PIPE_STATE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( ReadQueue->QueueState != Empty)
|
||||
if (ReadQueue->QueueState != Empty)
|
||||
{
|
||||
Status = STATUS_PIPE_BUSY;
|
||||
goto Quickie;
|
||||
|
@ -372,14 +376,14 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
Ccb->Fcb->NamedPipeType,
|
||||
&BytesWritten,
|
||||
Ccb,
|
||||
ServerSide,
|
||||
NamedPipeEnd,
|
||||
Irp->Tail.Overlay.Thread,
|
||||
List);
|
||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
||||
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||
if ( !NewIrp )
|
||||
if (!NewIrp)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
|
@ -387,20 +391,28 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
|
||||
|
||||
if ( BytesWritten )
|
||||
if (BytesWritten)
|
||||
{
|
||||
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool, BytesWritten, 'wFpN');
|
||||
if ( !NewIrp->AssociatedIrp.SystemBuffer )
|
||||
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool, BytesWritten, NPFS_WRITE_BLOCK_TAG);
|
||||
if (!NewIrp->AssociatedIrp.SystemBuffer)
|
||||
{
|
||||
IoFreeIrp(NewIrp);
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
|
||||
(PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
|
||||
BytesWritten);
|
||||
//ms_exc.registration.TryLevel = 1;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
goto Quickie;
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -416,19 +428,19 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
IoStack->Parameters.Read.Length = BytesWritten;
|
||||
IoStack->MajorFunction = IRP_MJ_WRITE;
|
||||
|
||||
if ( BytesWritten > 0 ) NewIrp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
|
||||
if (BytesWritten > 0) NewIrp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
|
||||
NewIrp->UserIosb = &NpUserIoStatusBlock;
|
||||
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||
Ccb,
|
||||
WriteQueue,
|
||||
WriteEntries,
|
||||
1,
|
||||
Unbuffered,
|
||||
BytesWritten,
|
||||
NewIrp,
|
||||
NULL,
|
||||
0);
|
||||
if ( Status != STATUS_PENDING )
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
NewIrp->IoStatus.Status = Status;
|
||||
InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
|
||||
|
@ -437,24 +449,23 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
ASSERT(ReadQueue->QueueState == Empty);
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||
Ccb,
|
||||
ReadQueue,
|
||||
ReadEntries,
|
||||
0,
|
||||
Buffered,
|
||||
OutLength,
|
||||
Irp,
|
||||
NULL,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
return Status;
|
||||
}
|
||||
|
@ -467,7 +478,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG InLength, NameLength;
|
||||
UNICODE_STRING SourceString, Prefix;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_CCB Ccb;
|
||||
PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
|
||||
NTSTATUS Status;
|
||||
|
@ -481,9 +492,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
SourceString.Buffer = NULL;
|
||||
|
||||
//ms_exc.registration.TryLevel = 0;
|
||||
|
||||
if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide) != NPFS_NTC_ROOT_DCB )
|
||||
if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
|
||||
{
|
||||
Status = STATUS_ILLEGAL_FUNCTION;
|
||||
goto Quickie;
|
||||
|
@ -497,15 +506,15 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
NameLength = Buffer->NameLength;
|
||||
if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength ))
|
||||
if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, 'WFpN');
|
||||
if (!SourceString.Buffer )
|
||||
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, NPFS_WRITE_BLOCK_TAG);
|
||||
if (!SourceString.Buffer)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
|
@ -522,7 +531,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
|
||||
|
||||
NodeTypeCode = Fcb ? Fcb->NodeType : 0;
|
||||
if ( NodeTypeCode != NPFS_NTC_FCB )
|
||||
if (NodeTypeCode != NPFS_NTC_FCB)
|
||||
{
|
||||
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto Quickie;
|
||||
|
@ -533,10 +542,10 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
NextEntry = NextEntry->Flink)
|
||||
{
|
||||
Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE ) break;
|
||||
if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
|
||||
}
|
||||
|
||||
if ( NextEntry == &Fcb->CcbList )
|
||||
if (NextEntry == &Fcb->CcbList)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -549,8 +558,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
if ( SourceString.Buffer ) ExFreePool(SourceString.Buffer);
|
||||
if (SourceString.Buffer) ExFreePool(SourceString.Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -572,22 +580,22 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
switch (Fsctl)
|
||||
{
|
||||
case FSCTL_PIPE_PEEK:
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpPeek(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_WRITE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpInternalWrite(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_TRANSCEIVE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpTransceive(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpInternalTransceive(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
|
@ -596,54 +604,54 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
// on purpose
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_READ:
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpInternalRead(DeviceObject, Irp, Overflow, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
||||
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpQueryClientProcess(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_ASSIGN_EVENT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpAssignEvent(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_DISCONNECT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpDisconnect(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_LISTEN:
|
||||
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpListen(DeviceObject, Irp, &List);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_EVENT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpQueryEvent(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_WAIT:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpWaitForNamedPipe(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_IMPERSONATE:
|
||||
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpImpersonate(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||
Status = NpSetClientProcess(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
|
@ -680,7 +688,7 @@ NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( Status != STATUS_PENDING )
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
|
|
|
@ -2,48 +2,6 @@
|
|||
|
||||
PDEVICE_OBJECT NpfsDeviceObject;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetSecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQuerySecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
|
|
@ -16,6 +16,35 @@
|
|||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Pool Tags for NPFS (from pooltag.txt)
|
||||
//
|
||||
// Npf* -npfs.sys - Npfs Allocations
|
||||
// NpFc - npfs.sys - CCB, client control block
|
||||
// NpFf - npts.sys - FCB, file control block
|
||||
// NpFC - npfs.sys - ROOT_DCB CCB
|
||||
// NpFD - npfs.sys - DCB, directory block
|
||||
// NpFg - npfs.sys - Global storage
|
||||
// NpFi - npfs.sys - NPFS client info buffer.
|
||||
// NpFn - npfs.sys - Name block
|
||||
// NpFq - npfs.sys - Query template buffer used for directory query
|
||||
// NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
|
||||
// NpFs - npfs.sys - Client security context
|
||||
// NpFw - npfs.sys - Write block
|
||||
// NpFW - npfs.sys - Write block
|
||||
#define NPFS_CCB_TAG 'NpFc'
|
||||
#define NPFS_ROOT_DCB_CCB_TAG 'NpFC'
|
||||
#define NPFS_DCB_TAG 'NpFD'
|
||||
#define NPFS_FCB_TAG 'NpFf'
|
||||
#define NPFS_GLOBAL_TAG 'NpFg'
|
||||
#define NPFS_CLIENT_INFO_TAG 'NpFi'
|
||||
#define NPFS_NAME_BLOCK_TAG 'NpFn'
|
||||
#define NPFS_QUERY_TEMPLATE_TAG 'NpFq'
|
||||
#define NPFS_DATA_ENTRY_TAG 'NpFr'
|
||||
#define NPFS_CLIENT_SEC_CTX_TAG 'NpFs'
|
||||
#define NPFS_WAIT_BLOCK_TAG 'NpFt'
|
||||
#define NPFS_WRITE_BLOCK_TAG 'NpFw'
|
||||
|
||||
//
|
||||
// Node Type Codes for NPFS
|
||||
//
|
||||
|
@ -190,8 +219,7 @@ typedef struct _NP_FCB
|
|||
typedef struct _NP_NONPAGED_CCB
|
||||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
PNP_EVENT_BUFFER EventBufferClient;
|
||||
PNP_EVENT_BUFFER EventBufferServer;
|
||||
PNP_EVENT_BUFFER EventBuffer[2];
|
||||
ERESOURCE Lock;
|
||||
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
|
||||
|
||||
|
@ -202,22 +230,16 @@ typedef struct _NP_CCB
|
|||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
UCHAR NamedPipeState;
|
||||
UCHAR ClientReadMode:1;
|
||||
UCHAR ClientCompletionMode:1;
|
||||
UCHAR ServerReadMode:1;
|
||||
UCHAR ClientReservedFlags:6;
|
||||
UCHAR ServerCompletionMode:1;
|
||||
UCHAR ServerReservedFlags:6;
|
||||
UCHAR ReadMode[2];
|
||||
UCHAR CompletionMode[2];
|
||||
SECURITY_QUALITY_OF_SERVICE ClientQos;
|
||||
LIST_ENTRY CcbEntry;
|
||||
PNP_FCB Fcb;
|
||||
PFILE_OBJECT ClientFileObject;
|
||||
PFILE_OBJECT ServerFileObject;
|
||||
PFILE_OBJECT FileObject[2];
|
||||
PEPROCESS Process;
|
||||
PVOID ClientSession;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
NP_DATA_QUEUE InQueue;
|
||||
NP_DATA_QUEUE OutQueue;
|
||||
NP_DATA_QUEUE DataQueue[2];
|
||||
PSECURITY_CLIENT_CONTEXT ClientContext;
|
||||
LIST_ENTRY IrpList;
|
||||
} NP_CCB, *PNP_CCB;
|
||||
|
@ -265,7 +287,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PNP_DATA_QUEUE DataQueue,
|
||||
IN ULONG Who,
|
||||
|
@ -400,7 +422,7 @@ NpInitializeSecurity(IN PNP_CCB Ccb,
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
||||
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PETHREAD Thread,
|
||||
IN PSECURITY_CLIENT_CONTEXT *Context);
|
||||
|
@ -410,14 +432,14 @@ NTAPI
|
|||
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
||||
IN PVOID PrimaryContext,
|
||||
IN PVOID Ccb,
|
||||
IN BOOLEAN ServerSide);
|
||||
IN ULONG NamedPipeEnd);
|
||||
|
||||
NODE_TYPE_CODE
|
||||
NTAPI
|
||||
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||
OUT PVOID* PrimaryContext OPTIONAL,
|
||||
OUT PNP_CCB* Ccb,
|
||||
OUT PBOOLEAN ServerSide OPTIONAL);
|
||||
OUT PULONG NamedPipeEnd OPTIONAL);
|
||||
|
||||
PNP_FCB
|
||||
NTAPI
|
||||
|
@ -475,7 +497,7 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN BOOLEAN ServerSide,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PETHREAD Thread,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
|
@ -505,3 +527,19 @@ NTAPI
|
|||
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQuerySecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetSecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ NpFindRelativePrefix(IN PNP_DCB Dcb,
|
|||
|
||||
ASSERT(Dcb->NodeType == NPFS_NTC_ROOT_DCB);
|
||||
|
||||
Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, 'nFpN');
|
||||
Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, NPFS_NAME_BLOCK_TAG);
|
||||
if (!Buffer)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
|
|
@ -12,17 +12,17 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
PNP_DATA_QUEUE Queue;
|
||||
PNP_DATA_QUEUE ReadQueue;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN ServerSide;
|
||||
ULONG NamedPipeEnd;
|
||||
PNP_CCB Ccb;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
BOOLEAN ReadOk;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStatus->Information = 0;
|
||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
|
||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
|
||||
if (!NodeType)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if ( NodeType != NPFS_NTC_CCB )
|
||||
if (NodeType != NPFS_NTC_CCB)
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
return TRUE;
|
||||
|
@ -39,9 +39,7 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
||||
|
||||
//ms_exc.registration.TryLevel = 0;
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE )
|
||||
if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE)
|
||||
{
|
||||
IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED;
|
||||
ReadOk = TRUE;
|
||||
|
@ -50,33 +48,33 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
|
||||
ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
|
||||
|
||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
|
||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND ))
|
||||
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
|
||||
(NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND))
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
ReadOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( ServerSide == 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
Queue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
Queue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
if ( Queue->QueueState == WriteEntries )
|
||||
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||
|
||||
if (ReadQueue->QueueState == WriteEntries)
|
||||
{
|
||||
*IoStatus = NpReadDataQueue(Queue,
|
||||
*IoStatus = NpReadDataQueue(ReadQueue,
|
||||
FALSE,
|
||||
FALSE,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
ServerSide ? Ccb->ServerReadMode : Ccb->ClientReadMode,
|
||||
Ccb->ReadMode[NamedPipeEnd],
|
||||
Ccb,
|
||||
List);
|
||||
if (!NT_SUCCESS(IoStatus->Status))
|
||||
|
@ -86,40 +84,40 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
}
|
||||
|
||||
ReadOk = TRUE;
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE )
|
||||
if (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE)
|
||||
{
|
||||
IoStatus->Status = STATUS_PIPE_BROKEN;
|
||||
ReadOk = TRUE;
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ((ServerSide ? Ccb->ServerCompletionMode : Ccb->ServerCompletionMode) == FILE_PIPE_COMPLETE_OPERATION)
|
||||
if (Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
|
||||
{
|
||||
IoStatus->Status = STATUS_PIPE_EMPTY;
|
||||
ReadOk = TRUE;
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( !Irp )
|
||||
if (!Irp)
|
||||
{
|
||||
ReadOk = FALSE;
|
||||
goto Quickie;
|
||||
|
||||
}
|
||||
Status = NpAddDataQueueEntry(ServerSide,
|
||||
|
||||
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||
Ccb,
|
||||
Queue,
|
||||
0,
|
||||
0,
|
||||
ReadQueue,
|
||||
ReadEntries,
|
||||
Buffered,
|
||||
BufferSize,
|
||||
Irp,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
IoStatus->Status = Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -129,11 +127,10 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
|||
else
|
||||
{
|
||||
ReadOk = TRUE;
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
return ReadOk;
|
||||
}
|
||||
|
@ -177,7 +174,7 @@ NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( IoStatus.Status != STATUS_PENDING )
|
||||
if (IoStatus.Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Information = IoStatus.Information;
|
||||
Irp->IoStatus.Status = IoStatus.Status;
|
||||
|
|
|
@ -19,13 +19,13 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
BOOLEAN CompleteWrites = FALSE;
|
||||
PAGED_CODE();
|
||||
|
||||
if ( ReadOverflowOperation ) Peek = TRUE;
|
||||
if (ReadOverflowOperation) Peek = TRUE;
|
||||
|
||||
RemainingSize = BufferSize;
|
||||
Status.Status = 0;
|
||||
Status.Status = STATUS_SUCCESS;
|
||||
TotalBytesCopied = 0;
|
||||
|
||||
if ( Peek )
|
||||
if (Peek)
|
||||
{
|
||||
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
||||
NP_DATA_QUEUE_ENTRY,
|
||||
|
@ -36,11 +36,13 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
|
||||
}
|
||||
|
||||
while (&DataEntry->QueueEntry != &DataQueue->Queue && RemainingSize )
|
||||
while ((&DataEntry->QueueEntry != &DataQueue->Queue) && (RemainingSize))
|
||||
{
|
||||
if ( !Peek || (DataEntry->DataEntryType == Buffered || DataEntry->DataEntryType == Unbuffered ))
|
||||
if (!Peek ||
|
||||
DataEntry->DataEntryType == Buffered ||
|
||||
DataEntry->DataEntryType == Unbuffered)
|
||||
{
|
||||
if ( DataEntry->DataEntryType == Unbuffered )
|
||||
if (DataEntry->DataEntryType == Unbuffered)
|
||||
{
|
||||
DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
||||
}
|
||||
|
@ -48,16 +50,17 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
{
|
||||
DataBuffer = &DataEntry[1];
|
||||
}
|
||||
|
||||
DataSize = DataEntry->DataSize;
|
||||
Offset = DataSize;
|
||||
|
||||
if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
|
||||
{
|
||||
Offset = DataSize - DataQueue->ByteOffset;
|
||||
Offset -= DataQueue->ByteOffset;
|
||||
}
|
||||
|
||||
DataLength = Offset;
|
||||
if ( Offset >= RemainingSize ) DataLength = RemainingSize;
|
||||
if (Offset >= RemainingSize) DataLength = RemainingSize;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -75,19 +78,20 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
RemainingSize -= DataLength;
|
||||
Offset -= DataLength;
|
||||
TotalBytesCopied += DataLength;
|
||||
if ( !Peek )
|
||||
|
||||
if (!Peek)
|
||||
{
|
||||
DataEntry->QuotaInEntry -= DataLength;
|
||||
DataQueue->QuotaUsed -= DataLength;
|
||||
DataQueue->ByteOffset += DataLength;
|
||||
CompleteWrites = TRUE;;
|
||||
CompleteWrites = TRUE;
|
||||
}
|
||||
|
||||
NpCopyClientContext(Ccb, DataEntry);
|
||||
|
||||
if ( Offset || (ReadOverflowOperation && !TotalBytesCopied ))
|
||||
if ((Offset) || (ReadOverflowOperation && !TotalBytesCopied))
|
||||
{
|
||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
||||
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
Status.Status = STATUS_BUFFER_OVERFLOW;
|
||||
break;
|
||||
|
@ -95,23 +99,23 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( !Peek || ReadOverflowOperation )
|
||||
if (!Peek || ReadOverflowOperation)
|
||||
{
|
||||
if ( ReadOverflowOperation)
|
||||
if (ReadOverflowOperation)
|
||||
{
|
||||
TempDataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
|
||||
ASSERT(TempDataEntry == DataEntry);
|
||||
}
|
||||
|
||||
Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
|
||||
if ( Irp )
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Information = DataSize;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
||||
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
Status.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
@ -119,7 +123,7 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
ASSERT(!ReadOverflowOperation);
|
||||
}
|
||||
}
|
||||
if ( Peek )
|
||||
if (Peek)
|
||||
{
|
||||
DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
|
||||
NP_DATA_QUEUE_ENTRY,
|
||||
|
@ -132,7 +136,7 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
|||
}
|
||||
|
||||
Status.Information = TotalBytesCopied;
|
||||
if ( CompleteWrites ) NpCompleteStalledWrites(DataQueue, List);
|
||||
if (CompleteWrites) NpCompleteStalledWrites(DataQueue, List);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,35 +58,36 @@ NpInitializeSecurity(IN PNP_CCB Ccb,
|
|||
}
|
||||
else
|
||||
{
|
||||
Ccb->ClientQos.Length = 12;
|
||||
Ccb->ClientQos.ImpersonationLevel = 2;
|
||||
Ccb->ClientQos.ContextTrackingMode = 1;
|
||||
Ccb->ClientQos.EffectiveOnly = 1;
|
||||
Ccb->ClientQos.Length = sizeof(Ccb->ClientQos);
|
||||
Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation;
|
||||
Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||||
Ccb->ClientQos.EffectiveOnly = TRUE;
|
||||
}
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
if (Ccb->ClientQos.ContextTrackingMode)
|
||||
if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
|
||||
{
|
||||
Status = 0;
|
||||
Ccb->ClientContext = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
Ccb->ClientContext = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), 'sFpN');
|
||||
ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), NPFS_CLIENT_SEC_CTX_TAG);
|
||||
Ccb->ClientContext = ClientContext;
|
||||
if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
|
||||
if (Status >= 0) return Status;
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
ExFreePool(Ccb->ClientContext);
|
||||
Ccb->ClientContext = 0;
|
||||
Ccb->ClientContext = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
||||
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PETHREAD Thread,
|
||||
IN PSECURITY_CLIENT_CONTEXT *Context)
|
||||
|
@ -96,15 +97,15 @@ NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
|||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
if ( ServerSide || Ccb->ClientQos.ContextTrackingMode != 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END || Ccb->ClientQos.ContextTrackingMode != SECURITY_DYNAMIC_TRACKING)
|
||||
{
|
||||
NewContext = NULL;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewContext = ExAllocatePoolWithQuotaTag(PagedPool, sizeof(*NewContext), 'sFpN');
|
||||
if ( !NewContext ) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
NewContext = ExAllocatePoolWithQuotaTag(PagedPool, sizeof(*NewContext), NPFS_CLIENT_SEC_CTX_TAG);
|
||||
if (!NewContext) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -116,3 +117,4 @@ NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
|||
*Context = NewContext;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
128
reactos/drivers/filesystems/npfs_new/seinfo.c
Normal file
128
reactos/drivers/filesystems/npfs_new/seinfo.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
ULONG NamedPipeEnd;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&NamedPipeEnd);
|
||||
if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
|
||||
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation,
|
||||
Irp->UserBuffer,
|
||||
&IoStack->Parameters.QuerySecurity.Length,
|
||||
&Fcb->SecurityDescriptor);
|
||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
Irp->IoStatus.Information = IoStack->Parameters.QuerySecurity.Length;
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NODE_TYPE_CODE NodeTypeCode;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
PNP_FCB Fcb;
|
||||
PNP_CCB Ccb;
|
||||
ULONG NamedPipeEnd;
|
||||
PVOID CachedSecurityDescriptor, SecurityDescriptor;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||
(PVOID*)&Fcb,
|
||||
&Ccb,
|
||||
&NamedPipeEnd);
|
||||
if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
|
||||
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
Status = SeSetSecurityDescriptorInfo(NULL,
|
||||
&IoStack->Parameters.SetSecurity.SecurityInformation,
|
||||
IoStack->Parameters.SetSecurity.SecurityDescriptor,
|
||||
&SecurityDescriptor,
|
||||
TRUE,
|
||||
IoGetFileObjectGenericMapping());
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = ObLogSecurityDescriptor(SecurityDescriptor, &CachedSecurityDescriptor, TRUE);
|
||||
ExFreePool(SecurityDescriptor);
|
||||
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
|
||||
ObDereferenceSecurityDescriptor(SecurityDescriptor, 1);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQuerySecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonQuerySecurityInfo(DeviceObject, Irp);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdSetSecurity(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonQuerySecurityInfo(DeviceObject, Irp);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ NpCancelListeningQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -28,10 +28,10 @@ NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
ASSERT(Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE);
|
||||
|
||||
Ccb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE;
|
||||
Ccb->ClientCompletionMode = FILE_PIPE_QUEUE_OPERATION;
|
||||
Ccb->ReadMode[FILE_PIPE_CLIENT_END] = FILE_PIPE_BYTE_STREAM_MODE;
|
||||
Ccb->CompletionMode[FILE_PIPE_CLIENT_END] = FILE_PIPE_QUEUE_OPERATION;
|
||||
Ccb->NamedPipeState = FILE_PIPE_CONNECTED_STATE;
|
||||
Ccb->ClientFileObject = FileObject;
|
||||
Ccb->FileObject[FILE_PIPE_CLIENT_END] = FileObject;
|
||||
|
||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, FALSE);
|
||||
|
||||
|
@ -97,56 +97,57 @@ NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
case FILE_PIPE_CONNECTED_STATE:
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
|
||||
|
||||
while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
while ( Ccb->OutQueue.QueueState != Empty)
|
||||
while (Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->OutQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CLOSING_STATE:
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
|
||||
while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(Ccb->OutQueue.QueueState == Empty);
|
||||
ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);
|
||||
|
||||
NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
|
||||
NonPagedCcb->EventBufferClient = NULL;
|
||||
NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END] = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
if ( Ccb->ClientSession )
|
||||
if (Ccb->ClientSession)
|
||||
{
|
||||
ExFreePool(Ccb->ClientSession);
|
||||
Ccb->ClientSession = NULL;
|
||||
|
@ -188,14 +189,14 @@ NpSetListeningPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
case FILE_PIPE_LISTENING_STATE:
|
||||
|
||||
if ( Ccb->ServerCompletionMode == FILE_PIPE_COMPLETE_OPERATION)
|
||||
if (Ccb->CompletionMode[FILE_PIPE_SERVER_END] == FILE_PIPE_COMPLETE_OPERATION)
|
||||
{
|
||||
Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
|
||||
return STATUS_PIPE_LISTENING;
|
||||
}
|
||||
|
||||
IoSetCancelRoutine(Irp, NpCancelListeningQueueIrp);
|
||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
return STATUS_CANCELLED;
|
||||
}
|
||||
|
@ -266,37 +267,37 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = NULL;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||
|
||||
NpDeleteCcb(Ccb, List);
|
||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
||||
if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CLOSING_STATE:
|
||||
|
||||
if ( NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
DataQueue = &Ccb->InQueue;
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
DataQueue = &Ccb->OutQueue;
|
||||
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = NULL;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = NULL;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
while (DataQueue->QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
|
@ -305,42 +306,43 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
|||
|
||||
NpUninitializeSecurity(Ccb);
|
||||
|
||||
if ( Ccb->ClientSession )
|
||||
if (Ccb->ClientSession)
|
||||
{
|
||||
ExFreePool(Ccb->ClientSession);
|
||||
Ccb->ClientSession = 0;
|
||||
Ccb->ClientSession = NULL;
|
||||
}
|
||||
|
||||
NpDeleteCcb(Ccb, List);
|
||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
||||
if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
|
||||
break;
|
||||
|
||||
case FILE_PIPE_CONNECTED_STATE:
|
||||
if ( NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ReadQueue = &Ccb->InQueue;
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
|
||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
||||
Ccb->ServerFileObject = 0;
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadQueue = &Ccb->OutQueue;
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
|
||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
||||
Ccb->ClientFileObject = 0;
|
||||
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||
}
|
||||
|
||||
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||
|
||||
Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;
|
||||
|
||||
while (Ccb->InQueue.QueueState != Empty)
|
||||
while (ReadQueue->QueueState != Empty)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
Irp = NpRemoveDataQueueEntry(ReadQueue, FALSE, List);
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
|
@ -350,18 +352,18 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
|||
while (WriteQueue->QueueState == WriteEntries)
|
||||
{
|
||||
Irp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
|
||||
if ( Irp )
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
KeBugCheckEx(0x25u, 0x1602F9, Ccb->NamedPipeState, 0, 0);
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x1602F9, Ccb->NamedPipeState, 0, 0);
|
||||
break;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -62,7 +62,7 @@ NpDeleteFcb(IN PNP_FCB Fcb,
|
|||
|
||||
RemoveEntryList(&Fcb->DcbEntry);
|
||||
|
||||
if ( Fcb->SecurityDescriptor )
|
||||
if (Fcb->SecurityDescriptor)
|
||||
{
|
||||
ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1);
|
||||
}
|
||||
|
@ -82,28 +82,28 @@ NpDeleteCcb(IN PNP_CCB Ccb,
|
|||
PAGED_CODE();
|
||||
|
||||
RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb;
|
||||
if ( Ccb->NodeType == NPFS_NTC_CCB )
|
||||
if (Ccb->NodeType == NPFS_NTC_CCB)
|
||||
{
|
||||
RemoveEntryList(&Ccb->CcbEntry);
|
||||
--Ccb->Fcb->CurrentInstances;
|
||||
|
||||
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
||||
Ccb->NonPagedCcb->EventBufferClient);
|
||||
Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END]);
|
||||
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
||||
Ccb->NonPagedCcb->EventBufferServer);
|
||||
NpUninitializeDataQueue(&Ccb->InQueue);
|
||||
NpUninitializeDataQueue(&Ccb->OutQueue);
|
||||
NpCheckForNotify(Ccb->Fcb->ParentDcb, 0, ListEntry);
|
||||
Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_SERVER_END]);
|
||||
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
|
||||
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND]);
|
||||
NpCheckForNotify(Ccb->Fcb->ParentDcb, FALSE, ListEntry);
|
||||
ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
NpUninitializeSecurity(Ccb);
|
||||
if ( Ccb->ClientSession )
|
||||
if (Ccb->ClientSession)
|
||||
{
|
||||
ExFreePool(Ccb->ClientSession);
|
||||
Ccb->ClientSession = 0;
|
||||
Ccb->ClientSession = NULL;
|
||||
}
|
||||
ExFreePool(Ccb->NonPagedCcb);
|
||||
}
|
||||
else if ( RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown)
|
||||
else if (RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown)
|
||||
{
|
||||
ExFreePool(RootDcbCcb->Unknown);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB* NewRootCcb)
|
|||
PNP_ROOT_DCB_FCB RootCcb;
|
||||
PAGED_CODE();
|
||||
|
||||
RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), 'CFpN');
|
||||
RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), NPFS_ROOT_DCB_CCB_TAG);
|
||||
if (!RootCcb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlZeroMemory(RootCcb, sizeof(*RootCcb));
|
||||
|
@ -155,10 +155,10 @@ NpCreateRootDcb(VOID)
|
|||
|
||||
if (NpVcb->RootDcb)
|
||||
{
|
||||
KeBugCheckEx(0x25, 0x1700F3, 0, 0, 0);
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x1700F3, 0, 0, 0);
|
||||
}
|
||||
|
||||
NpVcb->RootDcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Dcb), 'DFpN');
|
||||
NpVcb->RootDcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Dcb), NPFS_DCB_TAG);
|
||||
if (!NpVcb->RootDcb)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -185,7 +185,7 @@ NpCreateRootDcb(VOID)
|
|||
&Dcb->FullName,
|
||||
&Dcb->PrefixTableEntry))
|
||||
{
|
||||
KeBugCheckEx(0x25u, 0x170128, 0, 0, 0);
|
||||
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x170128, 0, 0, 0);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -224,7 +224,7 @@ NpCreateFcb(IN PNP_DCB Dcb,
|
|||
PipeNameLength += sizeof(WCHAR);
|
||||
}
|
||||
|
||||
Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), 'FfpN');
|
||||
Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), NPFS_FCB_TAG);
|
||||
if (!Fcb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlZeroMemory(Fcb, sizeof(*Fcb));
|
||||
|
@ -236,7 +236,7 @@ NpCreateFcb(IN PNP_DCB Dcb,
|
|||
|
||||
NameBuffer = ExAllocatePoolWithTag(PagedPool,
|
||||
PipeName->Length + (RootPipe ? 4 : 2),
|
||||
'nFpN');
|
||||
NPFS_NAME_BLOCK_TAG);
|
||||
if (!NameBuffer)
|
||||
{
|
||||
ExFreePool(Fcb);
|
||||
|
@ -292,10 +292,10 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
|||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), 'cFpN');
|
||||
Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), NPFS_CCB_TAG);
|
||||
if (!Ccb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), 'cFpN');
|
||||
CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), NPFS_CCB_TAG);
|
||||
if (!CcbNonPaged)
|
||||
{
|
||||
ExFreePool(Ccb);
|
||||
|
@ -308,13 +308,13 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
|||
RtlZeroMemory(Ccb, sizeof(*Ccb));
|
||||
Ccb->NodeType = NPFS_NTC_CCB;
|
||||
Ccb->NonPagedCcb = CcbNonPaged;
|
||||
Ccb->ServerFileObject = FileObject;
|
||||
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||
Ccb->Fcb = Fcb;
|
||||
Ccb->NamedPipeState = State;
|
||||
Ccb->ServerReadMode = ReadMode;
|
||||
Ccb->ServerCompletionMode = CompletionMode;
|
||||
Ccb->ReadMode[FILE_PIPE_SERVER_END] = ReadMode;
|
||||
Ccb->CompletionMode[FILE_PIPE_SERVER_END] = CompletionMode;
|
||||
|
||||
Status = NpInitializeDataQueue(&Ccb->InQueue, InQuota);
|
||||
Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND], InQuota);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(CcbNonPaged);
|
||||
|
@ -322,10 +322,10 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = NpInitializeDataQueue(&Ccb->OutQueue, InQuota);
|
||||
Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], OutQuota);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
NpUninitializeDataQueue(&Ccb->InQueue);
|
||||
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
|
||||
ExFreePool(CcbNonPaged);
|
||||
ExFreePool(Ccb);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
|
188
reactos/drivers/filesystems/npfs_new/volinfo.c
Normal file
188
reactos/drivers/filesystems/npfs_new/volinfo.c
Normal file
|
@ -0,0 +1,188 @@
|
|||
#include "npfs.h"
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryFsVolumeInfo(IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_VOLUME_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
USHORT NameLength;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
InfoBuffer->VolumeCreationTime.LowPart = 0;
|
||||
InfoBuffer->VolumeCreationTime.HighPart = 0;
|
||||
InfoBuffer->VolumeSerialNumber = 0;
|
||||
InfoBuffer->SupportsObjects = 0;
|
||||
|
||||
NameLength = 18;
|
||||
InfoBuffer->VolumeLabelLength = 18;
|
||||
|
||||
if (NameLength < 18)
|
||||
{
|
||||
NameLength = *Length;
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlCopyMemory(InfoBuffer->VolumeLabel, L"Named Pipe", NameLength);
|
||||
*Length -= NameLength;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryFsSizeInfo(IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_SIZE_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
InfoBuffer->TotalAllocationUnits.QuadPart = 0;
|
||||
InfoBuffer->AvailableAllocationUnits.QuadPart = 0;
|
||||
InfoBuffer->SectorsPerAllocationUnit = 1;
|
||||
InfoBuffer->BytesPerSector = 1;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryFsDeviceInfo(IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_DEVICE_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (*Length >= sizeof(*InfoBuffer))
|
||||
{
|
||||
InfoBuffer->DeviceType = 0;
|
||||
InfoBuffer->Characteristics = 0;
|
||||
InfoBuffer->DeviceType = FILE_DEVICE_NAMED_PIPE;
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryFsAttributeInfo(IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_ATTRIBUTE_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
USHORT NameLength;
|
||||
|
||||
NameLength = *Length - 12;
|
||||
if (NameLength < 8)
|
||||
{
|
||||
*Length = 0;
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Length -= 20;
|
||||
NameLength = 8;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
InfoBuffer->MaximumComponentNameLength = 0xFFFFFFFF;
|
||||
InfoBuffer->FileSystemNameLength = 8;
|
||||
InfoBuffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
||||
RtlCopyMemory(InfoBuffer->FileSystemName, L"NPFS", NameLength);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpQueryFsFullSizeInfo(IN PVOID Buffer,
|
||||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_FULL_SIZE_INFORMATION InfoBuffer = Buffer;
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpCommonQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
FILE_INFORMATION_CLASS InfoClass;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
Length = IoStack->Parameters.QueryVolume.Length;
|
||||
InfoClass = IoStack->Parameters.QueryVolume.FsInformationClass;
|
||||
|
||||
switch (InfoClass)
|
||||
{
|
||||
case FileFsVolumeInformation:
|
||||
Status = NpQueryFsVolumeInfo(Buffer, &Length);
|
||||
break;
|
||||
case FileFsSizeInformation:
|
||||
Status = NpQueryFsSizeInfo(Buffer, &Length);
|
||||
break;
|
||||
case FileFsDeviceInformation:
|
||||
Status = NpQueryFsDeviceInfo(Buffer, &Length);
|
||||
break;
|
||||
case FileFsAttributeInformation:
|
||||
Status = NpQueryFsAttributeInfo(Buffer, &Length);
|
||||
break;
|
||||
case FileFsFullSizeInformation:
|
||||
Status = NpQueryFsFullSizeInfo(Buffer, &Length);
|
||||
break;
|
||||
default:
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = IoStack->Parameters.QueryVolume.Length - Length;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
||||
Status = NpCommonQueryVolumeInformation(DeviceObject, Irp);
|
||||
|
||||
ExReleaseResourceLite(&NpVcb->Lock);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -16,10 +16,10 @@ NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
|
||||
|
||||
WaitEntry = (PNP_WAIT_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[1];
|
||||
if ( WaitEntry )
|
||||
if (WaitEntry)
|
||||
{
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
if ( !KeCancelTimer(&WaitEntry->Timer) )
|
||||
if (!KeCancelTimer(&WaitEntry->Timer))
|
||||
{
|
||||
WaitEntry->Irp = NULL;
|
||||
WaitEntry = NULL;
|
||||
|
@ -28,7 +28,7 @@ NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||
|
||||
if ( WaitEntry )
|
||||
if (WaitEntry)
|
||||
{
|
||||
ObfDereferenceObject(WaitEntry->FileObject);
|
||||
ExFreePool(WaitEntry);
|
||||
|
@ -36,7 +36,7 @@ NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -52,23 +52,23 @@ NpTimerDispatch(IN PKDPC Dpc,
|
|||
|
||||
OldIrql = KfAcquireSpinLock(&WaitEntry->WaitQueue->WaitLock);
|
||||
Irp = WaitEntry->Irp;
|
||||
if ( Irp);
|
||||
if (Irp)
|
||||
{
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
if ( !IoSetCancelRoutine(Irp, NULL))
|
||||
if (!IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Irp->Tail.Overlay.DriverContext[1] = NULL;
|
||||
Irp = NULL;
|
||||
}
|
||||
}
|
||||
KfReleaseSpinLock(&WaitEntry->WaitQueue->WaitLock, OldIrql);
|
||||
if ( Irp )
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
ObfDereferenceObject(WaitEntry->FileObject);
|
||||
ExFreePoolWithTag(WaitEntry, 0);
|
||||
ExFreePool(WaitEntry);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -90,7 +90,7 @@ NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
KIRQL OldIrql;
|
||||
PWCHAR Buffer;
|
||||
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length,'tFpN');
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length, NPFS_WAIT_BLOCK_TAG);
|
||||
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length);
|
||||
|
@ -122,13 +122,13 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), 'wFpN');
|
||||
if ( WaitEntry )
|
||||
WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), NPFS_WRITE_BLOCK_TAG);
|
||||
if (WaitEntry)
|
||||
{
|
||||
KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
|
||||
KeInitializeTimer(&WaitEntry->Timer);
|
||||
|
||||
if ( Name )
|
||||
if (Name)
|
||||
{
|
||||
WaitEntry->String = *Name;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
WaitEntry->Irp = Irp;
|
||||
|
||||
WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||
if ( WaitBuffer->TimeoutSpecified )
|
||||
if (WaitBuffer->TimeoutSpecified)
|
||||
{
|
||||
DueTime = WaitBuffer->Timeout;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
|
||||
IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
|
||||
|
||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
Status = STATUS_CANCELLED;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
|
||||
}
|
||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||
if ( WaitEntry ) ExFreePool(WaitEntry);
|
||||
if (WaitEntry) ExFreePool(WaitEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -13,17 +13,17 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
|||
IN PLIST_ENTRY List)
|
||||
{
|
||||
NODE_TYPE_CODE NodeType;
|
||||
BOOLEAN WriteOk, ServerSide;
|
||||
BOOLEAN WriteOk;
|
||||
PNP_CCB Ccb;
|
||||
PNP_NONPAGED_CCB NonPagedCcb;
|
||||
PNP_DATA_QUEUE WriteQueue;
|
||||
NTSTATUS Status;
|
||||
PNP_EVENT_BUFFER EventBuffer;
|
||||
ULONG BytesWritten;
|
||||
ULONG BytesWritten, NamedPipeEnd;
|
||||
PAGED_CODE();
|
||||
|
||||
IoStatus->Information = 0;
|
||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
|
||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||
|
||||
if (!NodeType)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if ( NodeType != NPFS_NTC_CCB )
|
||||
if (NodeType != NPFS_NTC_CCB)
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
return TRUE;
|
||||
|
@ -40,16 +40,14 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
|||
NonPagedCcb = Ccb->NonPagedCcb;
|
||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
||||
|
||||
// ms_exc.registration.TryLevel = 0;
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE )
|
||||
if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE)
|
||||
{
|
||||
IoStatus->Status = STATUS_PIPE_DISCONNECTED;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if ( Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE || Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE )
|
||||
if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE || Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE)
|
||||
{
|
||||
IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_LISTENING_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_CLOSING;
|
||||
WriteOk = TRUE;
|
||||
|
@ -58,84 +56,79 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
|||
|
||||
ASSERT(Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE);
|
||||
|
||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
|
||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
|
||||
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
|
||||
(NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
|
||||
{
|
||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
IoStatus->Status = 0;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = DataSize;
|
||||
|
||||
if ( ServerSide == 1 )
|
||||
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||
{
|
||||
WriteQueue = &Ccb->OutQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteQueue = &Ccb->InQueue;
|
||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
||||
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||
}
|
||||
|
||||
if (WriteQueue->QueueState != ReadEntries ||
|
||||
WriteQueue->BytesInQueue >= DataSize ||
|
||||
WriteQueue->Quota >= DataSize - WriteQueue->BytesInQueue )
|
||||
{
|
||||
if (WriteQueue->QueueState != ReadEntries ||
|
||||
WriteQueue->Quota - WriteQueue->QuotaUsed >= DataSize )
|
||||
{
|
||||
goto DoWrite;
|
||||
}
|
||||
}
|
||||
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||
|
||||
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE &&
|
||||
Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION)
|
||||
if ((WriteQueue->QueueState == ReadEntries &&
|
||||
WriteQueue->BytesInQueue < DataSize &&
|
||||
WriteQueue->Quota < DataSize - WriteQueue->BytesInQueue) ||
|
||||
(WriteQueue->QueueState == ReadEntries &&
|
||||
WriteQueue->Quota - WriteQueue->QuotaUsed < DataSize))
|
||||
{
|
||||
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE &&
|
||||
Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = 0;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
WriteOk = TRUE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
if (!Irp )
|
||||
if (!Irp)
|
||||
{
|
||||
WriteOk = 0;
|
||||
WriteOk = FALSE;
|
||||
goto Quickie;
|
||||
}
|
||||
}
|
||||
|
||||
DoWrite:
|
||||
Status = NpWriteDataQueue(WriteQueue,
|
||||
ServerSide ? Ccb->ClientReadMode : Ccb->ServerReadMode,
|
||||
Ccb->ReadMode[NamedPipeEnd],
|
||||
Buffer,
|
||||
DataSize,
|
||||
Ccb->Fcb->NamedPipeType,
|
||||
&BytesWritten,
|
||||
Ccb,
|
||||
ServerSide,
|
||||
NamedPipeEnd,
|
||||
Thread,
|
||||
List);
|
||||
IoStatus->Status = Status;
|
||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
||||
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
if ( (Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION || !Irp)
|
||||
&& WriteQueue->Quota - WriteQueue->QuotaUsed < BytesWritten )
|
||||
if ((Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION || !Irp)
|
||||
&& WriteQueue->Quota - WriteQueue->QuotaUsed < BytesWritten)
|
||||
{
|
||||
IoStatus->Information = DataSize - BytesWritten;
|
||||
IoStatus->Status = 0;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
|
||||
IoStatus->Status = NpAddDataQueueEntry(ServerSide,
|
||||
IoStatus->Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||
Ccb,
|
||||
WriteQueue,
|
||||
WriteEntries,
|
||||
0,
|
||||
Buffered,
|
||||
DataSize,
|
||||
Irp,
|
||||
Buffer,
|
||||
|
@ -143,11 +136,10 @@ DoWrite:
|
|||
}
|
||||
}
|
||||
|
||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
||||
WriteOk = 1;
|
||||
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||
WriteOk = TRUE;
|
||||
|
||||
Quickie:
|
||||
//ms_exc.registration.TryLevel = -1;
|
||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||
return WriteOk;
|
||||
}
|
||||
|
@ -192,7 +184,7 @@ NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
if ( IoStatus.Status != STATUS_PENDING )
|
||||
if (IoStatus.Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Information = IoStatus.Information;
|
||||
Irp->IoStatus.Status = IoStatus.Status;
|
||||
|
|
|
@ -9,7 +9,7 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN BOOLEAN ServerSide,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PETHREAD Thread,
|
||||
IN PLIST_ENTRY List)
|
||||
{
|
||||
|
@ -25,8 +25,11 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
|
||||
*BytesWritten = OutBufferSize;
|
||||
|
||||
MoreProcessing = 1;
|
||||
if ( PipeType != FILE_PIPE_OUTBOUND || (OutBufferSize) ) MoreProcessing = 0;
|
||||
MoreProcessing = TRUE;
|
||||
if ((PipeType != FILE_PIPE_MESSAGE_MODE) || (OutBufferSize))
|
||||
{
|
||||
MoreProcessing = FALSE;
|
||||
}
|
||||
|
||||
for (DataEntry = NpGetNextRealDataQueueEntry(WriteQueue, List);
|
||||
((WriteQueue->QueueState == ReadEntries) &&
|
||||
|
@ -37,12 +40,12 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
|
||||
IoStack = IoGetCurrentIrpStackLocation( DataEntry->Irp);
|
||||
|
||||
if ( IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
||||
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_WRITE &&
|
||||
(DataSize < OutBufferSize || MoreProcessing) )
|
||||
if (IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
||||
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_READ_OVFLOW &&
|
||||
(DataSize < OutBufferSize || MoreProcessing))
|
||||
{
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
||||
if (WriteIrp )
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
||||
if (WriteIrp)
|
||||
{
|
||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
|
@ -50,24 +53,24 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( DataEntry->DataEntryType == Unbuffered )
|
||||
if (DataEntry->DataEntryType == Unbuffered)
|
||||
{
|
||||
DataEntry->Irp->Overlay.AllocationSize.QuadPart = 0;
|
||||
}
|
||||
|
||||
BufferSize = *BytesWritten;
|
||||
if ( BufferSize >= DataSize ) BufferSize = DataSize;
|
||||
if (BufferSize >= DataSize) BufferSize = DataSize;
|
||||
|
||||
if ( DataEntry->DataEntryType != Unbuffered && BufferSize )
|
||||
if (DataEntry->DataEntryType != Unbuffered && BufferSize)
|
||||
{
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, 'RFpN');
|
||||
if ( !Buffer ) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
AllocatedBuffer = 1;
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, NPFS_DATA_ENTRY_TAG);
|
||||
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
AllocatedBuffer = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
||||
AllocatedBuffer = 0;
|
||||
AllocatedBuffer = FALSE;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
|
@ -78,65 +81,66 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
if (AllocatedBuffer) ExFreePool(Buffer);
|
||||
return _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if ( !HaveContext )
|
||||
if (!HaveContext)
|
||||
{
|
||||
HaveContext = 1;
|
||||
Status = NpGetClientSecurityContext(ServerSide, Ccb, Thread, &ClientContext);
|
||||
HaveContext = TRUE;
|
||||
Status = NpGetClientSecurityContext(NamedPipeEnd, Ccb, Thread, &ClientContext);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if ( AllocatedBuffer ) ExFreePool(Buffer);
|
||||
if (AllocatedBuffer) ExFreePool(Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ( ClientContext )
|
||||
if (ClientContext)
|
||||
{
|
||||
NpFreeClientSecurityContext(Ccb->ClientContext);
|
||||
Ccb->ClientContext = ClientContext;
|
||||
}
|
||||
}
|
||||
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
||||
if ( WriteIrp )
|
||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
||||
if (WriteIrp)
|
||||
{
|
||||
*BytesWritten -= BufferSize;
|
||||
WriteIrp->IoStatus.Information = BufferSize;
|
||||
|
||||
if ( AllocatedBuffer )
|
||||
if (AllocatedBuffer)
|
||||
{
|
||||
WriteIrp->AssociatedIrp.SystemBuffer = Buffer;
|
||||
WriteIrp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
|
||||
}
|
||||
|
||||
if ( !*BytesWritten )
|
||||
if (!*BytesWritten)
|
||||
{
|
||||
MoreProcessing = 0;
|
||||
WriteIrp->IoStatus.Status = 0;
|
||||
MoreProcessing = FALSE;
|
||||
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
||||
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteIrp->IoStatus.Status = 0;
|
||||
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
else if ( AllocatedBuffer )
|
||||
else if (AllocatedBuffer)
|
||||
{
|
||||
ExFreePool(Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if ( *BytesWritten > 0 || MoreProcessing )
|
||||
if (*BytesWritten > 0 || MoreProcessing)
|
||||
{
|
||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
||||
|
|
Loading…
Reference in a new issue