1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS Kernel
3c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4c2c66affSColin Finck * FILE: ntoskrnl/config/cmwraprs.c
5c2c66affSColin Finck * PURPOSE: Configuration Manager - Wrappers for Hive Operations
6c2c66affSColin Finck * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck /* INCLUDES ******************************************************************/
10c2c66affSColin Finck
11c2c66affSColin Finck #include "ntoskrnl.h"
12c2c66affSColin Finck #define NDEBUG
13c2c66affSColin Finck #include "debug.h"
14c2c66affSColin Finck
15c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
16c2c66affSColin Finck
17c2c66affSColin Finck NTSTATUS
18c2c66affSColin Finck NTAPI
CmpCreateEvent(IN EVENT_TYPE EventType,OUT PHANDLE EventHandle,OUT PKEVENT * Event)19c2c66affSColin Finck CmpCreateEvent(IN EVENT_TYPE EventType,
20c2c66affSColin Finck OUT PHANDLE EventHandle,
21c2c66affSColin Finck OUT PKEVENT *Event)
22c2c66affSColin Finck {
23c2c66affSColin Finck NTSTATUS Status;
24c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
25c2c66affSColin Finck
26c2c66affSColin Finck /* Create the event */
27c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
28c2c66affSColin Finck NULL,
29c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
30c2c66affSColin Finck NULL,
31c2c66affSColin Finck NULL);
32c2c66affSColin Finck Status = ZwCreateEvent(EventHandle,
33c2c66affSColin Finck EVENT_ALL_ACCESS,
34c2c66affSColin Finck &ObjectAttributes,
35c2c66affSColin Finck EventType,
36c2c66affSColin Finck FALSE);
37c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
38c2c66affSColin Finck
39c2c66affSColin Finck /* Get a pointer to the object itself */
40c2c66affSColin Finck Status = ObReferenceObjectByHandle(*EventHandle,
41c2c66affSColin Finck EVENT_ALL_ACCESS,
42c2c66affSColin Finck NULL,
43c2c66affSColin Finck KernelMode,
44c2c66affSColin Finck (PVOID*)Event,
45c2c66affSColin Finck NULL);
46c2c66affSColin Finck if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
47c2c66affSColin Finck
48c2c66affSColin Finck /* Return status */
49c2c66affSColin Finck return Status;
50c2c66affSColin Finck }
51c2c66affSColin Finck
52c2c66affSColin Finck PVOID
53c2c66affSColin Finck NTAPI
CmpAllocate(IN SIZE_T Size,IN BOOLEAN Paged,IN ULONG Tag)54c2c66affSColin Finck CmpAllocate(IN SIZE_T Size,
55c2c66affSColin Finck IN BOOLEAN Paged,
56c2c66affSColin Finck IN ULONG Tag)
57c2c66affSColin Finck {
58c2c66affSColin Finck return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
59c2c66affSColin Finck Size,
60c2c66affSColin Finck Tag);
61c2c66affSColin Finck }
62c2c66affSColin Finck
63c2c66affSColin Finck VOID
64c2c66affSColin Finck NTAPI
CmpFree(IN PVOID Ptr,IN ULONG Quota)65c2c66affSColin Finck CmpFree(IN PVOID Ptr,
66c2c66affSColin Finck IN ULONG Quota)
67c2c66affSColin Finck {
68c2c66affSColin Finck ExFreePool(Ptr);
69c2c66affSColin Finck }
70c2c66affSColin Finck
71c2c66affSColin Finck BOOLEAN
72c2c66affSColin Finck NTAPI
CmpFileRead(IN PHHIVE RegistryHive,IN ULONG FileType,IN PULONG FileOffset,OUT PVOID Buffer,IN SIZE_T BufferLength)73c2c66affSColin Finck CmpFileRead(IN PHHIVE RegistryHive,
74c2c66affSColin Finck IN ULONG FileType,
75c2c66affSColin Finck IN PULONG FileOffset,
76c2c66affSColin Finck OUT PVOID Buffer,
77c2c66affSColin Finck IN SIZE_T BufferLength)
78c2c66affSColin Finck {
79c2c66affSColin Finck PCMHIVE CmHive = (PCMHIVE)RegistryHive;
80c2c66affSColin Finck HANDLE HiveHandle = CmHive->FileHandles[FileType];
81c2c66affSColin Finck LARGE_INTEGER _FileOffset;
82c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
83c2c66affSColin Finck NTSTATUS Status;
84c2c66affSColin Finck
85da813452SHermès Bélusca-Maïto /* Just return success if no file is associated with this hive */
86da813452SHermès Bélusca-Maïto if (HiveHandle == NULL)
87da813452SHermès Bélusca-Maïto return TRUE;
88da813452SHermès Bélusca-Maïto
89c2c66affSColin Finck _FileOffset.QuadPart = *FileOffset;
9011baa0d7SSerge Gautherie Status = ZwReadFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
9111baa0d7SSerge Gautherie Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
9279b0fce5SThomas Faber /* We do synchronous I/O for simplicity - see CmpOpenHiveFiles. */
9379b0fce5SThomas Faber ASSERT(Status != STATUS_PENDING);
94c2c66affSColin Finck return NT_SUCCESS(Status) ? TRUE : FALSE;
95c2c66affSColin Finck }
96c2c66affSColin Finck
97c2c66affSColin Finck BOOLEAN
98c2c66affSColin Finck NTAPI
CmpFileWrite(IN PHHIVE RegistryHive,IN ULONG FileType,IN PULONG FileOffset,IN PVOID Buffer,IN SIZE_T BufferLength)99c2c66affSColin Finck CmpFileWrite(IN PHHIVE RegistryHive,
100c2c66affSColin Finck IN ULONG FileType,
101c2c66affSColin Finck IN PULONG FileOffset,
102c2c66affSColin Finck IN PVOID Buffer,
103c2c66affSColin Finck IN SIZE_T BufferLength)
104c2c66affSColin Finck {
105c2c66affSColin Finck PCMHIVE CmHive = (PCMHIVE)RegistryHive;
106c2c66affSColin Finck HANDLE HiveHandle = CmHive->FileHandles[FileType];
107c2c66affSColin Finck LARGE_INTEGER _FileOffset;
108c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
109c2c66affSColin Finck NTSTATUS Status;
110c2c66affSColin Finck
111da813452SHermès Bélusca-Maïto /* Just return success if no file is associated with this hive */
112da813452SHermès Bélusca-Maïto if (HiveHandle == NULL)
113da813452SHermès Bélusca-Maïto return TRUE;
114da813452SHermès Bélusca-Maïto
115da813452SHermès Bélusca-Maïto /* Don't do anything if we're not supposed to */
116da813452SHermès Bélusca-Maïto if (CmpNoWrite)
117da813452SHermès Bélusca-Maïto return TRUE;
118da813452SHermès Bélusca-Maïto
119c2c66affSColin Finck _FileOffset.QuadPart = *FileOffset;
120abb6ad90SSerge Gautherie Status = ZwWriteFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
121abb6ad90SSerge Gautherie Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
12279b0fce5SThomas Faber /* We do synchronous I/O for simplicity - see CmpOpenHiveFiles.
12379b0fce5SThomas Faber * Windows optimizes here by starting an async write for each 64k chunk,
12479b0fce5SThomas Faber * then waiting for all writes to complete at once.
12579b0fce5SThomas Faber */
12679b0fce5SThomas Faber ASSERT(Status != STATUS_PENDING);
127c2c66affSColin Finck return NT_SUCCESS(Status) ? TRUE : FALSE;
128c2c66affSColin Finck }
129c2c66affSColin Finck
130c2c66affSColin Finck BOOLEAN
131c2c66affSColin Finck NTAPI
CmpFileSetSize(_In_ PHHIVE RegistryHive,_In_ ULONG FileType,_In_ ULONG FileSize,_In_ ULONG OldFileSize)132*bfcb2878SGeorge Bișoc CmpFileSetSize(
133*bfcb2878SGeorge Bișoc _In_ PHHIVE RegistryHive,
134*bfcb2878SGeorge Bișoc _In_ ULONG FileType,
135*bfcb2878SGeorge Bișoc _In_ ULONG FileSize,
136*bfcb2878SGeorge Bișoc _In_ ULONG OldFileSize)
137c2c66affSColin Finck {
138c2c66affSColin Finck PCMHIVE CmHive = (PCMHIVE)RegistryHive;
139c2c66affSColin Finck HANDLE HiveHandle = CmHive->FileHandles[FileType];
140c2c66affSColin Finck FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
141c2c66affSColin Finck FILE_ALLOCATION_INFORMATION FileAllocationInfo;
142c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
143*bfcb2878SGeorge Bișoc BOOLEAN HardErrors;
144c2c66affSColin Finck NTSTATUS Status;
145c2c66affSColin Finck
146da813452SHermès Bélusca-Maïto /* Just return success if no file is associated with this hive */
147da813452SHermès Bélusca-Maïto if (HiveHandle == NULL)
148*bfcb2878SGeorge Bișoc {
149*bfcb2878SGeorge Bișoc DPRINT1("No hive handle associated with the given hive\n");
150da813452SHermès Bélusca-Maïto return TRUE;
151*bfcb2878SGeorge Bișoc }
152*bfcb2878SGeorge Bișoc
153*bfcb2878SGeorge Bișoc /*
154*bfcb2878SGeorge Bișoc * Disable hard errors so that we don't deadlock
155*bfcb2878SGeorge Bișoc * when touching with the hive files.
156*bfcb2878SGeorge Bișoc */
157*bfcb2878SGeorge Bișoc HardErrors = IoSetThreadHardErrorMode(FALSE);
158da813452SHermès Bélusca-Maïto
159c2c66affSColin Finck EndOfFileInfo.EndOfFile.QuadPart = FileSize;
160c2c66affSColin Finck Status = ZwSetInformationFile(HiveHandle,
161c2c66affSColin Finck &IoStatusBlock,
162c2c66affSColin Finck &EndOfFileInfo,
163c2c66affSColin Finck sizeof(FILE_END_OF_FILE_INFORMATION),
164c2c66affSColin Finck FileEndOfFileInformation);
165*bfcb2878SGeorge Bișoc if (!NT_SUCCESS(Status))
166*bfcb2878SGeorge Bișoc {
167*bfcb2878SGeorge Bișoc DPRINT1("ZwSetInformationFile failed to set new size of end of file (Status 0x%lx)\n", Status);
168*bfcb2878SGeorge Bișoc IoSetThreadHardErrorMode(HardErrors);
169*bfcb2878SGeorge Bișoc return FALSE;
170*bfcb2878SGeorge Bișoc }
171c2c66affSColin Finck
172c2c66affSColin Finck FileAllocationInfo.AllocationSize.QuadPart = FileSize;
173c2c66affSColin Finck Status = ZwSetInformationFile(HiveHandle,
174c2c66affSColin Finck &IoStatusBlock,
175c2c66affSColin Finck &FileAllocationInfo,
176c2c66affSColin Finck sizeof(FILE_ALLOCATION_INFORMATION),
177c2c66affSColin Finck FileAllocationInformation);
178*bfcb2878SGeorge Bișoc if (!NT_SUCCESS(Status))
179*bfcb2878SGeorge Bișoc {
180*bfcb2878SGeorge Bișoc DPRINT1("ZwSetInformationFile failed to set new of allocation file (Status 0x%lx)\n", Status);
181*bfcb2878SGeorge Bișoc IoSetThreadHardErrorMode(HardErrors);
182*bfcb2878SGeorge Bișoc return FALSE;
183*bfcb2878SGeorge Bișoc }
184c2c66affSColin Finck
185*bfcb2878SGeorge Bișoc /* Reset the hard errors back */
186*bfcb2878SGeorge Bișoc IoSetThreadHardErrorMode(HardErrors);
187c2c66affSColin Finck return TRUE;
188c2c66affSColin Finck }
189c2c66affSColin Finck
190c2c66affSColin Finck BOOLEAN
191c2c66affSColin Finck NTAPI
CmpFileFlush(IN PHHIVE RegistryHive,IN ULONG FileType,IN OUT PLARGE_INTEGER FileOffset,IN ULONG Length)192c2c66affSColin Finck CmpFileFlush(IN PHHIVE RegistryHive,
193c2c66affSColin Finck IN ULONG FileType,
194c2c66affSColin Finck IN OUT PLARGE_INTEGER FileOffset,
195c2c66affSColin Finck IN ULONG Length)
196c2c66affSColin Finck {
197c2c66affSColin Finck PCMHIVE CmHive = (PCMHIVE)RegistryHive;
198c2c66affSColin Finck HANDLE HiveHandle = CmHive->FileHandles[FileType];
199c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
200c2c66affSColin Finck NTSTATUS Status;
201c2c66affSColin Finck
202da813452SHermès Bélusca-Maïto /* Just return success if no file is associated with this hive */
203da813452SHermès Bélusca-Maïto if (HiveHandle == NULL)
204da813452SHermès Bélusca-Maïto return TRUE;
205da813452SHermès Bélusca-Maïto
206da813452SHermès Bélusca-Maïto /* Don't do anything if we're not supposed to */
207da813452SHermès Bélusca-Maïto if (CmpNoWrite)
208da813452SHermès Bélusca-Maïto return TRUE;
209da813452SHermès Bélusca-Maïto
210c2c66affSColin Finck Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
21179b0fce5SThomas Faber
21279b0fce5SThomas Faber /* This operation is always synchronous */
21379b0fce5SThomas Faber ASSERT(Status != STATUS_PENDING);
21479b0fce5SThomas Faber ASSERT(Status == IoStatusBlock.Status);
21579b0fce5SThomas Faber
216c2c66affSColin Finck return NT_SUCCESS(Status) ? TRUE : FALSE;
217c2c66affSColin Finck }
218