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