xref: /reactos/ntoskrnl/config/cmwraprs.c (revision bfcb2878)
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