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