ReactOS 0.4.15-dev-7842-g558ab78
FindActCtxSectionStringW.c
Go to the documentation of this file.
1/*
2 * Unit test suite for virtual substituted drive functions.
3 *
4 * Copyright 2017 Giannis Adamopoulos
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "precomp.h"
22
23#define STRSECTION_MAGIC 0x64487353 /* dHsS */
24
26{
35};
36
38{
42 ULONG name_offset; /* versioned name offset */
44 ULONG module_offset; /* container name offset to the section base */
45};
46
48{
52};
53
54#include <pshpack1.h>
55
57{
61 DWORD ulEncodedAssemblyIdentityOffset; /* offset to the section base */
64 DWORD ulManifestPathOffset; /* offset to the section base */
68 DWORD ulAssemblyDirectoryNameOffset; /* offset to the section base */
69 DWORD unk4[3]; /* In win10 there are two more fields */
70};
71
72#include <poppack.h>
73
75{
76 ACTCTXW ActCtx = {sizeof(ACTCTX)};
77 HANDLE h;
79
80 ok (GetModuleFileNameW(NULL, buffer, MAX_PATH), "GetModuleFileName failed\n");
81 separator = wcsrchr(buffer, L'\\');
82 if (separator)
84
85 ActCtx.lpSource = buffer;
86
87 SetLastError(0xdeaddead);
89 ok_(__FILE__, line)(h != INVALID_HANDLE_VALUE, "CreateActCtx failed for %S\n", FileName);
90 // In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
91 ok_(__FILE__, line)(GetLastError() == ERROR_BAD_EXE_FORMAT || GetLastError() == 0xdeaddead, "Wrong last error %lu\n", GetLastError());
92
93 return h;
94}
95
97{
98 BOOL res;
99
100 SetLastError(0xdeaddead);
102 ok_(__FILE__, line)(res == TRUE, "ActivateActCtx failed\n");
103 ok_(__FILE__, line)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError());
104}
105
107{
108 BOOL res;
109
110 SetLastError(0xdeaddead);
112 ok_(__FILE__, line)(res == TRUE, "DeactivateActCtx failed\n");
113 ok_(__FILE__, line)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError());
114}
115
116void TestClassRedirection(HANDLE h, LPCWSTR ClassToTest, LPCWSTR ExpectedClassPart, LPCWSTR ExpectedModule, ULONG ExpectedClassCount)
117{
118 ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 };
119 BOOL res;
121 struct wndclass_redirect_data *classData;
122 LPCWSTR VersionedClass, ClassLib;
123 int data_lenght;
124
125 SetLastError(0xdeaddead);
126 KeyedData.cbSize = sizeof(KeyedData);
127 res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
128 NULL,
129 ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
130 ClassToTest,
131 &KeyedData);
132 ok(res == TRUE, "FindActCtxSectionString failed\n");
133 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError());
134
135 ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu\n", KeyedData.ulDataFormatVersion);
136 ok(KeyedData.hActCtx == h, "Wrong handle\n");
137 ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n");
138 ok(KeyedData.lpData != NULL, "Expected non null lpData\n");
139 header = (struct strsection_header*)KeyedData.lpSectionBase;
140 classData = (struct wndclass_redirect_data*)KeyedData.lpData;
141
142 if(res == FALSE || KeyedData.ulDataFormatVersion != 1 || header == NULL || classData == NULL)
143 {
144 skip("Can't read data for class. Skipping\n");
145 }
146 else
147 {
148 ok(header->magic == STRSECTION_MAGIC, "%lu\n", header->magic );
149 ok(header->size == sizeof(*header), "Got %lu instead of %d\n", header->size, sizeof(*header));
150 ok(header->count == ExpectedClassCount, "Expected %lu classes, got %lu\n", ExpectedClassCount, header->count );
151
152 VersionedClass = (WCHAR*)((BYTE*)classData + classData->name_offset);
153 ClassLib = (WCHAR*)((BYTE*)header + classData->module_offset);
154 data_lenght = classData->size + classData->name_len + classData->module_len + 2*sizeof(WCHAR);
155 ok(KeyedData.ulLength == data_lenght, "Got lenght %lu instead of %d\n", KeyedData.ulLength, data_lenght);
156 ok(classData->size == sizeof(*classData), "Got %lu instead of %d\n", classData->size, sizeof(*classData));
157 ok(classData->res == 0, "Got res %lu\n", classData->res);
158 ok(classData->module_len == wcslen(ExpectedModule) * 2, "Got name len %lu, expected %d\n", classData->module_len, wcslen(ExpectedModule) *2);
159 ok(wcscmp(ClassLib, ExpectedModule) == 0, "Got %S, expected %S\n", ClassLib, ExpectedModule);
160 /* compare only if VersionedClass starts with ExpectedClassPart */
161 ok(memcmp(VersionedClass, ExpectedClassPart, sizeof(WCHAR) * wcslen(ExpectedClassPart)) == 0, "Expected %S to start with %S\n", VersionedClass, ExpectedClassPart);
162 }
163}
164
166{
167 ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 };
168 BOOL res;
169 struct strsection_header *SectionHeader;
170 struct dllredirect_data *redirData;
171 struct assemply_data *assemplyData;
172
173 SetLastError(0xdeaddead);
174 KeyedData.cbSize = sizeof(KeyedData);
175 res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
176 NULL,
177 ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
178 L"dep1.dll",
179 &KeyedData);
180 ok(res == TRUE, "FindActCtxSectionString failed\n");
181 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError());
182
183 ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu", KeyedData.ulDataFormatVersion);
184 ok(KeyedData.hActCtx == h, "Wrong handle\n");
185 ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n");
186 ok(KeyedData.lpData != NULL, "Expected non null lpData\n");
187 SectionHeader = (struct strsection_header*)KeyedData.lpSectionBase;
188 redirData = (struct dllredirect_data *)KeyedData.lpData;
189
190 if(res == FALSE || KeyedData.ulDataFormatVersion != 1 || SectionHeader == NULL || redirData == NULL)
191 {
192 skip("Can't read data for dep1.dll. Skipping\n");
193 }
194 else
195 {
196 ok(SectionHeader->magic == STRSECTION_MAGIC, "%lu\n", SectionHeader->magic );
197 ok(SectionHeader->size == sizeof(*SectionHeader), "Got %lu instead of %d\n", SectionHeader->size, sizeof(*SectionHeader));
198 ok(SectionHeader->count == 2, "%lu\n", SectionHeader->count ); /* 2 dlls? */
199 ok(redirData->size == sizeof(*redirData), "Got %lu instead of %d\n", redirData->size, sizeof(*redirData));
200 }
201
202 SetLastError(0xdeaddead);
203 KeyedData.cbSize = sizeof(KeyedData);
204 res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
205 NULL,
206 ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION,
207 L"dep1",
208 &KeyedData);
209 ok(res == TRUE, "FindActCtxSectionString failed\n");
210 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError());
211 ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu", KeyedData.ulDataFormatVersion);
212 ok(KeyedData.hActCtx == h, "Wrong handle\n");
213 ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n");
214 ok(KeyedData.lpData != NULL, "Expected non null lpData\n");
215 SectionHeader = (struct strsection_header*)KeyedData.lpSectionBase;
216 assemplyData = (struct assemply_data*)KeyedData.lpData;;
217
218 if(res == FALSE || KeyedData.ulDataFormatVersion != 1 || SectionHeader == NULL || assemplyData == NULL)
219 {
220 skip("Can't read data for dep1. Skipping\n");
221 }
222 else
223 {
224 LPCWSTR AssemblyIdentity, ManifestPath, AssemblyDirectory;
225 int data_lenght;
226 DWORD buffer[256];
227 PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION details = (PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION)buffer;
228
229 ok(SectionHeader->magic == STRSECTION_MAGIC, "%lu\n", SectionHeader->magic );
230 ok(SectionHeader->size == sizeof(*SectionHeader), "Got %lu instead of %d\n", SectionHeader->size, sizeof(*SectionHeader));
231 ok(SectionHeader->count == 2, "%lu\n", SectionHeader->count ); /* 2 dlls? */
232
233 data_lenght = assemplyData->size +
234 assemplyData->ulEncodedAssemblyIdentityLength +
235 assemplyData->ulManifestPathLength +
236 assemplyData->ulAssemblyDirectoryNameLength + 2 * sizeof(WCHAR);
237 ok(assemplyData->size == sizeof(*assemplyData), "Got %lu instead of %d\n", assemplyData->size, sizeof(*assemplyData));
238 ok(KeyedData.ulLength == data_lenght, "Got lenght %lu instead of %d\n", KeyedData.ulLength, data_lenght);
239
240 AssemblyIdentity = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulEncodedAssemblyIdentityOffset);
241 ManifestPath = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulManifestPathOffset);
242 AssemblyDirectory = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulAssemblyDirectoryNameOffset);
243
244 /* Use AssemblyDetailedInformationInActivationContext so as to infer the contents of assemplyData */
245 res = QueryActCtxW(0, h, &KeyedData.ulAssemblyRosterIndex,
246 AssemblyDetailedInformationInActivationContext,
247 &buffer, sizeof(buffer), NULL);
248 ok(res == TRUE, "QueryActCtxW failed\n");
249 ok(assemplyData->ulFlags == details->ulFlags, "\n");
250 ok(assemplyData->ulEncodedAssemblyIdentityLength == details->ulEncodedAssemblyIdentityLength, "\n");
251 ok(assemplyData->ulManifestPathType == details->ulManifestPathType, "\n");
252 ok(assemplyData->ulManifestPathLength == details->ulManifestPathLength, "\n");
253 ok(assemplyData->ulAssemblyDirectoryNameLength == details->ulAssemblyDirectoryNameLength, "\n");
254 ok(assemplyData->liManifestLastWriteTime.QuadPart == details->liManifestLastWriteTime.QuadPart, "\n");
255
256 ok(wcscmp(ManifestPath, details->lpAssemblyManifestPath) == 0, "Expected path %S, got %S\n", details->lpAssemblyManifestPath, ManifestPath);
257 ok(wcscmp(AssemblyDirectory, details->lpAssemblyDirectoryName) == 0, "Expected path %S, got %S\n", details->lpAssemblyManifestPath, ManifestPath);
258
259 /* It looks like that AssemblyIdentity isn't null terminated */
260 ok(memcmp(AssemblyIdentity, details->lpAssemblyEncodedAssemblyIdentity, assemplyData->ulEncodedAssemblyIdentityLength) == 0, "Got wrong AssemblyIdentity\n");
261 }
262}
263
265{
266 HANDLE h, h2;
267 ULONG_PTR cookie, cookie2;
268
269 /*First run the redirection tests without using our own actctx */
270 TestClassRedirection(NULL, L"Button", L"Button", L"comctl32.dll", 27);
271 /* Something activates an activation context that mentions comctl32 but comctl32 is not loaded */
272 ok( GetModuleHandleW(L"comctl32.dll") == NULL, "Expected comctl32 not to be loaded\n");
273 ok( GetModuleHandleW(L"user32.dll") == NULL, "Expected user32 not to be loaded\n");
274
275 /* Class redirection tests */
276 h = _CreateActCtxFromFile(L"classtest.manifest", __LINE__);
277 if (h != INVALID_HANDLE_VALUE)
278 {
279 _ActivateCtx(h, &cookie, __LINE__);
280 TestClassRedirection(h, L"Button", L"2.2.2.2!Button", L"testlib.dll", 5);
281 _ActivateCtx(NULL, &cookie2, __LINE__);
282 TestClassRedirection(NULL, L"Button", L"Button", L"comctl32.dll", 27);
283 _DeactivateCtx(cookie2, __LINE__);
284 _DeactivateCtx(cookie, __LINE__);
285 }
286 else
287 {
288 skip("Failed to create context for classtest.manifest\n");
289 }
290
291 /* Class redirection tests with multiple contexts in the activation stack */
292 h2 = _CreateActCtxFromFile(L"classtest2.manifest", __LINE__);
294 {
295 _ActivateCtx(h, &cookie, __LINE__);
296 _ActivateCtx(h2, &cookie2, __LINE__);
297 TestClassRedirection(NULL, L"Button", L"Button", L"comctl32.dll", 27);
298 TestClassRedirection(h2, L"MyClass", L"1.1.1.1!MyClass", L"testlib.dll", 5);
299 _DeactivateCtx(cookie2, __LINE__);
300 TestClassRedirection(h, L"Button", L"2.2.2.2!Button", L"testlib.dll", 5);
301 _DeactivateCtx(cookie, __LINE__);
302 }
303 else
304 {
305 skip("Failed to create context for classtest.manifest\n");
306 }
307
308 /* Dependency tests */
309 h = _CreateActCtxFromFile(L"deptest.manifest", __LINE__);
310 if (h != INVALID_HANDLE_VALUE)
311 {
312 _ActivateCtx(h, &cookie, __LINE__);
314 _DeactivateCtx(cookie, __LINE__);
315 }
316 else
317 {
318 skip("Failed to create context for deptest.manifest\n");
319 }
320
321 /* Activate a context that depends on comctl32 v6 and run class tests again */
322 h = _CreateActCtxFromFile(L"comctl32dep.manifest", __LINE__);
323 if (h != INVALID_HANDLE_VALUE)
324 {
325 _ActivateCtx(h, &cookie, __LINE__);
326 TestClassRedirection(h, L"Button", L"6.0.", L"comctl32.dll", 29);
327 ok( GetModuleHandleW(L"comctl32.dll") == NULL, "Expected comctl32 not to be loaded\n");
328 ok( GetModuleHandleW(L"user32.dll") == NULL, "Expected user32 not to be loaded\n");
329 _DeactivateCtx(cookie, __LINE__);
330 }
331 else
332 {
333 skip("Failed to create context for comctl32dep.manifest\n");
334 }
335}
VOID _DeactivateCtx(ULONG_PTR cookie, int line)
void TestClassRedirection(HANDLE h, LPCWSTR ClassToTest, LPCWSTR ExpectedClassPart, LPCWSTR ExpectedModule, ULONG ExpectedClassCount)
#define STRSECTION_MAGIC
HANDLE _CreateActCtxFromFile(LPCWSTR FileName, int line)
VOID TestLibDependency(HANDLE h)
VOID _ActivateCtx(HANDLE h, ULONG_PTR *cookie, int line)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcsrchr
Definition: compat.h:16
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
static const WCHAR separator[]
Definition: asmname.c:65
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI QueryActCtxW(IN DWORD dwFlags, IN HANDLE hActCtx, IN PVOID pvSubInstance, IN ULONG ulInfoClass, IN PVOID pvBuffer, IN SIZE_T cbBuffer, IN OUT SIZE_T *pcbWrittenOrRequired OPTIONAL)
Definition: actctx.c:328
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtGuid, ULONG ulId, LPCWSTR lpSearchStr, PACTCTX_SECTION_KEYED_DATA pInfo)
Definition: actctx.c:156
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:104
struct _FileName FileName
Definition: fatprocs.h:896
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
int details
Definition: msacm.c:1366
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
LARGE_INTEGER liManifestLastWriteTime
Definition: cookie.c:34
Definition: parser.c:49
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:251
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193