2 * Unit test suite for virtual substituted drive functions.
4 * Copyright 2017 Giannis Adamopoulos
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.
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.
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
24 #include "wine/test.h"
29 #define STRSECTION_MAGIC 0x64487353 /* dHsS */
31 struct strsection_header
43 struct wndclass_redirect_data
48 ULONG name_offset
; /* versioned name offset */
50 ULONG module_offset
; /* container name offset to the section base */
53 struct dllredirect_data
66 DWORD ulEncodedAssemblyIdentityLength
;
67 DWORD ulEncodedAssemblyIdentityOffset
; /* offset to the section base */
68 DWORD ulManifestPathType
;
69 DWORD ulManifestPathLength
;
70 DWORD ulManifestPathOffset
; /* offset to the section base */
71 LARGE_INTEGER liManifestLastWriteTime
;
73 DWORD ulAssemblyDirectoryNameLength
;
74 DWORD ulAssemblyDirectoryNameOffset
; /* offset to the section base */
75 DWORD unk4
[3]; /* In win10 there are two more fields */
80 HANDLE
_CreateActCtxFromFile(LPCWSTR FileName
, int line
)
82 ACTCTXW ActCtx
= {sizeof(ACTCTX
), 0, FileName
};
85 SetLastError(0xdeaddead);
86 h
= CreateActCtxW(&ActCtx
);
87 ok_(__FILE__
, line
)(h
!= INVALID_HANDLE_VALUE
, "CreateActCtx failed\n");
88 // In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
89 ok_(__FILE__
, line
)(GetLastError() == ERROR_BAD_EXE_FORMAT
, "Wrong last error. Expected %d, got %lu\n", ERROR_BAD_EXE_FORMAT
, GetLastError());
94 VOID
_ActivateCtx(HANDLE h
, ULONG_PTR
*cookie
, int line
)
98 SetLastError(0xdeaddead);
99 res
= ActivateActCtx(h
, cookie
);
100 ok_(__FILE__
, line
)(res
== TRUE
, "ActivateActCtx failed\n");
101 ok_(__FILE__
, line
)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD
)(0xdeaddead), GetLastError());
104 VOID
_DeactivateCtx(ULONG_PTR cookie
, int line
)
108 SetLastError(0xdeaddead);
109 res
= DeactivateActCtx(0, cookie
);
110 ok_(__FILE__
, line
)(res
== TRUE
, "DeactivateActCtx failed\n");
111 ok_(__FILE__
, line
)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD
)(0xdeaddead), GetLastError());
114 void TestClassRedirection(HANDLE h
, LPCWSTR ClassToTest
, LPCWSTR ExpectedClassName
, LPCWSTR ExpectedModule
, ULONG ExpectedClassCount
)
116 ACTCTX_SECTION_KEYED_DATA KeyedData
= { 0 };
118 struct strsection_header
*header
;
119 struct wndclass_redirect_data
*classData
;
120 LPCWSTR VersionedClass
, ClassLib
;
123 SetLastError(0xdeaddead);
124 KeyedData
.cbSize
= sizeof(KeyedData
);
125 res
= FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
,
127 ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION
,
130 ok(res
== TRUE
, "FindActCtxSectionString failed\n");
131 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD
)(0xdeaddead), GetLastError());
133 ok(KeyedData
.ulDataFormatVersion
== 1, "Wrong format version: %lu", KeyedData
.ulDataFormatVersion
);
134 ok(KeyedData
.hActCtx
== h
, "Wrong handle\n");
135 ok(KeyedData
.lpSectionBase
!= NULL
, "Expected non null lpSectionBase\n");
136 ok(KeyedData
.lpData
!= NULL
, "Expected non null lpData\n");
137 header
= (struct strsection_header
*)KeyedData
.lpSectionBase
;
138 classData
= (struct wndclass_redirect_data
*)KeyedData
.lpData
;
140 ok(header
->magic
== STRSECTION_MAGIC
, "%lu\n", header
->magic
);
141 ok(header
->size
== sizeof(*header
), "Got %lu instead of %d\n", header
->size
, sizeof(*header
));
142 ok(header
->count
== ExpectedClassCount
, "Expected %lu classes, got %lu\n", ExpectedClassCount
, header
->count
);
144 VersionedClass
= (WCHAR
*)((BYTE
*)classData
+ classData
->name_offset
);
145 ClassLib
= (WCHAR
*)((BYTE
*)header
+ classData
->module_offset
);
146 data_lenght
= classData
->size
+ classData
->name_len
+ classData
->module_len
+ 2*sizeof(WCHAR
);
147 ok(KeyedData
.ulLength
== data_lenght
, "Got lenght %lu instead of %d\n", KeyedData
.ulLength
, data_lenght
);
148 ok(classData
->size
== sizeof(*classData
), "Got %lu instead of %d\n", classData
->size
, sizeof(*classData
));
149 ok(classData
->res
== 0, "Got res %lu\n", classData
->res
);
150 ok(classData
->name_len
== wcslen(ExpectedClassName
) * 2, "Got name len %lu, expected %d\n", classData
->name_len
, wcslen(ExpectedClassName
) *2);
151 ok(classData
->module_len
== wcslen(ExpectedModule
) * 2, "Got name len %lu, expected %d\n", classData
->module_len
, wcslen(ExpectedModule
) *2);
152 ok(wcscmp(VersionedClass
, ExpectedClassName
) == 0, "Got %S, expected %S\n", VersionedClass
, ExpectedClassName
);
153 ok(wcscmp(ClassLib
, ExpectedModule
) == 0, "Got %S, expected %S\n", ClassLib
, ExpectedModule
);
156 VOID
TestLibDependency(HANDLE h
)
158 ACTCTX_SECTION_KEYED_DATA KeyedData
= { 0 };
160 struct strsection_header
*SectionHeader
;
161 struct dllredirect_data
*redirData
;
162 struct assemply_data
*assemplyData
;
164 SetLastError(0xdeaddead);
165 KeyedData
.cbSize
= sizeof(KeyedData
);
166 res
= FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
,
168 ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION
,
171 ok(res
== TRUE
, "FindActCtxSectionString failed\n");
172 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD
)(0xdeaddead), GetLastError());
174 ok(KeyedData
.ulDataFormatVersion
== 1, "Wrong format version: %lu", KeyedData
.ulDataFormatVersion
);
175 ok(KeyedData
.hActCtx
== h
, "Wrong handle\n");
176 ok(KeyedData
.lpSectionBase
!= NULL
, "Expected non null lpSectionBase\n");
177 ok(KeyedData
.lpData
!= NULL
, "Expected non null lpData\n");
178 SectionHeader
= (struct strsection_header
*)KeyedData
.lpSectionBase
;
179 redirData
= (struct dllredirect_data
*)KeyedData
.lpData
;
181 if(res
== FALSE
|| KeyedData
.ulDataFormatVersion
!= 1)
183 skip("Can't read data for dep1.dll. Skipping\n");
187 ok(SectionHeader
->magic
== STRSECTION_MAGIC
, "%lu\n", SectionHeader
->magic
);
188 ok(SectionHeader
->size
== sizeof(*SectionHeader
), "Got %lu instead of %d\n", SectionHeader
->size
, sizeof(*SectionHeader
));
189 ok(SectionHeader
->count
== 2, "%lu\n", SectionHeader
->count
); /* 2 dlls? */
190 ok(redirData
->size
== sizeof(*redirData
), "Got %lu instead of %d\n", redirData
->size
, sizeof(*redirData
));
193 SetLastError(0xdeaddead);
194 KeyedData
.cbSize
= sizeof(KeyedData
);
195 res
= FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
,
197 ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION
,
200 ok(res
== TRUE
, "FindActCtxSectionString failed\n");
201 ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD
)(0xdeaddead), GetLastError());
202 ok(KeyedData
.ulDataFormatVersion
== 1, "Wrong format version: %lu", KeyedData
.ulDataFormatVersion
);
203 ok(KeyedData
.hActCtx
== h
, "Wrong handle\n");
204 ok(KeyedData
.lpSectionBase
!= NULL
, "Expected non null lpSectionBase\n");
205 ok(KeyedData
.lpData
!= NULL
, "Expected non null lpData\n");
206 SectionHeader
= (struct strsection_header
*)KeyedData
.lpSectionBase
;
207 assemplyData
= (struct assemply_data
*)KeyedData
.lpData
;;
209 if(res
== FALSE
|| KeyedData
.ulDataFormatVersion
!= 1)
211 skip("Can't read data for dep1. Skipping\n");
215 LPCWSTR AssemblyIdentity
, ManifestPath
, AssemblyDirectory
;
218 PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION details
= (PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION
)buffer
;
220 ok(SectionHeader
->magic
== STRSECTION_MAGIC
, "%lu\n", SectionHeader
->magic
);
221 ok(SectionHeader
->size
== sizeof(*SectionHeader
), "Got %lu instead of %d\n", SectionHeader
->size
, sizeof(*SectionHeader
));
222 ok(SectionHeader
->count
== 2, "%lu\n", SectionHeader
->count
); /* 2 dlls? */
224 data_lenght
= assemplyData
->size
+
225 assemplyData
->ulEncodedAssemblyIdentityLength
+
226 assemplyData
->ulManifestPathLength
+
227 assemplyData
->ulAssemblyDirectoryNameLength
+ 2 * sizeof(WCHAR
);
228 ok(assemplyData
->size
== sizeof(*assemplyData
), "Got %lu instead of %d\n", assemplyData
->size
, sizeof(*assemplyData
));
229 ok(KeyedData
.ulLength
== data_lenght
, "Got lenght %lu instead of %d\n", KeyedData
.ulLength
, data_lenght
);
231 AssemblyIdentity
= (WCHAR
*)((BYTE
*)SectionHeader
+ assemplyData
->ulEncodedAssemblyIdentityOffset
);
232 ManifestPath
= (WCHAR
*)((BYTE
*)SectionHeader
+ assemplyData
->ulManifestPathOffset
);
233 AssemblyDirectory
= (WCHAR
*)((BYTE
*)SectionHeader
+ assemplyData
->ulAssemblyDirectoryNameOffset
);
235 /* Use AssemblyDetailedInformationInActivationContext so as to infer the contents of assemplyData */
236 res
= QueryActCtxW(0, h
, &KeyedData
.ulAssemblyRosterIndex
,
237 AssemblyDetailedInformationInActivationContext
,
238 &buffer
, sizeof(buffer
), NULL
);
239 ok(res
== TRUE
, "QueryActCtxW failed\n");
240 ok(assemplyData
->ulFlags
== details
->ulFlags
, "\n");
241 ok(assemplyData
->ulEncodedAssemblyIdentityLength
== details
->ulEncodedAssemblyIdentityLength
, "\n");
242 ok(assemplyData
->ulManifestPathType
== details
->ulManifestPathType
, "\n");
243 ok(assemplyData
->ulManifestPathLength
== details
->ulManifestPathLength
, "\n");
244 ok(assemplyData
->ulAssemblyDirectoryNameLength
== details
->ulAssemblyDirectoryNameLength
, "\n");
245 ok(assemplyData
->liManifestLastWriteTime
.QuadPart
== details
->liManifestLastWriteTime
.QuadPart
, "\n");
247 ok(wcscmp(ManifestPath
, details
->lpAssemblyManifestPath
) == 0, "Expected path %S, got %S\n", details
->lpAssemblyManifestPath
, ManifestPath
);
248 ok(wcscmp(AssemblyDirectory
, details
->lpAssemblyDirectoryName
) == 0, "Expected path %S, got %S\n", details
->lpAssemblyManifestPath
, ManifestPath
);
250 /* It looks like that AssemblyIdentity isn't null terminated */
251 ok(memcmp(AssemblyIdentity
, details
->lpAssemblyEncodedAssemblyIdentity
, assemplyData
->ulEncodedAssemblyIdentityLength
) == 0, "Got wrong AssemblyIdentity\n");
255 START_TEST(FindActCtxSectionStringW
)
260 /*First run the redirection tests without using our own actctx */
261 TestClassRedirection(NULL
, L
"Button", L
"Button", L
"comctl32.dll", 27);
262 /* Something activates an activation context that mentions comctl32 but comctl32 is not loaded */
263 ok( GetModuleHandleW(L
"comctl32.dll") == NULL
, "Expected comctl32 not to be loaded\n");
264 ok( GetModuleHandleW(L
"user32.dll") == NULL
, "Expected user32 not to be loaded\n");
266 /* Class redirection tests */
267 h
= _CreateActCtxFromFile(L
"classtest.manifest", __LINE__
);
268 _ActivateCtx(h
, &cookie
, __LINE__
);
269 TestClassRedirection(h
, L
"Button", L
"2.2.2.2!Button", L
"testlib.dll", 5);
270 _DeactivateCtx(cookie
, __LINE__
);
272 /* Dependency tests */
273 h
= _CreateActCtxFromFile(L
"deptest.manifest", __LINE__
);
274 _ActivateCtx(h
, &cookie
, __LINE__
);
275 TestLibDependency(h
);
276 _DeactivateCtx(cookie
, __LINE__
);
278 /* Activate a context that depends on comctl32 v6 and run class tests again */
279 h
= _CreateActCtxFromFile(L
"comctl32dep.manifest", __LINE__
);
280 _ActivateCtx(h
, &cookie
, __LINE__
);
281 TestClassRedirection(h
, L
"Button", L
"6.0.3790.1830!Button", L
"comctl32.dll", 29);
282 ok( GetModuleHandleW(L
"comctl32.dll") == NULL
, "Expected comctl32 not to be loaded\n");
283 ok( GetModuleHandleW(L
"user32.dll") == NULL
, "Expected user32 not to be loaded\n");
284 _DeactivateCtx(cookie
, __LINE__
);