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 = %lx\n", IoStatus
);
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
.Status
= STATUS_SUCCESS
;
126 IoStatus
.Information
= 0;
129 NamedPipeConfiguration
= Fcb
->NamedPipeConfiguration
;
131 SubjectSecurityContext
= &AccessState
->SubjectSecurityContext
;
132 SeLockSubjectContext(SubjectSecurityContext
);
134 AccessGranted
= SeAccessCheck(Fcb
->SecurityDescriptor
,
135 SubjectSecurityContext
,
140 IoGetFileObjectGenericMapping(),
147 SeAppendPrivileges(AccessState
, Privileges
);
148 SeFreePrivileges(Privileges
);
153 AccessState
->PreviouslyGrantedAccess
|= GrantedAccess
;
154 AccessState
->RemainingDesiredAccess
&= ~(GrantedAccess
| MAXIMUM_ALLOWED
);
157 ObjectTypeName
.Buffer
= L
"NamedPipe";
158 ObjectTypeName
.Length
= 18;
159 SeOpenObjectAuditAlarm(&ObjectTypeName
,
161 &FileObject
->FileName
,
162 Fcb
->SecurityDescriptor
,
167 &AccessState
->GenerateOnClose
);
168 SeUnlockSubjectContext(SubjectSecurityContext
);
169 if (!AccessGranted
) return IoStatus
;
171 if (((GrantedAccess
& FILE_READ_DATA
) && (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)) ||
172 ((GrantedAccess
& FILE_WRITE_DATA
) && (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)))
174 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
175 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
179 if (!(GrantedAccess
& (FILE_READ_DATA
| FILE_WRITE_DATA
))) SecurityQos
= NULL
;
181 ListHead
= &Fcb
->CcbList
;
182 NextEntry
= ListHead
->Flink
;
183 while (NextEntry
!= ListHead
)
185 Ccb
= CONTAINING_RECORD(NextEntry
, NP_CCB
, CcbEntry
);
186 if (Ccb
->NamedPipeState
== FILE_PIPE_LISTENING_STATE
) break;
188 NextEntry
= NextEntry
->Flink
;
191 if (NextEntry
== ListHead
)
193 IoStatus
.Status
= STATUS_PIPE_NOT_AVAILABLE
;
194 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
198 IoStatus
.Status
= NpInitializeSecurity(Ccb
, SecurityQos
, Thread
);
199 if (!NT_SUCCESS(IoStatus
.Status
)) return IoStatus
;
201 IoStatus
.Status
= NpSetConnectedPipeState(Ccb
, FileObject
, List
);
202 if (!NT_SUCCESS(IoStatus
.Status
))
204 NpUninitializeSecurity(Ccb
);
205 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
209 Ccb
->ClientSession
= NULL
;
210 Ccb
->Process
= IoThreadToProcess(Thread
);
212 IoStatus
.Information
= FILE_OPENED
;
213 IoStatus
.Status
= STATUS_SUCCESS
;
214 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
221 PUNICODE_STRING PipeName
)
223 WCHAR UpcaseBuffer
[MAX_INDEXED_LENGTH
+ 1];
224 UNICODE_STRING UpcaseString
;
226 PNPFS_ALIAS CurrentAlias
;
228 BOOLEAN BufferAllocated
, BackSlash
;
232 /* Get the pipe name length and check for empty string */
233 Length
= PipeName
->Length
;
236 return STATUS_SUCCESS
;
239 /* Check if the name starts with a path separator */
240 BackSlash
= (PipeName
->Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
);
243 /* We are only interested in the part after the backslash */
244 Length
-= sizeof(WCHAR
);
247 /* Check if the length is within our indexed list bounds */
248 if ((Length
>= MIN_INDEXED_LENGTH
* sizeof(WCHAR
)) &&
249 (Length
<= MAX_INDEXED_LENGTH
* sizeof(WCHAR
)))
251 /* Length is within bounds, use the list by length */
252 CurrentAlias
= NpAliasListByLength
[(Length
/ sizeof(WCHAR
)) - MIN_INDEXED_LENGTH
];
256 /* We use the generic list, search for an entry of the right size */
257 CurrentAlias
= NpAliasList
;
258 while ((CurrentAlias
!= NULL
) && (CurrentAlias
->Name
.Length
!= Length
))
260 /* Check if we went past the desired length */
261 if (CurrentAlias
->Name
.Length
> Length
)
263 /* In this case there is no matching alias, return success */
264 return STATUS_SUCCESS
;
267 /* Go to the next alias in the list */
268 CurrentAlias
= CurrentAlias
->Next
;
272 /* Did we find any alias? */
273 if (CurrentAlias
== NULL
)
275 /* Nothing found, no matching alias */
276 return STATUS_SUCCESS
;
279 /* Check whether we can use our stack buffer */
280 if (Length
<= MAX_INDEXED_LENGTH
* sizeof(WCHAR
))
282 /* Initialize the upcased string */
283 UpcaseString
.Buffer
= UpcaseBuffer
;
284 UpcaseString
.MaximumLength
= sizeof(UpcaseBuffer
);
286 /* Upcase the pipe name */
287 Status
= RtlUpcaseUnicodeString(&UpcaseString
, PipeName
, FALSE
);
288 NT_ASSERT(NT_SUCCESS(Status
));
289 BufferAllocated
= FALSE
;
293 /* Upcase the pipe name, allocate the string buffer */
294 Status
= RtlUpcaseUnicodeString(&UpcaseString
, PipeName
, TRUE
);
295 if (!NT_SUCCESS(Status
))
300 BufferAllocated
= TRUE
;
303 /* Did the original name start with a backslash? */
306 /* Skip it for the comparison */
307 UpcaseString
.Buffer
++;
308 UpcaseString
.Length
-= sizeof(WCHAR
);
311 /* Make sure the length matches the "raw" length */
312 NT_ASSERT(UpcaseString
.Length
== Length
);
313 NT_ASSERT(CurrentAlias
->Name
.Length
== Length
);
315 /* Loop while we have aliases */
318 /* Compare the names and check if they match */
319 Result
= NpCompareAliasNames(&UpcaseString
, &CurrentAlias
->Name
);
322 /* The names match, use the target name */
323 *PipeName
= *CurrentAlias
->TargetName
;
325 /* Did the original name start with a backslash? */
328 /* It didn't, so skip it in the target name as well */
330 PipeName
->Length
-= sizeof(WCHAR
);
335 /* Check if we went past all string candidates */
338 /* Nothing found, we're done */
342 /* Go to the next alias */
343 CurrentAlias
= CurrentAlias
->Next
;
345 /* Keep looping while we have aliases of the right length */
346 } while ((CurrentAlias
!= NULL
) && (CurrentAlias
->Name
.Length
== Length
));
348 /* Did we allocate a buffer? */
351 /* Free the allocated buffer */
352 ASSERT(UpcaseString
.Buffer
!= UpcaseBuffer
);
353 RtlFreeUnicodeString(&UpcaseString
);
356 return STATUS_SUCCESS
;
361 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject
,
364 IO_STATUS_BLOCK IoStatus
;
365 PEXTENDED_IO_STACK_LOCATION IoStack
;
366 UNICODE_STRING FileName
;
367 PFILE_OBJECT FileObject
;
368 PFILE_OBJECT RelatedFileObject
;
373 ACCESS_MASK DesiredAccess
;
374 LIST_ENTRY DeferredList
;
375 UNICODE_STRING Prefix
;
379 InitializeListHead(&DeferredList
);
380 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
381 FileObject
= IoStack
->FileObject
;
382 RelatedFileObject
= FileObject
->RelatedFileObject
;
383 FileName
= FileObject
->FileName
;
384 DesiredAccess
= IoStack
->Parameters
.CreatePipe
.SecurityContext
->DesiredAccess
;
386 IoStatus
.Information
= 0;
387 IoStatus
.Status
= STATUS_SUCCESS
;
389 FsRtlEnterFileSystem();
390 ExAcquireResourceExclusiveLite(&NpVcb
->Lock
, TRUE
);
392 if (RelatedFileObject
)
394 Type
= NpDecodeFileObject(RelatedFileObject
, (PVOID
*)&Fcb
, &Ccb
, FALSE
);
405 if ((FileName
.Length
== sizeof(OBJ_NAME_PATH_SEPARATOR
)) &&
406 (FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
) &&
407 !(RelatedFileObject
))
409 IoStatus
= NpOpenNamedPipeRootDirectory(NpVcb
->RootDcb
,
416 else if (!(RelatedFileObject
) || (Type
== NPFS_NTC_VCB
))
418 IoStatus
= NpOpenNamedPipeFileSystem(FileObject
,
422 else if (Type
== NPFS_NTC_ROOT_DCB
)
424 IoStatus
= NpOpenNamedPipeRootDirectory(NpVcb
->RootDcb
,
431 Status
= NpTranslateAlias(&FileName
);
432 if (!NT_SUCCESS(Status
)) goto Quickie
;
434 if (RelatedFileObject
)
436 if (Type
== NPFS_NTC_ROOT_DCB
)
439 IoStatus
.Status
= NpFindRelativePrefix(Dcb
,
444 if (!NT_SUCCESS(IoStatus
.Status
))
449 else if ((Type
!= NPFS_NTC_CCB
) || (FileName
.Length
))
451 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
461 if ((FileName
.Length
<= sizeof(OBJ_NAME_PATH_SEPARATOR
)) ||
462 (FileName
.Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
))
464 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
468 Fcb
= NpFindPrefix(&FileName
, TRUE
, &Prefix
);
473 IoStatus
.Status
= Fcb
->NodeType
!= NPFS_NTC_FCB
?
474 STATUS_OBJECT_NAME_NOT_FOUND
:
475 STATUS_OBJECT_NAME_INVALID
;
479 if (Fcb
->NodeType
!= NPFS_NTC_FCB
)
481 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
485 if (!Fcb
->ServerOpenCount
)
487 IoStatus
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
491 IoStatus
= NpCreateClientEnd(Fcb
,
494 IoStack
->Parameters
.CreatePipe
.
495 SecurityContext
->SecurityQos
,
496 IoStack
->Parameters
.CreatePipe
.
497 SecurityContext
->AccessState
,
499 SL_FORCE_ACCESS_CHECK
?
500 UserMode
: Irp
->RequestorMode
,
501 Irp
->Tail
.Overlay
.Thread
,
505 ExReleaseResourceLite(&NpVcb
->Lock
);
506 NpCompleteDeferredIrps(&DeferredList
);
507 FsRtlExitFileSystem();
509 Irp
->IoStatus
= IoStatus
;
510 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
511 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
512 return IoStatus
.Status
;
517 NpCreateExistingNamedPipe(IN PNP_FCB Fcb
,
518 IN PFILE_OBJECT FileObject
,
519 IN ACCESS_MASK DesiredAccess
,
520 IN PACCESS_STATE AccessState
,
521 IN KPROCESSOR_MODE PreviousMode
,
522 IN ULONG Disposition
,
523 IN ULONG ShareAccess
,
524 IN PNAMED_PIPE_CREATE_PARAMETERS Parameters
,
525 IN PEPROCESS Process
,
526 OUT PLIST_ENTRY List
)
528 PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
529 IO_STATUS_BLOCK IoStatus
;
530 UNICODE_STRING ObjectTypeName
;
531 ACCESS_MASK GrantedAccess
;
533 PPRIVILEGE_SET Privileges
;
534 USHORT NamedPipeConfiguration
, CheckShareAccess
;
535 BOOLEAN AccessGranted
;
541 NamedPipeConfiguration
= Fcb
->NamedPipeConfiguration
;
543 SubjectSecurityContext
= &AccessState
->SubjectSecurityContext
;
544 SeLockSubjectContext(SubjectSecurityContext
);
546 AccessGranted
= SeAccessCheck(Fcb
->SecurityDescriptor
,
547 SubjectSecurityContext
,
552 IoGetFileObjectGenericMapping(),
559 SeAppendPrivileges(AccessState
, Privileges
);
560 SeFreePrivileges(Privileges
);
565 AccessState
->PreviouslyGrantedAccess
|= GrantedAccess
;
566 AccessState
->RemainingDesiredAccess
&= ~(GrantedAccess
| 0x2000000);
569 ObjectTypeName
.Buffer
= L
"NamedPipe";
570 ObjectTypeName
.Length
= 18;
571 SeOpenObjectAuditAlarm(&ObjectTypeName
,
573 &FileObject
->FileName
,
574 Fcb
->SecurityDescriptor
,
579 &AccessState
->GenerateOnClose
);
581 SeUnlockSubjectContext(SubjectSecurityContext
);
584 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
588 if (Fcb
->CurrentInstances
>= Fcb
->MaximumInstances
)
590 IoStatus
.Status
= STATUS_INSTANCE_NOT_AVAILABLE
;
591 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
595 if (Disposition
== FILE_CREATE
)
597 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
598 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
602 CheckShareAccess
= 0;
603 if (NamedPipeConfiguration
== FILE_PIPE_FULL_DUPLEX
)
605 CheckShareAccess
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
607 else if (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)
609 CheckShareAccess
= FILE_SHARE_READ
;
611 else if (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)
613 CheckShareAccess
= FILE_SHARE_WRITE
;
616 if (CheckShareAccess
!= ShareAccess
)
618 IoStatus
.Status
= STATUS_ACCESS_DENIED
;
619 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
623 IoStatus
.Status
= NpCreateCcb(Fcb
,
625 FILE_PIPE_LISTENING_STATE
,
626 Parameters
->ReadMode
& 0xFF,
627 Parameters
->CompletionMode
& 0xFF,
628 Parameters
->InboundQuota
,
629 Parameters
->OutboundQuota
,
631 if (!NT_SUCCESS(IoStatus
.Status
)) return IoStatus
;
633 IoStatus
.Status
= NpCancelWaiter(&NpVcb
->WaitQueue
,
637 if (!NT_SUCCESS(IoStatus
.Status
))
639 --Ccb
->Fcb
->CurrentInstances
;
640 NpDeleteCcb(Ccb
, List
);
641 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
645 NpSetFileObject(FileObject
, Ccb
, Ccb
->NonPagedCcb
, TRUE
);
646 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
647 NpCheckForNotify(Fcb
->ParentDcb
, 0, List
);
649 IoStatus
.Status
= STATUS_SUCCESS
;
650 IoStatus
.Information
= 1;
651 TRACE("Leaving, IoStatus = %lx\n", IoStatus
);
657 NpCreateNewNamedPipe(IN PNP_DCB Dcb
,
658 IN PFILE_OBJECT FileObject
,
659 IN UNICODE_STRING PipeName
,
660 IN ACCESS_MASK DesiredAccess
,
661 IN PACCESS_STATE AccessState
,
662 IN USHORT Disposition
,
663 IN USHORT ShareAccess
,
664 IN PNAMED_PIPE_CREATE_PARAMETERS Parameters
,
665 IN PEPROCESS Process
,
667 IN PIO_STATUS_BLOCK IoStatus
)
670 USHORT NamedPipeConfiguration
;
671 PSECURITY_SUBJECT_CONTEXT SecurityContext
;
672 PSECURITY_DESCRIPTOR SecurityDescriptor
, CachedSecurityDescriptor
;
678 if (!(Parameters
->TimeoutSpecified
) ||
679 !(Parameters
->MaximumInstances
) ||
680 (Parameters
->DefaultTimeout
.HighPart
>= 0))
682 Status
= STATUS_INVALID_PARAMETER
;
686 if (Disposition
== FILE_OPEN
)
688 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
692 if (ShareAccess
== (FILE_SHARE_READ
| FILE_SHARE_WRITE
))
694 NamedPipeConfiguration
= FILE_PIPE_FULL_DUPLEX
;
696 else if (ShareAccess
== FILE_SHARE_READ
)
698 NamedPipeConfiguration
= FILE_PIPE_OUTBOUND
;
700 else if (ShareAccess
== FILE_SHARE_WRITE
)
702 NamedPipeConfiguration
= FILE_PIPE_INBOUND
;
706 Status
= STATUS_INVALID_PARAMETER
;
710 if (!Parameters
->NamedPipeType
&& Parameters
->ReadMode
== 1)
712 Status
= STATUS_INVALID_PARAMETER
;
716 Status
= NpCreateFcb(Dcb
,
718 Parameters
->MaximumInstances
,
719 Parameters
->DefaultTimeout
,
720 NamedPipeConfiguration
,
721 Parameters
->NamedPipeType
& 0xFFFF,
723 if (!NT_SUCCESS(Status
)) goto Quickie
;
725 Status
= NpCreateCcb(Fcb
,
727 FILE_PIPE_LISTENING_STATE
,
728 Parameters
->ReadMode
& 0xFF,
729 Parameters
->CompletionMode
& 0xFF,
730 Parameters
->InboundQuota
,
731 Parameters
->OutboundQuota
,
733 if (!NT_SUCCESS(Status
))
735 NpDeleteFcb(Fcb
, List
);
739 SecurityContext
= &AccessState
->SubjectSecurityContext
;
740 SeLockSubjectContext(&AccessState
->SubjectSecurityContext
);
742 Status
= SeAssignSecurity(0,
743 AccessState
->SecurityDescriptor
,
747 IoGetFileObjectGenericMapping(),
749 SeUnlockSubjectContext(SecurityContext
);
750 if (!NT_SUCCESS(Status
))
752 NpDeleteCcb(Ccb
, List
);
753 NpDeleteFcb(Fcb
, List
);
757 Status
= ObLogSecurityDescriptor(SecurityDescriptor
,
758 &CachedSecurityDescriptor
,
760 ExFreePool(SecurityDescriptor
);
762 if (!NT_SUCCESS(Status
))
764 NpDeleteCcb(Ccb
, List
);
765 NpDeleteFcb(Fcb
, List
);
769 Fcb
->SecurityDescriptor
= CachedSecurityDescriptor
;
771 NpSetFileObject(FileObject
, Ccb
, Ccb
->NonPagedCcb
, TRUE
);
772 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
774 NpCheckForNotify(Dcb
, TRUE
, List
);
776 IoStatus
->Status
= STATUS_SUCCESS
;
777 IoStatus
->Information
= FILE_CREATED
;
779 TRACE("Leaving, STATUS_SUCCESS\n");
780 return STATUS_SUCCESS
;
783 TRACE("Leaving, Status = %lx\n", Status
);
784 IoStatus
->Information
= 0;
785 IoStatus
->Status
= Status
;
791 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject
,
794 PEXTENDED_IO_STACK_LOCATION IoStack
;
795 PFILE_OBJECT FileObject
;
796 PFILE_OBJECT RelatedFileObject
;
797 USHORT Disposition
, ShareAccess
;
799 LIST_ENTRY DeferredList
;
800 UNICODE_STRING FileName
;
802 UNICODE_STRING Prefix
;
803 PNAMED_PIPE_CREATE_PARAMETERS Parameters
;
804 IO_STATUS_BLOCK IoStatus
;
807 InitializeListHead(&DeferredList
);
808 Process
= IoGetRequestorProcess(Irp
);
810 IoStack
= (PEXTENDED_IO_STACK_LOCATION
) IoGetCurrentIrpStackLocation(Irp
);
811 FileObject
= IoStack
->FileObject
;
812 RelatedFileObject
= FileObject
->RelatedFileObject
;
814 Disposition
= (IoStack
->Parameters
.CreatePipe
.Options
>> 24) & 0xFF;
815 ShareAccess
= IoStack
->Parameters
.CreatePipe
.ShareAccess
& 0xFFFF;
816 Parameters
= IoStack
->Parameters
.CreatePipe
.Parameters
;
818 FileName
= FileObject
->FileName
;
820 IoStatus
.Status
= STATUS_SUCCESS
;
821 IoStatus
.Information
= 0;
823 FsRtlEnterFileSystem();
824 NpAcquireExclusiveVcb();
826 if (RelatedFileObject
)
828 Fcb
= (PNP_FCB
)((ULONG_PTR
)RelatedFileObject
->FsContext
& ~1);
830 (Fcb
->NodeType
!= NPFS_NTC_ROOT_DCB
) ||
831 (FileName
.Length
< sizeof(WCHAR
)) ||
832 (FileName
.Buffer
[0] == OBJ_NAME_PATH_SEPARATOR
))
834 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
838 IoStatus
.Status
= NpFindRelativePrefix(RelatedFileObject
->FsContext
,
843 if (!NT_SUCCESS(IoStatus
.Status
))
850 if (FileName
.Length
<= sizeof(OBJ_NAME_PATH_SEPARATOR
) ||
851 FileName
.Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
)
853 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
857 Fcb
= NpFindPrefix(&FileName
, TRUE
, &Prefix
);
862 if (Fcb
->NodeType
== NPFS_NTC_ROOT_DCB
)
864 IoStatus
.Status
= NpCreateNewNamedPipe((PNP_DCB
)Fcb
,
867 IoStack
->Parameters
.CreatePipe
.
868 SecurityContext
->DesiredAccess
,
869 IoStack
->Parameters
.CreatePipe
.
870 SecurityContext
->AccessState
,
881 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
886 if (Fcb
->NodeType
!= NPFS_NTC_FCB
)
888 IoStatus
.Status
= STATUS_OBJECT_NAME_INVALID
;
892 IoStatus
= NpCreateExistingNamedPipe(Fcb
,
894 IoStack
->Parameters
.CreatePipe
.
895 SecurityContext
->DesiredAccess
,
896 IoStack
->Parameters
.CreatePipe
.
897 SecurityContext
->AccessState
,
899 SL_FORCE_ACCESS_CHECK
?
900 UserMode
: Irp
->RequestorMode
,
909 NpCompleteDeferredIrps(&DeferredList
);
910 FsRtlExitFileSystem();
912 TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus
.Status
);
913 Irp
->IoStatus
= IoStatus
;
914 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
915 return IoStatus
.Status
;