ReactOS  0.4.14-dev-49-gfb4591c
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 {
29  DWORD unk1[3];
32  DWORD unk2[2];
35 };
36 
38 {
42  ULONG name_offset; /* versioned name offset */
44  ULONG module_offset; /* container name offset to the section base */
45 };
46 
48 {
51  DWORD res[3];
52 };
53 
54 #include <pshpack1.h>
55 
57 {
61  DWORD ulEncodedAssemblyIdentityOffset; /* offset to the section base */
64  DWORD ulManifestPathOffset; /* offset to the section base */
66  DWORD unk3[11];
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);
101  res = ActivateActCtx(h, cookie);
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);
111  res = DeactivateActCtx(0, cookie);
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 
116 void TestClassRedirection(HANDLE h, LPCWSTR ClassToTest, LPCWSTR ExpectedClassPart, LPCWSTR ExpectedModule, ULONG ExpectedClassCount)
117 {
118  ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 };
119  BOOL res;
120  struct strsection_header *header;
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 }
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
VOID _DeactivateCtx(ULONG_PTR cookie, int line)
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:609
#define STRSECTION_MAGIC
#define TRUE
Definition: types.h:120
static const WCHAR separator[]
Definition: asmname.c:63
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
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
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
#define DWORD
Definition: nt_native.h:44
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
uint32_t ULONG_PTR
Definition: typedefs.h:63
START_TEST(FindActCtxSectionStringW)
LARGE_INTEGER liManifestLastWriteTime
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtGuid, ULONG ulId, LPCWSTR lpSearchStr, PACTCTX_SECTION_KEYED_DATA pInfo)
Definition: actctx.c:156
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:251
smooth NULL
Definition: ftsmooth.c:416
VOID TestLibDependency(HANDLE h)
Definition: parser.c:48
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
void TestClassRedirection(HANDLE h, LPCWSTR ClassToTest, LPCWSTR ExpectedClassPart, LPCWSTR ExpectedModule, ULONG ExpectedClassCount)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
struct _FileName FileName
Definition: fatprocs.h:884
#define ok(value,...)
Definition: atltest.h:57
HANDLE _CreateActCtxFromFile(LPCWSTR FileName, int line)
#define skip(...)
Definition: atltest.h:64
GLuint res
Definition: glext.h:9613
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:104
unsigned int ULONG
Definition: retypes.h:1
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
int details
Definition: msacm.c:1353
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct CFHEADER header
Definition: fdi.c:109
LONGLONG QuadPart
Definition: typedefs.h:112
#define ok_(x1, x2)
Definition: atltest.h:61
VOID _ActivateCtx(HANDLE h, ULONG_PTR *cookie, int line)