https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bfcb28787d635fd2765c7…
commit bfcb28787d635fd2765c7d4b3ea8de250142f48d
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Wed Oct 26 19:00:08 2022 +0200
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Sun Nov 19 20:44:26 2023 +0100
[NTOS:CM] Disable hard errors when setting up a new size for a hive file / annotate
CmpFileSetSize parameters with SAL
During a I/O failure of whatever kind the upper-level driver, namely a FSD, can raise
a hard error and a deadlock can occur. We wouldn't want that to happen for particular
files like hives or logs so in such cases we must disable hard errors before toying with
hives until we're done.
In addition to that, annotate the CmpFileSetSize function's parameters with SAL.
---
ntoskrnl/config/cmwraprs.c | 37 ++++++++++++++++++++++++++++++-------
ntoskrnl/include/internal/cm.h | 8 ++++----
2 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/ntoskrnl/config/cmwraprs.c b/ntoskrnl/config/cmwraprs.c
index b23092e0cd9..f75a52fbcb2 100644
--- a/ntoskrnl/config/cmwraprs.c
+++ b/ntoskrnl/config/cmwraprs.c
@@ -129,21 +129,32 @@ CmpFileWrite(IN PHHIVE RegistryHive,
BOOLEAN
NTAPI
-CmpFileSetSize(IN PHHIVE RegistryHive,
- IN ULONG FileType,
- IN ULONG FileSize,
- IN ULONG OldFileSize)
+CmpFileSetSize(
+ _In_ PHHIVE RegistryHive,
+ _In_ ULONG FileType,
+ _In_ ULONG FileSize,
+ _In_ ULONG OldFileSize)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo;
IO_STATUS_BLOCK IoStatusBlock;
+ BOOLEAN HardErrors;
NTSTATUS Status;
/* Just return success if no file is associated with this hive */
if (HiveHandle == NULL)
+ {
+ DPRINT1("No hive handle associated with the given hive\n");
return TRUE;
+ }
+
+ /*
+ * Disable hard errors so that we don't deadlock
+ * when touching with the hive files.
+ */
+ HardErrors = IoSetThreadHardErrorMode(FALSE);
EndOfFileInfo.EndOfFile.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
@@ -151,7 +162,12 @@ CmpFileSetSize(IN PHHIVE RegistryHive,
&EndOfFileInfo,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation);
- if (!NT_SUCCESS(Status)) return FALSE;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwSetInformationFile failed to set new size of end of file (Status
0x%lx)\n", Status);
+ IoSetThreadHardErrorMode(HardErrors);
+ return FALSE;
+ }
FileAllocationInfo.AllocationSize.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
@@ -159,8 +175,15 @@ CmpFileSetSize(IN PHHIVE RegistryHive,
&FileAllocationInfo,
sizeof(FILE_ALLOCATION_INFORMATION),
FileAllocationInformation);
- if (!NT_SUCCESS(Status)) return FALSE;
-
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwSetInformationFile failed to set new of allocation file (Status
0x%lx)\n", Status);
+ IoSetThreadHardErrorMode(HardErrors);
+ return FALSE;
+ }
+
+ /* Reset the hard errors back */
+ IoSetThreadHardErrorMode(HardErrors);
return TRUE;
}
diff --git a/ntoskrnl/include/internal/cm.h b/ntoskrnl/include/internal/cm.h
index e8fee77faf4..5c2f352f753 100644
--- a/ntoskrnl/include/internal/cm.h
+++ b/ntoskrnl/include/internal/cm.h
@@ -1236,10 +1236,10 @@ CmpFileWrite(
BOOLEAN
NTAPI
CmpFileSetSize(
- IN PHHIVE RegistryHive,
- IN ULONG FileType,
- IN ULONG FileSize,
- IN ULONG OldFileSize
+ _In_ PHHIVE RegistryHive,
+ _In_ ULONG FileType,
+ _In_ ULONG FileSize,
+ _In_ ULONG OldFileSize
);
BOOLEAN