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