https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f75ea083e356c4c9eba0e…
commit f75ea083e356c4c9eba0e59262f5fbeeca241136
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Tue Dec 25 13:45:41 2018 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Tue Dec 25 13:50:41 2018 +0100
[NTOSKRNL_VISTA] Implement FsRtlGetEcpListFromIrp and
FsRtlGetNextExtraCreateParameter
CORE-15452
---
sdk/lib/drivers/ntoskrnl_vista/fsrtl.c | 119 +++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/sdk/lib/drivers/ntoskrnl_vista/fsrtl.c
b/sdk/lib/drivers/ntoskrnl_vista/fsrtl.c
index 4d7831aa4c..8b714af57a 100644
--- a/sdk/lib/drivers/ntoskrnl_vista/fsrtl.c
+++ b/sdk/lib/drivers/ntoskrnl_vista/fsrtl.c
@@ -9,6 +9,33 @@
#include <ntdef.h>
#include <ntifs.h>
+typedef struct _ECP_LIST
+{
+ ULONG Signature;
+ ULONG Flags;
+ LIST_ENTRY EcpList;
+} ECP_LIST, *PECP_LIST;
+
+typedef ULONG ECP_HEADER_FLAGS;
+
+typedef struct _ECP_HEADER
+{
+ ULONG Signature;
+ ULONG Spare;
+ LIST_ENTRY ListEntry;
+ GUID EcpType;
+ PFSRTL_EXTRA_CREATE_PARAMETER_CLEANUP_CALLBACK CleanupCallback;
+ ECP_HEADER_FLAGS Flags;
+ ULONG Size;
+ PVOID ListAllocatedFrom;
+ PVOID Filter;
+} ECP_HEADER, *PECP_HEADER;
+
+#define ECP_HEADER_SIZE (sizeof(ECP_HEADER))
+
+#define ECP_HEADER_TO_CONTEXT(H) ((PVOID)((ULONG_PTR)H + ECP_HEADER_SIZE))
+#define ECP_CONTEXT_TO_HEADER(C) ((PECP_HEADER)((ULONG_PTR)C - ECP_HEADER_SIZE))
+
NTKERNELAPI
NTSTATUS
NTAPI
@@ -240,3 +267,95 @@ FsRtlValidateReparsePointBuffer(IN ULONG BufferLength,
return STATUS_IO_REPARSE_TAG_INVALID;
}
+NTKERNELAPI
+NTSTATUS
+NTAPI
+FsRtlGetEcpListFromIrp(IN PIRP Irp,
+ OUT PECP_LIST *EcpList)
+{
+ /* Call Io */
+ return IoGetIrpExtraCreateParameter(Irp, EcpList);
+}
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+FsRtlGetNextExtraCreateParameter(IN PECP_LIST EcpList,
+ IN PVOID CurrentEcpContext,
+ OUT LPGUID NextEcpType OPTIONAL,
+ OUT PVOID *NextEcpContext,
+ OUT PULONG NextEcpContextSize OPTIONAL)
+{
+ PECP_HEADER CurrentEntry;
+
+ /* If we have no context ... */
+ if (CurrentEcpContext == NULL)
+ {
+ if (IsListEmpty(&EcpList->EcpList))
+ {
+ goto FailEmpty;
+ }
+
+ /* Simply consider first entry */
+ CurrentEntry = CONTAINING_RECORD(EcpList->EcpList.Flink, ECP_HEADER,
ListEntry);
+ }
+ else
+ {
+ /* Otherwise, consider the entry matching the given context */
+ CurrentEntry = ECP_CONTEXT_TO_HEADER(CurrentEcpContext);
+
+ /* Make sure we didn't reach the end */
+ if (&CurrentEntry->ListEntry == &EcpList->EcpList)
+ {
+ goto FailEmpty;
+ }
+ }
+
+ /* We must have an entry */
+ if (CurrentEntry == NULL)
+ {
+ goto FailEmpty;
+ }
+
+ /* If caller wants a context, give it */
+ if (NextEcpContext != NULL)
+ {
+ *NextEcpContext = ECP_HEADER_TO_CONTEXT(CurrentEntry);
+ }
+
+ /* Same for its size (which the size minus the header overhead) */
+ if (NextEcpContextSize != NULL)
+ {
+ *NextEcpContextSize = CurrentEntry->Size - sizeof(ECP_HEADER);
+ }
+
+ /* And copy the type if asked to */
+ if (NextEcpType != NULL)
+ {
+ RtlCopyMemory(NextEcpType, &CurrentEntry->EcpType, sizeof(GUID));
+ }
+
+ /* Job done */
+ return STATUS_SUCCESS;
+
+ /* Failure case: just zero everything */
+FailEmpty:
+ if (NextEcpContext != NULL)
+ {
+ *NextEcpContext = NULL;
+ }
+
+ if (NextEcpContextSize != NULL)
+ {
+ *NextEcpContextSize = 0;
+ }
+
+ if (NextEcpType != NULL)
+ {
+ RtlZeroMemory(NextEcpType, sizeof(GUID));
+ }
+
+ /* And return failure */
+ return STATUS_NOT_FOUND;
+}
+