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