1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/ksfilter/ks/allocators.c 5 * PURPOSE: KS Allocator functions 6 * PROGRAMMER: Johannes Anderwald 7 */ 8 9 #include "precomp.h" 10 11 #include <ntimage.h> 12 #include <ndk/ldrfuncs.h> 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* 18 @implemented 19 */ 20 KSDDKAPI 21 NTSTATUS 22 NTAPI 23 KsLoadResource( 24 IN PVOID ImageBase, 25 IN POOL_TYPE PoolType, 26 IN ULONG_PTR ResourceName, 27 IN ULONG ResourceType, 28 OUT PVOID* Resource, 29 OUT PULONG ResourceSize) 30 { 31 NTSTATUS Status; 32 LDR_RESOURCE_INFO ResourceInfo; 33 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; 34 PVOID Data; 35 ULONG Size; 36 PVOID _SEH2_VOLATILE Result = NULL; 37 38 /* set up resource info */ 39 ResourceInfo.Type = ResourceType; 40 ResourceInfo.Name = ResourceName; 41 ResourceInfo.Language = 0; 42 43 _SEH2_TRY 44 { 45 /* find the resource */ 46 Status = LdrFindResource_U(ImageBase, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); 47 if (NT_SUCCESS(Status)) 48 { 49 /* try accessing it */ 50 Status = LdrAccessResource(ImageBase, ResourceDataEntry, &Data, &Size); 51 if (NT_SUCCESS(Status)) 52 { 53 /* allocate resource buffer */ 54 Result = AllocateItem(PoolType, Size); 55 if (Result) 56 { 57 /* copy resource */ 58 RtlMoveMemory(Result, Data, Size); 59 /* store result */ 60 *Resource = Result; 61 62 if (ResourceSize) 63 { 64 /* resource size is optional */ 65 *ResourceSize = Size; 66 } 67 } 68 else 69 { 70 /* not enough memory */ 71 Status = STATUS_INSUFFICIENT_RESOURCES; 72 } 73 } 74 } 75 } 76 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 77 { 78 /* Exception, get the error code */ 79 Status = _SEH2_GetExceptionCode(); 80 } 81 _SEH2_END; 82 83 if (!NT_SUCCESS(Status)) 84 { 85 /* failed */ 86 if (Result) 87 { 88 /* free resource buffer in case of a failure */ 89 FreeItem(Result); 90 } 91 } 92 /* done */ 93 return Status; 94 } 95 96 97 NTSTATUS 98 KspQueryRegValue( 99 IN HANDLE KeyHandle, 100 IN LPWSTR KeyName, 101 IN PVOID Buffer, 102 IN OUT PULONG BufferLength, 103 OUT PULONG Type) 104 { 105 UNIMPLEMENTED; 106 return STATUS_NOT_IMPLEMENTED; 107 } 108 109 /* 110 @implemented 111 */ 112 KSDDKAPI 113 NTSTATUS 114 NTAPI 115 KsGetImageNameAndResourceId( 116 IN HANDLE RegKey, 117 OUT PUNICODE_STRING ImageName, 118 OUT PULONG_PTR ResourceId, 119 OUT PULONG ValueType) 120 { 121 NTSTATUS Status; 122 ULONG ImageLength; 123 WCHAR ImagePath[] = {L"\\SystemRoot\\system32\\drivers\\"}; 124 125 /* first clear the provided ImageName */ 126 ImageName->Buffer = NULL; 127 ImageName->Length = ImageName->MaximumLength = 0; 128 129 ImageLength = 0; 130 /* retrieve length of image name */ 131 Status = KspQueryRegValue(RegKey, L"Image", NULL, &ImageLength, NULL); 132 133 if (Status != STATUS_BUFFER_OVERFLOW) 134 { 135 /* key value doesnt exist */ 136 return Status; 137 } 138 139 /* allocate image name buffer */ 140 ImageName->MaximumLength = (USHORT)(sizeof(ImagePath) + ImageLength); 141 ImageName->Buffer = AllocateItem(PagedPool, ImageName->MaximumLength); 142 143 /* check for success */ 144 if (!ImageName->Buffer) 145 { 146 /* insufficient memory */ 147 return STATUS_INSUFFICIENT_RESOURCES; 148 } 149 150 /* copy image name */ 151 RtlCopyMemory(ImageName->Buffer, ImagePath, sizeof(ImagePath)); 152 153 /* retrieve image name */ 154 Status = KspQueryRegValue(RegKey, 155 L"Image", 156 &ImageName->Buffer[sizeof(ImagePath) / sizeof(WCHAR)], 157 &ImageLength, 158 NULL); 159 160 if (!NT_SUCCESS(Status)) 161 { 162 /* unexpected error */ 163 FreeItem(ImageName->Buffer); 164 return Status; 165 } 166 167 /* now query for resource id length*/ 168 ImageLength = 0; 169 Status = KspQueryRegValue(RegKey, L"ResourceId", NULL, &ImageLength, ValueType); 170 171 /* allocate resource id buffer*/ 172 *ResourceId = (ULONG_PTR)AllocateItem(PagedPool, ImageLength); 173 174 /* check for success */ 175 if (!*ResourceId) 176 { 177 /* insufficient memory */ 178 FreeItem(ImageName->Buffer); 179 return STATUS_INSUFFICIENT_RESOURCES; 180 } 181 /* now query for resource id */ 182 Status = KspQueryRegValue(RegKey, L"ResourceId", (PVOID)*ResourceId, &ImageLength, ValueType); 183 184 if (!NT_SUCCESS(Status)) 185 { 186 /* unexpected error */ 187 FreeItem(ImageName->Buffer); 188 FreeItem((PVOID)*ResourceId); 189 } 190 191 /* return result */ 192 return Status; 193 } 194 195 /* 196 @implemented 197 */ 198 KSDDKAPI 199 NTSTATUS 200 NTAPI 201 KsMapModuleName( 202 IN PDEVICE_OBJECT PhysicalDeviceObject, 203 IN PUNICODE_STRING ModuleName, 204 OUT PUNICODE_STRING ImageName, 205 OUT PULONG_PTR ResourceId, 206 OUT PULONG ValueType) 207 { 208 NTSTATUS Status; 209 UNICODE_STRING SubKeyName; 210 UNICODE_STRING Modules = RTL_CONSTANT_STRING(L"Modules\\"); 211 HANDLE hKey, hSubKey; 212 OBJECT_ATTRIBUTES ObjectAttributes; 213 214 /* first open device key */ 215 Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, GENERIC_READ, &hKey); 216 217 /* check for success */ 218 if (!NT_SUCCESS(Status)) 219 { 220 /* invalid parameter */ 221 return STATUS_INVALID_PARAMETER; 222 } 223 224 /* initialize subkey buffer */ 225 SubKeyName.Length = 0; 226 SubKeyName.MaximumLength = Modules.MaximumLength + ModuleName->MaximumLength; 227 SubKeyName.Buffer = AllocateItem(PagedPool, SubKeyName.MaximumLength); 228 229 /* check for success */ 230 if (!SubKeyName.Buffer) 231 { 232 /* not enough memory */ 233 ZwClose(hKey); 234 return STATUS_NO_MEMORY; 235 } 236 237 /* build subkey string */ 238 RtlAppendUnicodeStringToString(&SubKeyName, &Modules); 239 RtlAppendUnicodeStringToString(&SubKeyName, ModuleName); 240 241 /* initialize subkey attributes */ 242 InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, hKey, NULL); 243 244 /* now open the subkey */ 245 Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes); 246 247 /* check for success */ 248 if (NT_SUCCESS(Status)) 249 { 250 /* defer work */ 251 Status = KsGetImageNameAndResourceId(hSubKey, ImageName, ResourceId, ValueType); 252 253 /* close subkey */ 254 ZwClose(hSubKey); 255 } 256 257 /* free subkey string */ 258 FreeItem(SubKeyName.Buffer); 259 260 /* close device key */ 261 ZwClose(hKey); 262 263 /* return status */ 264 return Status; 265 } 266