1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:     Test for LdrLoadDll
5  * COPYRIGHT:   Copyright 2017 Thomas Faber <thomas.faber@reactos.org>
6  *              Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7  */
8 
9 #include "precomp.h"
10 
11 /*
12 
13 NTSTATUS
14 NTAPI
15 LdrLoadDll(
16     IN PWSTR SearchPath OPTIONAL,
17     IN PULONG DllCharacteristics OPTIONAL,
18     IN PUNICODE_STRING DllName,
19     OUT PVOID *BaseAddress
20 );
21 
22 */
23 
START_TEST(LdrLoadDll)24 START_TEST(LdrLoadDll)
25 {
26     NTSTATUS Status = STATUS_SUCCESS;
27     UNICODE_STRING DllName;
28     PVOID BaseAddress, BaseAddress2;
29     WCHAR szWinDir[MAX_PATH], szSysDir[MAX_PATH], szPath[MAX_PATH];
30     WCHAR *pch;
31 
32     RtlInitEmptyUnicodeString(&DllName, NULL, 0);
33     GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
34     GetSystemDirectoryW(szSysDir, _countof(szSysDir));
35 
36     Status = 0xDEADFACE;
37     StartSeh()
38         Status = LdrLoadDll(NULL, NULL, &DllName, NULL);
39     EndSeh(STATUS_ACCESS_VIOLATION);
40     ok_ntstatus(Status, 0xDEADFACE);
41 
42     Status = 0xDEADFACE;
43     BaseAddress = InvalidPointer;
44     StartSeh()
45         Status = LdrLoadDll(NULL, NULL, &DllName, &BaseAddress);
46     EndSeh(STATUS_ACCESS_VIOLATION);
47     ok_ntstatus(Status, 0xDEADFACE);
48     ok_ptr(BaseAddress, InvalidPointer);
49 
50     Status = 0xDEADFACE;
51     StartSeh()
52         Status = LdrLoadDll(L"", NULL, &DllName, NULL);
53     EndSeh(STATUS_ACCESS_VIOLATION);
54     ok_ntstatus(Status, 0xDEADFACE);
55 
56     Status = 0xDEADFACE;
57     BaseAddress = InvalidPointer;
58     StartSeh()
59         Status = LdrLoadDll(L"", NULL, &DllName, &BaseAddress);
60     EndSeh(STATUS_ACCESS_VIOLATION);
61     ok_ntstatus(Status, 0xDEADFACE);
62     ok_ptr(BaseAddress, InvalidPointer);
63 
64     RtlInitUnicodeString(&DllName, L"advapi32.dll");
65 
66     Status = 0xDEADFACE;
67     BaseAddress = InvalidPointer;
68     StartSeh()
69         Status = LdrLoadDll(NULL, NULL, &DllName, NULL);
70         if (NT_SUCCESS(Status))
71             LdrUnloadDll(BaseAddress);
72     EndSeh(STATUS_ACCESS_VIOLATION);
73     ok_ntstatus(Status, 0xDEADFACE);
74     ok_ptr(BaseAddress, InvalidPointer);
75 
76     RtlInitUnicodeString(&DllName, L"advapi32.dll");
77     Status = 0xDEADFACE;
78     BaseAddress = InvalidPointer;
79     StartSeh()
80         BaseAddress = InvalidPointer;
81         Status = LdrLoadDll(NULL, NULL, &DllName, &BaseAddress);
82         ok_ntstatus(Status, STATUS_SUCCESS);
83         ok(BaseAddress != NULL && BaseAddress != InvalidPointer, "BaseAddress = %p\n", BaseAddress);
84         if (NT_SUCCESS(Status))
85         {
86             BaseAddress2 = InvalidPointer;
87             Status = LdrLoadDll(NULL, NULL, &DllName, &BaseAddress2);
88             ok_ntstatus(Status, STATUS_SUCCESS);
89             ok_ptr(BaseAddress2, BaseAddress);
90             LdrUnloadDll(BaseAddress);
91         }
92     EndSeh(STATUS_SUCCESS);
93     ok_ntstatus(Status, STATUS_SUCCESS);
94     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
95 
96     RtlInitUnicodeString(&DllName, L"advapi32.dll");
97     Status = 0xDEADFACE;
98     BaseAddress = InvalidPointer;
99     StartSeh()
100         Status = LdrLoadDll(L"\\SystemRoot\\System32", NULL, &DllName, NULL);
101     EndSeh(STATUS_ACCESS_VIOLATION);
102     ok_ntstatus(Status, 0xDEADFACE);
103     ok_ptr(BaseAddress, InvalidPointer);
104 
105     /* Test with only backslashes in path; no file extension */
106     StringCchPrintfW(szPath, _countof(szPath), L"%s\\advapi32", szSysDir);
107     RtlInitUnicodeString(&DllName, szPath);
108     Status = 0xDEADFACE;
109     BaseAddress = InvalidPointer;
110     StartSeh()
111         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
112         ok_ntstatus(Status, STATUS_SUCCESS);
113         if (NT_SUCCESS(Status))
114             LdrUnloadDll(BaseAddress);
115     EndSeh(STATUS_SUCCESS);
116     ok_ntstatus(Status, STATUS_SUCCESS);
117     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
118 
119     /* Test with only backslashes in path; with file extension */
120     StringCchPrintfW(szPath, _countof(szPath), L"%s\\advapi32.dll", szSysDir);
121     RtlInitUnicodeString(&DllName, szPath);
122     Status = 0xDEADFACE;
123     BaseAddress = InvalidPointer;
124     StartSeh()
125         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
126         ok_ntstatus(Status, STATUS_SUCCESS);
127         if (NT_SUCCESS(Status))
128             LdrUnloadDll(BaseAddress);
129     EndSeh(STATUS_SUCCESS);
130     ok_ntstatus(Status, STATUS_SUCCESS);
131     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
132 
133     /* Test with one forward slash in path; no file extension */
134     StringCchPrintfW(szPath, _countof(szPath), L"%s/advapi32", szSysDir);
135     RtlInitUnicodeString(&DllName, szPath);
136     Status = 0xDEADFACE;
137     BaseAddress = InvalidPointer;
138     StartSeh()
139         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
140         ok_ntstatus(Status, STATUS_SUCCESS);
141         if (NT_SUCCESS(Status))
142             LdrUnloadDll(BaseAddress);
143     EndSeh(STATUS_SUCCESS);
144     ok_ntstatus(Status, STATUS_SUCCESS);
145     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
146 
147     /* Test with one forward slash in path; with file extension */
148     StringCchPrintfW(szPath, _countof(szPath), L"%s/advapi32.dll", szSysDir);
149     RtlInitUnicodeString(&DllName, szPath);
150     Status = 0xDEADFACE;
151     BaseAddress = InvalidPointer;
152     StartSeh()
153         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
154         ok_ntstatus(Status, STATUS_SUCCESS);
155         if (NT_SUCCESS(Status))
156             LdrUnloadDll(BaseAddress);
157     EndSeh(STATUS_SUCCESS);
158     ok_ntstatus(Status, STATUS_SUCCESS);
159     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
160 
161     /* Test with only forward slashes in path; no file extension */
162     StringCchPrintfW(szPath, _countof(szPath), L"%s\\advapi32", szSysDir);
163     for (pch = szPath; *pch != UNICODE_NULL; ++pch)
164     {
165         if (*pch == L'\\')
166             *pch = L'/';
167     }
168 
169     RtlInitUnicodeString(&DllName, szPath);
170     Status = 0xDEADFACE;
171     BaseAddress = InvalidPointer;
172     StartSeh()
173         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
174         ok_ntstatus(Status, STATUS_SUCCESS);
175         if (NT_SUCCESS(Status))
176             LdrUnloadDll(BaseAddress);
177     EndSeh(STATUS_SUCCESS);
178     ok_ntstatus(Status, STATUS_SUCCESS);
179     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
180 
181     /* Test with only forward slashes in path; with file extension */
182     /* Test with only forward slashes in path; with file extension */
183     StringCchPrintfW(szPath, _countof(szPath), L"%s\\advapi32.dll", szSysDir);
184     for (pch = szPath; *pch != UNICODE_NULL; ++pch)
185     {
186         if (*pch == L'\\')
187             *pch = L'/';
188     }
189 
190     RtlInitUnicodeString(&DllName, szPath);
191     Status = 0xDEADFACE;
192     BaseAddress = InvalidPointer;
193     StartSeh()
194         Status = LdrLoadDll(szWinDir, NULL, &DllName, &BaseAddress);
195         ok_ntstatus(Status, STATUS_SUCCESS);
196         if (NT_SUCCESS(Status))
197             LdrUnloadDll(BaseAddress);
198     EndSeh(STATUS_SUCCESS);
199     ok_ntstatus(Status, STATUS_SUCCESS);
200     ok(BaseAddress != NULL, "BaseAddress was NULL\n");
201 }
202