https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f75ea083e356c4c9eba0e59262f5fbeeca241136
commit f75ea083e356c4c9eba0e59262f5fbeeca241136 Author: Pierre Schweitzer <pie...@reactos.org> AuthorDate: Tue Dec 25 13:45:41 2018 +0100 Commit: Pierre Schweitzer <pie...@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; +} +