2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/strucsup.c
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_STRUCSUP)
16 /* GLOBALS ********************************************************************/
18 PWCHAR NpRootDCBName
= L
"\\";
21 /* FUNCTIONS ******************************************************************/
23 RTL_GENERIC_COMPARE_RESULTS
25 NpEventTableCompareRoutine(IN PRTL_GENERIC_TABLE Table
,
27 IN PVOID SecondStruct
)
35 NpEventTableAllocate(IN PRTL_GENERIC_TABLE Table
,
44 NpEventTableDeallocate(IN PRTL_GENERIC_TABLE Table
,
52 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table
,
55 if (!Buffer
) return FALSE
;
57 ObDereferenceObject(((PNP_EVENT_BUFFER
)Buffer
)->Event
);
58 return RtlDeleteElementGenericTable(Table
, Buffer
);
63 NpDeleteFcb(IN PNP_FCB Fcb
,
64 IN PLIST_ENTRY ListEntry
)
70 if (Fcb
->CurrentInstances
) NpBugCheck(0, 0, 0);
72 NpCancelWaiter(&NpVcb
->WaitQueue
,
74 STATUS_OBJECT_NAME_NOT_FOUND
,
77 RemoveEntryList(&Fcb
->DcbEntry
);
79 if (Fcb
->SecurityDescriptor
)
81 ObDereferenceSecurityDescriptor(Fcb
->SecurityDescriptor
, 1);
84 RtlRemoveUnicodePrefix(&NpVcb
->PrefixTable
, &Fcb
->PrefixTableEntry
);
85 ExFreePool(Fcb
->FullName
.Buffer
);
87 NpCheckForNotify(Dcb
, TRUE
, ListEntry
);
92 NpDeleteCcb(IN PNP_CCB Ccb
,
93 IN PLIST_ENTRY ListEntry
)
95 PNP_ROOT_DCB_FCB RootDcbCcb
;
98 RootDcbCcb
= (PNP_ROOT_DCB_FCB
)Ccb
;
99 if (Ccb
->NodeType
== NPFS_NTC_CCB
)
101 RemoveEntryList(&Ccb
->CcbEntry
);
102 --Ccb
->Fcb
->CurrentInstances
;
104 NpDeleteEventTableEntry(&NpVcb
->EventTable
,
105 Ccb
->NonPagedCcb
->EventBuffer
[FILE_PIPE_CLIENT_END
]);
106 NpDeleteEventTableEntry(&NpVcb
->EventTable
,
107 Ccb
->NonPagedCcb
->EventBuffer
[FILE_PIPE_SERVER_END
]);
108 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
]);
109 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
]);
110 NpCheckForNotify(Ccb
->Fcb
->ParentDcb
, FALSE
, ListEntry
);
111 ExDeleteResourceLite(&Ccb
->NonPagedCcb
->Lock
);
112 NpUninitializeSecurity(Ccb
);
113 if (Ccb
->ClientSession
)
115 ExFreePool(Ccb
->ClientSession
);
116 Ccb
->ClientSession
= NULL
;
118 ExFreePool(Ccb
->NonPagedCcb
);
120 else if (RootDcbCcb
->NodeType
== NPFS_NTC_ROOT_DCB_CCB
&& RootDcbCcb
->Unknown
)
122 ExFreePool(RootDcbCcb
->Unknown
);
130 NpInitializeVcb(VOID
)
134 RtlZeroMemory(NpVcb
, sizeof(*NpVcb
));
136 NpVcb
->NodeType
= NPFS_NTC_VCB
;
137 RtlInitializeUnicodePrefix(&NpVcb
->PrefixTable
);
138 ExInitializeResourceLite(&NpVcb
->Lock
);
139 RtlInitializeGenericTable(&NpVcb
->EventTable
,
140 NpEventTableCompareRoutine
,
141 NpEventTableAllocate
,
142 NpEventTableDeallocate
,
144 NpInitializeWaitQueue(&NpVcb
->WaitQueue
);
149 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB
*NewRootCcb
)
151 PNP_ROOT_DCB_FCB RootCcb
;
154 RootCcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*RootCcb
), NPFS_ROOT_DCB_CCB_TAG
);
155 if (!RootCcb
) return STATUS_INSUFFICIENT_RESOURCES
;
157 RtlZeroMemory(RootCcb
, sizeof(*RootCcb
));
158 RootCcb
->NodeType
= NPFS_NTC_ROOT_DCB_CCB
;
159 *NewRootCcb
= RootCcb
;
160 return STATUS_SUCCESS
;
165 NpCreateRootDcb(VOID
)
175 NpVcb
->RootDcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Dcb
), NPFS_DCB_TAG
);
178 return STATUS_INSUFFICIENT_RESOURCES
;
181 Dcb
= NpVcb
->RootDcb
;
182 RtlZeroMemory(Dcb
, sizeof(*Dcb
));
183 Dcb
->NodeType
= NPFS_NTC_ROOT_DCB
;
185 InitializeListHead(&Dcb
->DcbEntry
);
186 InitializeListHead(&Dcb
->NotifyList
);
187 InitializeListHead(&Dcb
->NotifyList2
);
188 InitializeListHead(&Dcb
->FcbList
);
190 Dcb
->FullName
.Buffer
= NpRootDCBName
;
191 Dcb
->FullName
.Length
= 2;
192 Dcb
->FullName
.MaximumLength
= 4;
194 Dcb
->ShortName
.Length
= Dcb
->FullName
.Length
;
195 Dcb
->ShortName
.MaximumLength
= Dcb
->FullName
.MaximumLength
;
196 Dcb
->ShortName
.Buffer
= Dcb
->FullName
.Buffer
;
198 if (!RtlInsertUnicodePrefix(&NpVcb
->PrefixTable
,
200 &Dcb
->PrefixTableEntry
))
205 return STATUS_SUCCESS
;
210 NpCreateFcb(IN PNP_DCB Dcb
,
211 IN PUNICODE_STRING PipeName
,
212 IN ULONG MaximumInstances
,
213 IN LARGE_INTEGER Timeout
,
214 IN USHORT NamedPipeConfiguration
,
215 IN USHORT NamedPipeType
,
222 USHORT Length
, MaximumLength
;
225 Length
= PipeName
->Length
;
226 MaximumLength
= Length
+ sizeof(UNICODE_NULL
);
228 if ((Length
< sizeof(WCHAR
)) || (MaximumLength
< Length
))
230 return STATUS_INVALID_PARAMETER
;
234 if (PipeName
->Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
)
236 MaximumLength
+= sizeof(OBJ_NAME_PATH_SEPARATOR
);
238 if (MaximumLength
< sizeof(WCHAR
))
240 return STATUS_INVALID_PARAMETER
;
244 Fcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Fcb
), NPFS_FCB_TAG
);
245 if (!Fcb
) return STATUS_INSUFFICIENT_RESOURCES
;
247 RtlZeroMemory(Fcb
, sizeof(*Fcb
));
248 Fcb
->MaximumInstances
= MaximumInstances
;
249 Fcb
->Timeout
= Timeout
;
250 Fcb
->NodeType
= NPFS_NTC_FCB
;
251 Fcb
->ParentDcb
= Dcb
;
252 InitializeListHead(&Fcb
->CcbList
);
254 NameBuffer
= ExAllocatePoolWithTag(PagedPool
,
256 NPFS_NAME_BLOCK_TAG
);
260 return STATUS_INSUFFICIENT_RESOURCES
;
263 InsertTailList(&Dcb
->FcbList
, &Fcb
->DcbEntry
);
268 NameBuffer
[0] = OBJ_NAME_PATH_SEPARATOR
;
272 RtlCopyMemory(NameBuffer
+ BufferOffset
, PipeName
->Buffer
, Length
);
273 NameBuffer
[BufferOffset
+ (Length
/ sizeof(WCHAR
))] = UNICODE_NULL
;
275 Fcb
->FullName
.Length
= Length
;
276 Fcb
->FullName
.MaximumLength
= MaximumLength
;
277 Fcb
->FullName
.Buffer
= NameBuffer
;
279 Fcb
->ShortName
.MaximumLength
= Length
;
280 Fcb
->ShortName
.Length
= Length
- sizeof(OBJ_NAME_PATH_SEPARATOR
);
281 Fcb
->ShortName
.Buffer
= NameBuffer
+ 1;
283 if (!RtlInsertUnicodePrefix(&NpVcb
->PrefixTable
,
285 &Fcb
->PrefixTableEntry
))
290 Fcb
->NamedPipeConfiguration
= NamedPipeConfiguration
;
291 Fcb
->NamedPipeType
= NamedPipeType
;
293 return STATUS_SUCCESS
;
298 NpCreateCcb(IN PNP_FCB Fcb
,
299 IN PFILE_OBJECT FileObject
,
302 IN UCHAR CompletionMode
,
308 PNP_NONPAGED_CCB CcbNonPaged
;
312 Ccb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Ccb
), NPFS_CCB_TAG
);
313 if (!Ccb
) return STATUS_INSUFFICIENT_RESOURCES
;
315 CcbNonPaged
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(*CcbNonPaged
), NPFS_CCB_TAG
);
319 return STATUS_INSUFFICIENT_RESOURCES
;
322 RtlZeroMemory(CcbNonPaged
, sizeof(*CcbNonPaged
));
323 CcbNonPaged
->NodeType
= NPFS_NTC_NONPAGED_CCB
;
325 RtlZeroMemory(Ccb
, sizeof(*Ccb
));
326 Ccb
->NodeType
= NPFS_NTC_CCB
;
327 Ccb
->NonPagedCcb
= CcbNonPaged
;
328 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
330 Ccb
->NamedPipeState
= State
;
331 Ccb
->ReadMode
[FILE_PIPE_SERVER_END
] = ReadMode
;
332 Ccb
->CompletionMode
[FILE_PIPE_SERVER_END
] = CompletionMode
;
334 Status
= NpInitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
], InQuota
);
335 if (!NT_SUCCESS(Status
))
337 ExFreePool(CcbNonPaged
);
339 return STATUS_INSUFFICIENT_RESOURCES
;
342 Status
= NpInitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
], OutQuota
);
343 if (!NT_SUCCESS(Status
))
345 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
]);
346 ExFreePool(CcbNonPaged
);
348 return STATUS_INSUFFICIENT_RESOURCES
;
351 InsertTailList(&Fcb
->CcbList
, &Ccb
->CcbEntry
);
353 Fcb
->CurrentInstances
++;
354 Fcb
->ServerOpenCount
++;
355 InitializeListHead(&Ccb
->IrpList
);
356 ExInitializeResourceLite(&Ccb
->NonPagedCcb
->Lock
);
358 return STATUS_SUCCESS
;