Something went wrong. Try again.
Reactos
Something went wrong. Try again.
29 kB · 917 lines
C
at listview
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918/* * PROJECT: ReactOS Named Pipe FileSystem * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/filesystems/npfs/create.c * PURPOSE: Pipes Creation * PROGRAMMERS: ReactOS Portable Systems Group */
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_CREATE)
/* FUNCTIONS ******************************************************************/
VOIDNTAPINpCheckForNotify(IN PNP_DCB Dcb, IN BOOLEAN SecondList, IN PLIST_ENTRY List){ PLIST_ENTRY NextEntry, ListHead; PIRP Irp; ULONG i; PAGED_CODE();
ListHead = &Dcb->NotifyList; for (i = 0; i < 2; i++) { ASSERT(IsListEmpty(ListHead)); while (!IsListEmpty(ListHead)) { NextEntry = RemoveHeadList(ListHead);
Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
if (IoSetCancelRoutine(Irp, NULL)) { Irp->IoStatus.Status = STATUS_SUCCESS; InsertTailList(List, NextEntry); } else { InitializeListHead(NextEntry); } }
if (!SecondList) break; ListHead = &Dcb->NotifyList2; }}
IO_STATUS_BLOCKNTAPINpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject, IN ACCESS_MASK DesiredAccess){ IO_STATUS_BLOCK Status; PAGED_CODE(); TRACE("Entered\n");
NpSetFileObject(FileObject, NpVcb, NULL, FALSE); ++NpVcb->ReferenceCount;
Status.Information = FILE_OPENED; Status.Status = STATUS_SUCCESS; TRACE("Leaving, Status.Status = %lx\n", Status.Status); return Status;}
IO_STATUS_BLOCKNTAPINpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb, IN PFILE_OBJECT FileObject, IN ACCESS_MASK DesiredAccess, IN PLIST_ENTRY List){ IO_STATUS_BLOCK IoStatus; PNP_ROOT_DCB_FCB Ccb; PAGED_CODE(); TRACE("Entered\n");
IoStatus.Status = NpCreateRootDcbCcb(&Ccb); if (NT_SUCCESS(IoStatus.Status)) { NpSetFileObject(FileObject, Dcb, Ccb, FALSE); ++Dcb->CurrentInstances;
IoStatus.Information = FILE_OPENED; IoStatus.Status = STATUS_SUCCESS; } else { IoStatus.Information = 0; }
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus;}
IO_STATUS_BLOCKNTAPINpCreateClientEnd(IN PNP_FCB Fcb, IN PFILE_OBJECT FileObject, IN ACCESS_MASK DesiredAccess, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE PreviousMode, IN PETHREAD Thread, IN PLIST_ENTRY List){ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext; BOOLEAN AccessGranted; ACCESS_MASK GrantedAccess; PPRIVILEGE_SET Privileges; UNICODE_STRING ObjectTypeName; IO_STATUS_BLOCK IoStatus; USHORT NamedPipeConfiguration; PLIST_ENTRY NextEntry, ListHead; PNP_CCB Ccb = NULL; TRACE("Entered\n");
IoStatus.Information = 0; Privileges = NULL;
NamedPipeConfiguration = Fcb->NamedPipeConfiguration;
SubjectSecurityContext = &AccessState->SubjectSecurityContext; SeLockSubjectContext(SubjectSecurityContext);
AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor, SubjectSecurityContext, TRUE, DesiredAccess & ~4, 0, &Privileges, IoGetFileObjectGenericMapping(), PreviousMode, &GrantedAccess, &IoStatus.Status);
if (Privileges) { SeAppendPrivileges(AccessState, Privileges); SeFreePrivileges(Privileges); }
if (AccessGranted) { AccessState->PreviouslyGrantedAccess |= GrantedAccess; AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED); }
ObjectTypeName.Buffer = L"NamedPipe"; ObjectTypeName.Length = 18; SeOpenObjectAuditAlarm(&ObjectTypeName, NULL, &FileObject->FileName, Fcb->SecurityDescriptor, AccessState, FALSE, AccessGranted, PreviousMode, &AccessState->GenerateOnClose); SeUnlockSubjectContext(SubjectSecurityContext); if (!AccessGranted) return IoStatus;
if (((GrantedAccess & FILE_READ_DATA) && (NamedPipeConfiguration == FILE_PIPE_INBOUND)) || ((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND))) { IoStatus.Status = STATUS_ACCESS_DENIED; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
if (!(GrantedAccess & (FILE_READ_DATA | FILE_WRITE_DATA))) SecurityQos = NULL;
ListHead = &Fcb->CcbList; NextEntry = ListHead->Flink; while (NextEntry != ListHead) { Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry); if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
NextEntry = NextEntry->Flink; }
if (NextEntry == ListHead) { IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
IoStatus.Status = NpInitializeSecurity(Ccb, SecurityQos, Thread); if (!NT_SUCCESS(IoStatus.Status)) return IoStatus;
IoStatus.Status = NpSetConnectedPipeState(Ccb, FileObject, List); if (!NT_SUCCESS(IoStatus.Status)) { NpUninitializeSecurity(Ccb); TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
Ccb->ClientSession = NULL; Ccb->Process = IoThreadToProcess(Thread);
IoStatus.Information = FILE_OPENED; IoStatus.Status = STATUS_SUCCESS; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus;}
NTSTATUSNTAPINpTranslateAlias( PUNICODE_STRING PipeName){ WCHAR UpcaseBuffer[MAX_INDEXED_LENGTH + 1]; UNICODE_STRING UpcaseString; ULONG Length; PNPFS_ALIAS CurrentAlias; NTSTATUS Status; BOOLEAN BufferAllocated, BackSlash; LONG Result; PAGED_CODE();
/* Get the pipe name length and check for empty string */ Length = PipeName->Length; if (Length == 0) { return STATUS_SUCCESS; }
/* Check if the name starts with a path separator */ BackSlash = (PipeName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR); if (BackSlash) { /* We are only interested in the part after the backslash */ Length -= sizeof(WCHAR); }
/* Check if the length is within our indexed list bounds */ if ((Length >= MIN_INDEXED_LENGTH * sizeof(WCHAR)) && (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR))) { /* Length is within bounds, use the list by length */ CurrentAlias = NpAliasListByLength[(Length / sizeof(WCHAR)) - MIN_INDEXED_LENGTH]; } else { /* We use the generic list, search for an entry of the right size */ CurrentAlias = NpAliasList; while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length != Length)) { /* Check if we went past the desired length */ if (CurrentAlias->Name.Length > Length) { /* In this case there is no matching alias, return success */ return STATUS_SUCCESS; }
/* Go to the next alias in the list */ CurrentAlias = CurrentAlias->Next; } }
/* Did we find any alias? */ if (CurrentAlias == NULL) { /* Nothing found, no matching alias */ return STATUS_SUCCESS; }
/* Check whether we can use our stack buffer */ if (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR)) { /* Initialize the upcased string */ UpcaseString.Buffer = UpcaseBuffer; UpcaseString.MaximumLength = sizeof(UpcaseBuffer);
/* Upcase the pipe name */ Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, FALSE); NT_ASSERT(NT_SUCCESS(Status)); BufferAllocated = FALSE; } else { /* Upcase the pipe name, allocate the string buffer */ Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, TRUE); if (!NT_SUCCESS(Status)) { return Status; }
BufferAllocated = TRUE; }
/* Did the original name start with a backslash? */ if (BackSlash) { /* Skip it for the comparison */ UpcaseString.Buffer++; UpcaseString.Length -= sizeof(WCHAR); }
/* Make sure the length matches the "raw" length */ NT_ASSERT(UpcaseString.Length == Length); NT_ASSERT(CurrentAlias->Name.Length == Length);
/* Loop while we have aliases */ do { /* Compare the names and check if they match */ Result = NpCompareAliasNames(&UpcaseString, &CurrentAlias->Name); if (Result == 0) { /* The names match, use the target name */ *PipeName = *CurrentAlias->TargetName;
/* Did the original name start with a backslash? */ if (!BackSlash) { /* It didn't, so skip it in the target name as well */ PipeName->Buffer++; PipeName->Length -= sizeof(WCHAR); } break; }
/* Check if we went past all string candidates */ if (Result < 0) { /* Nothing found, we're done */ break; }
/* Go to the next alias */ CurrentAlias = CurrentAlias->Next;
/* Keep looping while we have aliases of the right length */ } while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length == Length));
/* Did we allocate a buffer? */ if (BufferAllocated) { /* Free the allocated buffer */ ASSERT(UpcaseString.Buffer != UpcaseBuffer); RtlFreeUnicodeString(&UpcaseString); }
return STATUS_SUCCESS;}
NTSTATUSNTAPINpFsdCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ IO_STATUS_BLOCK IoStatus; PIO_STACK_LOCATION IoStack; UNICODE_STRING FileName; PFILE_OBJECT FileObject; PFILE_OBJECT RelatedFileObject; NODE_TYPE_CODE Type; PNP_CCB Ccb; PNP_FCB Fcb; PNP_DCB Dcb; ACCESS_MASK DesiredAccess; LIST_ENTRY DeferredList; UNICODE_STRING Prefix; TRACE("Entered\n");
InitializeListHead(&DeferredList); IoStack = IoGetCurrentIrpStackLocation(Irp); FileObject = IoStack->FileObject; RelatedFileObject = FileObject->RelatedFileObject; FileName = FileObject->FileName; DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
IoStatus.Information = 0;
FsRtlEnterFileSystem(); NpAcquireExclusiveVcb();
if (RelatedFileObject) { Type = NpDecodeFileObject(RelatedFileObject, (PVOID*)&Fcb, &Ccb, FALSE); } else { Type = 0; Fcb = NULL; Ccb = NULL; }
if (FileName.Length) { if ((FileName.Length == sizeof(OBJ_NAME_PATH_SEPARATOR)) && (FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) && !(RelatedFileObject)) { IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb, FileObject, DesiredAccess, &DeferredList); goto Quickie; } } else if (!(RelatedFileObject) || (Type == NPFS_NTC_VCB)) { IoStatus = NpOpenNamedPipeFileSystem(FileObject, DesiredAccess); goto Quickie; } else if (Type == NPFS_NTC_ROOT_DCB) { IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb, FileObject, DesiredAccess, &DeferredList); goto Quickie; }
IoStatus.Status = NpTranslateAlias(&FileName); if (!NT_SUCCESS(IoStatus.Status)) goto Quickie;
if (RelatedFileObject) { if (Type == NPFS_NTC_ROOT_DCB) { Dcb = (PNP_DCB)Ccb; IoStatus.Status = NpFindRelativePrefix(Dcb, &FileName, 1, &Prefix, &Fcb); if (!NT_SUCCESS(IoStatus.Status)) { goto Quickie; } } else if ((Type != NPFS_NTC_CCB) || (FileName.Length)) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; } else { Prefix.Length = 0; } } else { if ((FileName.Length <= sizeof(OBJ_NAME_PATH_SEPARATOR)) || (FileName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR)) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; }
Fcb = NpFindPrefix(&FileName, 1, &Prefix); }
if (Prefix.Length) { IoStatus.Status = Fcb->NodeType != NPFS_NTC_FCB ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_OBJECT_NAME_INVALID; goto Quickie; }
if (Fcb->NodeType != NPFS_NTC_FCB) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; }
if (!Fcb->ServerOpenCount) { IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Quickie; }
IoStatus = NpCreateClientEnd(Fcb, FileObject, DesiredAccess, IoStack->Parameters.CreatePipe. SecurityContext->SecurityQos, IoStack->Parameters.CreatePipe. SecurityContext->AccessState, IoStack->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode, Irp->Tail.Overlay.Thread, &DeferredList);
Quickie: NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); FsRtlExitFileSystem();
Irp->IoStatus = IoStatus; IoCompleteRequest(Irp, IO_NO_INCREMENT); TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus.Status;}
IO_STATUS_BLOCKNTAPINpCreateExistingNamedPipe(IN PNP_FCB Fcb, IN PFILE_OBJECT FileObject, IN ACCESS_MASK DesiredAccess, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE PreviousMode, IN ULONG Disposition, IN ULONG ShareAccess, IN PNAMED_PIPE_CREATE_PARAMETERS Parameters, IN PEPROCESS Process, OUT PLIST_ENTRY List){ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext; IO_STATUS_BLOCK IoStatus; UNICODE_STRING ObjectTypeName; ACCESS_MASK GrantedAccess; PNP_CCB Ccb; PPRIVILEGE_SET Privileges; USHORT NamedPipeConfiguration, CheckShareAccess; BOOLEAN AccessGranted; PAGED_CODE(); TRACE("Entered\n");
Privileges = NULL;
NamedPipeConfiguration = Fcb->NamedPipeConfiguration;
SubjectSecurityContext = &AccessState->SubjectSecurityContext; SeLockSubjectContext(SubjectSecurityContext);
IoStatus.Information = 0;
AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor, SubjectSecurityContext, TRUE, DesiredAccess | 4, 0, &Privileges, IoGetFileObjectGenericMapping(), PreviousMode, &GrantedAccess, &IoStatus.Status);
if (Privileges) { SeAppendPrivileges(AccessState, Privileges); SeFreePrivileges(Privileges); }
if (AccessGranted) { AccessState->PreviouslyGrantedAccess |= GrantedAccess; AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED); }
ObjectTypeName.Buffer = L"NamedPipe"; ObjectTypeName.Length = 18; SeOpenObjectAuditAlarm(&ObjectTypeName, NULL, &FileObject->FileName, Fcb->SecurityDescriptor, AccessState, FALSE, AccessGranted, PreviousMode, &AccessState->GenerateOnClose);
SeUnlockSubjectContext(SubjectSecurityContext); if (!AccessGranted) { TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
if (Fcb->CurrentInstances >= Fcb->MaximumInstances) { IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
if (Disposition == FILE_CREATE) { IoStatus.Status = STATUS_ACCESS_DENIED; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
CheckShareAccess = 0; if (NamedPipeConfiguration == FILE_PIPE_FULL_DUPLEX) { CheckShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; } else if (NamedPipeConfiguration == FILE_PIPE_OUTBOUND) { CheckShareAccess = FILE_SHARE_READ; } else if (NamedPipeConfiguration == FILE_PIPE_INBOUND) { CheckShareAccess = FILE_SHARE_WRITE; }
if (CheckShareAccess != ShareAccess) { IoStatus.Status = STATUS_ACCESS_DENIED; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
IoStatus.Status = NpCreateCcb(Fcb, FileObject, FILE_PIPE_LISTENING_STATE, Parameters->ReadMode & 0xFF, Parameters->CompletionMode & 0xFF, Parameters->InboundQuota, Parameters->OutboundQuota, &Ccb); if (!NT_SUCCESS(IoStatus.Status)) return IoStatus;
IoStatus.Status = NpCancelWaiter(&NpVcb->WaitQueue, &Fcb->FullName, FALSE, List); if (!NT_SUCCESS(IoStatus.Status)) { --Ccb->Fcb->CurrentInstances; NpDeleteCcb(Ccb, List); TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus; }
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE); Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject; NpCheckForNotify(Fcb->ParentDcb, 0, List);
IoStatus.Status = STATUS_SUCCESS; IoStatus.Information = FILE_OPENED; TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); return IoStatus;}
NTSTATUSNTAPINpCreateNewNamedPipe(IN PNP_DCB Dcb, IN PFILE_OBJECT FileObject, IN UNICODE_STRING PipeName, IN ACCESS_MASK DesiredAccess, IN PACCESS_STATE AccessState, IN USHORT Disposition, IN USHORT ShareAccess, IN PNAMED_PIPE_CREATE_PARAMETERS Parameters, IN PEPROCESS Process, IN PLIST_ENTRY List, OUT PIO_STATUS_BLOCK IoStatus){ NTSTATUS Status; USHORT NamedPipeConfiguration; PSECURITY_SUBJECT_CONTEXT SecurityContext; PSECURITY_DESCRIPTOR SecurityDescriptor, CachedSecurityDescriptor; PNP_CCB Ccb; PNP_FCB Fcb; PAGED_CODE(); TRACE("Entered\n");
if (!(Parameters->TimeoutSpecified) || !(Parameters->MaximumInstances) || (Parameters->DefaultTimeout.QuadPart >= 0)) { Status = STATUS_INVALID_PARAMETER; goto Quickie; }
if (Disposition == FILE_OPEN) { Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Quickie; }
if (ShareAccess == (FILE_SHARE_READ | FILE_SHARE_WRITE)) { NamedPipeConfiguration = FILE_PIPE_FULL_DUPLEX; } else if (ShareAccess == FILE_SHARE_READ) { NamedPipeConfiguration = FILE_PIPE_OUTBOUND; } else if (ShareAccess == FILE_SHARE_WRITE) { NamedPipeConfiguration = FILE_PIPE_INBOUND; } else { Status = STATUS_INVALID_PARAMETER; goto Quickie; }
if (Parameters->NamedPipeType == FILE_PIPE_BYTE_STREAM_TYPE && Parameters->ReadMode == FILE_PIPE_MESSAGE_MODE) { Status = STATUS_INVALID_PARAMETER; goto Quickie; }
Status = NpCreateFcb(Dcb, &PipeName, Parameters->MaximumInstances, Parameters->DefaultTimeout, NamedPipeConfiguration, Parameters->NamedPipeType & 0xFFFF, &Fcb); if (!NT_SUCCESS(Status)) goto Quickie;
Status = NpCreateCcb(Fcb, FileObject, FILE_PIPE_LISTENING_STATE, Parameters->ReadMode & 0xFF, Parameters->CompletionMode & 0xFF, Parameters->InboundQuota, Parameters->OutboundQuota, &Ccb); if (!NT_SUCCESS(Status)) { NpDeleteFcb(Fcb, List); goto Quickie; }
SecurityContext = &AccessState->SubjectSecurityContext; SeLockSubjectContext(SecurityContext);
Status = SeAssignSecurity(NULL, AccessState->SecurityDescriptor, &SecurityDescriptor, FALSE, SecurityContext, IoGetFileObjectGenericMapping(), PagedPool); SeUnlockSubjectContext(SecurityContext); if (!NT_SUCCESS(Status)) { NpDeleteCcb(Ccb, List); NpDeleteFcb(Fcb, List); goto Quickie; }
Status = ObLogSecurityDescriptor(SecurityDescriptor, &CachedSecurityDescriptor, 1); ExFreePoolWithTag(SecurityDescriptor, 0);
if (!NT_SUCCESS(Status)) { NpDeleteCcb(Ccb, List); NpDeleteFcb(Fcb, List); goto Quickie; }
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE); Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
NpCheckForNotify(Dcb, TRUE, List);
IoStatus->Status = STATUS_SUCCESS; IoStatus->Information = FILE_CREATED;
TRACE("Leaving, STATUS_SUCCESS\n"); return STATUS_SUCCESS;
Quickie: TRACE("Leaving, Status = %lx\n", Status); IoStatus->Information = 0; IoStatus->Status = Status; return Status;}
NTSTATUSNTAPINpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PFILE_OBJECT RelatedFileObject; USHORT Disposition, ShareAccess; PEPROCESS Process; LIST_ENTRY DeferredList; UNICODE_STRING FileName; PNP_FCB Fcb; UNICODE_STRING Prefix; PNAMED_PIPE_CREATE_PARAMETERS Parameters; IO_STATUS_BLOCK IoStatus; TRACE("Entered\n");
InitializeListHead(&DeferredList); Process = IoGetRequestorProcess(Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp); FileObject = IoStack->FileObject; RelatedFileObject = FileObject->RelatedFileObject;
Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF; ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess & 0xFFFF; Parameters = IoStack->Parameters.CreatePipe.Parameters;
FileName = FileObject->FileName;
IoStatus.Information = 0;
FsRtlEnterFileSystem(); NpAcquireExclusiveVcb();
if (RelatedFileObject) { Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1); if (!(Fcb) || (Fcb->NodeType != NPFS_NTC_ROOT_DCB) || (FileName.Length < sizeof(WCHAR)) || (FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; }
IoStatus.Status = NpFindRelativePrefix(RelatedFileObject->FsContext, &FileName, TRUE, &Prefix, &Fcb); if (!NT_SUCCESS(IoStatus.Status)) { goto Quickie; } } else { if (FileName.Length <= sizeof(OBJ_NAME_PATH_SEPARATOR) || FileName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; }
Fcb = NpFindPrefix(&FileName, 1, &Prefix); }
if (Prefix.Length) { if (Fcb->NodeType == NPFS_NTC_ROOT_DCB) { IoStatus.Status = NpCreateNewNamedPipe((PNP_DCB)Fcb, FileObject, FileName, IoStack->Parameters.CreatePipe. SecurityContext->DesiredAccess, IoStack->Parameters.CreatePipe. SecurityContext->AccessState, Disposition, ShareAccess, Parameters, Process, &DeferredList, &IoStatus); goto Quickie; } else { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; } }
if (Fcb->NodeType != NPFS_NTC_FCB) { IoStatus.Status = STATUS_OBJECT_NAME_INVALID; goto Quickie; }
IoStatus = NpCreateExistingNamedPipe(Fcb, FileObject, IoStack->Parameters.CreatePipe. SecurityContext->DesiredAccess, IoStack->Parameters.CreatePipe. SecurityContext->AccessState, IoStack->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode, Disposition, ShareAccess, Parameters, Process, &DeferredList);
Quickie: NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); FsRtlExitFileSystem();
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status); Irp->IoStatus = IoStatus; IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT); return IoStatus.Status;}
/* EOF */