fixed some memory leaks
[reactos.git] / reactos / subsys / smss / initwkdll.c
1 /* $Id$
2 *
3 * initwkdll.c - Load the well known DLLs
4 *
5 * ReactOS Operating System
6 *
7 * --------------------------------------------------------------------
8 *
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this software; see the file COPYING.LIB. If not, write
21 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
22 * MA 02139, USA.
23 *
24 * --------------------------------------------------------------------
25 */
26
27 #include "smss.h"
28
29 #define NDEBUG
30 #include <debug.h>
31
32 static NTSTATUS STDCALL
33 SmpKnownDllsQueryRoutine(PWSTR ValueName,
34 ULONG ValueType,
35 PVOID ValueData,
36 ULONG ValueLength,
37 PVOID Context,
38 PVOID EntryContext)
39 {
40 OBJECT_ATTRIBUTES ObjectAttributes;
41 IO_STATUS_BLOCK IoStatusBlock;
42 UNICODE_STRING ImageName;
43 HANDLE FileHandle;
44 HANDLE SectionHandle;
45 NTSTATUS Status;
46
47 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
48 DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
49
50 /* Ignore the 'DllDirectory' value */
51 if (!_wcsicmp(ValueName, L"DllDirectory"))
52 return STATUS_SUCCESS;
53
54 /* Open the DLL image file */
55 RtlInitUnicodeString(&ImageName,
56 ValueData);
57 InitializeObjectAttributes(&ObjectAttributes,
58 &ImageName,
59 OBJ_CASE_INSENSITIVE,
60 (HANDLE)Context,
61 NULL);
62 Status = NtOpenFile(&FileHandle,
63 SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,
64 &ObjectAttributes,
65 &IoStatusBlock,
66 FILE_SHARE_READ,
67 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
68 if (!NT_SUCCESS(Status))
69 {
70 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
71 return STATUS_SUCCESS;
72 }
73
74 DPRINT("Opened file %wZ successfully\n", &ImageName);
75
76 /* Check for valid image checksum */
77 Status = LdrVerifyImageMatchesChecksum (FileHandle,
78 0,
79 0,
80 0);
81 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
82 {
83 /* Raise a hard error (crash the system/BSOD) */
84 NtRaiseHardError (Status,
85 0,
86 0,
87 0,
88 0,
89 0);
90 }
91 else if (!NT_SUCCESS(Status))
92 {
93 DPRINT1("Failed to check the image checksum\n");
94
95 NtClose(SectionHandle);
96 NtClose(FileHandle);
97
98 return STATUS_SUCCESS;
99 }
100
101 InitializeObjectAttributes(&ObjectAttributes,
102 &ImageName,
103 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
104 (HANDLE)EntryContext,
105 NULL);
106 Status = NtCreateSection(&SectionHandle,
107 SECTION_ALL_ACCESS,
108 &ObjectAttributes,
109 NULL,
110 PAGE_EXECUTE,
111 SEC_IMAGE,
112 FileHandle);
113 if (NT_SUCCESS(Status))
114 {
115 DPRINT("Created section successfully\n");
116 NtClose(SectionHandle);
117 }
118
119 NtClose(FileHandle);
120
121 return STATUS_SUCCESS;
122 }
123
124
125 NTSTATUS
126 SmLoadKnownDlls(VOID)
127 {
128 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
129 OBJECT_ATTRIBUTES ObjectAttributes;
130 IO_STATUS_BLOCK IoStatusBlock;
131 UNICODE_STRING DllDosPath;
132 UNICODE_STRING DllNtPath;
133 UNICODE_STRING Name;
134 HANDLE ObjectDirHandle;
135 HANDLE FileDirHandle;
136 HANDLE SymlinkHandle;
137 NTSTATUS Status;
138
139
140 DPRINT("SM: loading well-known DLLs\n");
141
142 DPRINT("SmLoadKnownDlls() called\n");
143
144 /* Create 'KnownDlls' object directory */
145 RtlInitUnicodeString(&Name,
146 L"\\KnownDlls");
147 InitializeObjectAttributes(&ObjectAttributes,
148 &Name,
149 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
150 NULL,
151 NULL);
152 Status = NtCreateDirectoryObject(&ObjectDirHandle,
153 DIRECTORY_ALL_ACCESS,
154 &ObjectAttributes);
155 if (!NT_SUCCESS(Status))
156 {
157 DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
158 return Status;
159 }
160
161 RtlInitUnicodeString(&DllDosPath, NULL);
162
163 RtlZeroMemory(&QueryTable,
164 sizeof(QueryTable));
165
166 QueryTable[0].Name = L"DllDirectory";
167 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
168 QueryTable[0].EntryContext = &DllDosPath;
169
170 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
171 L"\\Session Manager\\KnownDlls",
172 QueryTable,
173 NULL,
174 SmSystemEnvironment);
175 if (!NT_SUCCESS(Status))
176 {
177 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
178 return Status;
179 }
180
181 DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);
182
183 if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
184 &DllNtPath,
185 NULL,
186 NULL))
187 {
188 DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");
189 return STATUS_OBJECT_NAME_INVALID;
190 }
191
192 DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);
193
194 /* Open the dll path directory */
195 InitializeObjectAttributes(&ObjectAttributes,
196 &DllNtPath,
197 OBJ_CASE_INSENSITIVE,
198 NULL,
199 NULL);
200 Status = NtOpenFile(&FileDirHandle,
201 SYNCHRONIZE | FILE_READ_DATA,
202 &ObjectAttributes,
203 &IoStatusBlock,
204 FILE_SHARE_READ | FILE_SHARE_WRITE,
205 FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
206 if (!NT_SUCCESS(Status))
207 {
208 DPRINT1("NtOpenFile(%wZ) failed (Status %lx)\n", &DllNtPath, Status);
209 return Status;
210 }
211
212 /* Link 'KnownDllPath' the dll path directory */
213 RtlInitUnicodeString(&Name,
214 L"KnownDllPath");
215 InitializeObjectAttributes(&ObjectAttributes,
216 &Name,
217 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
218 ObjectDirHandle,
219 NULL);
220 Status = NtCreateSymbolicLinkObject(&SymlinkHandle,
221 SYMBOLIC_LINK_ALL_ACCESS,
222 &ObjectAttributes,
223 &DllDosPath);
224 if (!NT_SUCCESS(Status))
225 {
226 DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
227 return Status;
228 }
229
230 NtClose(SymlinkHandle);
231
232 RtlZeroMemory(&QueryTable,
233 sizeof(QueryTable));
234
235 QueryTable[0].QueryRoutine = SmpKnownDllsQueryRoutine;
236 QueryTable[0].EntryContext = ObjectDirHandle;
237
238 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
239 L"\\Session Manager\\KnownDlls",
240 QueryTable,
241 (PVOID)FileDirHandle,
242 NULL);
243 if (!NT_SUCCESS(Status))
244 {
245 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
246 }
247
248 DPRINT("SmLoadKnownDlls() done\n");
249
250 return Status;
251 }
252
253
254 /* EOF */