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( 133 _In_ PHHIVE RegistryHive, 134 _In_ ULONG FileType, 135 _In_ ULONG FileSize, 136 _In_ ULONG OldFileSize) 137 { 138 PCMHIVE CmHive = (PCMHIVE)RegistryHive; 139 HANDLE HiveHandle = CmHive->FileHandles[FileType]; 140 FILE_END_OF_FILE_INFORMATION EndOfFileInfo; 141 FILE_ALLOCATION_INFORMATION FileAllocationInfo; 142 IO_STATUS_BLOCK IoStatusBlock; 143 BOOLEAN HardErrors; 144 NTSTATUS Status; 145 146 /* Just return success if no file is associated with this hive */ 147 if (HiveHandle == NULL) 148 { 149 DPRINT1("No hive handle associated with the given hive\n"); 150 return TRUE; 151 } 152 153 /* 154 * Disable hard errors so that we don't deadlock 155 * when touching with the hive files. 156 */ 157 HardErrors = IoSetThreadHardErrorMode(FALSE); 158 159 EndOfFileInfo.EndOfFile.QuadPart = FileSize; 160 Status = ZwSetInformationFile(HiveHandle, 161 &IoStatusBlock, 162 &EndOfFileInfo, 163 sizeof(FILE_END_OF_FILE_INFORMATION), 164 FileEndOfFileInformation); 165 if (!NT_SUCCESS(Status)) 166 { 167 DPRINT1("ZwSetInformationFile failed to set new size of end of file (Status 0x%lx)\n", Status); 168 IoSetThreadHardErrorMode(HardErrors); 169 return FALSE; 170 } 171 172 FileAllocationInfo.AllocationSize.QuadPart = FileSize; 173 Status = ZwSetInformationFile(HiveHandle, 174 &IoStatusBlock, 175 &FileAllocationInfo, 176 sizeof(FILE_ALLOCATION_INFORMATION), 177 FileAllocationInformation); 178 if (!NT_SUCCESS(Status)) 179 { 180 DPRINT1("ZwSetInformationFile failed to set new of allocation file (Status 0x%lx)\n", Status); 181 IoSetThreadHardErrorMode(HardErrors); 182 return FALSE; 183 } 184 185 /* Reset the hard errors back */ 186 IoSetThreadHardErrorMode(HardErrors); 187 return TRUE; 188 } 189 190 BOOLEAN 191 NTAPI 192 CmpFileFlush(IN PHHIVE RegistryHive, 193 IN ULONG FileType, 194 IN OUT PLARGE_INTEGER FileOffset, 195 IN ULONG Length) 196 { 197 PCMHIVE CmHive = (PCMHIVE)RegistryHive; 198 HANDLE HiveHandle = CmHive->FileHandles[FileType]; 199 IO_STATUS_BLOCK IoStatusBlock; 200 NTSTATUS Status; 201 202 /* Just return success if no file is associated with this hive */ 203 if (HiveHandle == NULL) 204 return TRUE; 205 206 /* Don't do anything if we're not supposed to */ 207 if (CmpNoWrite) 208 return TRUE; 209 210 Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock); 211 212 /* This operation is always synchronous */ 213 ASSERT(Status != STATUS_PENDING); 214 ASSERT(Status == IoStatusBlock.Status); 215 216 return NT_SUCCESS(Status) ? TRUE : FALSE; 217 } 218