ReactOS  0.4.12-dev-721-g03c3dd5
apphelp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: apphelp_apitest
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Misc apphelp tests
5  * COPYRIGHT: Copyright 2012 Detlef Riekenberg
6  * Copyright 2013 Mislav Blažević
7  * Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
8  */
9 
10 #include <ntstatus.h>
11 #define WIN32_NO_STATUS
12 #include <windows.h>
13 #include <shlwapi.h>
14 #include <winnt.h>
15 #ifdef __REACTOS__
16 #include <ntndk.h>
17 #else
18 #include <winternl.h>
19 #endif
20 
21 #include <winerror.h>
22 #include <stdio.h>
23 #include <initguid.h>
24 #include <shlguid.h>
25 #include <shobjidl.h>
26 
27 #include "wine/test.h"
28 
29 #include "apphelp_apitest.h"
30 
31 
32 #define TAG_TYPE_MASK 0xF000
33 
34 #define TAG_TYPE_NULL 0x1000
35 #define TAG_TYPE_BYTE 0x2000
36 #define TAG_TYPE_WORD 0x3000
37 #define TAG_TYPE_DWORD 0x4000
38 #define TAG_TYPE_QWORD 0x5000
39 #define TAG_TYPE_STRINGREF 0x6000
40 #define TAG_TYPE_LIST 0x7000
41 #define TAG_TYPE_STRING 0x8000
42 #define TAG_TYPE_BINARY 0x9000
43 #define TAG_NULL 0x0
44 #define TAG_SIZE (0x1 | TAG_TYPE_DWORD)
45 #define TAG_CHECKSUM (0x3 | TAG_TYPE_DWORD)
46 #define TAG_MODULE_TYPE (0x6 | TAG_TYPE_DWORD)
47 #define TAG_VERDATEHI (0x7 | TAG_TYPE_DWORD)
48 #define TAG_VERDATELO (0x8 | TAG_TYPE_DWORD)
49 #define TAG_VERFILEOS (0x9 | TAG_TYPE_DWORD)
50 #define TAG_VERFILETYPE (0xA | TAG_TYPE_DWORD)
51 #define TAG_PE_CHECKSUM (0xB | TAG_TYPE_DWORD)
52 #define TAG_VER_LANGUAGE (0x12 | TAG_TYPE_DWORD)
53 #define TAG_LINKER_VERSION (0x1C | TAG_TYPE_DWORD)
54 #define TAG_LINK_DATE (0x1D | TAG_TYPE_DWORD)
55 #define TAG_UPTO_LINK_DATE (0x1E | TAG_TYPE_DWORD)
56 #define TAG_EXE_WRAPPER (0x31 | TAG_TYPE_DWORD)
57 #define TAG_BIN_FILE_VERSION (0x2 | TAG_TYPE_QWORD)
58 #define TAG_BIN_PRODUCT_VERSION (0x3 | TAG_TYPE_QWORD)
59 #define TAG_UPTO_BIN_PRODUCT_VERSION (0x6 | TAG_TYPE_QWORD)
60 #define TAG_UPTO_BIN_FILE_VERSION (0xD | TAG_TYPE_QWORD)
61 #define TAG_NAME (0x1 | TAG_TYPE_STRINGREF)
62 #define TAG_COMPANY_NAME (0x9 | TAG_TYPE_STRINGREF)
63 #define TAG_PRODUCT_NAME (0x10 | TAG_TYPE_STRINGREF)
64 #define TAG_PRODUCT_VERSION (0x11 | TAG_TYPE_STRINGREF)
65 #define TAG_FILE_DESCRIPTION (0x12 | TAG_TYPE_STRINGREF)
66 #define TAG_FILE_VERSION (0x13 | TAG_TYPE_STRINGREF)
67 #define TAG_ORIGINAL_FILENAME (0x14 | TAG_TYPE_STRINGREF)
68 #define TAG_INTERNAL_NAME (0x15 | TAG_TYPE_STRINGREF)
69 #define TAG_LEGAL_COPYRIGHT (0x16 | TAG_TYPE_STRINGREF)
70 #define TAG_16BIT_DESCRIPTION (0x17 | TAG_TYPE_STRINGREF)
71 #define TAG_16BIT_MODULE_NAME (0x20 | TAG_TYPE_STRINGREF)
72 #define TAG_EXPORT_NAME (0x24 | TAG_TYPE_STRINGREF)
73 
74 
75 #define ATTRIBUTE_AVAILABLE 0x1
76 #define ATTRIBUTE_FAILED 0x2
77 
78 typedef struct tagATTRINFO {
79  TAG type;
80  DWORD flags; /* ATTRIBUTE_AVAILABLE, ATTRIBUTE_FAILED */
81  union {
82  QWORD qwattr;
83  DWORD dwattr;
84  WCHAR *lpattr;
85  };
87 
88 static HMODULE hdll;
89 static BOOL (WINAPI *pApphelpCheckShellObject)(REFCLSID, BOOL, ULONGLONG *);
90 static LPCWSTR (WINAPI *pSdbTagToString)(TAG tag);
91 static BOOL (WINAPI *pSdbGUIDToString)(REFGUID Guid, PWSTR GuidString, SIZE_T Length);
92 static BOOL (WINAPI *pSdbIsNullGUID)(REFGUID Guid);
93 static BOOL (WINAPI *pSdbGetStandardDatabaseGUID)(DWORD Flags, GUID* Guid);
94 static BOOL (WINAPI *pSdbGetFileAttributes)(LPCWSTR wszPath, PATTRINFO *ppAttrInfo, LPDWORD pdwAttrCount);
95 static BOOL (WINAPI *pSdbFreeFileAttributes)(PATTRINFO AttrInfo);
96 static HRESULT (WINAPI* pSdbGetAppPatchDir)(PVOID hsdb, LPWSTR path, DWORD size);
97 
98 /* 'Known' database guids */
99 DEFINE_GUID(GUID_DATABASE_MSI,0xd8ff6d16,0x6a3a,0x468a,0x8b,0x44,0x01,0x71,0x4d,0xdc,0x49,0xea);
100 DEFINE_GUID(GUID_DATABASE_SHIM,0x11111111,0x1111,0x1111,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11);
101 DEFINE_GUID(GUID_DATABASE_DRIVERS,0xf9ab2228,0x3312,0x4a73,0xb6,0xf9,0x93,0x6d,0x70,0xe1,0x12,0xef);
102 
103 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
104 
105 DEFINE_GUID(test_Microsoft_Browser_Architecture, 0xa5e46e3a, 0x8849, 0x11d1, 0x9d, 0x8c, 0x00, 0xc0, 0x4f, 0xc9, 0x9d, 0x61);
106 DEFINE_GUID(test_UserAssist, 0xdd313e04, 0xfeff, 0x11d1, 0x8e, 0xcd, 0x00, 0x00, 0xf8, 0x7a, 0x47, 0x0c);
107 DEFINE_GUID(CLSID_InternetSecurityManager, 0x7b8a2d94, 0x0ac9, 0x11d1, 0x89, 0x6c, 0x00, 0xc0, 0x4f, 0xB6, 0xbf, 0xc4);
108 
109 static const CLSID * objects[] = {
110  &GUID_NULL,
111  /* used by IE */
112  &test_Microsoft_Browser_Architecture,
113  &CLSID_MenuBand,
114  &CLSID_ShellLink,
115  &CLSID_ShellWindows,
116  &CLSID_InternetSecurityManager,
117  &test_UserAssist,
118  (const CLSID *)NULL
119 };
120 
122 {
124  BOOL res;
125  int i;
126 
127  if (!pApphelpCheckShellObject)
128  {
129  win_skip("ApphelpCheckShellObject not available\n");
130  return;
131  }
132 
133  for (i = 0; objects[i]; i++)
134  {
135  flags = 0xdeadbeef;
136  SetLastError(0xdeadbeef);
137  res = pApphelpCheckShellObject(objects[i], FALSE, &flags);
138  ok(res && (flags == 0), "%s 0: got %d and 0x%x%08x with 0x%x (expected TRUE and 0)\n",
140 
141  flags = 0xdeadbeef;
142  SetLastError(0xdeadbeef);
143  res = pApphelpCheckShellObject(objects[i], TRUE, &flags);
144  ok(res && (flags == 0), "%s 1: got %d and 0x%x%08x with 0x%x (expected TRUE and 0)\n",
146 
147  }
148 
149  /* NULL as pointer to flags is checked */
150  SetLastError(0xdeadbeef);
151  res = pApphelpCheckShellObject(&GUID_NULL, FALSE, NULL);
152  ok(res, "%s 0: got %d with 0x%x (expected != FALSE)\n", wine_dbgstr_guid(&GUID_NULL), res, GetLastError());
153 
154  /* NULL as CLSID* crash on Windows */
155  if (0)
156  {
157  flags = 0xdeadbeef;
158  SetLastError(0xdeadbeef);
159  res = pApphelpCheckShellObject(NULL, FALSE, &flags);
160  trace("NULL as CLSID*: got %d and 0x%x%08x with 0x%x\n", res, (ULONG)(flags >> 32), (ULONG)flags, GetLastError());
161  }
162 }
163 
164 static void test_SdbTagToString(void)
165 {
166  static const TAG invalid_values[] = {
168  TAG_TYPE_DWORD | 0xFF,
169  TAG_TYPE_DWORD | (0x800 + 0xEE),
170  0x900, 0xFFFF, 0xDEAD, 0xBEEF
171  };
172  static const WCHAR invalid[] = {'I','n','v','a','l','i','d','T','a','g',0};
173  LPCWSTR ret;
174  WORD i;
175 
176  for (i = 0; i < 9; ++i)
177  {
178  ret = pSdbTagToString(invalid_values[i]);
179  ok(lstrcmpW(ret, invalid) == 0, "unexpected string %s, should be %s\n",
181  }
182 }
183 
184 static int strcmp_wa(LPCWSTR strw, const char *stra)
185 {
186  CHAR buf[512];
187  WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
188  return lstrcmpA(buf, stra);
189 }
190 
191 void test_tag(TAG base, const char* names[], size_t upperlimit, int line)
192 {
193  TAG n;
194  for (n = 0; names[n]; ++n)
195  {
196  LPCWSTR tagstr = pSdbTagToString(base | n);
197  ok_(__FILE__, line + 2)(!strcmp_wa(tagstr, names[n]), "Got %s instead of '%s' for %x\n", wine_dbgstr_w(tagstr), names[n], base | n);
198  }
199  for (; n < upperlimit; ++n)
200  {
201  LPCWSTR tagstr = pSdbTagToString(base | n);
202  ok_(__FILE__, line + 2)(!strcmp_wa(tagstr, "InvalidTag"), "Got %s instead of 'InvalidTag' for %x\n", wine_dbgstr_w(tagstr), base | n);
203  }
204 }
205 
206 static struct
207 {
213  const char* tags[7*8];
214 } data[] = {
215  {
216  TAG_TYPE_NULL, 0x1000, __LINE__, WINVER_ANY, WINVER_2003,
217  {
218  "InvalidTag", "INCLUDE", "GENERAL", "MATCH_LOGIC_NOT", "APPLY_ALL_SHIMS", "USE_SERVICE_PACK_FILES", NULL
219  }
220  },
221  {
222  TAG_TYPE_NULL, 0x1000, __LINE__, WINVER_VISTA, WINVER_VISTA,
223  {
224  "InvalidTag", "INCLUDE", "GENERAL", "MATCH_LOGIC_NOT", "APPLY_ALL_SHIMS", "USE_SERVICE_PACK_FILES", "MITIGATION_OS", "BLOCK_UPGRADE",
225  "INCLUDEEXCLUDEDLL", NULL
226  }
227  },
228  {
229  TAG_TYPE_NULL, 0x1000, __LINE__, WINVER_WIN7, WINVER_ANY,
230  {
231  "InvalidTag", "INCLUDE", "GENERAL", "MATCH_LOGIC_NOT", "APPLY_ALL_SHIMS", "USE_SERVICE_PACK_FILES", "MITIGATION_OS", "BLOCK_UPGRADE",
232  "INCLUDEEXCLUDEDLL", "RAC_EVENT_OFF", "TELEMETRY_OFF", "SHIM_ENGINE_OFF", "LAYER_PROPAGATION_OFF", "REINSTALL_UPGRADE", NULL
233  }
234  },
235 
236  {
237  TAG_TYPE_BYTE, 0x1000, __LINE__, WINVER_ANY, WINVER_ANY,
238  {
239  "InvalidTag", NULL
240  }
241  },
242 
243  {
244  TAG_TYPE_WORD, 0x800, __LINE__, WINVER_ANY, WINVER_WIN7,
245  {
246  "InvalidTag", "MATCH_MODE", NULL
247  }
248  },
249  {
250  TAG_TYPE_WORD, 0x800, __LINE__, WINVER_WIN8, WINVER_ANY,
251  {
252  "InvalidTag", "MATCH_MODE", "QUIRK_COMPONENT_CODE_ID", "QUIRK_CODE_ID", NULL
253  }
254  },
255  {
256  TAG_TYPE_WORD | 0x800, 0x800, __LINE__, WINVER_ANY, WINVER_ANY,
257  {
258  "InvalidTag", "TAG", "INDEX_TAG", "INDEX_KEY", NULL
259  }
260  },
261 
262  {
263  TAG_TYPE_DWORD, 0x800, __LINE__, WINVER_ANY, WINVER_WINXP,
264  {
265  "InvalidTag", "SIZE", "OFFSET", "CHECKSUM", "SHIM_TAGID", "PATCH_TAGID", "MODULE_TYPE", "VERFILEDATEHI",
266  "VERFILEDATELO", "VERFILEOS", "VERFILETYPE", "PE_CHECKSUM", "PREVOSMAJORVERSION", "PREVOSMINORVERSION", "PREVOSPLATFORMID", "PREVOSBUILDNO",
267  "PROBLEM_SEVERITY", "APPHELP_LANGID", "VER_LANGUAGE", "InvalidTag", "ENGINE", "HTMLHELPID", "INDEXFLAGS", "FLAGS",
268  "VALUETYPE", "DATA_DWORD", "LAYER_TAGID", "MSI_TRANSFORM_TAGID", "LINKER_VERSION", "LINK_DATE", "UPTO_LINK_DATE", "OS_SERVICE_PACK",
269  "FLAG_TAGID", "RUNTIME_PLATFORM", "OS_SKU", NULL
270  }
271  },
272  {
273  TAG_TYPE_DWORD, 0x800, __LINE__, WINVER_2003, WINVER_2003,
274  {
275  "InvalidTag", "SIZE", "OFFSET", "CHECKSUM", "SHIM_TAGID", "PATCH_TAGID", "MODULE_TYPE", "VERFILEDATEHI",
276  "VERFILEDATELO", "VERFILEOS", "VERFILETYPE", "PE_CHECKSUM", "PREVOSMAJORVERSION", "PREVOSMINORVERSION", "PREVOSPLATFORMID", "PREVOSBUILDNO",
277  "PROBLEM_SEVERITY", "APPHELP_LANGID", "VER_LANGUAGE", "InvalidTag", "ENGINE", "HTMLHELPID", "INDEXFLAGS", "FLAGS",
278  "VALUETYPE", "DATA_DWORD", "LAYER_TAGID", "MSI_TRANSFORM_TAGID", "LINKER_VERSION", "LINK_DATE", "UPTO_LINK_DATE", "OS_SERVICE_PACK",
279  "FLAG_TAGID", "RUNTIME_PLATFORM", "OS_SKU", "OS_PLATFORM", NULL
280  }
281  },
282  {
283  TAG_TYPE_DWORD, 0x800, __LINE__, WINVER_VISTA, WINVER_VISTA,
284  {
285  "InvalidTag", "SIZE", "OFFSET", "CHECKSUM", "SHIM_TAGID", "PATCH_TAGID", "MODULE_TYPE", "VERDATEHI",
286  "VERDATELO", "VERFILEOS", "VERFILETYPE", "PE_CHECKSUM", "PREVOSMAJORVER", "PREVOSMINORVER", "PREVOSPLATFORMID", "PREVOSBUILDNO",
287  "PROBLEMSEVERITY", "LANGID", "VER_LANGUAGE", "InvalidTag", "ENGINE", "HTMLHELPID", "INDEX_FLAGS", "FLAGS",
288  "DATA_VALUETYPE", "DATA_DWORD", "LAYER_TAGID", "MSI_TRANSFORM_TAGID", "LINKER_VERSION", "LINK_DATE", "UPTO_LINK_DATE", "OS_SERVICE_PACK",
289  "FLAG_TAGID", "RUNTIME_PLATFORM", "OS_SKU", "OS_PLATFORM", "APP_NAME_RC_ID", "VENDOR_NAME_RC_ID", "SUMMARY_MSG_RC_ID", "VISTA_SKU",
290  NULL
291  }
292  },
293  {
294  TAG_TYPE_DWORD, 0x800, __LINE__, WINVER_WIN7, WINVER_ANY,
295  {
296  "InvalidTag", "SIZE", "OFFSET", "CHECKSUM", "SHIM_TAGID", "PATCH_TAGID", "MODULE_TYPE", "VERDATEHI",
297  "VERDATELO", "VERFILEOS", "VERFILETYPE", "PE_CHECKSUM", "PREVOSMAJORVER", "PREVOSMINORVER", "PREVOSPLATFORMID", "PREVOSBUILDNO",
298  "PROBLEMSEVERITY", "LANGID", "VER_LANGUAGE", "InvalidTag", "ENGINE", "HTMLHELPID", "INDEX_FLAGS", "FLAGS",
299  "DATA_VALUETYPE", "DATA_DWORD", "LAYER_TAGID", "MSI_TRANSFORM_TAGID", "LINKER_VERSION", "LINK_DATE", "UPTO_LINK_DATE", "OS_SERVICE_PACK",
300  "FLAG_TAGID", "RUNTIME_PLATFORM", "OS_SKU", "OS_PLATFORM", "APP_NAME_RC_ID", "VENDOR_NAME_RC_ID", "SUMMARY_MSG_RC_ID", "VISTA_SKU",
301  "DESCRIPTION_RC_ID", "PARAMETER1_RC_ID", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
302  "CONTEXT_TAGID", "EXE_WRAPPER", "URL_ID", NULL
303  }
304  },
305  {
306  TAG_TYPE_DWORD | 0x800, 0x800, __LINE__, WINVER_ANY, WINVER_ANY,
307  {
308  "InvalidTag", "TAGID", NULL
309  }
310  },
311 
312  {
313  TAG_TYPE_QWORD, 0x1000, __LINE__, WINVER_ANY, WINVER_WINXP,
314  {
315  "InvalidTag", "TIME", "BIN_FILE_VERSION", "BIN_PRODUCT_VERSION", "MODTIME", "FLAG_MASK_KERNEL", "UPTO_BIN_PRODUCT_VERSION", "DATA_QWORD",
316  "FLAG_MASK_USER", "FLAGS_NTVDM1", "FLAGS_NTVDM2", "FLAGS_NTVDM3", "FLAG_MASK_SHELL", "UPTO_BIN_FILE_VERSION", NULL
317  }
318  },
319  {
320  TAG_TYPE_QWORD, 0x1000, __LINE__, WINVER_2003, WINVER_2003,
321  {
322  "InvalidTag", "TIME", "BIN_FILE_VERSION", "BIN_PRODUCT_VERSION", "MODTIME", "FLAG_MASK_KERNEL", "UPTO_BIN_PRODUCT_VERSION", "DATA_QWORD",
323  "FLAG_MASK_USER", "FLAGS_NTVDM1", "FLAGS_NTVDM2", "FLAGS_NTVDM3", "FLAG_MASK_SHELL", "UPTO_BIN_FILE_VERSION", "FLAG_MASK_FUSION", "FLAGS_PROCESSPARAM",
324  NULL
325  }
326  },
327  {
328  TAG_TYPE_QWORD, 0x1000, __LINE__, WINVER_VISTA, WINVER_ANY,
329  {
330  "InvalidTag", "TIME", "BIN_FILE_VERSION", "BIN_PRODUCT_VERSION", "MODTIME", "FLAG_MASK_KERNEL", "UPTO_BIN_PRODUCT_VERSION", "DATA_QWORD",
331  "FLAG_MASK_USER", "FLAGS_NTVDM1", "FLAGS_NTVDM2", "FLAGS_NTVDM3", "FLAG_MASK_SHELL", "UPTO_BIN_FILE_VERSION", "FLAG_MASK_FUSION", "FLAG_PROCESSPARAM",
332  "FLAG_LUA", "FLAG_INSTALL", NULL
333  }
334  },
335 
336  {
337  TAG_TYPE_STRINGREF, 0x1000, __LINE__, WINVER_ANY, WINVER_2003,
338  {
339  "InvalidTag", "NAME", "DESCRIPTION", "MODULE", "API", "VENDOR", "APP_NAME", "InvalidTag",
340  "COMMAND_LINE", "COMPANY_NAME", "DLLFILE", "WILDCARD_NAME", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
341  "PRODUCT_NAME", "PRODUCT_VERSION", "FILE_DESCRIPTION", "FILE_VERSION", "ORIGINAL_FILENAME", "INTERNAL_NAME", "LEGAL_COPYRIGHT", "S16BIT_DESCRIPTION",
342  "PROBLEM_DETAILS", "LINK_URL", "LINK_TEXT", "APPHELP_TITLE", "APPHELP_CONTACT", "SXS_MANIFEST", "DATA_STRING", "MSI_TRANSFORM_FILE",
343  "S16BIT_MODULE_NAME", "LAYER_DISPLAYNAME", "COMPILER_VERSION", "ACTION_TYPE", NULL
344  }
345  },
346  {
347  TAG_TYPE_STRINGREF, 0x1000, __LINE__, WINVER_VISTA, WINVER_VISTA,
348  {
349  "InvalidTag", "NAME", "DESCRIPTION", "MODULE", "API", "VENDOR", "APP_NAME", "InvalidTag",
350  "COMMAND_LINE", "COMPANY_NAME", "DLLFILE", "WILDCARD_NAME", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
351  "PRODUCT_NAME", "PRODUCT_VERSION", "FILE_DESCRIPTION", "FILE_VERSION", "ORIGINAL_FILENAME", "INTERNAL_NAME", "LEGAL_COPYRIGHT", "16BIT_DESCRIPTION",
352  "APPHELP_DETAILS", "LINK_URL", "LINK_TEXT", "APPHELP_TITLE", "APPHELP_CONTACT", "SXS_MANIFEST", "DATA_STRING", "MSI_TRANSFORM_FILE",
353  "16BIT_MODULE_NAME", "LAYER_DISPLAYNAME", "COMPILER_VERSION", "ACTION_TYPE", "EXPORT_NAME", NULL
354  }
355  },
356  {
357  TAG_TYPE_STRINGREF, 0x1000, __LINE__, WINVER_WIN7, WINVER_ANY,
358  {
359  "InvalidTag", "NAME", "DESCRIPTION", "MODULE", "API", "VENDOR", "APP_NAME", "InvalidTag",
360  "COMMAND_LINE", "COMPANY_NAME", "DLLFILE", "WILDCARD_NAME", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
361  "PRODUCT_NAME", "PRODUCT_VERSION", "FILE_DESCRIPTION", "FILE_VERSION", "ORIGINAL_FILENAME", "INTERNAL_NAME", "LEGAL_COPYRIGHT", "16BIT_DESCRIPTION",
362  "APPHELP_DETAILS", "LINK_URL", "LINK_TEXT", "APPHELP_TITLE", "APPHELP_CONTACT", "SXS_MANIFEST", "DATA_STRING", "MSI_TRANSFORM_FILE",
363  "16BIT_MODULE_NAME", "LAYER_DISPLAYNAME", "COMPILER_VERSION", "ACTION_TYPE", "EXPORT_NAME", "URL", NULL
364  }
365  },
366 
367  {
368  TAG_TYPE_LIST, 0x800, __LINE__, WINVER_ANY, WINVER_2003,
369  {
370  "InvalidTag", "DATABASE", "LIBRARY", "INEXCLUDE", "SHIM", "PATCH", "APP", "EXE",
371  "MATCHING_FILE", "SHIM_REF", "PATCH_REF", "LAYER", "FILE", "APPHELP", "LINK", "DATA",
372  "MSI TRANSFORM", "MSI TRANSFORM REF", "MSI PACKAGE", "FLAG", "MSI CUSTOM ACTION", "FLAG_REF", "ACTION", NULL
373  }
374  },
375  {
376  TAG_TYPE_LIST, 0x800, __LINE__, WINVER_VISTA, WINVER_VISTA,
377  {
378  "InvalidTag", "DATABASE", "LIBRARY", "INEXCLUDE", "SHIM", "PATCH", "APP", "EXE",
379  "MATCHING_FILE", "SHIM_REF", "PATCH_REF", "LAYER", "FILE", "APPHELP", "LINK", "DATA",
380  "MSI_TRANSFORM", "MSI_TRANSFORM_REF", "MSI_PACKAGE", "FLAG", "MSI_CUSTOM_ACTION", "FLAG_REF", "ACTION", "LOOKUP",
381  NULL
382  }
383  },
384  {
385  TAG_TYPE_LIST, 0x800, __LINE__, WINVER_WIN7, WINVER_ANY,
386  {
387  "InvalidTag", "DATABASE", "LIBRARY", "INEXCLUDE", "SHIM", "PATCH", "APP", "EXE",
388  "MATCHING_FILE", "SHIM_REF", "PATCH_REF", "LAYER", "FILE", "APPHELP", "LINK", "DATA",
389  "MSI_TRANSFORM", "MSI_TRANSFORM_REF", "MSI_PACKAGE", "FLAG", "MSI_CUSTOM_ACTION", "FLAG_REF", "ACTION", "LOOKUP",
390  "CONTEXT", "CONTEXT_REF", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
391  "SPC", NULL
392  }
393  },
394  {
395  TAG_TYPE_LIST | 0x800, 0x800, __LINE__, WINVER_ANY, WINVER_ANY,
396  {
397  "InvalidTag", "STRINGTABLE", "INDEXES", "INDEX", NULL
398  }
399  },
400 
401  {
402  TAG_TYPE_STRING, 0x800, __LINE__, WINVER_ANY, WINVER_ANY,
403  {
404  "InvalidTag", NULL
405  }
406  },
407  {
408  TAG_TYPE_STRING | 0x800, 0x800, __LINE__, WINVER_ANY, WINVER_2003,
409  {
410  "InvalidTag", "STRTAB_ITEM", NULL
411  }
412  },
413  {
414  TAG_TYPE_STRING | 0x800, 0x800, __LINE__, WINVER_VISTA, WINVER_ANY,
415  {
416  "InvalidTag", "STRINGTABLE_ITEM", NULL
417  }
418  },
419 
420 
421  {
422  TAG_TYPE_BINARY, 0x800, __LINE__, WINVER_ANY, WINVER_2003,
423  {
424  "InvalidTag", "InvalidTag", "PATCH_BITS", "FILE_BITS", "EXE_ID(GUID)", "DATA_BITS", "MSI_PACKAGE_ID(GUID)", "DATABASE_ID(GUID)",
425  NULL
426  }
427  },
428  {
429  TAG_TYPE_BINARY, 0x800, __LINE__, WINVER_VISTA, WINVER_VISTA,
430  {
431  "InvalidTag", "InvalidTag", "PATCH_BITS", "FILE_BITS", "EXE_ID", "DATA_BITS", "MSI_PACKAGE_ID", "DATABASE_ID",
432  NULL
433  }
434  },
435  {
436  TAG_TYPE_BINARY, 0x800, __LINE__, WINVER_WIN7, WINVER_ANY,
437  {
438  "InvalidTag", "InvalidTag", "PATCH_BITS", "FILE_BITS", "EXE_ID", "DATA_BITS", "MSI_PACKAGE_ID", "DATABASE_ID",
439  "CONTEXT_PLATFORM_ID", "CONTEXT_BRANCH_ID", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag", "InvalidTag",
440  "FIX_ID", "APP_ID", NULL
441  }
442  },
443  {
444  TAG_TYPE_BINARY | 0x800, 0x800, __LINE__, WINVER_ANY, WINVER_ANY,
445  {
446  "InvalidTag", "INDEX_BITS", NULL
447  }
448  },
449 
450  { 0, 0, 0, 0, 0, { NULL } }
451 };
452 
453 
454 static void test_SdbTagToStringAllTags(void)
455 {
456  int n;
457  for (n = 0; data[n].base; ++n)
458  {
459  if ((data[n].min_ver == WINVER_ANY || g_WinVersion >= data[n].min_ver) &&
461  {
463  }
464  }
465 }
466 
467 static void test_GuidFunctions(void)
468 {
469  GUID guid;
470  ok(pSdbIsNullGUID(&GUID_NULL), "expected GUID_NULL to be recognized as NULL GUID\n");
471  ok(pSdbIsNullGUID(NULL), "expected NULL to be recognized as NULL GUID\n");
472  ok(pSdbIsNullGUID(&test_UserAssist) == 0, "expected a set GUID not to be recognized as NULL GUID\n");
473 
474  memset(&guid, 0, sizeof(guid));
475  ok(pSdbGetStandardDatabaseGUID(0, &guid) == 0,"Expected SdbGetStandardDatabaseGUID to fail\n");
476  ok(IsEqualGUID(&GUID_NULL, &guid), "Expected guid not to be changed\n");
477 
478  ok(pSdbGetStandardDatabaseGUID(0x80020000, NULL),"Expected SdbGetStandardDatabaseGUID to succeed\n");
479 
480  memset(&guid, 0, sizeof(guid));
481  ok(pSdbGetStandardDatabaseGUID(0x80020000, &guid),"Expected SdbGetStandardDatabaseGUID to succeed\n");
482  ok(IsEqualGUID(&GUID_DATABASE_MSI, &guid), "Expected guid to equal GUID_DATABASE_MSI, was: %s\n", wine_dbgstr_guid(&guid));
483 
484  memset(&guid, 0, sizeof(guid));
485  ok(pSdbGetStandardDatabaseGUID(0x80030000, &guid),"Expected SdbGetStandardDatabaseGUID to succeed\n");
486  ok(IsEqualGUID(&GUID_DATABASE_SHIM, &guid), "Expected guid to equal GUID_DATABASE_SHIM, was: %s\n", wine_dbgstr_guid(&guid));
487 
488  memset(&guid, 0, sizeof(guid));
489  ok(pSdbGetStandardDatabaseGUID(0x80040000, &guid),"Expected SdbGetStandardDatabaseGUID to succeed\n");
490  ok(IsEqualGUID(&GUID_DATABASE_DRIVERS, &guid), "Expected guid to equal GUID_DATABASE_DRIVERS, was: %s\n", wine_dbgstr_guid(&guid));
491 }
492 
494 {
495  PATTRINFO p = &pattr[num];
496  winetest_ok(p->type == TAG_NULL, "expected entry #%d to be TAG_NULL, was %x\n", num, p->type);
497  winetest_ok(p->flags == ATTRIBUTE_FAILED, "expected entry #%d to be failed, was %d\n", num, p->flags);
498  winetest_ok(p->qwattr == 0, "expected entry #%d to be 0, was 0x%I64x\n", num, p->qwattr);
499 }
501 {
502  PATTRINFO p = &pattr[num];
503  winetest_ok(p->type == TAG_NULL, "expected entry #%d to be TAG_NULL, was %x\n", num, p->type);
504  winetest_ok(p->flags == 0, "expected entry #%d to be 0, was %d\n", num, p->flags);
505  winetest_ok(p->qwattr == 0, "expected entry #%d to be 0, was 0x%I64x\n", num, p->qwattr);
506 }
507 
509 {
510  PATTRINFO p = &pattr[num];
511  winetest_ok(p->type == tag, "expected entry #%d to be %x, was %x\n", num, tag, p->type);
512  winetest_ok(p->flags == ATTRIBUTE_AVAILABLE, "expected entry #%d to be available, was %d\n", num, p->flags);
513  winetest_ok(p->dwattr == value, "expected entry #%d to be 0x%x, was 0x%x\n", num, value, p->dwattr);
514 }
515 
517 {
518  PATTRINFO p = &pattr[num];
519  winetest_ok(p->type == tag, "expected entry #%d to be %x, was %x\n", num, tag, p->type);
520  winetest_ok(p->flags == ATTRIBUTE_AVAILABLE, "expected entry #%d to be available, was %d\n", num, p->flags);
521  winetest_ok(p->qwattr == value, "expected entry #%d to be 0x%I64x, was 0x%I64x\n", num, value, p->qwattr);
522 }
523 
524 static void expect_tag_str_imp(PATTRINFO pattr, DWORD num, TAG tag, const WCHAR* value)
525 {
526  PATTRINFO p = &pattr[num];
527  winetest_ok(p->type == tag, "expected entry #%d to be %x, was %x\n", num, tag, p->type);
528  winetest_ok(p->flags == ATTRIBUTE_AVAILABLE, "expected entry #%d to be available, was %d\n", num, p->flags);
529  winetest_ok(p->lpattr && wcscmp(p->lpattr, value) == 0, "expected entry #%d to be %s, was %s\n", num, wine_dbgstr_w(value), wine_dbgstr_w(p->lpattr));
530 }
531 
532 #define expect_tag_skip (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_tag_skip_imp
533 #define expect_tag_empty (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_tag_empty_imp
534 #define expect_tag_dword (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_tag_dword_imp
535 #define expect_tag_qword (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_tag_qword_imp
536 #define expect_tag_str (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_tag_str_imp
537 #define expect_tag_skip_range(ptr, from, to) \
538  do { \
539  int n = (from), n_end = (to); \
540  winetest_set_location(__FILE__, __LINE__); \
541  for ( ; n < n_end; ++n) \
542  expect_tag_skip_imp((ptr), n); \
543  } while (0)
544 #define test_crc (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_crc_imp
545 #define test_crc2 (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_crc2_imp
546 
548 {
549  PATTRINFO pattrinfo;
550  DWORD num;
551 
552  if (!pSdbFreeFileAttributes)
553  {
554  hdll = LoadLibraryA("apphelp.dll");
555  pSdbTagToString = (void *)GetProcAddress(hdll, "SdbTagToString");
556  pSdbGetFileAttributes = (void *)GetProcAddress(hdll, "SdbGetFileAttributes");
557  pSdbFreeFileAttributes = (void *)GetProcAddress(hdll, "SdbFreeFileAttributes");
558  }
559 
560  if (pSdbGetFileAttributes(filename, &pattrinfo, &num))
561  {
562  if (pattrinfo[16].flags == ATTRIBUTE_AVAILABLE)
563  {
564  if (pattrinfo[16].type != TAG_MODULE_TYPE)//SdbpSetAttrFail(&attr_info[16]); /* TAG_MODULE_TYPE (1: WIN16?) (3: WIN32?) (WIN64?), Win32VersionValue? */)
565  printf("FAIL TAG_MODULE_TYPE (%S)\n", filename);
566  if (pattrinfo[16].dwattr != 3 && pattrinfo[16].dwattr != 2)
567  printf("TAG_MODULE_TYPE(%S): %d\n", filename, pattrinfo[16].dwattr); // C:\Program Files (x86)\Windows Kits\8.1\Lib\win7\stub512.com
568  if (pattrinfo[16].dwattr == 2)
569  {
570  printf("TAG_MODULE_TYPE(%S): %d, %d\n", filename, pattrinfo[16].dwattr, pattrinfo[0].dwattr);
571  }
572  }
573 
574  if (pattrinfo[27].flags == ATTRIBUTE_AVAILABLE)
575  {
576  if (pattrinfo[27].type != TAG_EXE_WRAPPER)
577  printf("FAIL TAG_EXE_WRAPPER (%S)\n", filename);
578  if (pattrinfo[27].dwattr != 0)
579  printf("TAG_EXE_WRAPPER(%S): %d\n", filename, pattrinfo[27].dwattr);
580  }
581 
582  pSdbFreeFileAttributes(pattrinfo);
583  }
584 }
585 
586 static void test_crc_imp(size_t len, DWORD expected)
587 {
588  static const WCHAR path[] = {'t','e','s','t','x','x','.','e','x','e',0};
589  static char crc_test[] = {4, 4, 4, 4, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2};
590 
591  PATTRINFO pattrinfo = (PATTRINFO)0xdead;
592  DWORD num = 333;
593  BOOL ret;
594 
595  test_create_file_imp(L"testxx.exe", crc_test, len);
596  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
597  winetest_ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
598  winetest_ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
599  winetest_ok(num == 28, "expected 28 items, got %d.\n", num);
600 
601  if (num == 28 && ret)
602  {
604  }
605  if (ret)
606  pSdbFreeFileAttributes(pattrinfo);
607 }
608 
610 {
611  static const WCHAR path[] = {'t','e','s','t','x','x','.','e','x','e',0};
612 
613  PATTRINFO pattrinfo = (PATTRINFO)0xdead;
614  DWORD num = 333;
615  BOOL ret;
616  size_t n;
617  char* crc_test = malloc(len);
618  for (n = 0; n < len; ++n)
619  crc_test[n] = (char)(fill ? fill : n);
620 
621  test_create_file_imp(L"testxx.exe", crc_test, len);
622  free(crc_test);
623  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
624  winetest_ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
625  winetest_ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
626  winetest_ok(num == 28, "expected 28 items, got %d.\n", num);
627 
628  if (num == 28 && ret)
629  {
630  expect_tag_dword_imp(pattrinfo, 0, TAG_SIZE, len);
632  }
633  if (ret)
634  pSdbFreeFileAttributes(pattrinfo);
635 }
636 
637 
638 
639 static void test_ApplicationAttributes(void)
640 {
641  static const WCHAR path[] = {'t','e','s','t','x','x','.','e','x','e',0};
642  static const WCHAR PRODUCT_VERSION[] = {'1','.','0','.','0','.','1',0};
643  static const WCHAR FILE_DESCRIPTION[] = {'F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0};
644  static const WCHAR COMPANY_NAME[] = {'C','o','m','p','a','n','y','N','a','m','e',0};
645  static const WCHAR PRODUCT_NAME[] = {'P','r','o','d','u','c','t','N','a','m','e',0};
646  static const WCHAR FILE_VERSION[] = {'1','.','0','.','0','.','0',0};
647  static const WCHAR ORIGINAL_FILENAME[] = {'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e',0};
648  static const WCHAR INTERNAL_NAME[] = {'I','n','t','e','r','n','a','l','N','a','m','e',0};
649  static const WCHAR LEGAL_COPYRIGHT[] = {'L','e','g','a','l','C','o','p','y','r','i','g','h','t',0};
650  static const WCHAR EXPORT_NAME[] = {'T','e','S','t','2','.','e','x','e',0};
651  static const WCHAR OS2_DESCRIPTION[] = {'M','O','D',' ','D','E','S','C','R','I','P','T','I','O','N',' ','H','E','R','E',0};
652  static const WCHAR OS2_EXPORT_NAME[] = {'T','E','S','T','M','O','D','.','h','X','x',0};
653  static const WCHAR OS2_DESCRIPTION_broken[] = {'Z',0};
654  static const WCHAR OS2_EXPORT_NAME_broken[] = {'E',0};
655 
656  PATTRINFO pattrinfo = (PATTRINFO)0xdead;
657  DWORD num = 333;
658  BOOL ret;
659 
660  /* ensure the file is not there. */
661  DeleteFileA("testxx.exe");
662  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
663  ok(ret == FALSE, "expected SdbGetFileAttributes to fail.\n");
664  ok(pattrinfo == (PATTRINFO)0xdead, "expected the pointer not to change.\n");
665  ok(num == 333, "expected the number of items not to change.\n");
666  if (ret)
667  pSdbFreeFileAttributes(pattrinfo);
668 
669  /* Test a file with as much features as possible */
670  test_create_exe(L"testxx.exe", 0);
671 
672  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
673  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
674  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
675  ok(num == 28, "expected 28 items, got %d.\n", num);
676 
677  if (num == 28 && ret)
678  {
679  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0x800);
680  expect_tag_dword(pattrinfo, 1, TAG_CHECKSUM, 0x178bd629);
681  expect_tag_qword(pattrinfo, 2, TAG_BIN_FILE_VERSION, 0x1000000000000ull);
682  expect_tag_qword(pattrinfo, 3, TAG_BIN_PRODUCT_VERSION, 0x1000000000001ull);
683  expect_tag_str(pattrinfo, 4, TAG_PRODUCT_VERSION, PRODUCT_VERSION);
684  expect_tag_str(pattrinfo, 5, TAG_FILE_DESCRIPTION, FILE_DESCRIPTION);
685  expect_tag_str(pattrinfo, 6, TAG_COMPANY_NAME, COMPANY_NAME);
687  expect_tag_str(pattrinfo, 8, TAG_FILE_VERSION, FILE_VERSION);
688  expect_tag_str(pattrinfo, 9, TAG_ORIGINAL_FILENAME, ORIGINAL_FILENAME);
689  expect_tag_str(pattrinfo, 10, TAG_INTERNAL_NAME, INTERNAL_NAME);
690  expect_tag_str(pattrinfo, 11, TAG_LEGAL_COPYRIGHT, LEGAL_COPYRIGHT);
691  expect_tag_dword(pattrinfo, 12, TAG_VERDATEHI, 0x1d1a019);
692  expect_tag_dword(pattrinfo, 13, TAG_VERDATELO, 0xac754c50);
694  expect_tag_dword(pattrinfo, 15, TAG_VERFILETYPE, VFT_APP);
695  expect_tag_dword(pattrinfo, 16, TAG_MODULE_TYPE, 0x3); /* Win32 */
696  expect_tag_dword(pattrinfo, 17, TAG_PE_CHECKSUM, 0xBAAD);
697  expect_tag_dword(pattrinfo, 18, TAG_LINKER_VERSION, 0x40002);
698  expect_tag_skip(pattrinfo, 19); /* TAG_16BIT_DESCRIPTION */
699  expect_tag_skip(pattrinfo, 20); /* TAG_16BIT_MODULE_NAME */
700  expect_tag_qword(pattrinfo, 21, TAG_UPTO_BIN_FILE_VERSION, 0x1000000000000ull);
701  expect_tag_qword(pattrinfo, 22, TAG_UPTO_BIN_PRODUCT_VERSION, 0x1000000000001ull);
702  expect_tag_dword(pattrinfo, 23, TAG_LINK_DATE, 0x12345);
703  expect_tag_dword(pattrinfo, 24, TAG_UPTO_LINK_DATE, 0x12345);
704  expect_tag_str(pattrinfo, 25, TAG_EXPORT_NAME, EXPORT_NAME);
705  expect_tag_dword(pattrinfo, 26, TAG_VER_LANGUAGE, 0xffff);
706  expect_tag_dword(pattrinfo, 27, TAG_EXE_WRAPPER, 0x0);
707  }
708  if (ret)
709  pSdbFreeFileAttributes(pattrinfo);
710 
711 
712  /* Disable resource and exports */
713  test_create_exe(L"testxx.exe", 1);
714 
715  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
716  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
717  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
718  ok(num == 28, "expected 28 items, got %d.\n", num);
719 
720  if (num == 28 && ret)
721  {
722  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0x800);
723  expect_tag_dword(pattrinfo, 1, TAG_CHECKSUM, 0xea7caffd);
724  expect_tag_skip_range(pattrinfo, 2, 16);
725  expect_tag_dword(pattrinfo, 16, TAG_MODULE_TYPE, 0x3); /* Win32 */
726  expect_tag_dword(pattrinfo, 17, TAG_PE_CHECKSUM, 0xBAAD);
727  expect_tag_dword(pattrinfo, 18, TAG_LINKER_VERSION, 0x40002);
728  expect_tag_skip_range(pattrinfo, 19, 23);
729  expect_tag_dword(pattrinfo, 23, TAG_LINK_DATE, 0x12345);
730  expect_tag_dword(pattrinfo, 24, TAG_UPTO_LINK_DATE, 0x12345);
731  expect_tag_skip(pattrinfo, 25); /* TAG_EXPORT_NAME */
732  expect_tag_empty(pattrinfo, 26); /* TAG_VER_LANGUAGE */
733  expect_tag_dword(pattrinfo, 27, TAG_EXE_WRAPPER, 0x0);
734  }
735  if (ret)
736  pSdbFreeFileAttributes(pattrinfo);
737 
738  /* A file with just 'MZ' */
739  test_create_file(L"testxx.exe", "MZ", 2);
740 
741  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
742  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
743  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
744  ok(num == 28, "expected 28 items, got %d.\n", num);
745 
746  if (num == 28 && ret)
747  {
748  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0x2);
749  expect_tag_dword(pattrinfo, 1, TAG_CHECKSUM, 0);
750  expect_tag_skip_range(pattrinfo, 2, 16);
751  expect_tag_dword(pattrinfo, 16, TAG_MODULE_TYPE, 0x1);
752  expect_tag_skip_range(pattrinfo, 17, 26);
753  expect_tag_empty(pattrinfo, 26); /* TAG_VER_LANGUAGE */
754  expect_tag_skip(pattrinfo, 27); /* TAG_EXE_WRAPPER */
755  }
756  if (ret)
757  pSdbFreeFileAttributes(pattrinfo);
758 
759  /* Empty file */
760  test_create_file(L"testxx.exe", NULL, 0);
761 
762  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
763  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
764  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
765  ok(num == 28, "expected 28 items, got %d.\n", num);
766 
767  if (num == 28 && ret)
768  {
769  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0);
770  expect_tag_skip_range(pattrinfo, 1, 26);
771  expect_tag_empty(pattrinfo, 26); /* TAG_VER_LANGUAGE */
772  expect_tag_skip(pattrinfo, 27); /* TAG_EXE_WRAPPER */
773  }
774  if (ret)
775  pSdbFreeFileAttributes(pattrinfo);
776 
777  /* minimal NE executable */
778  test_create_ne(L"testxx.exe", 0);
779 
780  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
781  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
782  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
783  ok(num == 28, "expected 28 items, got %d.\n", num);
784 
785  if (num == 28 && ret)
786  {
787  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0xa8);
788  expect_tag_dword(pattrinfo, 1, TAG_CHECKSUM, 0xf2abe4e9);
789  expect_tag_skip_range(pattrinfo, 2, 16);
790  expect_tag_dword(pattrinfo, 16, TAG_MODULE_TYPE, 0x2);
791  expect_tag_skip(pattrinfo, 17); /* TAG_PE_CHECKSUM */
792  expect_tag_skip(pattrinfo, 18); /* TAG_LINKER_VERSION */
793  expect_tag_str(pattrinfo, 19, TAG_16BIT_DESCRIPTION, OS2_DESCRIPTION);
794  expect_tag_str(pattrinfo, 20, TAG_16BIT_MODULE_NAME, OS2_EXPORT_NAME);
795  expect_tag_skip_range(pattrinfo, 21, 26);
796  expect_tag_empty(pattrinfo, 26); /* TAG_VER_LANGUAGE */
797  expect_tag_skip(pattrinfo, 27); /* TAG_EXE_WRAPPER */
798  }
799  if (ret)
800  pSdbFreeFileAttributes(pattrinfo);
801 
802  /* NE executable with description / module name pointers zero, to show they are always used */
803  test_create_ne(L"testxx.exe", 1);
804 
805  ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
806  ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
807  ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
808  ok(num == 28, "expected 28 items, got %d.\n", num);
809 
810  if (num == 28 && ret)
811  {
812  expect_tag_dword(pattrinfo, 0, TAG_SIZE, 0xa8);
813  expect_tag_dword(pattrinfo, 1, TAG_CHECKSUM, 0xddcbe4c9);
814  expect_tag_skip_range(pattrinfo, 2, 16);
815  expect_tag_dword(pattrinfo, 16, TAG_MODULE_TYPE, 0x2);
816  expect_tag_skip(pattrinfo, 17); /* TAG_PE_CHECKSUM */
817  expect_tag_skip(pattrinfo, 18); /* TAG_LINKER_VERSION */
818  expect_tag_str(pattrinfo, 19, TAG_16BIT_DESCRIPTION, OS2_DESCRIPTION_broken); /* the 'Z' from 'MZ' */
819  expect_tag_str(pattrinfo, 20, TAG_16BIT_MODULE_NAME, OS2_EXPORT_NAME_broken); /* the 'E' from 'NE' */
820  expect_tag_skip_range(pattrinfo, 21, 26);
821  expect_tag_empty(pattrinfo, 26); /* TAG_VER_LANGUAGE */
822  expect_tag_skip(pattrinfo, 27); /* TAG_EXE_WRAPPER */
823  }
824  if (ret)
825  pSdbFreeFileAttributes(pattrinfo);
826 
827  test_crc(1, 0);
828  test_crc(2, 0);
829  test_crc(3, 0);
830  test_crc(4, 0x2020202);
831  test_crc(5, 0x2020202);
832  test_crc(6, 0x2020202);
833  test_crc(7, 0x2020202);
834  test_crc(8, 0x81818181);
835  test_crc(9, 0x81818181);
836  test_crc(10, 0x81818181);
837  test_crc(11, 0x81818181);
838  test_crc(12, 0xc2c2c2c2);
839  test_crc(16, 0x62626262);
840 
841  /* This seems to be the cutoff point */
842  test_crc2(0xffc, 4, 0xfbfbfcfc);
843  test_crc2(0xffc, 8, 0x7070717);
844  test_crc2(0xffc, 0xcc, 0xc8eba002);
845  test_crc2(0xffc, 0, 0x4622028d);
846 
847  test_crc2(0x1000, 4, 0x80);
848  test_crc2(0x1000, 8, 0x8787878f);
849  test_crc2(0x1000, 0xcc, 0x4adc3667);
850  test_crc2(0x1000, 0, 0xa3108044);
851 
852  /* Here is another cutoff point */
853  test_crc2(0x11fc, 4, 0x80);
854  test_crc2(0x11fc, 8, 0x8787878f);
855  test_crc2(0x11fc, 0xcc, 0x4adc3667);
856  test_crc2(0x11fc, 0, 0xf03e0800);
857 
858  test_crc2(0x1200, 4, 0x80);
859  test_crc2(0x1200, 8, 0x8787878f);
860  test_crc2(0x1200, 0xcc, 0x4adc3667);
861  test_crc2(0x1200, 0, 0xa3108044);
862 
863  /* After that, it stays the same for all sizes */
864  test_crc2(0xf000, 4, 0x80);
865  test_crc2(0xf000, 8, 0x8787878f);
866  test_crc2(0xf000, 0xcc, 0x4adc3667);
867  test_crc2(0xf000, 0, 0xa3108044);
868 
869 
870  DeleteFileA("testxx.exe");
871 }
872 
873 /* Showing that SdbGetAppPatchDir returns HRESULT */
874 static void test_SdbGetAppPatchDir(void)
875 {
878  int n;
879 
880 
881  _SEH2_TRY
882  {
883  hr = pSdbGetAppPatchDir(NULL, NULL, 0);
884  ok_hex(hr, S_FALSE);
885  }
887  {
888  /* Some versions accept it, some don't */
889  trace("SdbGetAppPatchDir did not handle a NULL pointer very gracefully.\n");
890  }
891  _SEH2_END;
892 
893 
894 
895  memset(Buffer, 0xbb, sizeof(Buffer));
896  hr = pSdbGetAppPatchDir(NULL, Buffer, 0);
899  else if (g_WinVersion < WINVER_WIN10)
900  expect_hr = S_OK;
901  else
902  expect_hr = S_FALSE;
903  ok_hex(hr, expect_hr);
904 
907  else if (g_WinVersion < WINVER_WIN10)
908  expect_hr = S_OK;
909  else
910  expect_hr = TRUE;
911 
912  memset(Buffer, 0xbb, sizeof(Buffer));
913  hr = pSdbGetAppPatchDir(NULL, Buffer, 1);
914  ok_hex(hr, expect_hr);
915 
916 
917  for (n = 2; n < _countof(Buffer) - 1; ++n)
918  {
919  memset(Buffer, 0xbb, sizeof(Buffer));
920  hr = pSdbGetAppPatchDir(NULL, Buffer, n);
921  ok(Buffer[n] == 0xbbbb, "Expected SdbGetAppPatchDir to leave WCHAR at %d untouched, was: %d\n",
922  n, Buffer[n]);
923  ok(hr == S_OK || hr == expect_hr, "Expected S_OK or 0x%x, was: 0x%x (at %d)\n", expect_hr, hr, n);
924  }
925 }
926 START_TEST(apphelp)
927 {
928  //SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");
929  //SetEnvironmentVariable("DEBUGCHANNEL", "+apphelp");
931 
932  hdll = LoadLibraryA("apphelp.dll");
934  trace("Detected apphelp.dll version: 0x%x\n", g_WinVersion);
935 
936 #define RESOLVE(fnc) do { p##fnc = (void *) GetProcAddress(hdll, #fnc); ok(!!p##fnc, #fnc " not found.\n"); } while (0)
945 #undef RESOLVE
946 
952  if (pSdbGetAppPatchDir)
954 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static void test_ApplicationAttributes(void)
Definition: apphelp.c:639
#define TAG_INTERNAL_NAME
Definition: apphelp.c:68
static const WCHAR invalid[]
Definition: assoc.c:39
static PWSTR GuidString
Definition: apphelp.c:91
#define trace(...)
Definition: kmt_test.h:217
#define TAG_16BIT_DESCRIPTION
Definition: apphelp.c:70
#define WINVER_ANY
#define TAG_TYPE_STRING
Definition: apphelp.c:41
#define test_create_ne
#define expect_tag_skip_range(ptr, from, to)
Definition: apphelp.c:537
#define TAG_FILE_VERSION
Definition: apphelp.c:66
static void test_SdbGetAppPatchDir(void)
Definition: apphelp.c:874
#define TRUE
Definition: types.h:120
const char * tags[7 *8]
Definition: apphelp.c:213
#define VOS__WINDOWS32
Definition: verrsrc.h:64
static void expect_tag_skip_imp(PATTRINFO pattr, DWORD num)
Definition: apphelp.c:493
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
GLint x0
Definition: linetemp.h:95
#define TAG_EXE_WRAPPER
Definition: apphelp.c:56
Definition: scsiwmi.h:51
struct tagATTRINFO ATTRINFO
#define TAG_VER_LANGUAGE
Definition: apphelp.c:52
#define TAG_BIN_PRODUCT_VERSION
Definition: apphelp.c:58
#define TAG_VERFILEOS
Definition: apphelp.c:49
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL WINAPI SdbGetFileAttributes(LPCWSTR path, PATTRINFO *attr_info_ret, LPDWORD attr_count)
Definition: sdbfileattr.c:239
DWORD flags
Definition: apphelp.h:34
uint16_t * PWSTR
Definition: typedefs.h:54
WCHAR * lpattr
Definition: apphelp.h:38
#define REFCLSID
Definition: guiddef.h:112
#define CP_ACP
Definition: compat.h:99
#define _countof(array)
Definition: fontsub.cpp:30
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static void expect_tag_empty_imp(PATTRINFO pattr, DWORD num)
Definition: apphelp.c:500
char CHAR
Definition: xmlstorage.h:175
#define free
Definition: debug_ros.c:5
static void test_ApphelpCheckShellObject(void)
Definition: apphelp.c:121
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
HRESULT WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
Definition: hsdb.c:579
GLdouble n
Definition: glext.h:7729
#define TAG_TYPE_BYTE
Definition: apphelp.c:35
static void test_crc_imp(size_t len, DWORD expected)
Definition: apphelp.c:586
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static const GUID GUID_DATABASE_SHIM
Definition: sdbapi.c:17
const char * wine_dbgstr_guid(const GUID *guid)
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
Definition: ecma_167.h:138
DWORD get_module_version(HMODULE mod)
Definition: data.c:803
#define TAG_PRODUCT_NAME
Definition: apphelp.c:63
#define RESOLVE(fnc)
#define TAG_NULL
Definition: apphelp.c:43
static LPWSTR DWORD size
Definition: apphelp.c:96
static void test_crc2_imp(DWORD len, int fill, DWORD expected)
Definition: apphelp.c:609
const char * filename
Definition: ioapi.h:135
static void test_GuidFunctions(void)
Definition: apphelp.c:467
_SEH2_TRY
Definition: create.c:4250
static const GUID GUID_DATABASE_DRIVERS
Definition: sdbapi.c:18
static void test_SdbTagToString(void)
Definition: apphelp.c:164
static PATTRINFO * ppAttrInfo
Definition: apphelp.c:94
#define TAG_SIZE
Definition: apphelp.c:44
GLuint GLuint * names
Definition: glext.h:11545
DWORD min_ver
Definition: apphelp.c:211
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define TAG_PRODUCT_VERSION
Definition: apphelp.c:64
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
static const CLSID * objects[]
Definition: apphelp.c:109
#define TAG_VERDATEHI
Definition: apphelp.c:47
BOOL WINAPI ApphelpCheckShellObject(REFCLSID ObjectCLSID, BOOL bShimIfNecessary, ULONGLONG *pullFlags)
Definition: apphelp.c:74
#define WINVER_WIN10
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
void test_tag(TAG base, const char *names[], size_t upperlimit, int line)
Definition: apphelp.c:191
#define expect_tag_dword
Definition: apphelp.c:534
static ULONGLONG *static LPCWSTR(WINAPI *pSdbTagToString)(TAG tag)
static BOOL
Definition: apphelp.c:89
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
#define TAG_BIN_FILE_VERSION
Definition: apphelp.c:57
#define S_FALSE
Definition: winerror.h:2357
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL WINAPI SdbGUIDToString(CONST GUID *Guid, PWSTR GuidString, SIZE_T Length)
Definition: sdbapi.c:397
static GUID * Guid
Definition: apphelp.c:93
LPCWSTR WINAPI SdbTagToString(TAG tag)
Definition: sdbapi.c:695
QWORD qwattr
Definition: apphelp.h:36
smooth NULL
Definition: ftsmooth.c:416
#define WINVER_WINXP
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: parser.c:48
#define TAG_PE_CHECKSUM
Definition: apphelp.c:51
#define TAG_FILE_DESCRIPTION
Definition: apphelp.c:65
Definition: bufpool.h:45
static const GUID GUID_DATABASE_MSI
Definition: sdbapi.c:16
TAG type
Definition: apphelp.h:33
#define expect_tag_qword
Definition: apphelp.c:535
#define TAG_CHECKSUM
Definition: apphelp.c:45
#define TAG_TYPE_DWORD
Definition: apphelp.c:37
static DWORD g_WinVersion
#define ok(value,...)
Definition: CComObject.cpp:34
static void expect_tag_qword_imp(PATTRINFO pattr, DWORD num, TAG tag, QWORD value)
Definition: apphelp.c:516
static void test_SdbTagToStringAllTags(void)
Definition: apphelp.c:454
#define ok_hex(expression, result)
Definition: test.h:759
static int strcmp_wa(LPCWSTR strw, const char *stra)
Definition: apphelp.c:184
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TAG_LEGAL_COPYRIGHT
Definition: apphelp.c:69
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
#define TAG_TYPE_WORD
Definition: apphelp.c:36
#define TAG_COMPANY_NAME
Definition: apphelp.c:62
LONG HRESULT
Definition: typedefs.h:77
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
uint64_t ULONGLONG
Definition: typedefs.h:65
BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid)
Definition: sdbapi.c:416
UINT64 QWORD
Definition: shimdbg.c:104
static LPWSTR path
Definition: apphelp.c:96
#define TAG_TYPE_QWORD
Definition: apphelp.c:38
#define MAX_PATH
Definition: compat.h:26
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define expect_tag_empty
Definition: apphelp.c:533
GLuint GLuint num
Definition: glext.h:9618
#define SetLastError(x)
Definition: compat.h:409
DEFINE_GUID(GUID_DATABASE_MSI, 0xd8ff6d16, 0x6a3a, 0x468a, 0x8b, 0x44, 0x01, 0x71, 0x4d, 0xdc, 0x49, 0xea)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
#define TAG_VERFILETYPE
Definition: apphelp.c:50
int ret
#define WINVER_WIN7
static const WCHAR L[]
Definition: oid.c:1250
void silence_debug_output(void)
Definition: data.c:833
DWORD line
Definition: apphelp.c:210
DWORD upper_limit
Definition: apphelp.c:209
#define TAG_TYPE_LIST
Definition: apphelp.c:40
#define test_create_exe
GLenum GLsizei len
Definition: glext.h:6722
#define TAG_ORIGINAL_FILENAME
Definition: apphelp.c:67
#define GUID_NULL
Definition: ks.h:106
#define TAG_TYPE_NULL
Definition: apphelp.c:34
DWORD dwattr
Definition: apphelp.h:37
#define WINVER_WIN8
#define WINAPI
Definition: msvc.h:20
#define TAG_UPTO_BIN_PRODUCT_VERSION
Definition: apphelp.c:59
static PWSTR SIZE_T Length
Definition: apphelp.c:91
static HMODULE hdll
Definition: apphelp.c:88
#define expect_hr(expected, got)
Definition: assoc.c:27
#define TAG_TYPE_STRINGREF
Definition: apphelp.c:39
#define TAG_MODULE_TYPE
Definition: apphelp.c:46
#define test_crc
Definition: apphelp.c:544
#define TAG_16BIT_MODULE_NAME
Definition: apphelp.c:71
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define TAG_TYPE_BINARY
Definition: apphelp.c:42
#define TAG_LINK_DATE
Definition: apphelp.c:54
#define S_OK
Definition: intsafe.h:59
_SEH2_END
Definition: create.c:4424
static void expect_tag_dword_imp(PATTRINFO pattr, DWORD num, TAG tag, DWORD value)
Definition: apphelp.c:508
#define WINVER_VISTA
#define WINVER_2003
#define TAG_TYPE_MASK
Definition: apphelp.c:32
START_TEST(apphelp)
Definition: apphelp.c:926
void test_create_file_imp(const WCHAR *name, const char *contents, size_t len)
Definition: data.c:547
Definition: services.c:325
BOOL WINAPI SdbFreeFileAttributes(PATTRINFO attr_info)
Definition: sdbfileattr.c:214
BOOL WINAPI SdbGetStandardDatabaseGUID(DWORD Flags, GUID *Guid)
Definition: sdbapi.c:430
#define ATTRIBUTE_AVAILABLE
Definition: apphelp.c:75
#define test_create_file
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
#define TAG_UPTO_BIN_FILE_VERSION
Definition: apphelp.c:60
Definition: fs_rec.h:142
static HRESULT(WINAPI *pSdbGetAppPatchDir)(PVOID hsdb
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
#define ATTRIBUTE_FAILED
Definition: apphelp.c:76
#define expect_tag_str
Definition: apphelp.c:536
static PATTRINFO LPDWORD pdwAttrCount
Definition: apphelp.c:94
GLuint res
Definition: glext.h:9613
uint32_t * LPDWORD
Definition: typedefs.h:57
unsigned int ULONG
Definition: retypes.h:1
#define TAG_VERDATELO
Definition: apphelp.c:48
#define test_crc2
Definition: apphelp.c:545
DWORD max_ver
Definition: apphelp.c:212
#define GetProcAddress(x, y)
Definition: compat.h:410
#define malloc
Definition: debug_ros.c:4
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
void test_onefile(WCHAR *filename)
Definition: apphelp.c:547
#define TAG_UPTO_LINK_DATE
Definition: apphelp.c:55
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define TAG_EXPORT_NAME
Definition: apphelp.c:72
#define VFT_APP
Definition: verrsrc.h:75
static void expect_tag_str_imp(PATTRINFO pattr, DWORD num, TAG tag, const WCHAR *value)
Definition: apphelp.c:524
#define memset(x, y, z)
Definition: compat.h:39
#define expect_tag_skip
Definition: apphelp.c:532
static const char * strw(LPCWSTR x)
Definition: actctx.c:49
#define TAG_LINKER_VERSION
Definition: apphelp.c:53
#define win_skip
Definition: test.h:141
TAG base
Definition: apphelp.c:208
BOOL expected
Definition: store.c:2063
#define ok_(x1, x2)
Definition: CString.cpp:56
#define PRODUCT_NAME
#define printf
Definition: config.h:203
struct tagATTRINFO * PATTRINFO
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
char * tag
Definition: main.c:59