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
KsLoadResource(IN PVOID ImageBase,IN POOL_TYPE PoolType,IN ULONG_PTR ResourceName,IN ULONG ResourceType,OUT PVOID * Resource,OUT PULONG ResourceSize)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
KspQueryRegValue(IN HANDLE KeyHandle,IN LPWSTR KeyName,IN PVOID Buffer,IN OUT PULONG BufferLength,OUT PULONG Type)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
KsGetImageNameAndResourceId(IN HANDLE RegKey,OUT PUNICODE_STRING ImageName,OUT PULONG_PTR ResourceId,OUT PULONG ValueType)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
KsMapModuleName(IN PDEVICE_OBJECT PhysicalDeviceObject,IN PUNICODE_STRING ModuleName,OUT PUNICODE_STRING ImageName,OUT PULONG_PTR ResourceId,OUT PULONG ValueType)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