[KS]
[reactos.git] / reactos / drivers / ksfilter / ks / image.c
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 "priv.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, 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
267
268