mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 00:12:57 +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
|
read.c
|
||||||
readsup.c
|
readsup.c
|
||||||
secursup.c
|
secursup.c
|
||||||
|
seinfo.c
|
||||||
statesup.c
|
statesup.c
|
||||||
strucsup.c
|
strucsup.c
|
||||||
|
volinfo.c
|
||||||
waitsup.c
|
waitsup.c
|
||||||
write.c
|
write.c
|
||||||
writesup.c)
|
writesup.c)
|
||||||
|
|
|
@ -10,7 +10,7 @@ NpCommonCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||||
LIST_ENTRY List;
|
LIST_ENTRY List;
|
||||||
PNP_FCB Fcb;
|
PNP_FCB Fcb;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PLIST_ENTRY ThisEntry, NextEntry;
|
PLIST_ENTRY ThisEntry, NextEntry;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -21,16 +21,16 @@ NpCommonCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||||
(PVOID*)&Fcb,
|
(PVOID*)&Fcb,
|
||||||
&Ccb,
|
&Ccb,
|
||||||
&ServerSide);
|
&NamedPipeEnd);
|
||||||
if (NodeTypeCode == NPFS_NTC_CCB )
|
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
if ( ServerSide == 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
ASSERT(Ccb->Fcb->ServerOpenCount != 0);
|
ASSERT(Ccb->Fcb->ServerOpenCount != 0);
|
||||||
--Ccb->Fcb->ServerOpenCount;
|
--Ccb->Fcb->ServerOpenCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpSetClosingPipeState(Ccb, Irp, ServerSide, &List);
|
NpSetClosingPipeState(Ccb, Irp, NamedPipeEnd, &List);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseResourceLite(&NpVcb->Lock);
|
ExReleaseResourceLite(&NpVcb->Lock);
|
||||||
|
@ -62,7 +62,7 @@ NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( Status != STATUS_PENDING )
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
|
|
|
@ -10,7 +10,7 @@ NpCommonClose(IN PDEVICE_OBJECT DeviceObject,
|
||||||
LIST_ENTRY List;
|
LIST_ENTRY List;
|
||||||
PNP_FCB Fcb;
|
PNP_FCB Fcb;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PLIST_ENTRY ThisEntry, NextEntry;
|
PLIST_ENTRY ThisEntry, NextEntry;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ NpCommonClose(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||||
(PVOID*)&Fcb,
|
(PVOID*)&Fcb,
|
||||||
&Ccb,
|
&Ccb,
|
||||||
&ServerSide);
|
&NamedPipeEnd);
|
||||||
if (NodeTypeCode == NPFS_NTC_ROOT_DCB)
|
if (NodeTypeCode == NPFS_NTC_ROOT_DCB)
|
||||||
{
|
{
|
||||||
--Fcb->CurrentInstances;
|
--Fcb->CurrentInstances;
|
||||||
|
|
|
@ -400,15 +400,15 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
||||||
&AccessState->GenerateOnClose);
|
&AccessState->GenerateOnClose);
|
||||||
|
|
||||||
SeUnlockSubjectContext(SubjectSecurityContext);
|
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;
|
IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
|
||||||
return IoStatus;
|
return IoStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Disposition == FILE_CREATE )
|
if (Disposition == FILE_CREATE)
|
||||||
{
|
{
|
||||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||||
return IoStatus;
|
return IoStatus;
|
||||||
|
@ -428,7 +428,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
||||||
CheckShareAccess = FILE_SHARE_WRITE;
|
CheckShareAccess = FILE_SHARE_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( CheckShareAccess != ShareAccess )
|
if (CheckShareAccess != ShareAccess)
|
||||||
{
|
{
|
||||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||||
return IoStatus;
|
return IoStatus;
|
||||||
|
@ -456,7 +456,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
||||||
}
|
}
|
||||||
|
|
||||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
||||||
Ccb->ServerFileObject = FileObject;
|
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||||
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
||||||
|
|
||||||
IoStatus.Status = STATUS_SUCCESS;
|
IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
@ -518,7 +518,7 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !Parameters->NamedPipeType && Parameters->ReadMode == 1 )
|
if (!Parameters->NamedPipeType && Parameters->ReadMode == 1)
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -580,11 +580,11 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
||||||
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
|
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
|
||||||
|
|
||||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
|
||||||
Ccb->ServerFileObject = FileObject;
|
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||||
|
|
||||||
NpCheckForNotify(Dcb, 1, List);
|
NpCheckForNotify(Dcb, 1, List);
|
||||||
|
|
||||||
IoStatus->Status = 0;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
IoStatus->Information = 2;
|
IoStatus->Information = 2;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
DPRINT1("FileName %wZ\n", &FileObject->FileName);
|
DPRINT1("FileName %wZ\n", &FileObject->FileName);
|
||||||
DPRINT1("FileName->Length: %hu RelatedFileObject: %p\n", FileName.Length, RelatedFileObject);
|
DPRINT1("FileName->Length: %hu RelatedFileObject: %p\n", FileName.Length, RelatedFileObject);
|
||||||
|
|
||||||
if ( RelatedFileObject )
|
if (RelatedFileObject)
|
||||||
{
|
{
|
||||||
Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1);
|
Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1);
|
||||||
if (!(Fcb) ||
|
if (!(Fcb) ||
|
||||||
|
@ -659,7 +659,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( FileName.Length <= 2u || *FileName.Buffer != '\\' )
|
if (FileName.Length <= 2u || *FileName.Buffer != '\\')
|
||||||
{
|
{
|
||||||
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -667,9 +667,9 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Fcb = NpFindPrefix(&FileName, 1u, &Prefix);
|
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,
|
IoStatus.Status = NpCreateNewNamedPipe((PNP_DCB)Fcb,
|
||||||
FileObject,
|
FileObject,
|
||||||
|
@ -692,7 +692,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Fcb->NodeType != NPFS_NTC_FCB )
|
if (Fcb->NodeType != NPFS_NTC_FCB)
|
||||||
{
|
{
|
||||||
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
|
|
@ -45,7 +45,7 @@ NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
|
||||||
NextEntry = DataQueue->Queue.Flink;
|
NextEntry = DataQueue->Queue.Flink;
|
||||||
while (NextEntry != &DataQueue->Queue)
|
while (NextEntry != &DataQueue->Queue)
|
||||||
{
|
{
|
||||||
if ( !QuotaLeft ) break;
|
if (!QuotaLeft) break;
|
||||||
|
|
||||||
DataQueueEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, Irp);
|
DataQueueEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, Irp);
|
||||||
|
|
||||||
|
@ -55,10 +55,10 @@ NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
|
||||||
{
|
{
|
||||||
DataLeft = DataQueueEntry->DataSize - ByteOffset;
|
DataLeft = DataQueueEntry->DataSize - ByteOffset;
|
||||||
|
|
||||||
if ( DataQueueEntry->QuotaInEntry < DataLeft )
|
if (DataQueueEntry->QuotaInEntry < DataLeft)
|
||||||
{
|
{
|
||||||
NewQuotaLeft = DataLeft - DataQueueEntry->QuotaInEntry;
|
NewQuotaLeft = DataLeft - DataQueueEntry->QuotaInEntry;
|
||||||
if ( NewQuotaLeft > QuotaLeft ) NewQuotaLeft = QuotaLeft;
|
if (NewQuotaLeft > QuotaLeft) NewQuotaLeft = QuotaLeft;
|
||||||
|
|
||||||
QuotaLeft -= NewQuotaLeft;
|
QuotaLeft -= NewQuotaLeft;
|
||||||
DataQueueEntry->QuotaInEntry += NewQuotaLeft;
|
DataQueueEntry->QuotaInEntry += NewQuotaLeft;
|
||||||
|
@ -93,7 +93,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
||||||
PNP_DATA_QUEUE_ENTRY QueueEntry;
|
PNP_DATA_QUEUE_ENTRY QueueEntry;
|
||||||
BOOLEAN HasWrites;
|
BOOLEAN HasWrites;
|
||||||
|
|
||||||
if ( DataQueue->QueueState == Empty)
|
if (DataQueue->QueueState == Empty)
|
||||||
{
|
{
|
||||||
Irp = NULL;
|
Irp = NULL;
|
||||||
ASSERT(IsListEmpty(&DataQueue->Queue));
|
ASSERT(IsListEmpty(&DataQueue->Queue));
|
||||||
|
@ -111,7 +111,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
||||||
--DataQueue->EntriesInQueue;
|
--DataQueue->EntriesInQueue;
|
||||||
|
|
||||||
HasWrites = 1;
|
HasWrites = 1;
|
||||||
if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !QueueEntry->QuotaInEntry )
|
if (!DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !QueueEntry->QuotaInEntry)
|
||||||
{
|
{
|
||||||
HasWrites = 0;
|
HasWrites = 0;
|
||||||
}
|
}
|
||||||
|
@ -134,12 +134,12 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
||||||
|
|
||||||
ExFreePool(QueueEntry);
|
ExFreePool(QueueEntry);
|
||||||
|
|
||||||
if ( Flag )
|
if (Flag)
|
||||||
{
|
{
|
||||||
NpGetNextRealDataQueueEntry(DataQueue, List);
|
NpGetNextRealDataQueueEntry(DataQueue, List);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( HasWrites )
|
if (HasWrites)
|
||||||
{
|
{
|
||||||
NpCompleteStalledWrites(DataQueue, List);
|
NpCompleteStalledWrites(DataQueue, List);
|
||||||
}
|
}
|
||||||
|
@ -168,10 +168,10 @@ NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
||||||
DataEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, QueueEntry);
|
DataEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, QueueEntry);
|
||||||
|
|
||||||
Type = DataEntry->DataEntryType;
|
Type = DataEntry->DataEntryType;
|
||||||
if ( Type == Buffered || Type == Unbuffered ) break;
|
if (Type == Buffered || Type == Unbuffered) break;
|
||||||
|
|
||||||
Irp = NpRemoveDataQueueEntry(DataQueue, 0, List);
|
Irp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
@ -193,23 +193,23 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
BOOLEAN CompleteWrites, FirstEntry;
|
BOOLEAN CompleteWrites, FirstEntry;
|
||||||
PLIST_ENTRY NextEntry, ThisEntry;
|
PLIST_ENTRY NextEntry, ThisEntry;
|
||||||
|
|
||||||
if ( DeviceObject ) IoReleaseCancelSpinLock(Irp->CancelIrql);
|
if (DeviceObject) IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
|
||||||
InitializeListHead(&List);
|
InitializeListHead(&List);
|
||||||
|
|
||||||
DataQueue = (PNP_DATA_QUEUE)Irp->Tail.Overlay.DriverContext[2];
|
DataQueue = (PNP_DATA_QUEUE)Irp->Tail.Overlay.DriverContext[2];
|
||||||
ClientSecurityContext = NULL;
|
ClientSecurityContext = NULL;
|
||||||
|
|
||||||
if ( DeviceObject )
|
if (DeviceObject)
|
||||||
{
|
{
|
||||||
FsRtlEnterFileSystem();
|
FsRtlEnterFileSystem();
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataEntry = (PNP_DATA_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[3];
|
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;
|
DataQueue->ByteOffset = 0;
|
||||||
FirstEntry = 1;
|
FirstEntry = 1;
|
||||||
|
@ -224,7 +224,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
ClientSecurityContext = DataEntry->ClientSecurityContext;
|
ClientSecurityContext = DataEntry->ClientSecurityContext;
|
||||||
|
|
||||||
CompleteWrites = 1;
|
CompleteWrites = 1;
|
||||||
if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !DataEntry->QuotaInEntry )
|
if (!DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed < DataQueue->Quota || !DataEntry->QuotaInEntry)
|
||||||
{
|
{
|
||||||
CompleteWrites = 0;
|
CompleteWrites = 0;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
DataQueue->QuotaUsed -= DataEntry->QuotaInEntry;
|
DataQueue->QuotaUsed -= DataEntry->QuotaInEntry;
|
||||||
--DataQueue->EntriesInQueue;
|
--DataQueue->EntriesInQueue;
|
||||||
|
|
||||||
if (DataQueue->Queue.Flink == &DataQueue->Queue )
|
if (DataQueue->Queue.Flink == &DataQueue->Queue)
|
||||||
{
|
{
|
||||||
DataQueue->QueueState = Empty;
|
DataQueue->QueueState = Empty;
|
||||||
ASSERT(DataQueue->BytesInQueue == 0);
|
ASSERT(DataQueue->BytesInQueue == 0);
|
||||||
|
@ -242,28 +242,28 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( FirstEntry )
|
if (FirstEntry)
|
||||||
{
|
{
|
||||||
NpGetNextRealDataQueueEntry(DataQueue, &List);
|
NpGetNextRealDataQueueEntry(DataQueue, &List);
|
||||||
}
|
}
|
||||||
if ( CompleteWrites )
|
if (CompleteWrites)
|
||||||
{
|
{
|
||||||
NpCompleteStalledWrites(DataQueue, &List);
|
NpCompleteStalledWrites(DataQueue, &List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( DeviceObject )
|
if (DeviceObject)
|
||||||
{
|
{
|
||||||
ExReleaseResourceLite(&NpVcb->Lock);
|
ExReleaseResourceLite(&NpVcb->Lock);
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( DataEntry ) ExFreePool(DataEntry);
|
if (DataEntry) ExFreePool(DataEntry);
|
||||||
|
|
||||||
NpFreeClientSecurityContext(ClientSecurityContext);
|
NpFreeClientSecurityContext(ClientSecurityContext);
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
IofCompleteRequest(Irp, IO_DISK_INCREMENT);
|
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
|
||||||
|
|
||||||
NextEntry = List.Flink;
|
NextEntry = List.Flink;
|
||||||
while (NextEntry != &List)
|
while (NextEntry != &List)
|
||||||
|
@ -278,7 +278,7 @@ NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN PNP_DATA_QUEUE DataQueue,
|
IN PNP_DATA_QUEUE DataQueue,
|
||||||
IN ULONG Who,
|
IN ULONG Who,
|
||||||
|
@ -302,7 +302,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
|
|
||||||
if ((Type != 2) && (Who == WriteEntries))
|
if ((Type != 2) && (Who == WriteEntries))
|
||||||
{
|
{
|
||||||
Status = NpGetClientSecurityContext(ServerSide,
|
Status = NpGetClientSecurityContext(NamedPipeEnd,
|
||||||
Ccb,
|
Ccb,
|
||||||
Irp ? Irp->Tail.Overlay.Thread :
|
Irp ? Irp->Tail.Overlay.Thread :
|
||||||
PsGetCurrentThread(),
|
PsGetCurrentThread(),
|
||||||
|
@ -317,8 +317,8 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
case 3:
|
case 3:
|
||||||
|
|
||||||
ASSERT(Irp != NULL);
|
ASSERT(Irp != NULL);
|
||||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*DataEntry), 'rFpN');
|
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*DataEntry), NPFS_DATA_ENTRY_TAG);
|
||||||
if ( DataEntry )
|
if (DataEntry)
|
||||||
{
|
{
|
||||||
DataEntry->DataEntryType = Type;
|
DataEntry->DataEntryType = Type;
|
||||||
DataEntry->QuotaInEntry = 0;
|
DataEntry->QuotaInEntry = 0;
|
||||||
|
@ -336,10 +336,10 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
case Buffered:
|
case Buffered:
|
||||||
|
|
||||||
EntrySize = sizeof(*DataEntry);
|
EntrySize = sizeof(*DataEntry);
|
||||||
if ( Who != Empty)
|
if (Who != Empty)
|
||||||
{
|
{
|
||||||
EntrySize = DataSize + sizeof(*DataEntry);
|
EntrySize = DataSize + sizeof(*DataEntry);
|
||||||
if ((DataSize + sizeof(*DataEntry)) < DataSize )
|
if ((DataSize + sizeof(*DataEntry)) < DataSize)
|
||||||
{
|
{
|
||||||
NpFreeClientSecurityContext(ClientContext);
|
NpFreeClientSecurityContext(ClientContext);
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -347,7 +347,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
}
|
}
|
||||||
|
|
||||||
QuotaInEntry = DataSize - ByteOffset;
|
QuotaInEntry = DataSize - ByteOffset;
|
||||||
if ( DataQueue->Quota - DataQueue->QuotaUsed < QuotaInEntry )
|
if (DataQueue->Quota - DataQueue->QuotaUsed < QuotaInEntry)
|
||||||
{
|
{
|
||||||
QuotaInEntry = DataQueue->Quota - DataQueue->QuotaUsed;
|
QuotaInEntry = DataQueue->Quota - DataQueue->QuotaUsed;
|
||||||
HasSpace = 1;
|
HasSpace = 1;
|
||||||
|
@ -357,8 +357,8 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
HasSpace = 0;
|
HasSpace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, EntrySize, 'rFpN');
|
DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, EntrySize, NPFS_DATA_ENTRY_TAG);
|
||||||
if ( !DataEntry )
|
if (!DataEntry)
|
||||||
{
|
{
|
||||||
NpFreeClientSecurityContext(ClientContext);
|
NpFreeClientSecurityContext(ClientContext);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -370,7 +370,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
DataEntry->ClientSecurityContext = ClientContext;
|
DataEntry->ClientSecurityContext = ClientContext;
|
||||||
DataEntry->DataSize = DataSize;
|
DataEntry->DataSize = DataSize;
|
||||||
|
|
||||||
if ( Who == ReadEntries)
|
if (Who == ReadEntries)
|
||||||
{
|
{
|
||||||
ASSERT(Irp);
|
ASSERT(Irp);
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
if ( HasSpace && Irp )
|
if (HasSpace && Irp)
|
||||||
{
|
{
|
||||||
Status = STATUS_PENDING;
|
Status = STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState == Who));
|
ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState == Who));
|
||||||
if ( DataQueue->QueueState == Empty )
|
if (DataQueue->QueueState == Empty)
|
||||||
{
|
{
|
||||||
ASSERT(DataQueue->BytesInQueue == 0);
|
ASSERT(DataQueue->BytesInQueue == 0);
|
||||||
ASSERT(DataQueue->EntriesInQueue == 0);
|
ASSERT(DataQueue->EntriesInQueue == 0);
|
||||||
|
@ -430,7 +430,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
DataQueue->QueueState = Who;
|
DataQueue->QueueState = Who;
|
||||||
DataQueue->BytesInQueue += DataEntry->DataSize;
|
DataQueue->BytesInQueue += DataEntry->DataSize;
|
||||||
++DataQueue->EntriesInQueue;
|
++DataQueue->EntriesInQueue;
|
||||||
if ( ByteOffset )
|
if (ByteOffset)
|
||||||
{
|
{
|
||||||
DataQueue->ByteOffset = ByteOffset;
|
DataQueue->ByteOffset = ByteOffset;
|
||||||
ASSERT(Who == WriteEntries);
|
ASSERT(Who == WriteEntries);
|
||||||
|
@ -440,7 +440,7 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
|
|
||||||
InsertTailList(&DataQueue->Queue, &DataEntry->QueueEntry);
|
InsertTailList(&DataQueue->Queue, &DataEntry->QueueEntry);
|
||||||
|
|
||||||
if ( Status == STATUS_PENDING )
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
IoMarkIrpPending(Irp);
|
IoMarkIrpPending(Irp);
|
||||||
Irp->Tail.Overlay.DriverContext[2] = DataQueue;
|
Irp->Tail.Overlay.DriverContext[2] = DataQueue;
|
||||||
|
@ -448,10 +448,10 @@ NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
||||||
|
|
||||||
IoSetCancelRoutine(Irp, NpCancelDataQueueIrp);
|
IoSetCancelRoutine(Irp, NpCancelDataQueueIrp);
|
||||||
|
|
||||||
if ( Irp->Cancel )
|
if (Irp->Cancel)
|
||||||
{
|
{
|
||||||
IoSetCancelRoutine(Irp, NULL);
|
IoSetCancelRoutine(Irp, NULL);
|
||||||
NpCancelDataQueueIrp(0, Irp);
|
NpCancelDataQueueIrp(NULL, Irp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,51 +14,43 @@ NTAPI
|
||||||
NpSetPipeInfo(IN PNP_FCB Fcb,
|
NpSetPipeInfo(IN PNP_FCB Fcb,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN PFILE_PIPE_INFORMATION Buffer,
|
IN PFILE_PIPE_INFORMATION Buffer,
|
||||||
IN ULONG ServerSide,
|
IN ULONG NamedPipeEnd,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||||
ULONG CompletionMode;
|
|
||||||
PAGED_CODE();
|
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;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ServerSide )
|
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
|
||||||
{
|
{
|
||||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xA04EFu, ServerSide, 0, 0);
|
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
|
||||||
ReadQueue = &Ccb->InQueue;
|
{
|
||||||
WriteQueue = &Ccb->OutQueue;
|
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xA04EFu, NamedPipeEnd, 0, 0);
|
||||||
CompletionMode = Ccb->ServerCompletionMode;
|
}
|
||||||
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReadQueue = &Ccb->OutQueue;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
WriteQueue = &Ccb->InQueue;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
CompletionMode = Ccb->ClientCompletionMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Buffer->CompletionMode != FILE_PIPE_COMPLETE_OPERATION ||
|
if (Buffer->CompletionMode != FILE_PIPE_COMPLETE_OPERATION ||
|
||||||
CompletionMode == FILE_PIPE_COMPLETE_OPERATION ||
|
Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION ||
|
||||||
(ReadQueue->QueueState == ReadEntries &&
|
(ReadQueue->QueueState == ReadEntries &&
|
||||||
WriteQueue->QueueState != WriteEntries ))
|
WriteQueue->QueueState != WriteEntries))
|
||||||
{
|
{
|
||||||
if (ServerSide)
|
Ccb->ReadMode[NamedPipeEnd] = Buffer->ReadMode & 0xFF;
|
||||||
{
|
Ccb->CompletionMode[NamedPipeEnd] = Buffer->CompletionMode & 0xFF;
|
||||||
Ccb->ServerReadMode = Buffer->ReadMode & 0xFF;
|
|
||||||
Ccb->ServerCompletionMode = Buffer->CompletionMode & 0xFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ccb->ClientReadMode = Buffer->ReadMode & 0xFF;
|
|
||||||
Ccb->ClientCompletionMode = Buffer->CompletionMode & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpCheckForNotify(Fcb->ParentDcb, 0, List);
|
NpCheckForNotify(Fcb->ParentDcb, FALSE, List);
|
||||||
Status = 0;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -80,7 +72,7 @@ NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
PNP_FCB Fcb;
|
PNP_FCB Fcb;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -88,18 +80,18 @@ NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
|
||||||
(PVOID*)&Fcb,
|
(PVOID*)&Fcb,
|
||||||
&Ccb,
|
&Ccb,
|
||||||
&ServerSide);
|
&NamedPipeEnd);
|
||||||
if ( !NodeTypeCode ) return STATUS_PIPE_DISCONNECTED;
|
if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
|
||||||
if ( NodeTypeCode != NPFS_NTC_CCB ) return STATUS_INVALID_PARAMETER;
|
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
InfoClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
InfoClass = IoStack->Parameters.QueryFile.FileInformationClass;
|
||||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
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
|
NTSTATUS
|
||||||
|
@ -133,7 +125,7 @@ NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( Status != STATUS_PENDING )
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
|
@ -142,13 +134,322 @@ NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpCommonQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
NpCommonQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PIO_STACK_LOCATION IoStack;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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
|
NTSTATUS
|
||||||
|
@ -167,7 +468,7 @@ NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
ExReleaseResourceLite(&NpVcb->Lock);
|
ExReleaseResourceLite(&NpVcb->Lock);
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( Status != STATUS_PENDING )
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
|
@ -176,3 +477,6 @@ NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// volinfo.c
|
||||||
|
//
|
|
@ -5,7 +5,7 @@ NTAPI
|
||||||
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||||
OUT PVOID* PrimaryContext OPTIONAL,
|
OUT PVOID* PrimaryContext OPTIONAL,
|
||||||
OUT PNP_CCB* Ccb,
|
OUT PNP_CCB* Ccb,
|
||||||
OUT PBOOLEAN ServerSide OPTIONAL)
|
OUT PULONG NamedPipeEnd OPTIONAL)
|
||||||
{
|
{
|
||||||
ULONG_PTR Context;
|
ULONG_PTR Context;
|
||||||
PNP_CCB Node;
|
PNP_CCB Node;
|
||||||
|
@ -14,7 +14,7 @@ NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||||
Context = (ULONG_PTR)FileObject->FsContext;
|
Context = (ULONG_PTR)FileObject->FsContext;
|
||||||
if ((Context) && (Context != 1))
|
if ((Context) && (Context != 1))
|
||||||
{
|
{
|
||||||
if (ServerSide) *ServerSide = Context & 1;
|
if (NamedPipeEnd) *NamedPipeEnd = Context & 1;
|
||||||
|
|
||||||
Node = (PVOID)(Context & ~1);
|
Node = (PVOID)(Context & ~1);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ NTAPI
|
||||||
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
||||||
IN PVOID PrimaryContext,
|
IN PVOID PrimaryContext,
|
||||||
IN PVOID Ccb,
|
IN PVOID Ccb,
|
||||||
IN BOOLEAN ServerSide)
|
IN ULONG NamedPipeEnd)
|
||||||
{
|
{
|
||||||
BOOLEAN FileIsPipe;
|
BOOLEAN FileIsPipe;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -57,7 +57,10 @@ NpSetFileObject(IN PFILE_OBJECT FileObject,
|
||||||
if ((PrimaryContext) && (((PNP_CCB)PrimaryContext)->NodeType == NPFS_NTC_CCB))
|
if ((PrimaryContext) && (((PNP_CCB)PrimaryContext)->NodeType == NPFS_NTC_CCB))
|
||||||
{
|
{
|
||||||
FileIsPipe = TRUE;
|
FileIsPipe = TRUE;
|
||||||
if (ServerSide) PrimaryContext = (PVOID)((ULONG_PTR)PrimaryContext | 1);
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
|
{
|
||||||
|
PrimaryContext = (PVOID) ((ULONG_PTR) PrimaryContext | 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
NODE_TYPE_CODE NodeTypeCode;
|
NODE_TYPE_CODE NodeTypeCode;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNP_DATA_QUEUE FlushQueue;
|
PNP_DATA_QUEUE FlushQueue;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -15,22 +15,27 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NodeTypeCode = NpDecodeFileObject(IoGetCurrentIrpStackLocation(Irp)->FileObject,
|
NodeTypeCode = NpDecodeFileObject(IoGetCurrentIrpStackLocation(Irp)->FileObject,
|
||||||
NULL,
|
NULL,
|
||||||
&Ccb,
|
&Ccb,
|
||||||
&ServerSide);
|
&NamedPipeEnd);
|
||||||
if (NodeTypeCode != NPFS_NTC_CCB ) return STATUS_PIPE_DISCONNECTED;
|
if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_PIPE_DISCONNECTED;
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||||
//ms_exc.registration.TryLevel = 0;
|
|
||||||
|
|
||||||
FlushQueue = &Ccb->OutQueue;
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
if ( ServerSide != 1 ) FlushQueue = &Ccb->InQueue;
|
|
||||||
|
|
||||||
if ( FlushQueue->QueueState == WriteEntries)
|
|
||||||
{
|
{
|
||||||
Status = NpAddDataQueueEntry(ServerSide,
|
FlushQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FlushQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlushQueue->QueueState == WriteEntries)
|
||||||
|
{
|
||||||
|
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||||
Ccb,
|
Ccb,
|
||||||
FlushQueue,
|
FlushQueue,
|
||||||
1,
|
WriteEntries,
|
||||||
2u,
|
2,
|
||||||
0,
|
0,
|
||||||
Irp,
|
Irp,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -41,9 +46,7 @@ NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ms_exc.registration.TryLevel = -1;
|
|
||||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
NODE_TYPE_CODE NodeTypeCode;
|
NODE_TYPE_CODE NodeTypeCode;
|
||||||
|
@ -93,10 +93,10 @@ NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
if ( ServerSide == 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ NpListen(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
NODE_TYPE_CODE NodeTypeCode;
|
NODE_TYPE_CODE NodeTypeCode;
|
||||||
|
@ -134,10 +134,10 @@ NpListen(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
if (NodeTypeCode == NPFS_NTC_CCB)
|
if (NodeTypeCode == NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
if ( ServerSide == 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
NODE_TYPE_CODE Type;
|
NODE_TYPE_CODE Type;
|
||||||
ULONG InputLength;
|
ULONG InputLength;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
|
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
|
||||||
PNP_DATA_QUEUE DataQueue;
|
PNP_DATA_QUEUE DataQueue;
|
||||||
|
@ -181,8 +181,12 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
InputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
InputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||||
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
if (!Type) return STATUS_PIPE_DISCONNECTED;
|
|
||||||
|
if (!Type)
|
||||||
|
{
|
||||||
|
return STATUS_PIPE_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Type != NPFS_NTC_CCB) && (InputLength < sizeof(*PeekBuffer)))
|
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;
|
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
|
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;
|
return STATUS_INVALID_PIPE_STATE;
|
||||||
}
|
}
|
||||||
if ( DataQueue->QueueState != WriteEntries)
|
|
||||||
|
if (DataQueue->QueueState != WriteEntries)
|
||||||
{
|
{
|
||||||
return STATUS_PIPE_BROKEN;
|
return STATUS_PIPE_BROKEN;
|
||||||
}
|
}
|
||||||
|
@ -222,7 +228,7 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
|
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
|
||||||
BytesPeeked = sizeof(*PeekBuffer);
|
BytesPeeked = sizeof(*PeekBuffer);
|
||||||
|
|
||||||
if ( DataQueue->QueueState == WriteEntries)
|
if (DataQueue->QueueState == WriteEntries)
|
||||||
{
|
{
|
||||||
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
||||||
NP_DATA_QUEUE_ENTRY,
|
NP_DATA_QUEUE_ENTRY,
|
||||||
|
@ -230,14 +236,14 @@ NpPeek(IN PDEVICE_OBJECT DeviceObject,
|
||||||
ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
|
ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
|
||||||
|
|
||||||
PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
|
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->NumberOfMessages = DataQueue->EntriesInQueue;
|
||||||
PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -270,7 +276,7 @@ NpCompleteTransceiveIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if ( Irp->AssociatedIrp.SystemBuffer )
|
if (Irp->AssociatedIrp.SystemBuffer)
|
||||||
{
|
{
|
||||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||||
}
|
}
|
||||||
|
@ -287,10 +293,10 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PVOID InBuffer, OutBuffer;
|
PVOID InBuffer, OutBuffer;
|
||||||
ULONG InLength, OutLength, ReadMode, BytesWritten;
|
ULONG InLength, OutLength, BytesWritten;
|
||||||
NODE_TYPE_CODE NodeTypeCode;
|
NODE_TYPE_CODE NodeTypeCode;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_NONPAGED_CCB NonPagedCcb;
|
PNP_NONPAGED_CCB NonPagedCcb;
|
||||||
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
PNP_DATA_QUEUE ReadQueue, WriteQueue;
|
||||||
PNP_EVENT_BUFFER EventBuffer;
|
PNP_EVENT_BUFFER EventBuffer;
|
||||||
|
@ -304,7 +310,7 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
|
||||||
OutBuffer = Irp->UserBuffer;
|
OutBuffer = Irp->UserBuffer;
|
||||||
|
|
||||||
if ( Irp->RequestorMode == UserMode)
|
if (Irp->RequestorMode == UserMode)
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -313,13 +319,13 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
ASSERT(FALSE);
|
return _SEH2_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide);
|
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
if (NodeTypeCode != NPFS_NTC_CCB )
|
if (NodeTypeCode != NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
return STATUS_PIPE_DISCONNECTED;
|
return STATUS_PIPE_DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
@ -327,39 +333,37 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NonPagedCcb = Ccb->NonPagedCcb;
|
NonPagedCcb = Ccb->NonPagedCcb;
|
||||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
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;
|
Status = STATUS_INVALID_PIPE_STATE;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ServerSide )
|
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
|
||||||
{
|
{
|
||||||
if ( ServerSide != 1 ) KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD0538, ServerSide, 0, 0);
|
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
|
||||||
ReadQueue = &Ccb->InQueue;
|
{
|
||||||
WriteQueue = &Ccb->OutQueue;
|
KeBugCheckEx(NPFS_FILE_SYSTEM, 0xD0538, NamedPipeEnd, 0, 0);
|
||||||
WriteQueue = &Ccb->OutQueue;
|
}
|
||||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
ReadMode = Ccb->ServerReadMode;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReadQueue = &Ccb->OutQueue;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
WriteQueue = &Ccb->InQueue;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
|
||||||
ReadMode = Ccb->ClientReadMode;
|
|
||||||
WriteQueue = &Ccb->InQueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||||
|
|
||||||
if (Ccb->Fcb->NamedPipeConfiguration != FILE_PIPE_FULL_DUPLEX ||
|
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;
|
Status = STATUS_INVALID_PIPE_STATE;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ReadQueue->QueueState != Empty)
|
if (ReadQueue->QueueState != Empty)
|
||||||
{
|
{
|
||||||
Status = STATUS_PIPE_BUSY;
|
Status = STATUS_PIPE_BUSY;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -372,14 +376,14 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Ccb->Fcb->NamedPipeType,
|
Ccb->Fcb->NamedPipeType,
|
||||||
&BytesWritten,
|
&BytesWritten,
|
||||||
Ccb,
|
Ccb,
|
||||||
ServerSide,
|
NamedPipeEnd,
|
||||||
Irp->Tail.Overlay.Thread,
|
Irp->Tail.Overlay.Thread,
|
||||||
List);
|
List);
|
||||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||||
{
|
{
|
||||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||||
NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||||
if ( !NewIrp )
|
if (!NewIrp)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -387,20 +391,28 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
|
IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
if ( BytesWritten )
|
if (BytesWritten)
|
||||||
{
|
{
|
||||||
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool, BytesWritten, 'wFpN');
|
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool, BytesWritten, NPFS_WRITE_BLOCK_TAG);
|
||||||
if ( !NewIrp->AssociatedIrp.SystemBuffer )
|
if (!NewIrp->AssociatedIrp.SystemBuffer)
|
||||||
{
|
{
|
||||||
IoFreeIrp(NewIrp);
|
IoFreeIrp(NewIrp);
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
|
_SEH2_TRY
|
||||||
(PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
|
{
|
||||||
BytesWritten);
|
RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
|
||||||
//ms_exc.registration.TryLevel = 1;
|
(PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
|
||||||
|
BytesWritten);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -416,19 +428,19 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IoStack->Parameters.Read.Length = BytesWritten;
|
IoStack->Parameters.Read.Length = BytesWritten;
|
||||||
IoStack->MajorFunction = IRP_MJ_WRITE;
|
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;
|
NewIrp->UserIosb = &NpUserIoStatusBlock;
|
||||||
|
|
||||||
Status = NpAddDataQueueEntry(ServerSide,
|
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||||
Ccb,
|
Ccb,
|
||||||
WriteQueue,
|
WriteQueue,
|
||||||
WriteEntries,
|
WriteEntries,
|
||||||
1,
|
Unbuffered,
|
||||||
BytesWritten,
|
BytesWritten,
|
||||||
NewIrp,
|
NewIrp,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
if ( Status != STATUS_PENDING )
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
NewIrp->IoStatus.Status = Status;
|
NewIrp->IoStatus.Status = Status;
|
||||||
InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
|
||||||
|
@ -437,24 +449,23 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
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);
|
ASSERT(ReadQueue->QueueState == Empty);
|
||||||
Status = NpAddDataQueueEntry(ServerSide,
|
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||||
Ccb,
|
Ccb,
|
||||||
ReadQueue,
|
ReadQueue,
|
||||||
ReadEntries,
|
ReadEntries,
|
||||||
0,
|
Buffered,
|
||||||
OutLength,
|
OutLength,
|
||||||
Irp,
|
Irp,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
//ms_exc.registration.TryLevel = -1;
|
|
||||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -467,7 +478,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
ULONG InLength, NameLength;
|
ULONG InLength, NameLength;
|
||||||
UNICODE_STRING SourceString, Prefix;
|
UNICODE_STRING SourceString, Prefix;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
|
PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -481,9 +492,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
SourceString.Buffer = NULL;
|
SourceString.Buffer = NULL;
|
||||||
|
|
||||||
//ms_exc.registration.TryLevel = 0;
|
if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
|
||||||
|
|
||||||
if (NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &ServerSide) != NPFS_NTC_ROOT_DCB )
|
|
||||||
{
|
{
|
||||||
Status = STATUS_ILLEGAL_FUNCTION;
|
Status = STATUS_ILLEGAL_FUNCTION;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -497,15 +506,15 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
NameLength = Buffer->NameLength;
|
NameLength = Buffer->NameLength;
|
||||||
if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength ))
|
if ((NameLength > 0xFFFD) || ((NameLength + sizeof(*Buffer)) > InLength))
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||||
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, 'WFpN');
|
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool, SourceString.Length, NPFS_WRITE_BLOCK_TAG);
|
||||||
if (!SourceString.Buffer )
|
if (!SourceString.Buffer)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -522,7 +531,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
|
Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
|
||||||
|
|
||||||
NodeTypeCode = Fcb ? Fcb->NodeType : 0;
|
NodeTypeCode = Fcb ? Fcb->NodeType : 0;
|
||||||
if ( NodeTypeCode != NPFS_NTC_FCB )
|
if (NodeTypeCode != NPFS_NTC_FCB)
|
||||||
{
|
{
|
||||||
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -533,10 +542,10 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NextEntry = NextEntry->Flink)
|
NextEntry = NextEntry->Flink)
|
||||||
{
|
{
|
||||||
Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
|
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;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -549,8 +558,7 @@ NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
//ms_exc.registration.TryLevel = -1;
|
if (SourceString.Buffer) ExFreePool(SourceString.Buffer);
|
||||||
if ( SourceString.Buffer ) ExFreePool(SourceString.Buffer);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,22 +580,22 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
switch (Fsctl)
|
switch (Fsctl)
|
||||||
{
|
{
|
||||||
case FSCTL_PIPE_PEEK:
|
case FSCTL_PIPE_PEEK:
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpPeek(DeviceObject, Irp, &List);
|
Status = NpPeek(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_WRITE:
|
case FSCTL_PIPE_INTERNAL_WRITE:
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpInternalWrite(DeviceObject, Irp, &List);
|
Status = NpInternalWrite(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_TRANSCEIVE:
|
case FSCTL_PIPE_TRANSCEIVE:
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpTransceive(DeviceObject, Irp, &List);
|
Status = NpTransceive(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpInternalTransceive(DeviceObject, Irp, &List);
|
Status = NpInternalTransceive(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -596,54 +604,54 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
// on purpose
|
// on purpose
|
||||||
|
|
||||||
case FSCTL_PIPE_INTERNAL_READ:
|
case FSCTL_PIPE_INTERNAL_READ:
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpInternalRead(DeviceObject, Irp, Overflow, &List);
|
Status = NpInternalRead(DeviceObject, Irp, Overflow, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpQueryClientProcess(DeviceObject, Irp);
|
Status = NpQueryClientProcess(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_ASSIGN_EVENT:
|
case FSCTL_PIPE_ASSIGN_EVENT:
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpAssignEvent(DeviceObject, Irp);
|
Status = NpAssignEvent(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_DISCONNECT:
|
case FSCTL_PIPE_DISCONNECT:
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpDisconnect(DeviceObject, Irp, &List);
|
Status = NpDisconnect(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_LISTEN:
|
case FSCTL_PIPE_LISTEN:
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpListen(DeviceObject, Irp, &List);
|
Status = NpListen(DeviceObject, Irp, &List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_QUERY_EVENT:
|
case FSCTL_PIPE_QUERY_EVENT:
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpQueryEvent(DeviceObject, Irp);
|
Status = NpQueryEvent(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_WAIT:
|
case FSCTL_PIPE_WAIT:
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpWaitForNamedPipe(DeviceObject, Irp);
|
Status = NpWaitForNamedPipe(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_IMPERSONATE:
|
case FSCTL_PIPE_IMPERSONATE:
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpImpersonate(DeviceObject, Irp);
|
Status = NpImpersonate(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
||||||
ExAcquireResourceExclusiveLite(&NpVcb->Lock, 1u);
|
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
|
||||||
Status = NpSetClientProcess(DeviceObject, Irp);
|
Status = NpSetClientProcess(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -680,7 +688,7 @@ NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( Status != STATUS_PENDING )
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
|
|
|
@ -2,48 +2,6 @@
|
||||||
|
|
||||||
PDEVICE_OBJECT NpfsDeviceObject;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
|
@ -16,6 +16,35 @@
|
||||||
#pragma warning(disable:4100)
|
#pragma warning(disable:4100)
|
||||||
#endif
|
#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
|
// Node Type Codes for NPFS
|
||||||
//
|
//
|
||||||
|
@ -190,8 +219,7 @@ typedef struct _NP_FCB
|
||||||
typedef struct _NP_NONPAGED_CCB
|
typedef struct _NP_NONPAGED_CCB
|
||||||
{
|
{
|
||||||
NODE_TYPE_CODE NodeType;
|
NODE_TYPE_CODE NodeType;
|
||||||
PNP_EVENT_BUFFER EventBufferClient;
|
PNP_EVENT_BUFFER EventBuffer[2];
|
||||||
PNP_EVENT_BUFFER EventBufferServer;
|
|
||||||
ERESOURCE Lock;
|
ERESOURCE Lock;
|
||||||
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
|
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
|
||||||
|
|
||||||
|
@ -202,22 +230,16 @@ typedef struct _NP_CCB
|
||||||
{
|
{
|
||||||
NODE_TYPE_CODE NodeType;
|
NODE_TYPE_CODE NodeType;
|
||||||
UCHAR NamedPipeState;
|
UCHAR NamedPipeState;
|
||||||
UCHAR ClientReadMode:1;
|
UCHAR ReadMode[2];
|
||||||
UCHAR ClientCompletionMode:1;
|
UCHAR CompletionMode[2];
|
||||||
UCHAR ServerReadMode:1;
|
|
||||||
UCHAR ClientReservedFlags:6;
|
|
||||||
UCHAR ServerCompletionMode:1;
|
|
||||||
UCHAR ServerReservedFlags:6;
|
|
||||||
SECURITY_QUALITY_OF_SERVICE ClientQos;
|
SECURITY_QUALITY_OF_SERVICE ClientQos;
|
||||||
LIST_ENTRY CcbEntry;
|
LIST_ENTRY CcbEntry;
|
||||||
PNP_FCB Fcb;
|
PNP_FCB Fcb;
|
||||||
PFILE_OBJECT ClientFileObject;
|
PFILE_OBJECT FileObject[2];
|
||||||
PFILE_OBJECT ServerFileObject;
|
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PVOID ClientSession;
|
PVOID ClientSession;
|
||||||
PNP_NONPAGED_CCB NonPagedCcb;
|
PNP_NONPAGED_CCB NonPagedCcb;
|
||||||
NP_DATA_QUEUE InQueue;
|
NP_DATA_QUEUE DataQueue[2];
|
||||||
NP_DATA_QUEUE OutQueue;
|
|
||||||
PSECURITY_CLIENT_CONTEXT ClientContext;
|
PSECURITY_CLIENT_CONTEXT ClientContext;
|
||||||
LIST_ENTRY IrpList;
|
LIST_ENTRY IrpList;
|
||||||
} NP_CCB, *PNP_CCB;
|
} NP_CCB, *PNP_CCB;
|
||||||
|
@ -265,7 +287,7 @@ NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpAddDataQueueEntry(IN BOOLEAN ServerSide,
|
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN PNP_DATA_QUEUE DataQueue,
|
IN PNP_DATA_QUEUE DataQueue,
|
||||||
IN ULONG Who,
|
IN ULONG Who,
|
||||||
|
@ -400,7 +422,7 @@ NpInitializeSecurity(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN PETHREAD Thread,
|
IN PETHREAD Thread,
|
||||||
IN PSECURITY_CLIENT_CONTEXT *Context);
|
IN PSECURITY_CLIENT_CONTEXT *Context);
|
||||||
|
@ -410,14 +432,14 @@ NTAPI
|
||||||
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
NpSetFileObject(IN PFILE_OBJECT FileObject,
|
||||||
IN PVOID PrimaryContext,
|
IN PVOID PrimaryContext,
|
||||||
IN PVOID Ccb,
|
IN PVOID Ccb,
|
||||||
IN BOOLEAN ServerSide);
|
IN ULONG NamedPipeEnd);
|
||||||
|
|
||||||
NODE_TYPE_CODE
|
NODE_TYPE_CODE
|
||||||
NTAPI
|
NTAPI
|
||||||
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||||
OUT PVOID* PrimaryContext OPTIONAL,
|
OUT PVOID* PrimaryContext OPTIONAL,
|
||||||
OUT PNP_CCB* Ccb,
|
OUT PNP_CCB* Ccb,
|
||||||
OUT PBOOLEAN ServerSide OPTIONAL);
|
OUT PULONG NamedPipeEnd OPTIONAL);
|
||||||
|
|
||||||
PNP_FCB
|
PNP_FCB
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -475,7 +497,7 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
IN ULONG PipeType,
|
IN ULONG PipeType,
|
||||||
OUT PULONG BytesWritten,
|
OUT PULONG BytesWritten,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN BOOLEAN ServerSide,
|
IN ULONG NamedPipeEnd,
|
||||||
IN PETHREAD Thread,
|
IN PETHREAD Thread,
|
||||||
IN PLIST_ENTRY List);
|
IN PLIST_ENTRY List);
|
||||||
|
|
||||||
|
@ -505,3 +527,19 @@ NTAPI
|
||||||
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp);
|
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);
|
ASSERT(Dcb->NodeType == NPFS_NTC_ROOT_DCB);
|
||||||
|
|
||||||
Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, 'nFpN');
|
Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, NPFS_NAME_BLOCK_TAG);
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
|
@ -12,17 +12,17 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
NODE_TYPE_CODE NodeType;
|
NODE_TYPE_CODE NodeType;
|
||||||
PNP_DATA_QUEUE Queue;
|
PNP_DATA_QUEUE ReadQueue;
|
||||||
PNP_EVENT_BUFFER EventBuffer;
|
PNP_EVENT_BUFFER EventBuffer;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOLEAN ServerSide;
|
ULONG NamedPipeEnd;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
PNP_NONPAGED_CCB NonPagedCcb;
|
PNP_NONPAGED_CCB NonPagedCcb;
|
||||||
BOOLEAN ReadOk;
|
BOOLEAN ReadOk;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
|
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
|
|
||||||
if (!NodeType)
|
if (!NodeType)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( NodeType != NPFS_NTC_CCB )
|
if (NodeType != NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -39,9 +39,7 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
NonPagedCcb = Ccb->NonPagedCcb;
|
NonPagedCcb = Ccb->NonPagedCcb;
|
||||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
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;
|
IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED;
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
|
@ -50,33 +48,33 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
|
ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
|
||||||
|
|
||||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
|
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
|
||||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND ))
|
(NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND))
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ServerSide == 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
Queue = &Ccb->InQueue;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Queue = &Ccb->OutQueue;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Queue->QueueState == WriteEntries )
|
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||||
|
|
||||||
|
if (ReadQueue->QueueState == WriteEntries)
|
||||||
{
|
{
|
||||||
*IoStatus = NpReadDataQueue(Queue,
|
*IoStatus = NpReadDataQueue(ReadQueue,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
Buffer,
|
Buffer,
|
||||||
BufferSize,
|
BufferSize,
|
||||||
ServerSide ? Ccb->ServerReadMode : Ccb->ClientReadMode,
|
Ccb->ReadMode[NamedPipeEnd],
|
||||||
Ccb,
|
Ccb,
|
||||||
List);
|
List);
|
||||||
if (!NT_SUCCESS(IoStatus->Status))
|
if (!NT_SUCCESS(IoStatus->Status))
|
||||||
|
@ -86,41 +84,41 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE )
|
if (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE)
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_PIPE_BROKEN;
|
IoStatus->Status = STATUS_PIPE_BROKEN;
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
goto Quickie;
|
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;
|
IoStatus->Status = STATUS_PIPE_EMPTY;
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !Irp )
|
if (!Irp)
|
||||||
{
|
{
|
||||||
ReadOk = FALSE;
|
ReadOk = FALSE;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
|
||||||
}
|
}
|
||||||
Status = NpAddDataQueueEntry(ServerSide,
|
|
||||||
Ccb,
|
Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||||
Queue,
|
Ccb,
|
||||||
0,
|
ReadQueue,
|
||||||
0,
|
ReadEntries,
|
||||||
BufferSize,
|
Buffered,
|
||||||
Irp,
|
BufferSize,
|
||||||
0,
|
Irp,
|
||||||
0);
|
NULL,
|
||||||
|
0);
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -129,11 +127,10 @@ NpCommonRead(IN PFILE_OBJECT FileObject,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReadOk = TRUE;
|
ReadOk = TRUE;
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
//ms_exc.registration.TryLevel = -1;
|
|
||||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||||
return ReadOk;
|
return ReadOk;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +174,7 @@ NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( IoStatus.Status != STATUS_PENDING )
|
if (IoStatus.Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = IoStatus.Information;
|
Irp->IoStatus.Information = IoStatus.Information;
|
||||||
Irp->IoStatus.Status = IoStatus.Status;
|
Irp->IoStatus.Status = IoStatus.Status;
|
||||||
|
|
|
@ -19,13 +19,13 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
BOOLEAN CompleteWrites = FALSE;
|
BOOLEAN CompleteWrites = FALSE;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if ( ReadOverflowOperation ) Peek = TRUE;
|
if (ReadOverflowOperation) Peek = TRUE;
|
||||||
|
|
||||||
RemainingSize = BufferSize;
|
RemainingSize = BufferSize;
|
||||||
Status.Status = 0;
|
Status.Status = STATUS_SUCCESS;
|
||||||
TotalBytesCopied = 0;
|
TotalBytesCopied = 0;
|
||||||
|
|
||||||
if ( Peek )
|
if (Peek)
|
||||||
{
|
{
|
||||||
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
|
||||||
NP_DATA_QUEUE_ENTRY,
|
NP_DATA_QUEUE_ENTRY,
|
||||||
|
@ -36,11 +36,13 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
|
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;
|
DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
||||||
}
|
}
|
||||||
|
@ -48,16 +50,17 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
{
|
{
|
||||||
DataBuffer = &DataEntry[1];
|
DataBuffer = &DataEntry[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSize = DataEntry->DataSize;
|
DataSize = DataEntry->DataSize;
|
||||||
Offset = DataSize;
|
Offset = DataSize;
|
||||||
|
|
||||||
if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
|
if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
|
||||||
{
|
{
|
||||||
Offset = DataSize - DataQueue->ByteOffset;
|
Offset -= DataQueue->ByteOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataLength = Offset;
|
DataLength = Offset;
|
||||||
if ( Offset >= RemainingSize ) DataLength = RemainingSize;
|
if (Offset >= RemainingSize) DataLength = RemainingSize;
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -75,19 +78,20 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
RemainingSize -= DataLength;
|
RemainingSize -= DataLength;
|
||||||
Offset -= DataLength;
|
Offset -= DataLength;
|
||||||
TotalBytesCopied += DataLength;
|
TotalBytesCopied += DataLength;
|
||||||
if ( !Peek )
|
|
||||||
|
if (!Peek)
|
||||||
{
|
{
|
||||||
DataEntry->QuotaInEntry -= DataLength;
|
DataEntry->QuotaInEntry -= DataLength;
|
||||||
DataQueue->QuotaUsed -= DataLength;
|
DataQueue->QuotaUsed -= DataLength;
|
||||||
DataQueue->ByteOffset += DataLength;
|
DataQueue->ByteOffset += DataLength;
|
||||||
CompleteWrites = TRUE;;
|
CompleteWrites = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpCopyClientContext(Ccb, DataEntry);
|
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;
|
Status.Status = STATUS_BUFFER_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
|
@ -95,23 +99,23 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( !Peek || ReadOverflowOperation )
|
if (!Peek || ReadOverflowOperation)
|
||||||
{
|
{
|
||||||
if ( ReadOverflowOperation)
|
if (ReadOverflowOperation)
|
||||||
{
|
{
|
||||||
TempDataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
|
TempDataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
|
||||||
ASSERT(TempDataEntry == DataEntry);
|
ASSERT(TempDataEntry == DataEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
|
Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = DataSize;
|
Irp->IoStatus.Information = DataSize;
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
||||||
{
|
{
|
||||||
Status.Status = STATUS_SUCCESS;
|
Status.Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
@ -119,7 +123,7 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
ASSERT(!ReadOverflowOperation);
|
ASSERT(!ReadOverflowOperation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( Peek )
|
if (Peek)
|
||||||
{
|
{
|
||||||
DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
|
DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
|
||||||
NP_DATA_QUEUE_ENTRY,
|
NP_DATA_QUEUE_ENTRY,
|
||||||
|
@ -132,7 +136,7 @@ NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||||
}
|
}
|
||||||
|
|
||||||
Status.Information = TotalBytesCopied;
|
Status.Information = TotalBytesCopied;
|
||||||
if ( CompleteWrites ) NpCompleteStalledWrites(DataQueue, List);
|
if (CompleteWrites) NpCompleteStalledWrites(DataQueue, List);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,35 +58,36 @@ NpInitializeSecurity(IN PNP_CCB Ccb,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ccb->ClientQos.Length = 12;
|
Ccb->ClientQos.Length = sizeof(Ccb->ClientQos);
|
||||||
Ccb->ClientQos.ImpersonationLevel = 2;
|
Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation;
|
||||||
Ccb->ClientQos.ContextTrackingMode = 1;
|
Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||||||
Ccb->ClientQos.EffectiveOnly = 1;
|
Ccb->ClientQos.EffectiveOnly = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpUninitializeSecurity(Ccb);
|
NpUninitializeSecurity(Ccb);
|
||||||
|
|
||||||
if (Ccb->ClientQos.ContextTrackingMode)
|
if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
|
||||||
{
|
{
|
||||||
Status = 0;
|
Status = STATUS_SUCCESS;
|
||||||
Ccb->ClientContext = 0;
|
Ccb->ClientContext = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), 'sFpN');
|
ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), NPFS_CLIENT_SEC_CTX_TAG);
|
||||||
Ccb->ClientContext = ClientContext;
|
Ccb->ClientContext = ClientContext;
|
||||||
if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
|
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
|
||||||
if (Status >= 0) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
ExFreePool(Ccb->ClientContext);
|
ExFreePool(Ccb->ClientContext);
|
||||||
Ccb->ClientContext = 0;
|
Ccb->ClientContext = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN PETHREAD Thread,
|
IN PETHREAD Thread,
|
||||||
IN PSECURITY_CLIENT_CONTEXT *Context)
|
IN PSECURITY_CLIENT_CONTEXT *Context)
|
||||||
|
@ -96,15 +97,15 @@ NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if ( ServerSide || Ccb->ClientQos.ContextTrackingMode != 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END || Ccb->ClientQos.ContextTrackingMode != SECURITY_DYNAMIC_TRACKING)
|
||||||
{
|
{
|
||||||
NewContext = NULL;
|
NewContext = NULL;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NewContext = ExAllocatePoolWithQuotaTag(PagedPool, sizeof(*NewContext), 'sFpN');
|
NewContext = ExAllocatePoolWithQuotaTag(PagedPool, sizeof(*NewContext), NPFS_CLIENT_SEC_CTX_TAG);
|
||||||
if ( !NewContext ) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!NewContext) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
|
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -116,3 +117,4 @@ NpGetClientSecurityContext(IN BOOLEAN ServerSide,
|
||||||
*Context = NewContext;
|
*Context = NewContext;
|
||||||
return Status;
|
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);
|
ExReleaseResourceLite(&NpVcb->Lock);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -28,10 +28,10 @@ NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
ASSERT(Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE);
|
ASSERT(Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE);
|
||||||
|
|
||||||
Ccb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE;
|
Ccb->ReadMode[FILE_PIPE_CLIENT_END] = FILE_PIPE_BYTE_STREAM_MODE;
|
||||||
Ccb->ClientCompletionMode = FILE_PIPE_QUEUE_OPERATION;
|
Ccb->CompletionMode[FILE_PIPE_CLIENT_END] = FILE_PIPE_QUEUE_OPERATION;
|
||||||
Ccb->NamedPipeState = FILE_PIPE_CONNECTED_STATE;
|
Ccb->NamedPipeState = FILE_PIPE_CONNECTED_STATE;
|
||||||
Ccb->ClientFileObject = FileObject;
|
Ccb->FileObject[FILE_PIPE_CLIENT_END] = FileObject;
|
||||||
|
|
||||||
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, FALSE);
|
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, FALSE);
|
||||||
|
|
||||||
|
@ -97,56 +97,57 @@ NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
case FILE_PIPE_CONNECTED_STATE:
|
case FILE_PIPE_CONNECTED_STATE:
|
||||||
|
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
|
||||||
while (Ccb->InQueue.QueueState != Empty)
|
|
||||||
|
while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
|
||||||
{
|
{
|
||||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
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);
|
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
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;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_PIPE_CLOSING_STATE:
|
case FILE_PIPE_CLOSING_STATE:
|
||||||
|
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
|
||||||
while (Ccb->InQueue.QueueState != Empty)
|
while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
|
||||||
{
|
{
|
||||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(Ccb->OutQueue.QueueState == Empty);
|
ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);
|
||||||
|
|
||||||
NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
|
NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
|
||||||
NonPagedCcb->EventBufferClient = NULL;
|
NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END] = NULL;
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||||
Ccb->ClientFileObject = NULL;
|
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||||
|
|
||||||
NpUninitializeSecurity(Ccb);
|
NpUninitializeSecurity(Ccb);
|
||||||
|
|
||||||
if ( Ccb->ClientSession )
|
if (Ccb->ClientSession)
|
||||||
{
|
{
|
||||||
ExFreePool(Ccb->ClientSession);
|
ExFreePool(Ccb->ClientSession);
|
||||||
Ccb->ClientSession = NULL;
|
Ccb->ClientSession = NULL;
|
||||||
|
@ -188,14 +189,14 @@ NpSetListeningPipeState(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
case FILE_PIPE_LISTENING_STATE:
|
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;
|
Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
|
||||||
return STATUS_PIPE_LISTENING;
|
return STATUS_PIPE_LISTENING;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoSetCancelRoutine(Irp, NpCancelListeningQueueIrp);
|
IoSetCancelRoutine(Irp, NpCancelListeningQueueIrp);
|
||||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||||
{
|
{
|
||||||
return STATUS_CANCELLED;
|
return STATUS_CANCELLED;
|
||||||
}
|
}
|
||||||
|
@ -266,37 +267,37 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
|
ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
|
||||||
Ccb->ServerFileObject = NULL;
|
Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||||
Ccb->ClientFileObject = NULL;
|
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||||
|
|
||||||
NpDeleteCcb(Ccb, List);
|
NpDeleteCcb(Ccb, List);
|
||||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_PIPE_CLOSING_STATE:
|
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
|
else
|
||||||
{
|
{
|
||||||
DataQueue = &Ccb->OutQueue;
|
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
}
|
}
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ServerFileObject, NULL, NULL, TRUE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
|
||||||
Ccb->ServerFileObject = NULL;
|
Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||||
Ccb->ClientFileObject = NULL;
|
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||||
|
|
||||||
while (Ccb->InQueue.QueueState != Empty)
|
while (DataQueue->QueueState != Empty)
|
||||||
{
|
{
|
||||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
Irp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
@ -305,42 +306,43 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||||
|
|
||||||
NpUninitializeSecurity(Ccb);
|
NpUninitializeSecurity(Ccb);
|
||||||
|
|
||||||
if ( Ccb->ClientSession )
|
if (Ccb->ClientSession)
|
||||||
{
|
{
|
||||||
ExFreePool(Ccb->ClientSession);
|
ExFreePool(Ccb->ClientSession);
|
||||||
Ccb->ClientSession = 0;
|
Ccb->ClientSession = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpDeleteCcb(Ccb, List);
|
NpDeleteCcb(Ccb, List);
|
||||||
if ( !Fcb->CurrentInstances ) NpDeleteFcb(Fcb, List);
|
if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_PIPE_CONNECTED_STATE:
|
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);
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
Ccb->ServerFileObject = 0;
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
ReadQueue = &Ccb->OutQueue;
|
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
WriteQueue = &Ccb->InQueue;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
|
||||||
|
|
||||||
NpSetFileObject(Ccb->ClientFileObject, NULL, NULL, FALSE);
|
NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
|
||||||
Ccb->ClientFileObject = 0;
|
Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||||
|
|
||||||
Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;
|
Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;
|
||||||
|
|
||||||
while (Ccb->InQueue.QueueState != Empty)
|
while (ReadQueue->QueueState != Empty)
|
||||||
{
|
{
|
||||||
Irp = NpRemoveDataQueueEntry(&Ccb->InQueue, FALSE, List);
|
Irp = NpRemoveDataQueueEntry(ReadQueue, FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
@ -350,18 +352,18 @@ NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||||
while (WriteQueue->QueueState == WriteEntries)
|
while (WriteQueue->QueueState == WriteEntries)
|
||||||
{
|
{
|
||||||
Irp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
|
Irp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||||
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
KeBugCheckEx(0x25u, 0x1602F9, Ccb->NamedPipeState, 0, 0);
|
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x1602F9, Ccb->NamedPipeState, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -62,7 +62,7 @@ NpDeleteFcb(IN PNP_FCB Fcb,
|
||||||
|
|
||||||
RemoveEntryList(&Fcb->DcbEntry);
|
RemoveEntryList(&Fcb->DcbEntry);
|
||||||
|
|
||||||
if ( Fcb->SecurityDescriptor )
|
if (Fcb->SecurityDescriptor)
|
||||||
{
|
{
|
||||||
ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1);
|
ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1);
|
||||||
}
|
}
|
||||||
|
@ -82,28 +82,28 @@ NpDeleteCcb(IN PNP_CCB Ccb,
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb;
|
RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb;
|
||||||
if ( Ccb->NodeType == NPFS_NTC_CCB )
|
if (Ccb->NodeType == NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Ccb->CcbEntry);
|
RemoveEntryList(&Ccb->CcbEntry);
|
||||||
--Ccb->Fcb->CurrentInstances;
|
--Ccb->Fcb->CurrentInstances;
|
||||||
|
|
||||||
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
||||||
Ccb->NonPagedCcb->EventBufferClient);
|
Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END]);
|
||||||
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
NpDeleteEventTableEntry(&NpVcb->EventTable,
|
||||||
Ccb->NonPagedCcb->EventBufferServer);
|
Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_SERVER_END]);
|
||||||
NpUninitializeDataQueue(&Ccb->InQueue);
|
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
|
||||||
NpUninitializeDataQueue(&Ccb->OutQueue);
|
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND]);
|
||||||
NpCheckForNotify(Ccb->Fcb->ParentDcb, 0, ListEntry);
|
NpCheckForNotify(Ccb->Fcb->ParentDcb, FALSE, ListEntry);
|
||||||
ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock);
|
ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||||
NpUninitializeSecurity(Ccb);
|
NpUninitializeSecurity(Ccb);
|
||||||
if ( Ccb->ClientSession )
|
if (Ccb->ClientSession)
|
||||||
{
|
{
|
||||||
ExFreePool(Ccb->ClientSession);
|
ExFreePool(Ccb->ClientSession);
|
||||||
Ccb->ClientSession = 0;
|
Ccb->ClientSession = NULL;
|
||||||
}
|
}
|
||||||
ExFreePool(Ccb->NonPagedCcb);
|
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);
|
ExFreePool(RootDcbCcb->Unknown);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB* NewRootCcb)
|
||||||
PNP_ROOT_DCB_FCB RootCcb;
|
PNP_ROOT_DCB_FCB RootCcb;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), 'CFpN');
|
RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), NPFS_ROOT_DCB_CCB_TAG);
|
||||||
if (!RootCcb) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!RootCcb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
RtlZeroMemory(RootCcb, sizeof(*RootCcb));
|
RtlZeroMemory(RootCcb, sizeof(*RootCcb));
|
||||||
|
@ -155,10 +155,10 @@ NpCreateRootDcb(VOID)
|
||||||
|
|
||||||
if (NpVcb->RootDcb)
|
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)
|
if (!NpVcb->RootDcb)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -185,7 +185,7 @@ NpCreateRootDcb(VOID)
|
||||||
&Dcb->FullName,
|
&Dcb->FullName,
|
||||||
&Dcb->PrefixTableEntry))
|
&Dcb->PrefixTableEntry))
|
||||||
{
|
{
|
||||||
KeBugCheckEx(0x25u, 0x170128, 0, 0, 0);
|
KeBugCheckEx(NPFS_FILE_SYSTEM, 0x170128, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -224,7 +224,7 @@ NpCreateFcb(IN PNP_DCB Dcb,
|
||||||
PipeNameLength += sizeof(WCHAR);
|
PipeNameLength += sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), 'FfpN');
|
Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), NPFS_FCB_TAG);
|
||||||
if (!Fcb) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Fcb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
RtlZeroMemory(Fcb, sizeof(*Fcb));
|
RtlZeroMemory(Fcb, sizeof(*Fcb));
|
||||||
|
@ -236,7 +236,7 @@ NpCreateFcb(IN PNP_DCB Dcb,
|
||||||
|
|
||||||
NameBuffer = ExAllocatePoolWithTag(PagedPool,
|
NameBuffer = ExAllocatePoolWithTag(PagedPool,
|
||||||
PipeName->Length + (RootPipe ? 4 : 2),
|
PipeName->Length + (RootPipe ? 4 : 2),
|
||||||
'nFpN');
|
NPFS_NAME_BLOCK_TAG);
|
||||||
if (!NameBuffer)
|
if (!NameBuffer)
|
||||||
{
|
{
|
||||||
ExFreePool(Fcb);
|
ExFreePool(Fcb);
|
||||||
|
@ -292,10 +292,10 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), 'cFpN');
|
Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), NPFS_CCB_TAG);
|
||||||
if (!Ccb) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Ccb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), 'cFpN');
|
CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), NPFS_CCB_TAG);
|
||||||
if (!CcbNonPaged)
|
if (!CcbNonPaged)
|
||||||
{
|
{
|
||||||
ExFreePool(Ccb);
|
ExFreePool(Ccb);
|
||||||
|
@ -308,13 +308,13 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
||||||
RtlZeroMemory(Ccb, sizeof(*Ccb));
|
RtlZeroMemory(Ccb, sizeof(*Ccb));
|
||||||
Ccb->NodeType = NPFS_NTC_CCB;
|
Ccb->NodeType = NPFS_NTC_CCB;
|
||||||
Ccb->NonPagedCcb = CcbNonPaged;
|
Ccb->NonPagedCcb = CcbNonPaged;
|
||||||
Ccb->ServerFileObject = FileObject;
|
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
|
||||||
Ccb->Fcb = Fcb;
|
Ccb->Fcb = Fcb;
|
||||||
Ccb->NamedPipeState = State;
|
Ccb->NamedPipeState = State;
|
||||||
Ccb->ServerReadMode = ReadMode;
|
Ccb->ReadMode[FILE_PIPE_SERVER_END] = ReadMode;
|
||||||
Ccb->ServerCompletionMode = CompletionMode;
|
Ccb->CompletionMode[FILE_PIPE_SERVER_END] = CompletionMode;
|
||||||
|
|
||||||
Status = NpInitializeDataQueue(&Ccb->InQueue, InQuota);
|
Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND], InQuota);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(CcbNonPaged);
|
ExFreePool(CcbNonPaged);
|
||||||
|
@ -322,10 +322,10 @@ NpCreateCcb(IN PNP_FCB Fcb,
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NpInitializeDataQueue(&Ccb->OutQueue, InQuota);
|
Status = NpInitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], OutQuota);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
NpUninitializeDataQueue(&Ccb->InQueue);
|
NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
|
||||||
ExFreePool(CcbNonPaged);
|
ExFreePool(CcbNonPaged);
|
||||||
ExFreePool(Ccb);
|
ExFreePool(Ccb);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
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);
|
OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock);
|
||||||
|
|
||||||
WaitEntry = (PNP_WAIT_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[1];
|
WaitEntry = (PNP_WAIT_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[1];
|
||||||
if ( WaitEntry )
|
if (WaitEntry)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
if ( !KeCancelTimer(&WaitEntry->Timer) )
|
if (!KeCancelTimer(&WaitEntry->Timer))
|
||||||
{
|
{
|
||||||
WaitEntry->Irp = NULL;
|
WaitEntry->Irp = NULL;
|
||||||
WaitEntry = NULL;
|
WaitEntry = NULL;
|
||||||
|
@ -28,7 +28,7 @@ NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||||
|
|
||||||
if ( WaitEntry )
|
if (WaitEntry)
|
||||||
{
|
{
|
||||||
ObfDereferenceObject(WaitEntry->FileObject);
|
ObfDereferenceObject(WaitEntry->FileObject);
|
||||||
ExFreePool(WaitEntry);
|
ExFreePool(WaitEntry);
|
||||||
|
@ -36,7 +36,7 @@ NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -52,23 +52,23 @@ NpTimerDispatch(IN PKDPC Dpc,
|
||||||
|
|
||||||
OldIrql = KfAcquireSpinLock(&WaitEntry->WaitQueue->WaitLock);
|
OldIrql = KfAcquireSpinLock(&WaitEntry->WaitQueue->WaitLock);
|
||||||
Irp = WaitEntry->Irp;
|
Irp = WaitEntry->Irp;
|
||||||
if ( Irp);
|
if (Irp)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
if ( !IoSetCancelRoutine(Irp, NULL))
|
if (!IoSetCancelRoutine(Irp, NULL))
|
||||||
{
|
{
|
||||||
Irp->Tail.Overlay.DriverContext[1] = NULL;
|
Irp->Tail.Overlay.DriverContext[1] = NULL;
|
||||||
Irp = NULL;
|
Irp = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KfReleaseSpinLock(&WaitEntry->WaitQueue->WaitLock, OldIrql);
|
KfReleaseSpinLock(&WaitEntry->WaitQueue->WaitLock, OldIrql);
|
||||||
if ( Irp )
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
|
||||||
IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||||
}
|
}
|
||||||
ObfDereferenceObject(WaitEntry->FileObject);
|
ObfDereferenceObject(WaitEntry->FileObject);
|
||||||
ExFreePoolWithTag(WaitEntry, 0);
|
ExFreePool(WaitEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -90,7 +90,7 @@ NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PWCHAR Buffer;
|
PWCHAR Buffer;
|
||||||
|
|
||||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length,'tFpN');
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length, NPFS_WAIT_BLOCK_TAG);
|
||||||
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length);
|
RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length);
|
||||||
|
@ -122,13 +122,13 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), 'wFpN');
|
WaitEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*WaitEntry), NPFS_WRITE_BLOCK_TAG);
|
||||||
if ( WaitEntry )
|
if (WaitEntry)
|
||||||
{
|
{
|
||||||
KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
|
KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
|
||||||
KeInitializeTimer(&WaitEntry->Timer);
|
KeInitializeTimer(&WaitEntry->Timer);
|
||||||
|
|
||||||
if ( Name )
|
if (Name)
|
||||||
{
|
{
|
||||||
WaitEntry->String = *Name;
|
WaitEntry->String = *Name;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||||
WaitEntry->Irp = Irp;
|
WaitEntry->Irp = Irp;
|
||||||
|
|
||||||
WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
WaitBuffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
|
||||||
if ( WaitBuffer->TimeoutSpecified )
|
if (WaitBuffer->TimeoutSpecified)
|
||||||
{
|
{
|
||||||
DueTime = WaitBuffer->Timeout;
|
DueTime = WaitBuffer->Timeout;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||||
|
|
||||||
IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
|
IoSetCancelRoutine(Irp, NpCancelWaitQueueIrp);
|
||||||
|
|
||||||
if ( Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||||
{
|
{
|
||||||
Status = STATUS_CANCELLED;
|
Status = STATUS_CANCELLED;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||||
|
|
||||||
}
|
}
|
||||||
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
|
||||||
if ( WaitEntry ) ExFreePool(WaitEntry);
|
if (WaitEntry) ExFreePool(WaitEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,17 +13,17 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
NODE_TYPE_CODE NodeType;
|
NODE_TYPE_CODE NodeType;
|
||||||
BOOLEAN WriteOk, ServerSide;
|
BOOLEAN WriteOk;
|
||||||
PNP_CCB Ccb;
|
PNP_CCB Ccb;
|
||||||
PNP_NONPAGED_CCB NonPagedCcb;
|
PNP_NONPAGED_CCB NonPagedCcb;
|
||||||
PNP_DATA_QUEUE WriteQueue;
|
PNP_DATA_QUEUE WriteQueue;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PNP_EVENT_BUFFER EventBuffer;
|
PNP_EVENT_BUFFER EventBuffer;
|
||||||
ULONG BytesWritten;
|
ULONG BytesWritten, NamedPipeEnd;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
|
NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
|
||||||
|
|
||||||
if (!NodeType)
|
if (!NodeType)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( NodeType != NPFS_NTC_CCB )
|
if (NodeType != NPFS_NTC_CCB)
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -40,16 +40,14 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
||||||
NonPagedCcb = Ccb->NonPagedCcb;
|
NonPagedCcb = Ccb->NonPagedCcb;
|
||||||
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
|
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;
|
IoStatus->Status = STATUS_PIPE_DISCONNECTED;
|
||||||
WriteOk = TRUE;
|
WriteOk = TRUE;
|
||||||
goto Quickie;
|
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;
|
IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_LISTENING_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_CLOSING;
|
||||||
WriteOk = TRUE;
|
WriteOk = TRUE;
|
||||||
|
@ -58,96 +56,90 @@ NpCommonWrite(IN PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
ASSERT(Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE);
|
ASSERT(Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE);
|
||||||
|
|
||||||
if ((ServerSide == 1 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
|
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
|
||||||
(ServerSide == 0 && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
|
(NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
IoStatus->Status = STATUS_INVALID_PARAMETER;
|
||||||
WriteOk = TRUE;
|
WriteOk = TRUE;
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoStatus->Status = 0;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
IoStatus->Information = DataSize;
|
IoStatus->Information = DataSize;
|
||||||
|
|
||||||
if ( ServerSide == 1 )
|
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
|
||||||
{
|
{
|
||||||
WriteQueue = &Ccb->OutQueue;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferClient;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteQueue = &Ccb->InQueue;
|
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
|
||||||
EventBuffer = NonPagedCcb->EventBufferServer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WriteQueue->QueueState != ReadEntries ||
|
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
|
||||||
WriteQueue->BytesInQueue >= DataSize ||
|
|
||||||
WriteQueue->Quota >= DataSize - WriteQueue->BytesInQueue )
|
if ((WriteQueue->QueueState == ReadEntries &&
|
||||||
|
WriteQueue->BytesInQueue < DataSize &&
|
||||||
|
WriteQueue->Quota < DataSize - WriteQueue->BytesInQueue) ||
|
||||||
|
(WriteQueue->QueueState == ReadEntries &&
|
||||||
|
WriteQueue->Quota - WriteQueue->QuotaUsed < DataSize))
|
||||||
{
|
{
|
||||||
if (WriteQueue->QueueState != ReadEntries ||
|
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE &&
|
||||||
WriteQueue->Quota - WriteQueue->QuotaUsed >= DataSize )
|
Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
|
||||||
{
|
{
|
||||||
goto DoWrite;
|
IoStatus->Information = 0;
|
||||||
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
|
WriteOk = TRUE;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
WriteOk = FALSE;
|
||||||
|
goto Quickie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE &&
|
|
||||||
Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION)
|
|
||||||
{
|
|
||||||
IoStatus->Information = 0;
|
|
||||||
IoStatus->Status = 0;
|
|
||||||
WriteOk = TRUE;
|
|
||||||
goto Quickie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Irp )
|
|
||||||
{
|
|
||||||
WriteOk = 0;
|
|
||||||
goto Quickie;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoWrite:
|
|
||||||
Status = NpWriteDataQueue(WriteQueue,
|
Status = NpWriteDataQueue(WriteQueue,
|
||||||
ServerSide ? Ccb->ClientReadMode : Ccb->ServerReadMode,
|
Ccb->ReadMode[NamedPipeEnd],
|
||||||
Buffer,
|
Buffer,
|
||||||
DataSize,
|
DataSize,
|
||||||
Ccb->Fcb->NamedPipeType,
|
Ccb->Fcb->NamedPipeType,
|
||||||
&BytesWritten,
|
&BytesWritten,
|
||||||
Ccb,
|
Ccb,
|
||||||
ServerSide,
|
NamedPipeEnd,
|
||||||
Thread,
|
Thread,
|
||||||
List);
|
List);
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
if ( Status == STATUS_MORE_PROCESSING_REQUIRED )
|
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||||
{
|
{
|
||||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||||
if ( (Ccb->ServerCompletionMode & FILE_PIPE_COMPLETE_OPERATION || !Irp)
|
if ((Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION || !Irp)
|
||||||
&& WriteQueue->Quota - WriteQueue->QuotaUsed < BytesWritten )
|
&& WriteQueue->Quota - WriteQueue->QuotaUsed < BytesWritten)
|
||||||
{
|
{
|
||||||
IoStatus->Information = DataSize - BytesWritten;
|
IoStatus->Information = DataSize - BytesWritten;
|
||||||
IoStatus->Status = 0;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||||
|
|
||||||
IoStatus->Status = NpAddDataQueueEntry(ServerSide,
|
IoStatus->Status = NpAddDataQueueEntry(NamedPipeEnd,
|
||||||
Ccb,
|
Ccb,
|
||||||
WriteQueue,
|
WriteQueue,
|
||||||
WriteEntries,
|
WriteEntries,
|
||||||
0,
|
Buffered,
|
||||||
DataSize,
|
DataSize,
|
||||||
Irp,
|
Irp,
|
||||||
Buffer,
|
Buffer,
|
||||||
DataSize - BytesWritten);
|
DataSize - BytesWritten);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( EventBuffer ) KeSetEvent(EventBuffer->Event, 0, 0);
|
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
|
||||||
WriteOk = 1;
|
WriteOk = TRUE;
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
//ms_exc.registration.TryLevel = -1;
|
|
||||||
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
|
||||||
return WriteOk;
|
return WriteOk;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +184,7 @@ NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
FsRtlExitFileSystem();
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
if ( IoStatus.Status != STATUS_PENDING )
|
if (IoStatus.Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = IoStatus.Information;
|
Irp->IoStatus.Information = IoStatus.Information;
|
||||||
Irp->IoStatus.Status = IoStatus.Status;
|
Irp->IoStatus.Status = IoStatus.Status;
|
||||||
|
|
|
@ -9,7 +9,7 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
IN ULONG PipeType,
|
IN ULONG PipeType,
|
||||||
OUT PULONG BytesWritten,
|
OUT PULONG BytesWritten,
|
||||||
IN PNP_CCB Ccb,
|
IN PNP_CCB Ccb,
|
||||||
IN BOOLEAN ServerSide,
|
IN ULONG NamedPipeEnd,
|
||||||
IN PETHREAD Thread,
|
IN PETHREAD Thread,
|
||||||
IN PLIST_ENTRY List)
|
IN PLIST_ENTRY List)
|
||||||
{
|
{
|
||||||
|
@ -25,8 +25,11 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
|
|
||||||
*BytesWritten = OutBufferSize;
|
*BytesWritten = OutBufferSize;
|
||||||
|
|
||||||
MoreProcessing = 1;
|
MoreProcessing = TRUE;
|
||||||
if ( PipeType != FILE_PIPE_OUTBOUND || (OutBufferSize) ) MoreProcessing = 0;
|
if ((PipeType != FILE_PIPE_MESSAGE_MODE) || (OutBufferSize))
|
||||||
|
{
|
||||||
|
MoreProcessing = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
for (DataEntry = NpGetNextRealDataQueueEntry(WriteQueue, List);
|
for (DataEntry = NpGetNextRealDataQueueEntry(WriteQueue, List);
|
||||||
((WriteQueue->QueueState == ReadEntries) &&
|
((WriteQueue->QueueState == ReadEntries) &&
|
||||||
|
@ -37,12 +40,12 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation( DataEntry->Irp);
|
IoStack = IoGetCurrentIrpStackLocation( DataEntry->Irp);
|
||||||
|
|
||||||
if ( IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
if (IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
||||||
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_WRITE &&
|
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_READ_OVFLOW &&
|
||||||
(DataSize < OutBufferSize || MoreProcessing) )
|
(DataSize < OutBufferSize || MoreProcessing))
|
||||||
{
|
{
|
||||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
||||||
if (WriteIrp )
|
if (WriteIrp)
|
||||||
{
|
{
|
||||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||||
|
@ -50,24 +53,24 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( DataEntry->DataEntryType == Unbuffered )
|
if (DataEntry->DataEntryType == Unbuffered)
|
||||||
{
|
{
|
||||||
DataEntry->Irp->Overlay.AllocationSize.QuadPart = 0;
|
DataEntry->Irp->Overlay.AllocationSize.QuadPart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferSize = *BytesWritten;
|
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');
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, NPFS_DATA_ENTRY_TAG);
|
||||||
if ( !Buffer ) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
AllocatedBuffer = 1;
|
AllocatedBuffer = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Buffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
Buffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
||||||
AllocatedBuffer = 0;
|
AllocatedBuffer = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
|
@ -78,65 +81,66 @@ NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
ASSERT(FALSE);
|
if (AllocatedBuffer) ExFreePool(Buffer);
|
||||||
|
return _SEH2_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
if ( !HaveContext )
|
if (!HaveContext)
|
||||||
{
|
{
|
||||||
HaveContext = 1;
|
HaveContext = TRUE;
|
||||||
Status = NpGetClientSecurityContext(ServerSide, Ccb, Thread, &ClientContext);
|
Status = NpGetClientSecurityContext(NamedPipeEnd, Ccb, Thread, &ClientContext);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if ( AllocatedBuffer ) ExFreePool(Buffer);
|
if (AllocatedBuffer) ExFreePool(Buffer);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ClientContext )
|
if (ClientContext)
|
||||||
{
|
{
|
||||||
NpFreeClientSecurityContext(Ccb->ClientContext);
|
NpFreeClientSecurityContext(Ccb->ClientContext);
|
||||||
Ccb->ClientContext = ClientContext;
|
Ccb->ClientContext = ClientContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, 1, List);
|
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
||||||
if ( WriteIrp )
|
if (WriteIrp)
|
||||||
{
|
{
|
||||||
*BytesWritten -= BufferSize;
|
*BytesWritten -= BufferSize;
|
||||||
WriteIrp->IoStatus.Information = BufferSize;
|
WriteIrp->IoStatus.Information = BufferSize;
|
||||||
|
|
||||||
if ( AllocatedBuffer )
|
if (AllocatedBuffer)
|
||||||
{
|
{
|
||||||
WriteIrp->AssociatedIrp.SystemBuffer = Buffer;
|
WriteIrp->AssociatedIrp.SystemBuffer = Buffer;
|
||||||
WriteIrp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
|
WriteIrp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !*BytesWritten )
|
if (!*BytesWritten)
|
||||||
{
|
{
|
||||||
MoreProcessing = 0;
|
MoreProcessing = FALSE;
|
||||||
WriteIrp->IoStatus.Status = 0;
|
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Mode == FILE_PIPE_MESSAGE_MODE )
|
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
||||||
{
|
{
|
||||||
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteIrp->IoStatus.Status = 0;
|
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
||||||
}
|
}
|
||||||
else if ( AllocatedBuffer )
|
else if (AllocatedBuffer)
|
||||||
{
|
{
|
||||||
ExFreePool(Buffer);
|
ExFreePool(Buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *BytesWritten > 0 || MoreProcessing )
|
if (*BytesWritten > 0 || MoreProcessing)
|
||||||
{
|
{
|
||||||
ASSERT(WriteQueue->QueueState != ReadEntries);
|
ASSERT(WriteQueue->QueueState != ReadEntries);
|
||||||
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue