[CMAKE]
[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 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 *ResourceSize = Size;
56 }
57 else
58 {
59 /* not enough memory */
60 Status = STATUS_INSUFFICIENT_RESOURCES;
61 }
62 }
63 }
64 }
65 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
66 {
67 /* Exception, get the error code */
68 Status = _SEH2_GetExceptionCode();
69 }
70 _SEH2_END;
71
72 if (!NT_SUCCESS(Status))
73 {
74 /* failed */
75 if (Result)
76 {
77 /* free resource buffer in case of a failure */
78 FreeItem(Result);
79 }
80 }
81 /* done */
82 return Status;
83 }
84
85
86 NTSTATUS
87 KspQueryRegValue(
88 IN HANDLE KeyHandle,
89 IN LPWSTR KeyName,
90 IN PVOID Buffer,
91 IN OUT PULONG BufferLength,
92 OUT PULONG Type)
93 {
94 UNIMPLEMENTED
95 return STATUS_NOT_IMPLEMENTED;
96 }
97
98 /*
99 @implemented
100 */
101 KSDDKAPI
102 NTSTATUS
103 NTAPI
104 KsGetImageNameAndResourceId(
105 IN HANDLE RegKey,
106 OUT PUNICODE_STRING ImageName,
107 OUT PULONG_PTR ResourceId,
108 OUT PULONG ValueType)
109 {
110 NTSTATUS Status;
111 ULONG ImageLength;
112 WCHAR ImagePath[] = {L"\\SystemRoot\\system32\\drivers\\"};
113
114 /* first clear the provided ImageName */
115 ImageName->Buffer = NULL;
116 ImageName->Length = ImageName->MaximumLength = 0;
117
118 ImageLength = 0;
119 /* retrieve length of image name */
120 Status = KspQueryRegValue(RegKey, L"Image", NULL, &ImageLength, NULL);
121
122 if (Status != STATUS_BUFFER_OVERFLOW)
123 {
124 /* key value doesnt exist */
125 return Status;
126 }
127
128 /* allocate image name buffer */
129 ImageName->MaximumLength = sizeof(ImagePath) + ImageLength;
130 ImageName->Buffer = AllocateItem(PagedPool, ImageName->MaximumLength);
131
132 /* check for success */
133 if (!ImageName->Buffer)
134 {
135 /* insufficient memory */
136 return STATUS_INSUFFICIENT_RESOURCES;
137 }
138
139 /* copy image name */
140 RtlCopyMemory(ImageName->Buffer, ImagePath, sizeof(ImagePath));
141
142 /* retrieve image name */
143 Status = KspQueryRegValue(RegKey, L"Image", &ImageName->Buffer[sizeof(ImagePath) / sizeof(WCHAR)], &ImageLength, NULL);
144
145 if (!NT_SUCCESS(Status))
146 {
147 /* unexpected error */
148 FreeItem(ImageName->Buffer);
149 return Status;
150 }
151
152 /* now query for resource id length*/
153 ImageLength = 0;
154 Status = KspQueryRegValue(RegKey, L"ResourceId", NULL, &ImageLength, ValueType);
155
156 /* allocate resource id buffer*/
157 *ResourceId = (ULONG_PTR)AllocateItem(PagedPool, ImageLength);
158
159 /* check for success */
160 if (!*ResourceId)
161 {
162 /* insufficient memory */
163 FreeItem(ImageName->Buffer);
164 return STATUS_INSUFFICIENT_RESOURCES;
165 }
166 /* now query for resource id */
167 Status = KspQueryRegValue(RegKey, L"ResourceId", (PVOID)*ResourceId, &ImageLength, ValueType);
168
169 if (!NT_SUCCESS(Status))
170 {
171 /* unexpected error */
172 FreeItem(ImageName->Buffer);
173 FreeItem((PVOID)*ResourceId);
174 }
175
176 /* return result */
177 return Status;
178 }
179
180 /*
181 @implemented
182 */
183 KSDDKAPI
184 NTSTATUS
185 NTAPI
186 KsMapModuleName(
187 IN PDEVICE_OBJECT PhysicalDeviceObject,
188 IN PUNICODE_STRING ModuleName,
189 OUT PUNICODE_STRING ImageName,
190 OUT PULONG_PTR ResourceId,
191 OUT PULONG ValueType)
192 {
193 NTSTATUS Status;
194 UNICODE_STRING SubKeyName;
195 UNICODE_STRING Modules = RTL_CONSTANT_STRING(L"Modules\\");
196 HANDLE hKey, hSubKey;
197 OBJECT_ATTRIBUTES ObjectAttributes;
198
199 /* first open device key */
200 Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, GENERIC_READ, &hKey);
201
202 /* check for success */
203 if (!NT_SUCCESS(Status))
204 {
205 /* invalid parameter */
206 return STATUS_INVALID_PARAMETER;
207 }
208
209 /* initialize subkey buffer */
210 SubKeyName.Length = 0;
211 SubKeyName.MaximumLength = Modules.MaximumLength + ModuleName->MaximumLength;
212 SubKeyName.Buffer = AllocateItem(PagedPool, SubKeyName.MaximumLength);
213
214 /* check for success */
215 if (!SubKeyName.Buffer)
216 {
217 /* not enough memory */
218 ZwClose(hKey);
219 return STATUS_NO_MEMORY;
220 }
221
222 /* build subkey string */
223 RtlAppendUnicodeStringToString(&SubKeyName, &Modules);
224 RtlAppendUnicodeStringToString(&SubKeyName, ModuleName);
225
226 /* initialize subkey attributes */
227 InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE, hKey, NULL);
228
229 /* now open the subkey */
230 Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
231
232 /* check for success */
233 if (NT_SUCCESS(Status))
234 {
235 /* defer work */
236 Status = KsGetImageNameAndResourceId(hSubKey, ImageName, ResourceId, ValueType);
237
238 /* close subkey */
239 ZwClose(hSubKey);
240 }
241
242 /* free subkey string */
243 FreeItem(SubKeyName.Buffer);
244
245 /* close device key */
246 ZwClose(hKey);
247
248 /* return status */
249 return Status;
250 }
251
252
253