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 ********************************************************************/
20 PWCHAR NpRootDCBName
= L
"\\";
23 /* FUNCTIONS ******************************************************************/
25 RTL_GENERIC_COMPARE_RESULTS
27 NpEventTableCompareRoutine(IN PRTL_GENERIC_TABLE Table
,
29 IN PVOID SecondStruct
)
37 NpEventTableAllocate(IN PRTL_GENERIC_TABLE Table
,
46 NpEventTableDeallocate(IN PRTL_GENERIC_TABLE Table
,
54 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table
,
57 if (!Buffer
) return FALSE
;
59 ObDereferenceObject(((PNP_EVENT_BUFFER
)Buffer
)->Event
);
60 return RtlDeleteElementGenericTable(Table
, Buffer
);
65 NpDeleteFcb(IN PNP_FCB Fcb
,
66 IN PLIST_ENTRY ListEntry
)
72 if (Fcb
->CurrentInstances
) NpBugCheck(0, 0, 0);
74 NpCancelWaiter(&NpVcb
->WaitQueue
,
76 STATUS_OBJECT_NAME_NOT_FOUND
,
79 RemoveEntryList(&Fcb
->DcbEntry
);
81 if (Fcb
->SecurityDescriptor
)
83 ObDereferenceSecurityDescriptor(Fcb
->SecurityDescriptor
, 1);
86 RtlRemoveUnicodePrefix(&NpVcb
->PrefixTable
, &Fcb
->PrefixTableEntry
);
87 ExFreePool(Fcb
->FullName
.Buffer
);
89 NpCheckForNotify(Dcb
, TRUE
, ListEntry
);
94 NpDeleteCcb(IN PNP_CCB Ccb
,
95 IN PLIST_ENTRY ListEntry
)
97 PNP_ROOT_DCB_FCB RootDcbCcb
;
100 RootDcbCcb
= (PNP_ROOT_DCB_FCB
)Ccb
;
101 if (Ccb
->NodeType
== NPFS_NTC_CCB
)
103 RemoveEntryList(&Ccb
->CcbEntry
);
104 --Ccb
->Fcb
->CurrentInstances
;
106 NpDeleteEventTableEntry(&NpVcb
->EventTable
,
107 Ccb
->NonPagedCcb
->EventBuffer
[FILE_PIPE_CLIENT_END
]);
108 NpDeleteEventTableEntry(&NpVcb
->EventTable
,
109 Ccb
->NonPagedCcb
->EventBuffer
[FILE_PIPE_SERVER_END
]);
110 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
]);
111 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
]);
112 NpCheckForNotify(Ccb
->Fcb
->ParentDcb
, FALSE
, ListEntry
);
113 ExDeleteResourceLite(&Ccb
->NonPagedCcb
->Lock
);
114 NpUninitializeSecurity(Ccb
);
115 if (Ccb
->ClientSession
)
117 ExFreePool(Ccb
->ClientSession
);
118 Ccb
->ClientSession
= NULL
;
120 ExFreePool(Ccb
->NonPagedCcb
);
122 else if (RootDcbCcb
->NodeType
== NPFS_NTC_ROOT_DCB_CCB
&& RootDcbCcb
->Unknown
)
124 ExFreePool(RootDcbCcb
->Unknown
);
132 NpInitializeVcb(VOID
)
136 RtlZeroMemory(NpVcb
, sizeof(*NpVcb
));
138 NpVcb
->NodeType
= NPFS_NTC_VCB
;
139 RtlInitializeUnicodePrefix(&NpVcb
->PrefixTable
);
140 ExInitializeResourceLite(&NpVcb
->Lock
);
141 RtlInitializeGenericTable(&NpVcb
->EventTable
,
142 NpEventTableCompareRoutine
,
143 NpEventTableAllocate
,
144 NpEventTableDeallocate
,
146 NpInitializeWaitQueue(&NpVcb
->WaitQueue
);
151 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB
*NewRootCcb
)
153 PNP_ROOT_DCB_FCB RootCcb
;
156 RootCcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*RootCcb
), NPFS_ROOT_DCB_CCB_TAG
);
157 if (!RootCcb
) return STATUS_INSUFFICIENT_RESOURCES
;
159 RtlZeroMemory(RootCcb
, sizeof(*RootCcb
));
160 RootCcb
->NodeType
= NPFS_NTC_ROOT_DCB_CCB
;
161 *NewRootCcb
= RootCcb
;
162 return STATUS_SUCCESS
;
167 NpCreateRootDcb(VOID
)
177 NpVcb
->RootDcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Dcb
), NPFS_DCB_TAG
);
180 return STATUS_INSUFFICIENT_RESOURCES
;
183 Dcb
= NpVcb
->RootDcb
;
184 RtlZeroMemory(Dcb
, sizeof(*Dcb
));
185 Dcb
->NodeType
= NPFS_NTC_ROOT_DCB
;
187 InitializeListHead(&Dcb
->DcbEntry
);
188 InitializeListHead(&Dcb
->NotifyList
);
189 InitializeListHead(&Dcb
->NotifyList2
);
190 InitializeListHead(&Dcb
->FcbList
);
192 Dcb
->FullName
.Buffer
= NpRootDCBName
;
193 Dcb
->FullName
.Length
= 2;
194 Dcb
->FullName
.MaximumLength
= 4;
196 Dcb
->ShortName
.Length
= Dcb
->FullName
.Length
;
197 Dcb
->ShortName
.MaximumLength
= Dcb
->FullName
.MaximumLength
;
198 Dcb
->ShortName
.Buffer
= Dcb
->FullName
.Buffer
;
200 if (!RtlInsertUnicodePrefix(&NpVcb
->PrefixTable
,
202 &Dcb
->PrefixTableEntry
))
207 return STATUS_SUCCESS
;
212 NpCreateFcb(IN PNP_DCB Dcb
,
213 IN PUNICODE_STRING PipeName
,
214 IN ULONG MaximumInstances
,
215 IN LARGE_INTEGER Timeout
,
216 IN USHORT NamedPipeConfiguration
,
217 IN USHORT NamedPipeType
,
224 USHORT Length
, MaximumLength
;
227 Length
= PipeName
->Length
;
228 MaximumLength
= Length
+ sizeof(UNICODE_NULL
);
230 if ((Length
< sizeof(WCHAR
)) || (MaximumLength
< Length
))
232 return STATUS_INVALID_PARAMETER
;
236 if (PipeName
->Buffer
[0] != OBJ_NAME_PATH_SEPARATOR
)
238 MaximumLength
+= sizeof(OBJ_NAME_PATH_SEPARATOR
);
240 if (MaximumLength
< sizeof(WCHAR
))
242 return STATUS_INVALID_PARAMETER
;
246 Fcb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Fcb
), NPFS_FCB_TAG
);
247 if (!Fcb
) return STATUS_INSUFFICIENT_RESOURCES
;
249 RtlZeroMemory(Fcb
, sizeof(*Fcb
));
250 Fcb
->MaximumInstances
= MaximumInstances
;
251 Fcb
->Timeout
= Timeout
;
252 Fcb
->NodeType
= NPFS_NTC_FCB
;
253 Fcb
->ParentDcb
= Dcb
;
254 InitializeListHead(&Fcb
->CcbList
);
256 NameBuffer
= ExAllocatePoolWithTag(PagedPool
,
258 NPFS_NAME_BLOCK_TAG
);
262 return STATUS_INSUFFICIENT_RESOURCES
;
265 InsertTailList(&Dcb
->FcbList
, &Fcb
->DcbEntry
);
270 NameBuffer
[0] = OBJ_NAME_PATH_SEPARATOR
;
274 RtlCopyMemory(NameBuffer
+ BufferOffset
, PipeName
->Buffer
, Length
);
275 NameBuffer
[BufferOffset
+ (Length
/ sizeof(WCHAR
))] = UNICODE_NULL
;
277 Fcb
->FullName
.Length
= Length
;
278 Fcb
->FullName
.MaximumLength
= MaximumLength
;
279 Fcb
->FullName
.Buffer
= NameBuffer
;
281 Fcb
->ShortName
.MaximumLength
= Length
;
282 Fcb
->ShortName
.Length
= Length
- sizeof(OBJ_NAME_PATH_SEPARATOR
);
283 Fcb
->ShortName
.Buffer
= NameBuffer
+ 1;
285 if (!RtlInsertUnicodePrefix(&NpVcb
->PrefixTable
,
287 &Fcb
->PrefixTableEntry
))
292 Fcb
->NamedPipeConfiguration
= NamedPipeConfiguration
;
293 Fcb
->NamedPipeType
= NamedPipeType
;
295 return STATUS_SUCCESS
;
300 NpCreateCcb(IN PNP_FCB Fcb
,
301 IN PFILE_OBJECT FileObject
,
304 IN UCHAR CompletionMode
,
310 PNP_NONPAGED_CCB CcbNonPaged
;
314 Ccb
= ExAllocatePoolWithTag(PagedPool
, sizeof(*Ccb
), NPFS_CCB_TAG
);
315 if (!Ccb
) return STATUS_INSUFFICIENT_RESOURCES
;
317 CcbNonPaged
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(*CcbNonPaged
), NPFS_CCB_TAG
);
321 return STATUS_INSUFFICIENT_RESOURCES
;
324 RtlZeroMemory(CcbNonPaged
, sizeof(*CcbNonPaged
));
325 CcbNonPaged
->NodeType
= NPFS_NTC_NONPAGED_CCB
;
327 RtlZeroMemory(Ccb
, sizeof(*Ccb
));
328 Ccb
->NodeType
= NPFS_NTC_CCB
;
329 Ccb
->NonPagedCcb
= CcbNonPaged
;
330 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = FileObject
;
332 Ccb
->NamedPipeState
= State
;
333 Ccb
->ReadMode
[FILE_PIPE_SERVER_END
] = ReadMode
;
334 Ccb
->CompletionMode
[FILE_PIPE_SERVER_END
] = CompletionMode
;
336 Status
= NpInitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
], InQuota
);
337 if (!NT_SUCCESS(Status
))
339 ExFreePool(CcbNonPaged
);
341 return STATUS_INSUFFICIENT_RESOURCES
;
344 Status
= NpInitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
], OutQuota
);
345 if (!NT_SUCCESS(Status
))
347 NpUninitializeDataQueue(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
]);
348 ExFreePool(CcbNonPaged
);
350 return STATUS_INSUFFICIENT_RESOURCES
;
353 InsertTailList(&Fcb
->CcbList
, &Ccb
->CcbEntry
);
355 Fcb
->CurrentInstances
++;
356 Fcb
->ServerOpenCount
++;
357 InitializeListHead(&Ccb
->IrpList
);
358 ExInitializeResourceLite(&Ccb
->NonPagedCcb
->Lock
);
360 return STATUS_SUCCESS
;