2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/create.c
5 * PURPOSE: Pipes Creation
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_CREATE)
16 /* FUNCTIONS ******************************************************************/
20 NpCheckForNotify(IN PNP_DCB Dcb
,
21 IN BOOLEAN SecondList
,
24 PLIST_ENTRY NextEntry
, ListHead
;
29 ListHead
= &Dcb
->NotifyList
;
30 for (i
= 0; i
< 2; i
++)
32 ASSERT(IsListEmpty(ListHead
));
33 while (!IsListEmpty(ListHead
))
35 NextEntry
= RemoveHeadList(ListHead
);
37 Irp
= CONTAINING_RECORD(NextEntry
, IRP
, Tail
.Overlay
.ListEntry
);
39 if (IoSetCancelRoutine(Irp
, NULL
))
41 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
42 InsertTailList(List
, NextEntry
);
46 InitializeListHead(NextEntry
);
50 if (!SecondList
) break;
51 ListHead
= &Dcb
->NotifyList2
;
57 NpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject
,
58 IN ACCESS_MASK DesiredAccess
)
60 IO_STATUS_BLOCK Status
;
64 NpSetFileObject(FileObject
, NpVcb
, NULL
, FALSE
);
65 ++NpVcb
->ReferenceCount
;
67 Status
.Information
= FILE_OPENED
;
68 Status
.Status
= STATUS_SUCCESS
;
69 TRACE("Leaving, Status.Status = %lx\n", Status
.Status
);
75 NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb
,
76 IN PFILE_OBJECT FileObject
,
77 IN ACCESS_MASK DesiredAccess
,
80 IO_STATUS_BLOCK IoStatus
;
85 IoStatus
.Status
= NpCreateRootDcbCcb(&Ccb
);
86 if (NT_SUCCESS(IoStatus
.Status
))
88 NpSetFileObject(FileObject
, Dcb
, Ccb
, FALSE
);
89 ++Dcb
->CurrentInstances
;
91 IoStatus
.Information
= FILE_OPENED
;
92 IoStatus
.Status
= STATUS_SUCCESS
;
96 IoStatus
.Information
= 0;
99 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
105 NpCreateClientEnd(IN PNP_FCB Fcb
,
106 IN PFILE_OBJECT FileObject
,
107 IN ACCESS_MASK DesiredAccess
,
108 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
,
109 IN PACCESS_STATE AccessState
,
110 IN KPROCESSOR_MODE PreviousMode
,
114 PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
115 BOOLEAN AccessGranted
;
116 ACCESS_MASK GrantedAccess
;
117 PPRIVILEGE_SET Privileges
;
118 UNICODE_STRING ObjectTypeName
;
119 IO_STATUS_BLOCK IoStatus
;
120 USHORT NamedPipeConfiguration
;
121 PLIST_ENTRY NextEntry
, ListHead
;
125 IoStatus
.Information
= 0;
128 NamedPipeConfiguration
= Fcb
->NamedPipeConfiguration
;
130 SubjectSecurityContext
= &AccessState
->SubjectSecurityContext
;
131 SeLockSubjectContext(SubjectSecurityContext
);
133 AccessGranted
= SeAccessCheck(Fcb
->SecurityDescriptor
,
134 SubjectSecurityContext
,
139 IoGetFileObjectGenericMapping(),
146 SeAppendPrivileges(AccessState
, Privileges
);
147 SeFreePrivileges(Privileges
);
152 AccessState
->PreviouslyGrantedAccess
|= GrantedAccess
;
153 AccessState
->RemainingDesiredAccess
&= ~(GrantedAccess
| MAXIMUM_ALLOWED
);
156 ObjectTypeName
.Buffer
= L
"NamedPipe";
157 ObjectTypeName
.Length
= 18;
158 SeOpenObjectAuditAlarm(&ObjectTypeName
,
160 &FileObject
->FileName
,
161 Fcb
->SecurityDescriptor
,
166 &AccessState
->GenerateOnClose
);
167 SeUnlockSubjectContext(SubjectSecurityContext
);
168 if (!AccessGranted
) return IoStatus
;
170 if (((GrantedAccess
& FILE_READ_DATA
) && (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)) ||
171 ((GrantedAccess
& FILE_WRITE_DATA
) && (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)))
173 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
174 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
178 if (!(GrantedAccess
& (FILE_READ_DATA
| FILE_WRITE_DATA
))) SecurityQos
= NULL
;
180 ListHead
= &Fcb
->CcbList
;
181 NextEntry
= ListHead
->Flink
;
182 while (NextEntry
!= ListHead
)
184 Ccb
= CONTAINING_RECORD(NextEntry
, NP_CCB
, CcbEntry
);
185 if (Ccb
->NamedPipeState
== FILE_PIPE_LISTENING_STATE
) break;
187 NextEntry
= NextEntry
->Flink
;
190 if (NextEntry
== ListHead
)
192 IoStatus
.Status
= STATUS_PIPE_NOT_AVAILABLE
;
193 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
197 IoStatus
.Status
= NpInitializeSecurity(Ccb
, SecurityQos
, Thread
);
198 if (!NT_SUCCESS(IoStatus
.Status
)) return IoStatus
;
200 IoStatus
.Status
= NpSetConnectedPipeState(Ccb
, FileObject
, List
);
201 if (!NT_SUCCESS(IoStatus
.Status
))
203 NpUninitializeSecurity(Ccb
);
204 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
208 Ccb
->ClientSession
= NULL
;
209 Ccb
->Process
= IoThreadToProcess(Thread
);
211 IoStatus
.Information
= FILE_OPENED
;
212 IoStatus
.Status
= STATUS_SUCCESS
;
213 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
220 PUNICODE_STRING PipeName
)
222 WCHAR UpcaseBuffer
[MAX_INDEXED_LENGTH
+ 1];
223 UNICODE_STRING UpcaseString
;
225 PNPFS_ALIAS CurrentAlias
;
227 BOOLEAN BufferAllocated
, BackSlash
;
231 /* Get the pipe name length and check for empty string */
232 Length
= PipeName
->Length
;
235 return STATUS_SUCCESS
;
238 /* Check if the name starts with a path separator */
239 BackSlash
= (PipeName
->Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
);
242 /* We are only interested in the part after the backslash */
243 Length
-= sizeof(WCHAR
);
246 /* Check if the length is within our indexed list bounds */
247 if ((Length
>= MIN_INDEXED_LENGTH
* sizeof(WCHAR
)) &&
248 (Length
<= MAX_INDEXED_LENGTH
* sizeof(WCHAR
)))
250 /* Length is within bounds, use the list by length */
251 CurrentAlias
= NpAliasListByLength
[(Length
/ sizeof(WCHAR
)) - MIN_INDEXED_LENGTH
];
255 /* We use the generic list, search for an entry of the right size */
256 CurrentAlias
= NpAliasList
;
257 while ((CurrentAlias
!= NULL
) && (CurrentAlias
->Name
.Length
!= Length
))
259 /* Check if we went past the desired length */
260 if (CurrentAlias
->Name
.Length
> Length
)
262 /* In this case there is no matching alias, return success */
263 return STATUS_SUCCESS
;
266 /* Go to the next alias in the list */
267 CurrentAlias
= CurrentAlias
->Next
;
271 /* Did we find any alias? */
272 if (CurrentAlias
== NULL
)
274 /* Nothing found, no matching alias */
275 return STATUS_SUCCESS
;
278 /* Check whether we can use our stack buffer */
279 if (Length
<= MAX_INDEXED_LENGTH
* sizeof(WCHAR
))
281 /* Initialize the upcased string */
282 UpcaseString
.Buffer
= UpcaseBuffer
;
283 UpcaseString
.MaximumLength
= sizeof(UpcaseBuffer
);
285 /* Upcase the pipe name */
286 Status
= RtlUpcaseUnicodeString(&UpcaseString
, PipeName
, FALSE
);
287 NT_ASSERT(NT_SUCCESS(Status
));
288 BufferAllocated
= FALSE
;
292 /* Upcase the pipe name, allocate the string buffer */
293 Status
= RtlUpcaseUnicodeString(&UpcaseString
, PipeName
, TRUE
);
294 if (!NT_SUCCESS(Status
))
299 BufferAllocated
= TRUE
;
302 /* Did the original name start with a backslash? */
305 /* Skip it for the comparison */
306 UpcaseString
.Buffer
++;
307 UpcaseString
.Length
-= sizeof(WCHAR
);
310 /* Make sure the length matches the "raw" length */
311 NT_ASSERT(UpcaseString
.Length
== Length
);
312 NT_ASSERT(CurrentAlias
->Name
.Length
== Length
);
314 /* Loop while we have aliases */
317 /* Compare the names and check if they match */
318 Result
= NpCompareAliasNames(&UpcaseString
, &CurrentAlias
->Name
);
321 /* The names match, use the target name */
322 *PipeName
= *CurrentAlias
->TargetName
;
324 /* Did the original name start with a backslash? */
327 /* It didn't, so skip it in the target name as well */
329 PipeName
->Length
-= sizeof(WCHAR
);
334 /* Check if we went past all string candidates */
337 /* Nothing found, we're done */
341 /* Go to the next alias */
342 CurrentAlias
= CurrentAlias
->Next
;
344 /* Keep looping while we have aliases of the right length */
345 } while ((CurrentAlias
!= NULL
) && (CurrentAlias
->Name
.Length
== Length
));
347 /* Did we allocate a buffer? */
350 /* Free the allocated buffer */
351 ASSERT(UpcaseString
.Buffer
!= UpcaseBuffer
);
352 RtlFreeUnicodeString(&UpcaseString
);
355 return STATUS_SUCCESS
;
360 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject
,
363 IO_STATUS_BLOCK IoStatus
;
364 PEXTENDED_IO_STACK_LOCATION IoStack
;
365 UNICODE_STRING FileName
;
366 PFILE_OBJECT FileObject
;
367 PFILE_OBJECT RelatedFileObject
;
372 ACCESS_MASK DesiredAccess
;
373 LIST_ENTRY DeferredList
;
374 UNICODE_STRING Prefix
;
377 InitializeListHead(&DeferredList
);
378 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
379 FileObject
= IoStack
->FileObject
;
380 RelatedFileObject
= FileObject
->RelatedFileObject
;
381 FileName
= FileObject
->FileName
;
382 DesiredAccess
= IoStack
->Parameters
.CreatePipe
.SecurityContext
->DesiredAccess
;
384 IoStatus
.Information
= 0;
386 FsRtlEnterFileSystem();
387 ExAcquireResourceExclusiveLite(&NpVcb
->Lock
, TRUE
);
389 if (RelatedFileObject
)
391 Type
= NpDecodeFileObject(RelatedFileObject
, (PVOID
*)&Fcb
, &Ccb
, FALSE
);
402 if ((FileName
.Length
== sizeof(OBJ_NAME_PATH_SEPARATOR
)) &&
403 (FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
) &&
404 !(RelatedFileObject
))
406 IoStatus
= NpOpenNamedPipeRootDirectory(NpVcb
->RootDcb
,
413 else if (!(RelatedFileObject
) || (Type
== NPFS_NTC_VCB
))
415 IoStatus
= NpOpenNamedPipeFileSystem(FileObject
,
419 else if (Type
== NPFS_NTC_ROOT_DCB
)
421 IoStatus
= NpOpenNamedPipeRootDirectory(NpVcb
->RootDcb
,
428 IoStatus
.Status
= NpTranslateAlias(&FileName
);
429 if (!NT_SUCCESS(IoStatus
.Status
)) goto Quickie
;
431 if (RelatedFileObject
)
433 if (Type
== NPFS_NTC_ROOT_DCB
)
436 IoStatus
.Status
= NpFindRelativePrefix(Dcb
,
441 if (!NT_SUCCESS(IoStatus
.Status
))
446 else if ((Type
!= NPFS_NTC_CCB
) || (FileName
.Length
))
448 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
458 if ((FileName
.Length
<= sizeof(OBJ_NAME_PATH_SEPARATOR
)) ||
459 (FileName
.Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
))
461 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
465 Fcb
= NpFindPrefix(&FileName
, TRUE
, &Prefix
);
470 IoStatus
.Status
= Fcb
->NodeType
!= NPFS_NTC_FCB
?
471 STATUS_OBJECT_NAME_NOT_FOUND
:
472 STATUS_OBJECT_NAME_INVALID
;
476 if (Fcb
->NodeType
!= NPFS_NTC_FCB
)
478 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
482 if (!Fcb
->ServerOpenCount
)
484 IoStatus
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
488 IoStatus
= NpCreateClientEnd(Fcb
,
491 IoStack
->Parameters
.CreatePipe
.
492 SecurityContext
->SecurityQos
,
493 IoStack
->Parameters
.CreatePipe
.
494 SecurityContext
->AccessState
,
496 SL_FORCE_ACCESS_CHECK
?
497 UserMode
: Irp
->RequestorMode
,
498 Irp
->Tail
.Overlay
.Thread
,
502 ExReleaseResourceLite(&NpVcb
->Lock
);
503 NpCompleteDeferredIrps(&DeferredList
);
504 FsRtlExitFileSystem();
506 Irp
->IoStatus
= IoStatus
;
507 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
508 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
509 return IoStatus
.Status
;
514 NpCreateExistingNamedPipe(IN PNP_FCB Fcb
,
515 IN PFILE_OBJECT FileObject
,
516 IN ACCESS_MASK DesiredAccess
,
517 IN PACCESS_STATE AccessState
,
518 IN KPROCESSOR_MODE PreviousMode
,
519 IN ULONG Disposition
,
520 IN ULONG ShareAccess
,
521 IN PNAMED_PIPE_CREATE_PARAMETERS Parameters
,
522 IN PEPROCESS Process
,
523 OUT PLIST_ENTRY List
)
525 PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
526 IO_STATUS_BLOCK IoStatus
;
527 UNICODE_STRING ObjectTypeName
;
528 ACCESS_MASK GrantedAccess
;
530 PPRIVILEGE_SET Privileges
;
531 USHORT NamedPipeConfiguration
, CheckShareAccess
;
532 BOOLEAN AccessGranted
;
538 NamedPipeConfiguration
= Fcb
->NamedPipeConfiguration
;
540 SubjectSecurityContext
= &AccessState
->SubjectSecurityContext
;
541 SeLockSubjectContext(SubjectSecurityContext
);
543 IoStatus
.Information
= 0;
545 AccessGranted
= SeAccessCheck(Fcb
->SecurityDescriptor
,
546 SubjectSecurityContext
,
551 IoGetFileObjectGenericMapping(),
558 SeAppendPrivileges(AccessState
, Privileges
);
559 SeFreePrivileges(Privileges
);
564 AccessState
->PreviouslyGrantedAccess
|= GrantedAccess
;
565 AccessState
->RemainingDesiredAccess
&= ~(GrantedAccess
| 0x2000000);
568 ObjectTypeName
.Buffer
= L
"NamedPipe";
569 ObjectTypeName
.Length
= 18;
570 SeOpenObjectAuditAlarm(&ObjectTypeName
,
572 &FileObject
->FileName
,
573 Fcb
->SecurityDescriptor
,
578 &AccessState
->GenerateOnClose
);
580 SeUnlockSubjectContext(SubjectSecurityContext
);
583 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
587 if (Fcb
->CurrentInstances
>= Fcb
->MaximumInstances
)
589 IoStatus
.Status
= STATUS_INSTANCE_NOT_AVAILABLE
;
590 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
594 if (Disposition
== FILE_CREATE
)
596 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
597 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
601 CheckShareAccess
= 0;
602 if (NamedPipeConfiguration
== FILE_PIPE_FULL_DUPLEX
)
604 CheckShareAccess
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
606 else if (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)
608 CheckShareAccess
= FILE_SHARE_READ
;
610 else if (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)
612 CheckShareAccess
= FILE_SHARE_WRITE
;
615 if (CheckShareAccess
!= ShareAccess
)
617 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
618 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
622 IoStatus
.Status
= NpCreateCcb(Fcb
,
624 FILE_PIPE_LISTENING_STATE
,
625 Parameters
->ReadMode
& 0xFF,
626 Parameters
->CompletionMode
& 0xFF,
627 Parameters
->InboundQuota
,
628 Parameters
->OutboundQuota
,
630 if (!NT_SUCCESS(IoStatus
.Status
)) return IoStatus
;
632 IoStatus
.Status
= NpCancelWaiter(&NpVcb
->WaitQueue
,
636 if (!NT_SUCCESS(IoStatus
.Status
))
638 --Ccb
->Fcb
->CurrentInstances
;
639 NpDeleteCcb(Ccb
, List
);
640 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
644 NpSetFileObject(FileObject
, Ccb
, Ccb
->NonPagedCcb
, TRUE
);
645 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
646 NpCheckForNotify(Fcb
->ParentDcb
, 0, List
);
648 IoStatus
.Status
= STATUS_SUCCESS
;
649 IoStatus
.Information
= FILE_OPENED
;
650 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
656 NpCreateNewNamedPipe(IN PNP_DCB Dcb
,
657 IN PFILE_OBJECT FileObject
,
658 IN UNICODE_STRING PipeName
,
659 IN ACCESS_MASK DesiredAccess
,
660 IN PACCESS_STATE AccessState
,
661 IN USHORT Disposition
,
662 IN USHORT ShareAccess
,
663 IN PNAMED_PIPE_CREATE_PARAMETERS Parameters
,
664 IN PEPROCESS Process
,
666 OUT PIO_STATUS_BLOCK IoStatus
)
669 USHORT NamedPipeConfiguration
;
670 PSECURITY_SUBJECT_CONTEXT SecurityContext
;
671 PSECURITY_DESCRIPTOR SecurityDescriptor
, CachedSecurityDescriptor
;
677 if (!(Parameters
->TimeoutSpecified
) ||
678 !(Parameters
->MaximumInstances
) ||
679 (Parameters
->DefaultTimeout
.HighPart
>= 0))
681 Status
= STATUS_INVALID_PARAMETER
;
685 if (Disposition
== FILE_OPEN
)
687 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
691 if (ShareAccess
== (FILE_SHARE_READ
| FILE_SHARE_WRITE
))
693 NamedPipeConfiguration
= FILE_PIPE_FULL_DUPLEX
;
695 else if (ShareAccess
== FILE_SHARE_READ
)
697 NamedPipeConfiguration
= FILE_PIPE_OUTBOUND
;
699 else if (ShareAccess
== FILE_SHARE_WRITE
)
701 NamedPipeConfiguration
= FILE_PIPE_INBOUND
;
705 Status
= STATUS_INVALID_PARAMETER
;
709 if (!Parameters
->NamedPipeType
&& Parameters
->ReadMode
== 1)
711 Status
= STATUS_INVALID_PARAMETER
;
715 Status
= NpCreateFcb(Dcb
,
717 Parameters
->MaximumInstances
,
718 Parameters
->DefaultTimeout
,
719 NamedPipeConfiguration
,
720 Parameters
->NamedPipeType
& 0xFFFF,
722 if (!NT_SUCCESS(Status
)) goto Quickie
;
724 Status
= NpCreateCcb(Fcb
,
726 FILE_PIPE_LISTENING_STATE
,
727 Parameters
->ReadMode
& 0xFF,
728 Parameters
->CompletionMode
& 0xFF,
729 Parameters
->InboundQuota
,
730 Parameters
->OutboundQuota
,
732 if (!NT_SUCCESS(Status
))
734 NpDeleteFcb(Fcb
, List
);
738 SecurityContext
= &AccessState
->SubjectSecurityContext
;
739 SeLockSubjectContext(&AccessState
->SubjectSecurityContext
);
741 Status
= SeAssignSecurity(0,
742 AccessState
->SecurityDescriptor
,
746 IoGetFileObjectGenericMapping(),
748 SeUnlockSubjectContext(SecurityContext
);
749 if (!NT_SUCCESS(Status
))
751 NpDeleteCcb(Ccb
, List
);
752 NpDeleteFcb(Fcb
, List
);
756 Status
= ObLogSecurityDescriptor(SecurityDescriptor
,
757 &CachedSecurityDescriptor
,
759 ExFreePool(SecurityDescriptor
);
761 if (!NT_SUCCESS(Status
))
763 NpDeleteCcb(Ccb
, List
);
764 NpDeleteFcb(Fcb
, List
);
768 Fcb
->SecurityDescriptor
= CachedSecurityDescriptor
;
770 NpSetFileObject(FileObject
, Ccb
, Ccb
->NonPagedCcb
, TRUE
);
771 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
773 NpCheckForNotify(Dcb
, TRUE
, List
);
775 IoStatus
->Status
= STATUS_SUCCESS
;
776 IoStatus
->Information
= FILE_CREATED
;
778 TRACE("Leaving, STATUS_SUCCESS\n");
779 return STATUS_SUCCESS
;
782 TRACE("Leaving, Status = %lx\n", Status
);
783 IoStatus
->Information
= 0;
784 IoStatus
->Status
= Status
;
790 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject
,
793 PEXTENDED_IO_STACK_LOCATION IoStack
;
794 PFILE_OBJECT FileObject
;
795 PFILE_OBJECT RelatedFileObject
;
796 USHORT Disposition
, ShareAccess
;
798 LIST_ENTRY DeferredList
;
799 UNICODE_STRING FileName
;
801 UNICODE_STRING Prefix
;
802 PNAMED_PIPE_CREATE_PARAMETERS Parameters
;
803 IO_STATUS_BLOCK IoStatus
;
806 InitializeListHead(&DeferredList
);
807 Process
= IoGetRequestorProcess(Irp
);
809 IoStack
= (PEXTENDED_IO_STACK_LOCATION
) IoGetCurrentIrpStackLocation(Irp
);
810 FileObject
= IoStack
->FileObject
;
811 RelatedFileObject
= FileObject
->RelatedFileObject
;
813 Disposition
= (IoStack
->Parameters
.CreatePipe
.Options
>> 24) & 0xFF;
814 ShareAccess
= IoStack
->Parameters
.CreatePipe
.ShareAccess
& 0xFFFF;
815 Parameters
= IoStack
->Parameters
.CreatePipe
.Parameters
;
817 FileName
= FileObject
->FileName
;
819 IoStatus
.Information
= 0;
821 FsRtlEnterFileSystem();
822 NpAcquireExclusiveVcb();
824 if (RelatedFileObject
)
826 Fcb
= (PNP_FCB
)((ULONG_PTR
)RelatedFileObject
->FsContext
& ~1);
828 (Fcb
->NodeType
!= NPFS_NTC_ROOT_DCB
) ||
829 (FileName
.Length
< sizeof(WCHAR
)) ||
830 (FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
))
832 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
836 IoStatus
.Status
= NpFindRelativePrefix(RelatedFileObject
->FsContext
,
841 if (!NT_SUCCESS(IoStatus
.Status
))
848 if (FileName
.Length
<= sizeof(OBJ_NAME_PATH_SEPARATOR
) ||
849 FileName
.Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
)
851 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
855 Fcb
= NpFindPrefix(&FileName
, TRUE
, &Prefix
);
860 if (Fcb
->NodeType
== NPFS_NTC_ROOT_DCB
)
862 IoStatus
.Status
= NpCreateNewNamedPipe((PNP_DCB
)Fcb
,
865 IoStack
->Parameters
.CreatePipe
.
866 SecurityContext
->DesiredAccess
,
867 IoStack
->Parameters
.CreatePipe
.
868 SecurityContext
->AccessState
,
879 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
884 if (Fcb
->NodeType
!= NPFS_NTC_FCB
)
886 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
890 IoStatus
= NpCreateExistingNamedPipe(Fcb
,
892 IoStack
->Parameters
.CreatePipe
.
893 SecurityContext
->DesiredAccess
,
894 IoStack
->Parameters
.CreatePipe
.
895 SecurityContext
->AccessState
,
897 SL_FORCE_ACCESS_CHECK
?
898 UserMode
: Irp
->RequestorMode
,
907 NpCompleteDeferredIrps(&DeferredList
);
908 FsRtlExitFileSystem();
910 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
911 Irp
->IoStatus
= IoStatus
;
912 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
913 return IoStatus
.Status
;