ntdll: Default to Windows 10.
[wine.git] / dlls / msi / tests / package.c
blobcad396aa05a39abfd3b65c2635eb11e8c1811023
1 /*
2 * tests for Microsoft Installer functionality
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2005 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include <assert.h>
25 #include <stdio.h>
26 #include <windows.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <msiquery.h>
30 #include <srrestoreptapi.h>
31 #include <shlobj.h>
32 #include <sddl.h>
34 #include "wine/test.h"
36 static BOOL is_wow64;
37 static const char msifile[] = "winetest-package.msi";
38 static const WCHAR msifileW[] = L"winetest-package.msi";
39 static char CURR_DIR[MAX_PATH];
41 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
43 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
44 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
45 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
46 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
47 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
49 static void init_functionpointers(void)
51 HMODULE hmsi = GetModuleHandleA("msi.dll");
52 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
53 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
54 HMODULE hsrclient = LoadLibraryA("srclient.dll");
56 #define GET_PROC(mod, func) \
57 p ## func = (void*)GetProcAddress(mod, #func);
59 GET_PROC(hmsi, MsiGetComponentPathExA);
61 GET_PROC(hadvapi32, RegDeleteKeyExA)
62 GET_PROC(hadvapi32, RegDeleteKeyExW)
63 GET_PROC(hkernel32, IsWow64Process)
65 GET_PROC(hsrclient, SRRemoveRestorePoint);
66 GET_PROC(hsrclient, SRSetRestorePointA);
68 #undef GET_PROC
71 static BOOL is_process_limited(void)
73 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
74 PSID Group = NULL;
75 BOOL IsInGroup;
76 HANDLE token;
78 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
79 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
80 !CheckTokenMembership(NULL, Group, &IsInGroup))
82 trace("Could not check if the current user is an administrator\n");
83 FreeSid(Group);
84 return FALSE;
86 FreeSid(Group);
88 if (!IsInGroup)
90 if (!AllocateAndInitializeSid(&NtAuthority, 2,
91 SECURITY_BUILTIN_DOMAIN_RID,
92 DOMAIN_ALIAS_RID_POWER_USERS,
93 0, 0, 0, 0, 0, 0, &Group) ||
94 !CheckTokenMembership(NULL, Group, &IsInGroup))
96 trace("Could not check if the current user is a power user\n");
97 return FALSE;
99 if (!IsInGroup)
101 /* Only administrators and power users can be powerful */
102 return TRUE;
106 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
108 BOOL ret;
109 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
110 DWORD size;
112 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
113 CloseHandle(token);
114 return (ret && type == TokenElevationTypeLimited);
116 return FALSE;
119 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
121 if (pRegDeleteKeyExA)
122 return pRegDeleteKeyExA( key, subkey, access, 0 );
123 return RegDeleteKeyA( key, subkey );
126 static char *get_user_sid(void)
128 HANDLE token;
129 DWORD size = 0;
130 TOKEN_USER *user;
131 char *usersid = NULL;
133 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
134 GetTokenInformation(token, TokenUser, NULL, size, &size);
136 user = malloc(size);
137 GetTokenInformation(token, TokenUser, user, size, &size);
138 ConvertSidToStringSidA(user->User.Sid, &usersid);
139 free(user);
141 CloseHandle(token);
142 return usersid;
145 /* RegDeleteTreeW from dlls/advapi32/registry.c */
146 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
148 LONG ret;
149 DWORD dwMaxSubkeyLen, dwMaxValueLen;
150 DWORD dwMaxLen, dwSize;
151 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
152 HKEY hSubKey = hKey;
154 if(lpszSubKey)
156 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
157 if (ret) return ret;
160 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
161 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
162 if (ret) goto cleanup;
164 dwMaxSubkeyLen++;
165 dwMaxValueLen++;
166 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
167 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
169 /* Name too big: alloc a buffer for it */
170 if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR))))
172 ret = ERROR_NOT_ENOUGH_MEMORY;
173 goto cleanup;
177 /* Recursively delete all the subkeys */
178 while (TRUE)
180 dwSize = dwMaxLen;
181 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
182 NULL, NULL, NULL)) break;
184 ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
185 if (ret) goto cleanup;
188 if (lpszSubKey)
190 if (pRegDeleteKeyExW)
191 ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
192 else
193 ret = RegDeleteKeyW(hKey, lpszSubKey);
195 else
196 while (TRUE)
198 dwSize = dwMaxLen;
199 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
200 NULL, NULL, NULL, NULL)) break;
202 ret = RegDeleteValueW(hKey, lpszName);
203 if (ret) goto cleanup;
206 cleanup:
207 if (lpszName != szNameBuf) free(lpszName);
208 if (lpszSubKey) RegCloseKey(hSubKey);
209 return ret;
212 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
214 DWORD i,n=1;
215 GUID guid;
217 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
218 return FALSE;
220 for(i=0; i<8; i++)
221 out[7-i] = in[n++];
222 n++;
223 for(i=0; i<4; i++)
224 out[11-i] = in[n++];
225 n++;
226 for(i=0; i<4; i++)
227 out[15-i] = in[n++];
228 n++;
229 for(i=0; i<2; i++)
231 out[17+i*2] = in[n++];
232 out[16+i*2] = in[n++];
234 n++;
235 for( ; i<8; i++)
237 out[17+i*2] = in[n++];
238 out[16+i*2] = in[n++];
240 out[32]=0;
241 return TRUE;
244 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
246 WCHAR guidW[MAX_PATH];
247 WCHAR squashedW[MAX_PATH];
248 GUID guid;
249 HRESULT hr;
250 int size;
252 hr = CoCreateGuid(&guid);
253 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
255 size = StringFromGUID2(&guid, guidW, MAX_PATH);
256 ok(size == 39, "Expected 39, got %#lx\n", hr);
258 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
259 squash_guid(guidW, squashedW);
260 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
263 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
264 LPCSTR guid, LPSTR usersid, BOOL dir)
266 WCHAR guidW[MAX_PATH];
267 WCHAR squashedW[MAX_PATH];
268 CHAR squashed[MAX_PATH];
269 CHAR comppath[MAX_PATH + 81];
270 CHAR prodpath[MAX_PATH];
271 CHAR path[MAX_PATH];
272 LPCSTR prod = NULL;
273 HKEY hkey;
274 REGSAM access = KEY_ALL_ACCESS;
276 if (is_wow64)
277 access |= KEY_WOW64_64KEY;
279 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
280 squash_guid(guidW, squashedW);
281 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
283 if (context == MSIINSTALLCONTEXT_MACHINE)
285 prod = "3D0DAE300FACA1300AD792060BCDAA92";
286 sprintf(comppath,
287 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
288 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
289 lstrcpyA(prodpath,
290 "SOFTWARE\\Classes\\Installer\\"
291 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
293 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
295 prod = "7D2F387510109040002000060BECB6AB";
296 sprintf(comppath,
297 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
298 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
299 sprintf(prodpath,
300 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
301 "Installer\\%s\\Installer\\Products\\"
302 "7D2F387510109040002000060BECB6AB", usersid);
304 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
306 prod = "7D2F387510109040002000060BECB6AB";
307 sprintf(comppath,
308 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
309 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
310 sprintf(prodpath,
311 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
312 "Installer\\Managed\\%s\\Installer\\Products\\"
313 "7D2F387510109040002000060BECB6AB", usersid);
316 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
318 lstrcpyA(path, CURR_DIR);
319 lstrcatA(path, "\\");
320 if (!dir) lstrcatA(path, filename);
322 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
323 RegCloseKey(hkey);
325 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
326 RegCloseKey(hkey);
329 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
331 WCHAR guidW[MAX_PATH];
332 WCHAR squashedW[MAX_PATH];
333 WCHAR substrW[MAX_PATH];
334 CHAR squashed[MAX_PATH];
335 CHAR comppath[MAX_PATH + 81];
336 CHAR prodpath[MAX_PATH];
337 REGSAM access = KEY_ALL_ACCESS;
339 if (is_wow64)
340 access |= KEY_WOW64_64KEY;
342 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
343 squash_guid(guidW, squashedW);
344 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
346 if (context == MSIINSTALLCONTEXT_MACHINE)
348 sprintf(comppath,
349 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
350 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
351 lstrcpyA(prodpath,
352 "SOFTWARE\\Classes\\Installer\\"
353 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
355 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
357 sprintf(comppath,
358 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
359 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
360 sprintf(prodpath,
361 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
362 "Installer\\%s\\Installer\\Products\\"
363 "7D2F387510109040002000060BECB6AB", usersid);
365 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
367 sprintf(comppath,
368 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
369 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
370 sprintf(prodpath,
371 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
372 "Installer\\Managed\\%s\\Installer\\Products\\"
373 "7D2F387510109040002000060BECB6AB", usersid);
376 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
377 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
379 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
380 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
383 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
385 MSIHANDLE hview = 0;
386 UINT r, ret;
388 /* open a select query */
389 r = MsiDatabaseOpenViewA(hdb, query, &hview);
390 if (r != ERROR_SUCCESS)
391 return r;
392 r = MsiViewExecute(hview, 0);
393 if (r != ERROR_SUCCESS)
394 return r;
395 ret = MsiViewFetch(hview, phrec);
396 r = MsiViewClose(hview);
397 if (r != ERROR_SUCCESS)
398 return r;
399 r = MsiCloseHandle(hview);
400 if (r != ERROR_SUCCESS)
401 return r;
402 return ret;
405 static UINT run_query( MSIHANDLE hdb, const char *query )
407 MSIHANDLE hview = 0;
408 UINT r;
410 r = MsiDatabaseOpenViewA(hdb, query, &hview);
411 if( r != ERROR_SUCCESS )
412 return r;
414 r = MsiViewExecute(hview, 0);
415 if( r == ERROR_SUCCESS )
416 r = MsiViewClose(hview);
417 MsiCloseHandle(hview);
418 return r;
421 static UINT create_component_table( MSIHANDLE hdb )
423 UINT r = run_query( hdb,
424 "CREATE TABLE `Component` ( "
425 "`Component` CHAR(72) NOT NULL, "
426 "`ComponentId` CHAR(38), "
427 "`Directory_` CHAR(72) NOT NULL, "
428 "`Attributes` SHORT NOT NULL, "
429 "`Condition` CHAR(255), "
430 "`KeyPath` CHAR(72) "
431 "PRIMARY KEY `Component`)" );
432 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
433 return r;
436 static UINT create_feature_table( MSIHANDLE hdb )
438 UINT r = run_query( hdb,
439 "CREATE TABLE `Feature` ( "
440 "`Feature` CHAR(38) NOT NULL, "
441 "`Feature_Parent` CHAR(38), "
442 "`Title` CHAR(64), "
443 "`Description` CHAR(255), "
444 "`Display` SHORT NOT NULL, "
445 "`Level` SHORT NOT NULL, "
446 "`Directory_` CHAR(72), "
447 "`Attributes` SHORT NOT NULL "
448 "PRIMARY KEY `Feature`)" );
449 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r);
450 return r;
453 static UINT create_feature_components_table( MSIHANDLE hdb )
455 UINT r = run_query( hdb,
456 "CREATE TABLE `FeatureComponents` ( "
457 "`Feature_` CHAR(38) NOT NULL, "
458 "`Component_` CHAR(72) NOT NULL "
459 "PRIMARY KEY `Feature_`, `Component_` )" );
460 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
461 return r;
464 static UINT create_file_table( MSIHANDLE hdb )
466 UINT r = run_query( hdb,
467 "CREATE TABLE `File` ("
468 "`File` CHAR(72) NOT NULL, "
469 "`Component_` CHAR(72) NOT NULL, "
470 "`FileName` CHAR(255) NOT NULL, "
471 "`FileSize` LONG NOT NULL, "
472 "`Version` CHAR(72), "
473 "`Language` CHAR(20), "
474 "`Attributes` SHORT, "
475 "`Sequence` SHORT NOT NULL "
476 "PRIMARY KEY `File`)" );
477 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r);
478 return r;
481 static UINT create_remove_file_table( MSIHANDLE hdb )
483 UINT r = run_query( hdb,
484 "CREATE TABLE `RemoveFile` ("
485 "`FileKey` CHAR(72) NOT NULL, "
486 "`Component_` CHAR(72) NOT NULL, "
487 "`FileName` CHAR(255) LOCALIZABLE, "
488 "`DirProperty` CHAR(72) NOT NULL, "
489 "`InstallMode` SHORT NOT NULL "
490 "PRIMARY KEY `FileKey`)" );
491 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r);
492 return r;
495 static UINT create_appsearch_table( MSIHANDLE hdb )
497 UINT r = run_query( hdb,
498 "CREATE TABLE `AppSearch` ("
499 "`Property` CHAR(72) NOT NULL, "
500 "`Signature_` CHAR(72) NOT NULL "
501 "PRIMARY KEY `Property`, `Signature_`)" );
502 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r);
503 return r;
506 static UINT create_reglocator_table( MSIHANDLE hdb )
508 UINT r = run_query( hdb,
509 "CREATE TABLE `RegLocator` ("
510 "`Signature_` CHAR(72) NOT NULL, "
511 "`Root` SHORT NOT NULL, "
512 "`Key` CHAR(255) NOT NULL, "
513 "`Name` CHAR(255), "
514 "`Type` SHORT "
515 "PRIMARY KEY `Signature_`)" );
516 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r);
517 return r;
520 static UINT create_signature_table( MSIHANDLE hdb )
522 UINT r = run_query( hdb,
523 "CREATE TABLE `Signature` ("
524 "`Signature` CHAR(72) NOT NULL, "
525 "`FileName` CHAR(255) NOT NULL, "
526 "`MinVersion` CHAR(20), "
527 "`MaxVersion` CHAR(20), "
528 "`MinSize` LONG, "
529 "`MaxSize` LONG, "
530 "`MinDate` LONG, "
531 "`MaxDate` LONG, "
532 "`Languages` CHAR(255) "
533 "PRIMARY KEY `Signature`)" );
534 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r);
535 return r;
538 static UINT create_launchcondition_table( MSIHANDLE hdb )
540 UINT r = run_query( hdb,
541 "CREATE TABLE `LaunchCondition` ("
542 "`Condition` CHAR(255) NOT NULL, "
543 "`Description` CHAR(255) NOT NULL "
544 "PRIMARY KEY `Condition`)" );
545 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r);
546 return r;
549 static UINT create_property_table( MSIHANDLE hdb )
551 UINT r = run_query( hdb,
552 "CREATE TABLE `Property` ("
553 "`Property` CHAR(72) NOT NULL, "
554 "`Value` CHAR(0) "
555 "PRIMARY KEY `Property`)" );
556 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r);
557 return r;
560 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
562 UINT r = run_query( hdb,
563 "CREATE TABLE `InstallExecuteSequence` ("
564 "`Action` CHAR(72) NOT NULL, "
565 "`Condition` CHAR(255), "
566 "`Sequence` SHORT "
567 "PRIMARY KEY `Action`)" );
568 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r);
569 return r;
572 static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
574 UINT r = run_query( hdb,
575 "CREATE TABLE `InstallUISequence` ("
576 "`Action` CHAR(72) NOT NULL, "
577 "`Condition` CHAR(255), "
578 "`Sequence` SHORT "
579 "PRIMARY KEY `Action`)" );
580 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r);
581 return r;
584 static UINT create_media_table( MSIHANDLE hdb )
586 UINT r = run_query( hdb,
587 "CREATE TABLE `Media` ("
588 "`DiskId` SHORT NOT NULL, "
589 "`LastSequence` SHORT NOT NULL, "
590 "`DiskPrompt` CHAR(64), "
591 "`Cabinet` CHAR(255), "
592 "`VolumeLabel` CHAR(32), "
593 "`Source` CHAR(72) "
594 "PRIMARY KEY `DiskId`)" );
595 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r);
596 return r;
599 static UINT create_ccpsearch_table( MSIHANDLE hdb )
601 UINT r = run_query( hdb,
602 "CREATE TABLE `CCPSearch` ("
603 "`Signature_` CHAR(72) NOT NULL "
604 "PRIMARY KEY `Signature_`)" );
605 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r);
606 return r;
609 static UINT create_drlocator_table( MSIHANDLE hdb )
611 UINT r = run_query( hdb,
612 "CREATE TABLE `DrLocator` ("
613 "`Signature_` CHAR(72) NOT NULL, "
614 "`Parent` CHAR(72), "
615 "`Path` CHAR(255), "
616 "`Depth` SHORT "
617 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
618 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r);
619 return r;
622 static UINT create_complocator_table( MSIHANDLE hdb )
624 UINT r = run_query( hdb,
625 "CREATE TABLE `CompLocator` ("
626 "`Signature_` CHAR(72) NOT NULL, "
627 "`ComponentId` CHAR(38) NOT NULL, "
628 "`Type` SHORT "
629 "PRIMARY KEY `Signature_`)" );
630 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r);
631 return r;
634 static UINT create_inilocator_table( MSIHANDLE hdb )
636 UINT r = run_query( hdb,
637 "CREATE TABLE `IniLocator` ("
638 "`Signature_` CHAR(72) NOT NULL, "
639 "`FileName` CHAR(255) NOT NULL, "
640 "`Section` CHAR(96)NOT NULL, "
641 "`Key` CHAR(128)NOT NULL, "
642 "`Field` SHORT, "
643 "`Type` SHORT "
644 "PRIMARY KEY `Signature_`)" );
645 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r);
646 return r;
649 static UINT create_custom_action_table( MSIHANDLE hdb )
651 UINT r = run_query( hdb,
652 "CREATE TABLE `CustomAction` ("
653 "`Action` CHAR(72) NOT NULL, "
654 "`Type` SHORT NOT NULL, "
655 "`Source` CHAR(75), "
656 "`Target` CHAR(255) "
657 "PRIMARY KEY `Action`)" );
658 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
659 return r;
662 static UINT create_dialog_table( MSIHANDLE hdb )
664 UINT r = run_query(hdb,
665 "CREATE TABLE `Dialog` ("
666 "`Dialog` CHAR(72) NOT NULL, "
667 "`HCentering` SHORT NOT NULL, "
668 "`VCentering` SHORT NOT NULL, "
669 "`Width` SHORT NOT NULL, "
670 "`Height` SHORT NOT NULL, "
671 "`Attributes` LONG, "
672 "`Title` CHAR(128) LOCALIZABLE, "
673 "`Control_First` CHAR(50) NOT NULL, "
674 "`Control_Default` CHAR(50), "
675 "`Control_Cancel` CHAR(50) "
676 "PRIMARY KEY `Dialog`)");
677 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r);
678 return r;
681 static UINT create_control_table( MSIHANDLE hdb )
683 UINT r = run_query(hdb,
684 "CREATE TABLE `Control` ("
685 "`Dialog_` CHAR(72) NOT NULL, "
686 "`Control` CHAR(50) NOT NULL, "
687 "`Type` CHAR(20) NOT NULL, "
688 "`X` SHORT NOT NULL, "
689 "`Y` SHORT NOT NULL, "
690 "`Width` SHORT NOT NULL, "
691 "`Height` SHORT NOT NULL, "
692 "`Attributes` LONG, "
693 "`Property` CHAR(50), "
694 "`Text` CHAR(0) LOCALIZABLE, "
695 "`Control_Next` CHAR(50), "
696 "`Help` CHAR(255) LOCALIZABLE "
697 "PRIMARY KEY `Dialog_`, `Control`)");
698 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r);
699 return r;
702 static UINT create_controlevent_table( MSIHANDLE hdb )
704 UINT r = run_query(hdb,
705 "CREATE TABLE `ControlEvent` ("
706 "`Dialog_` CHAR(72) NOT NULL, "
707 "`Control_` CHAR(50) NOT NULL, "
708 "`Event` CHAR(50) NOT NULL, "
709 "`Argument` CHAR(255) NOT NULL, "
710 "`Condition` CHAR(255), "
711 "`Ordering` SHORT "
712 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
713 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r);
714 return r;
717 static UINT create_actiontext_table( MSIHANDLE hdb )
719 UINT r = run_query(hdb,
720 "CREATE TABLE `ActionText` ("
721 "`Action` CHAR(72) NOT NULL, "
722 "`Description` CHAR(64) LOCALIZABLE, "
723 "`Template` CHAR(128) LOCALIZABLE "
724 "PRIMARY KEY `Action`)");
725 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
726 return r;
729 static UINT create_upgrade_table( MSIHANDLE hdb )
731 UINT r = run_query( hdb,
732 "CREATE TABLE `Upgrade` ("
733 "`UpgradeCode` CHAR(38) NOT NULL, "
734 "`VersionMin` CHAR(20), "
735 "`VersionMax` CHAR(20), "
736 "`Language` CHAR(255), "
737 "`Attributes` SHORT, "
738 "`Remove` CHAR(255), "
739 "`ActionProperty` CHAR(72) NOT NULL "
740 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
741 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r);
742 return r;
745 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
747 char *query;
748 UINT sz, r;
750 sz = strlen(values) + strlen(insert) + 1;
751 query = malloc(sz);
752 sprintf(query, insert, values);
753 r = run_query(hdb, query);
754 free(query);
755 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
756 return r;
759 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
760 "INSERT INTO `Component` " \
761 "(`Component`, `ComponentId`, `Directory_`, " \
762 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
764 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
765 "INSERT INTO `Directory` " \
766 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
768 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
769 "INSERT INTO `Feature` " \
770 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
771 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
773 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
774 "INSERT INTO `FeatureComponents` " \
775 "(`Feature_`, `Component_`) VALUES( %s )")
777 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
778 "INSERT INTO `File` " \
779 "(`File`, `Component_`, `FileName`, `FileSize`, " \
780 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
782 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
783 "INSERT INTO `AppSearch` " \
784 "(`Property`, `Signature_`) VALUES( %s )")
786 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
787 "INSERT INTO `Signature` " \
788 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
789 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
790 "VALUES( %s )")
792 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
793 "INSERT INTO `LaunchCondition` " \
794 "(`Condition`, `Description`) VALUES( %s )")
796 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
797 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
799 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
800 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
802 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
803 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
805 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
806 "INSERT INTO `InstallExecuteSequence` " \
807 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
809 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
810 "INSERT INTO `InstallUISequence` " \
811 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
813 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
814 "INSERT INTO `Media` " \
815 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
816 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
818 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
819 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
821 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
822 "INSERT INTO `DrLocator` " \
823 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
825 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
826 "INSERT INTO `CompLocator` " \
827 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
829 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
830 "INSERT INTO `IniLocator` " \
831 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
832 "VALUES( %s )")
834 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
835 "INSERT INTO `CustomAction` " \
836 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
838 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
839 "INSERT INTO `Dialog` " \
840 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
842 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
843 "INSERT INTO `Control` " \
844 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
846 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
847 "INSERT INTO `ControlEvent` " \
848 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
850 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
851 "INSERT INTO `ActionText` " \
852 "(`Action`, `Description`, `Template`) VALUES( %s )");
854 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
855 "INSERT INTO `Upgrade` " \
856 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
858 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
859 const char *name, UINT type )
861 const char insert[] =
862 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
863 "VALUES( '%s', %u, '%s', '%s', %u )";
864 char *query;
865 UINT sz, r;
867 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
868 query = malloc( sz );
869 sprintf( query, insert, sig, root, path, name, type );
870 r = run_query( hdb, query );
871 free( query );
872 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
873 return r;
876 static UINT set_summary_info(MSIHANDLE hdb)
878 UINT res;
879 MSIHANDLE suminfo;
881 /* build summary info */
882 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
883 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
885 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL,
886 "Installation Database");
887 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
889 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL,
890 "Installation Database");
891 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
893 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL,
894 "Wine Hackers");
895 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
897 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL,
898 ";1033");
899 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
901 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL,
902 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
903 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
905 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
906 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
908 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
909 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
911 res = MsiSummaryInfoPersist(suminfo);
912 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
914 res = MsiCloseHandle( suminfo);
915 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
917 return res;
921 static MSIHANDLE create_package_db(void)
923 MSIHANDLE hdb = 0;
924 UINT res;
926 DeleteFileA(msifile);
928 /* create an empty database */
929 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb );
930 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
931 if( res != ERROR_SUCCESS )
932 return hdb;
934 res = MsiDatabaseCommit( hdb );
935 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
937 res = set_summary_info(hdb);
938 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
940 res = run_query( hdb,
941 "CREATE TABLE `Directory` ( "
942 "`Directory` CHAR(255) NOT NULL, "
943 "`Directory_Parent` CHAR(255), "
944 "`DefaultDir` CHAR(255) NOT NULL "
945 "PRIMARY KEY `Directory`)" );
946 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
948 return hdb;
951 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
953 UINT res;
954 CHAR szPackage[12];
955 MSIHANDLE hPackage;
957 sprintf(szPackage, "#%lu", hdb);
958 res = MsiOpenPackageA(szPackage, &hPackage);
959 if (res != ERROR_SUCCESS)
961 MsiCloseHandle(hdb);
962 return res;
965 res = MsiCloseHandle(hdb);
966 if (res != ERROR_SUCCESS)
968 MsiCloseHandle(hPackage);
969 return res;
972 *handle = hPackage;
973 return ERROR_SUCCESS;
976 static void create_file_data(LPCSTR name, LPCSTR data)
978 HANDLE file;
979 DWORD written;
981 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
982 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
983 if (file == INVALID_HANDLE_VALUE)
984 return;
986 WriteFile(file, data, strlen(data), &written, NULL);
987 WriteFile(file, "\n", strlen("\n"), &written, NULL);
989 CloseHandle(file);
992 static void create_test_file(const CHAR *name)
994 create_file_data(name, name);
997 typedef struct _tagVS_VERSIONINFO
999 WORD wLength;
1000 WORD wValueLength;
1001 WORD wType;
1002 WCHAR szKey[1];
1003 WORD wPadding1[1];
1004 VS_FIXEDFILEINFO Value;
1005 WORD wPadding2[1];
1006 WORD wChildren[1];
1007 } VS_VERSIONINFO;
1009 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
1010 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
1012 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
1014 VS_VERSIONINFO *pVerInfo;
1015 VS_FIXEDFILEINFO *pFixedInfo;
1016 LPBYTE buffer, ofs;
1017 CHAR path[MAX_PATH];
1018 DWORD handle, size;
1019 HANDLE resource;
1020 BOOL ret = FALSE;
1022 GetSystemDirectoryA(path, MAX_PATH);
1023 /* Some dlls can't be updated on Vista/W2K8 */
1024 lstrcatA(path, "\\version.dll");
1026 CopyFileA(path, name, FALSE);
1028 size = GetFileVersionInfoSizeA(path, &handle);
1029 buffer = malloc(size);
1031 GetFileVersionInfoA(path, 0, size, buffer);
1033 pVerInfo = (VS_VERSIONINFO *)buffer;
1034 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
1035 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
1037 pFixedInfo->dwFileVersionMS = ms;
1038 pFixedInfo->dwFileVersionLS = ls;
1039 pFixedInfo->dwProductVersionMS = ms;
1040 pFixedInfo->dwProductVersionLS = ls;
1042 resource = BeginUpdateResourceA(name, FALSE);
1043 if (!resource)
1044 goto done;
1046 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO),
1047 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
1048 goto done;
1050 if (!EndUpdateResourceA(resource, FALSE))
1051 goto done;
1053 ret = TRUE;
1055 done:
1056 free(buffer);
1057 return ret;
1060 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
1062 RESTOREPOINTINFOA spec;
1064 spec.dwEventType = event_type;
1065 spec.dwRestorePtType = APPLICATION_INSTALL;
1066 spec.llSequenceNumber = status->llSequenceNumber;
1067 lstrcpyA(spec.szDescription, "msitest restore point");
1069 return pSRSetRestorePointA(&spec, status);
1072 static void remove_restore_point(DWORD seq_number)
1074 DWORD res;
1076 res = pSRRemoveRestorePoint(seq_number);
1077 if (res != ERROR_SUCCESS)
1078 trace("Failed to remove the restore point: %#lx\n", res);
1081 static BOOL is_root(const char *path)
1083 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
1086 static void test_createpackage(void)
1088 MSIHANDLE hPackage = 0;
1089 UINT res;
1091 res = package_from_db(create_package_db(), &hPackage);
1092 if (res == ERROR_INSTALL_PACKAGE_REJECTED)
1094 skip("Not enough rights to perform tests\n");
1095 DeleteFileA(msifile);
1096 return;
1098 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
1100 res = MsiCloseHandle( hPackage);
1101 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
1102 DeleteFileA(msifile);
1105 static void test_doaction( void )
1107 MSIHANDLE hpkg;
1108 UINT r;
1110 r = MsiDoActionA( -1, NULL );
1111 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1113 r = package_from_db(create_package_db(), &hpkg);
1114 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1116 skip("Not enough rights to perform tests\n");
1117 DeleteFileA(msifile);
1118 return;
1120 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1122 r = MsiDoActionA(hpkg, NULL);
1123 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1125 r = MsiDoActionA(0, "boo");
1126 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1128 r = MsiDoActionA(hpkg, "boo");
1129 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
1131 MsiCloseHandle( hpkg );
1132 DeleteFileA(msifile);
1135 static void test_gettargetpath_bad(void)
1137 char buffer[0x80];
1138 WCHAR bufferW[0x80];
1139 MSIHANDLE hpkg;
1140 DWORD sz;
1141 UINT r;
1143 r = package_from_db(create_package_db(), &hpkg);
1144 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1146 skip("Not enough rights to perform tests\n");
1147 DeleteFileA(msifile);
1148 return;
1150 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1152 r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1153 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1155 r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1156 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1158 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1159 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1161 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1162 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1164 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1165 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1167 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1168 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1170 sz = 0;
1171 r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1172 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1174 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1175 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1177 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1178 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1180 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1181 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1183 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1184 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1186 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL );
1187 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1189 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL );
1190 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1192 sz = 0;
1193 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz );
1194 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1196 MsiCloseHandle( hpkg );
1197 DeleteFileA(msifile);
1200 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1202 UINT r;
1203 DWORD size;
1204 MSIHANDLE rec;
1206 rec = MsiCreateRecord( 1 );
1207 ok(rec, "MsiCreate record failed\n");
1209 r = MsiRecordSetStringA( rec, 0, file );
1210 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1212 size = MAX_PATH;
1213 r = MsiFormatRecordA( hpkg, rec, buff, &size );
1214 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1216 MsiCloseHandle( rec );
1219 static void test_settargetpath(void)
1221 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20];
1222 DWORD sz;
1223 MSIHANDLE hpkg;
1224 UINT r;
1225 MSIHANDLE hdb;
1227 hdb = create_package_db();
1228 ok ( hdb, "failed to create package database\n" );
1230 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1232 create_component_table( hdb );
1233 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1234 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1236 create_feature_table( hdb );
1237 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1239 create_feature_components_table( hdb );
1240 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1241 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1243 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1244 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1246 create_file_table( hdb );
1247 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1248 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1250 r = package_from_db( hdb, &hpkg );
1251 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1253 skip("Not enough rights to perform tests\n");
1254 DeleteFileA(msifile);
1255 return;
1257 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1259 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1261 r = MsiDoActionA( hpkg, "CostInitialize");
1262 ok( r == ERROR_SUCCESS, "cost init failed\n");
1264 r = MsiDoActionA( hpkg, "FileCost");
1265 ok( r == ERROR_SUCCESS, "file cost failed\n");
1267 r = MsiDoActionA( hpkg, "CostFinalize");
1268 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1270 buffer[0] = 0;
1271 sz = sizeof(buffer);
1272 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1273 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1274 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1276 r = MsiSetTargetPathA( 0, NULL, NULL );
1277 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1279 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1280 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1282 r = MsiSetTargetPathA( hpkg, "boo", NULL );
1283 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1285 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1286 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1288 sz = sizeof tempdir - 1;
1289 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1290 sprintf( file, "%srootfile.txt", tempdir );
1291 buffer[0] = 0;
1292 query_file_path( hpkg, "[#RootFile]", buffer );
1293 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1294 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1296 GetTempFileNameA( tempdir, "_wt", 0, buffer );
1297 sprintf( tempdir, "%s\\subdir", buffer );
1299 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1300 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1301 "MsiSetTargetPath on file returned %d\n", r );
1303 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1304 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1305 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1307 DeleteFileA( buffer );
1309 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1310 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1312 r = GetFileAttributesA( buffer );
1313 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1315 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1316 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1318 buffer[0] = 0;
1319 sz = sizeof buffer - 1;
1320 lstrcatA( tempdir, "\\" );
1321 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1322 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1323 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1325 sprintf( file, "%srootfile.txt", tempdir );
1326 query_file_path( hpkg, "[#RootFile]", buffer );
1327 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1329 buffer[0] = 0;
1330 sz = sizeof(buffer);
1331 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1332 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1333 lstrcatA( tempdir, "TestParent\\" );
1334 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1336 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1337 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1339 buffer[0] = 0;
1340 sz = sizeof(buffer);
1341 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1342 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1343 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1344 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1346 buffer[0] = 0;
1347 query_file_path( hpkg, "[#TestFile]", buffer );
1348 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1349 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1351 buffer[0] = 0;
1352 sz = sizeof buffer - 1;
1353 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1354 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1355 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1357 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1358 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1360 buffer[0] = 0;
1361 sz = sizeof buffer - 1;
1362 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1363 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1364 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1366 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " );
1367 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1369 buffer[0] = 0;
1370 sz = sizeof buffer - 1;
1371 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1372 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1373 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1375 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1376 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1378 buffer[0] = 0;
1379 sz = sizeof buffer - 1;
1380 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1381 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1382 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1384 MsiCloseHandle( hpkg );
1387 static void test_condition(void)
1389 MSICONDITION r;
1390 MSIHANDLE hpkg;
1392 r = package_from_db(create_package_db(), &hpkg);
1393 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1395 skip("Not enough rights to perform tests\n");
1396 DeleteFileA(msifile);
1397 return;
1399 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1401 r = MsiEvaluateConditionA(0, NULL);
1402 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1404 r = MsiEvaluateConditionA(hpkg, NULL);
1405 ok( r == MSICONDITION_NONE, "wrong return val\n");
1407 r = MsiEvaluateConditionA(hpkg, "");
1408 ok( r == MSICONDITION_NONE, "wrong return val\n");
1410 r = MsiEvaluateConditionA(hpkg, "1");
1411 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1413 r = MsiEvaluateConditionA(hpkg, "0");
1414 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1416 r = MsiEvaluateConditionA(hpkg, "-1");
1417 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1419 r = MsiEvaluateConditionA(hpkg, "0 = 0");
1420 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1422 r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1423 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1425 r = MsiEvaluateConditionA(hpkg, "0 = 1");
1426 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1428 r = MsiEvaluateConditionA(hpkg, "0 > 1");
1429 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1431 r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1432 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1434 r = MsiEvaluateConditionA(hpkg, "1 > 1");
1435 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1437 r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1438 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1440 r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1441 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1443 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1444 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1446 r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1447 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1449 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1450 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1452 r = MsiEvaluateConditionA(hpkg, "0 < 1");
1453 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1455 r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1456 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1458 r = MsiEvaluateConditionA(hpkg, "1 < 1");
1459 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1461 r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1462 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1464 r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1465 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1467 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1468 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1470 r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1471 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1473 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1474 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1476 r = MsiEvaluateConditionA(hpkg, "0 >=");
1477 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1479 r = MsiEvaluateConditionA(hpkg, " ");
1480 ok( r == MSICONDITION_NONE, "wrong return val\n");
1482 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1483 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1485 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1486 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1488 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1489 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1491 r = MsiEvaluateConditionA(hpkg, "not 0");
1492 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1494 r = MsiEvaluateConditionA(hpkg, "not LicView");
1495 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1497 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1498 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1500 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1501 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1503 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1504 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1506 r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1507 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1509 r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1510 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1512 r = MsiEvaluateConditionA(hpkg, "\"0\"");
1513 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1515 r = MsiEvaluateConditionA(hpkg, "1 and 2");
1516 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1518 r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1519 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1521 r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1522 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1524 r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1525 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1527 r = MsiEvaluateConditionA(hpkg, "(0)");
1528 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1530 r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1531 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1533 r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1534 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1536 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1537 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1539 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1540 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1542 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1543 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1545 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1546 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1548 r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1549 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1551 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1552 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1554 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1555 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1557 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1558 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1560 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1561 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1563 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1564 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1566 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1567 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1569 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1570 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1572 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1573 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1575 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1576 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1578 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1579 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1581 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1582 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1584 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1585 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1587 r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1588 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1590 r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1591 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1593 r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1594 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1596 r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1599 r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1600 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1602 r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1603 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1605 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1606 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1608 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1609 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1611 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1612 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1614 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1615 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1617 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1618 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1620 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1621 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1623 MsiSetPropertyA(hpkg, "mm", "5" );
1625 r = MsiEvaluateConditionA(hpkg, "mm = 5");
1626 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1628 r = MsiEvaluateConditionA(hpkg, "mm < 6");
1629 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1631 r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1632 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1634 r = MsiEvaluateConditionA(hpkg, "mm > 4");
1635 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1637 r = MsiEvaluateConditionA(hpkg, "mm < 12");
1638 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1640 r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1641 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1643 r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1644 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1646 r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1647 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1649 r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1650 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1652 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1653 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1655 r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1656 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1658 r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1659 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1661 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1662 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1664 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1665 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1667 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1668 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1670 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1671 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1673 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1674 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1676 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1677 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1679 r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1680 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1682 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1683 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1685 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1686 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1688 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1689 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1691 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1692 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1694 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1695 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1697 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1698 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1700 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1701 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1703 r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1704 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1706 r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1707 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1709 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1710 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1712 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1713 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1715 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1716 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1718 MsiSetPropertyA(hpkg, "bandalmael", "0" );
1719 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1720 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1722 MsiSetPropertyA(hpkg, "bandalmael", "" );
1723 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1724 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1726 MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1727 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1728 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1730 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1731 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1732 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1734 MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1735 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1736 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1738 MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1739 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1740 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1742 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1743 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1744 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1746 MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1747 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1748 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1750 MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1751 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1752 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1754 MsiSetPropertyA(hpkg, "bandalmael", "-" );
1755 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1756 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1758 MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1759 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1760 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1762 MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1763 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1764 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1765 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1766 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1768 MsiSetPropertyA(hpkg, "one", "hi");
1769 MsiSetPropertyA(hpkg, "two", "hithere");
1770 r = MsiEvaluateConditionA(hpkg, "one >< two");
1771 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1773 MsiSetPropertyA(hpkg, "one", "hithere");
1774 MsiSetPropertyA(hpkg, "two", "hi");
1775 r = MsiEvaluateConditionA(hpkg, "one >< two");
1776 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1778 MsiSetPropertyA(hpkg, "one", "hello");
1779 MsiSetPropertyA(hpkg, "two", "hi");
1780 r = MsiEvaluateConditionA(hpkg, "one >< two");
1781 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1783 MsiSetPropertyA(hpkg, "one", "hellohithere");
1784 MsiSetPropertyA(hpkg, "two", "hi");
1785 r = MsiEvaluateConditionA(hpkg, "one >< two");
1786 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1788 MsiSetPropertyA(hpkg, "one", "");
1789 MsiSetPropertyA(hpkg, "two", "hi");
1790 r = MsiEvaluateConditionA(hpkg, "one >< two");
1791 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1793 MsiSetPropertyA(hpkg, "one", "hi");
1794 MsiSetPropertyA(hpkg, "two", "");
1795 r = MsiEvaluateConditionA(hpkg, "one >< two");
1796 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1798 MsiSetPropertyA(hpkg, "one", "");
1799 MsiSetPropertyA(hpkg, "two", "");
1800 r = MsiEvaluateConditionA(hpkg, "one >< two");
1801 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1803 MsiSetPropertyA(hpkg, "one", "1234");
1804 MsiSetPropertyA(hpkg, "two", "1");
1805 r = MsiEvaluateConditionA(hpkg, "one >< two");
1806 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1808 MsiSetPropertyA(hpkg, "one", "one 1234");
1809 MsiSetPropertyA(hpkg, "two", "1");
1810 r = MsiEvaluateConditionA(hpkg, "one >< two");
1811 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1813 MsiSetPropertyA(hpkg, "one", "hithere");
1814 MsiSetPropertyA(hpkg, "two", "hi");
1815 r = MsiEvaluateConditionA(hpkg, "one << two");
1816 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1818 MsiSetPropertyA(hpkg, "one", "hi");
1819 MsiSetPropertyA(hpkg, "two", "hithere");
1820 r = MsiEvaluateConditionA(hpkg, "one << two");
1821 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1823 MsiSetPropertyA(hpkg, "one", "hi");
1824 MsiSetPropertyA(hpkg, "two", "hi");
1825 r = MsiEvaluateConditionA(hpkg, "one << two");
1826 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1828 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1829 MsiSetPropertyA(hpkg, "two", "hi");
1830 r = MsiEvaluateConditionA(hpkg, "one << two");
1831 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1833 MsiSetPropertyA(hpkg, "one", "");
1834 MsiSetPropertyA(hpkg, "two", "hi");
1835 r = MsiEvaluateConditionA(hpkg, "one << two");
1836 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1838 MsiSetPropertyA(hpkg, "one", "hithere");
1839 MsiSetPropertyA(hpkg, "two", "");
1840 r = MsiEvaluateConditionA(hpkg, "one << two");
1841 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1843 MsiSetPropertyA(hpkg, "one", "");
1844 MsiSetPropertyA(hpkg, "two", "");
1845 r = MsiEvaluateConditionA(hpkg, "one << two");
1846 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1848 MsiSetPropertyA(hpkg, "one", "1234");
1849 MsiSetPropertyA(hpkg, "two", "1");
1850 r = MsiEvaluateConditionA(hpkg, "one << two");
1851 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1853 MsiSetPropertyA(hpkg, "one", "1234 one");
1854 MsiSetPropertyA(hpkg, "two", "1");
1855 r = MsiEvaluateConditionA(hpkg, "one << two");
1856 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1858 MsiSetPropertyA(hpkg, "one", "hithere");
1859 MsiSetPropertyA(hpkg, "two", "there");
1860 r = MsiEvaluateConditionA(hpkg, "one >> two");
1861 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1863 MsiSetPropertyA(hpkg, "one", "hithere");
1864 MsiSetPropertyA(hpkg, "two", "hi");
1865 r = MsiEvaluateConditionA(hpkg, "one >> two");
1866 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1868 MsiSetPropertyA(hpkg, "one", "there");
1869 MsiSetPropertyA(hpkg, "two", "hithere");
1870 r = MsiEvaluateConditionA(hpkg, "one >> two");
1871 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1873 MsiSetPropertyA(hpkg, "one", "there");
1874 MsiSetPropertyA(hpkg, "two", "there");
1875 r = MsiEvaluateConditionA(hpkg, "one >> two");
1876 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1878 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1879 MsiSetPropertyA(hpkg, "two", "hi");
1880 r = MsiEvaluateConditionA(hpkg, "one >> two");
1881 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1883 MsiSetPropertyA(hpkg, "one", "");
1884 MsiSetPropertyA(hpkg, "two", "there");
1885 r = MsiEvaluateConditionA(hpkg, "one >> two");
1886 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1888 MsiSetPropertyA(hpkg, "one", "there");
1889 MsiSetPropertyA(hpkg, "two", "");
1890 r = MsiEvaluateConditionA(hpkg, "one >> two");
1891 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1893 MsiSetPropertyA(hpkg, "one", "");
1894 MsiSetPropertyA(hpkg, "two", "");
1895 r = MsiEvaluateConditionA(hpkg, "one >> two");
1896 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1898 MsiSetPropertyA(hpkg, "one", "1234");
1899 MsiSetPropertyA(hpkg, "two", "4");
1900 r = MsiEvaluateConditionA(hpkg, "one >> two");
1901 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1903 MsiSetPropertyA(hpkg, "one", "one 1234");
1904 MsiSetPropertyA(hpkg, "two", "4");
1905 r = MsiEvaluateConditionA(hpkg, "one >> two");
1906 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1908 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1910 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1911 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1913 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1914 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1916 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1917 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1919 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1920 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1922 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1923 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1925 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1926 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1928 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1929 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1931 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1932 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1934 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1935 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1937 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1938 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1940 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1941 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1943 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1944 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1946 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1947 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1949 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1950 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1952 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1953 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1955 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1956 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1958 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1959 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1961 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1962 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1964 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1965 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1967 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1968 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1970 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1971 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1973 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1974 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1976 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1977 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1979 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1980 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1982 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1983 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1985 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1986 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1988 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1989 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1991 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1992 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1994 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1995 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1997 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1998 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2000 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
2001 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2003 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
2004 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2006 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
2007 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2009 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
2010 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2012 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
2013 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2015 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
2016 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2018 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
2019 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2021 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
2022 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
2023 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2025 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
2026 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2028 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
2029 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2031 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
2032 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2034 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
2035 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2037 MsiSetPropertyA(hpkg, "one", "1");
2038 r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
2039 ok( r == MSICONDITION_FALSE, "wrong return val\n");
2041 MsiSetPropertyA(hpkg, "X", "5.0");
2043 r = MsiEvaluateConditionA(hpkg, "X != \"\"");
2044 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2046 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
2047 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2049 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
2050 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2052 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
2053 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2055 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
2056 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2058 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2059 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2061 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2062 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2064 /* feature doesn't exist */
2065 r = MsiEvaluateConditionA(hpkg, "&nofeature");
2066 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2067 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\"");
2068 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2069 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3");
2070 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2071 r = MsiEvaluateConditionA(hpkg, "\"\"<>3");
2072 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2073 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\"");
2074 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2075 r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\"");
2076 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2077 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\"");
2078 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2080 MsiSetPropertyA(hpkg, "A", "2");
2081 MsiSetPropertyA(hpkg, "X", "50");
2083 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2084 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2086 r = MsiEvaluateConditionA(hpkg, "A <= X");
2087 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2089 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2090 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2092 MsiSetPropertyA(hpkg, "X", "50val");
2094 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2095 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2097 r = MsiEvaluateConditionA(hpkg, "A <= X");
2098 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2100 MsiSetPropertyA(hpkg, "A", "7");
2101 MsiSetPropertyA(hpkg, "X", "50");
2103 r = MsiEvaluateConditionA(hpkg, "7 <= X");
2104 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2106 r = MsiEvaluateConditionA(hpkg, "A <= X");
2107 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2109 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2110 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2112 MsiSetPropertyA(hpkg, "X", "50val");
2114 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2115 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2117 r = MsiEvaluateConditionA(hpkg, "A <= X");
2118 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2120 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
2121 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2122 "wrong return val (%d)\n", r);
2124 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
2125 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2126 "wrong return val (%d)\n", r);
2128 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
2129 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2130 "wrong return val (%d)\n", r);
2132 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
2133 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2134 "wrong return val (%d)\n", r);
2136 MsiCloseHandle( hpkg );
2137 DeleteFileA(msifile);
2140 static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value)
2142 char buffer[MAX_PATH] = "x";
2143 DWORD sz = sizeof(buffer);
2144 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz);
2145 ok(!r, "'%s': got %u\n", prop, r);
2146 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz);
2147 if (match_case)
2148 todo_wine_if (todo_value) ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2149 else
2150 todo_wine_if (todo_value) ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2153 static void test_props(void)
2155 MSIHANDLE hpkg, hdb;
2156 UINT r;
2157 DWORD sz;
2158 char buffer[0x100];
2159 WCHAR bufferW[10];
2161 hdb = create_package_db();
2163 create_property_table(hdb);
2164 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'");
2166 r = package_from_db( hdb, &hpkg );
2167 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2169 skip("Not enough rights to perform tests\n");
2170 DeleteFileA(msifile);
2171 return;
2173 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2175 /* test invalid values */
2176 r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2177 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2179 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2180 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2182 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2183 ok(!r, "got %u\n", r);
2185 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2186 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2188 /* test retrieving an empty/nonexistent property */
2189 sz = sizeof buffer;
2190 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2191 ok(!r, "got %u\n", r);
2192 ok(sz == 0, "got size %lu\n", sz);
2194 sz = 0;
2195 strcpy(buffer,"x");
2196 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2197 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2198 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer);
2199 ok(sz == 0, "got size %lu\n", sz);
2201 sz = 1;
2202 strcpy(buffer,"x");
2203 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2204 ok(!r, "got %u\n", r);
2205 ok(!buffer[0], "got \"%s\"\n", buffer);
2206 ok(sz == 0, "got size %lu\n", sz);
2208 /* set the property to something */
2209 r = MsiSetPropertyA( 0, NULL, NULL );
2210 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r);
2212 r = MsiSetPropertyA( hpkg, NULL, NULL );
2213 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2215 r = MsiSetPropertyA( hpkg, "", NULL );
2216 ok(!r, "got %u\n", r);
2218 r = MsiSetPropertyA( hpkg, "", "asdf" );
2219 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
2221 r = MsiSetPropertyA( hpkg, "=", "asdf" );
2222 ok(!r, "got %u\n", r);
2223 check_prop(hpkg, "=", "asdf", 1, 0);
2225 r = MsiSetPropertyA( hpkg, " ", "asdf" );
2226 ok(!r, "got %u\n", r);
2227 check_prop(hpkg, " ", "asdf", 1, 0);
2229 r = MsiSetPropertyA( hpkg, "'", "asdf" );
2230 ok(!r, "got %u\n", r);
2231 check_prop(hpkg, "'", "asdf", 1, 0);
2233 /* set empty values */
2234 r = MsiSetPropertyA( hpkg, "boo", NULL );
2235 ok(!r, "got %u\n", r);
2236 check_prop(hpkg, "boo", "", 1, 0);
2238 r = MsiSetPropertyA( hpkg, "boo", "" );
2239 ok(!r, "got %u\n", r);
2240 check_prop(hpkg, "boo", "", 1, 0);
2242 /* set a non-empty value */
2243 r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2244 ok(!r, "got %u\n", r);
2245 check_prop(hpkg, "boo", "xyz", 1, 0);
2247 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
2248 ok(!r, "got %u\n", r);
2250 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL);
2251 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2253 sz = 0;
2254 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz);
2255 ok(!r, "got %u\n", r);
2256 ok(sz == 3, "got size %lu\n", sz);
2258 sz = 0;
2259 strcpy(buffer, "q");
2260 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz);
2261 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2262 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer);
2263 ok(sz == 3, "got size %lu\n", sz);
2265 sz = 1;
2266 strcpy(buffer,"x");
2267 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2268 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2269 ok(!buffer[0], "got \"%s\"\n", buffer);
2270 ok(sz == 3, "got size %lu\n", sz);
2272 sz = 3;
2273 strcpy(buffer,"x");
2274 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2275 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2276 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer);
2277 ok(sz == 3, "got size %lu\n", sz);
2279 sz = 4;
2280 strcpy(buffer,"x");
2281 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2282 ok(!r, "got %u\n", r);
2283 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer);
2284 ok(sz == 3, "got size %lu\n", sz);
2286 sz = 0;
2287 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz);
2288 ok(!r, "got %u\n", r);
2289 ok(sz == 3, "got size %lu\n", sz);
2291 sz = 0;
2292 lstrcpyW(bufferW, L"boo");
2293 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz);
2294 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2295 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW));
2296 ok(sz == 3, "got size %lu\n", sz);
2298 sz = 1;
2299 lstrcpyW(bufferW, L"boo");
2300 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2301 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2302 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
2303 ok(sz == 3, "got size %lu\n", sz);
2305 sz = 3;
2306 lstrcpyW(bufferW, L"boo");
2307 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2308 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2309 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW));
2310 ok(sz == 3, "got size %lu\n", sz);
2312 sz = 4;
2313 lstrcpyW(bufferW, L"boo");
2314 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2315 ok(!r, "got %u\n", r);
2316 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW));
2317 ok(sz == 3, "got size %lu\n", sz);
2319 /* properties are case-sensitive */
2320 check_prop(hpkg, "BOO", "", 1, 0);
2322 /* properties set in Property table should work */
2323 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1, 0);
2325 MsiCloseHandle( hpkg );
2326 DeleteFileA(msifile);
2329 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2331 MSIHANDLE hview, hrec;
2332 BOOL found = FALSE;
2333 CHAR buffer[MAX_PATH];
2334 DWORD sz;
2335 UINT r;
2337 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2338 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2339 r = MsiViewExecute(hview, 0);
2340 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2342 if (len < 0) len = lstrlenA(val);
2344 while (r == ERROR_SUCCESS && !found)
2346 r = MsiViewFetch(hview, &hrec);
2347 if (r != ERROR_SUCCESS) break;
2349 sz = MAX_PATH;
2350 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2351 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2353 sz = MAX_PATH;
2354 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2355 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2357 ok(sz == len, "wrong size %lu\n", sz);
2358 found = TRUE;
2362 MsiCloseHandle(hrec);
2364 MsiViewClose(hview);
2365 MsiCloseHandle(hview);
2366 return found;
2369 static void test_property_table(void)
2371 const char *query;
2372 UINT r;
2373 MSIHANDLE hpkg, hdb, hrec;
2374 char buffer[MAX_PATH], package[10];
2375 DWORD sz;
2376 BOOL found;
2378 hdb = create_package_db();
2379 ok( hdb, "failed to create package\n");
2381 r = package_from_db(hdb, &hpkg);
2382 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2384 skip("Not enough rights to perform tests\n");
2385 DeleteFileA(msifile);
2386 return;
2388 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2390 MsiCloseHandle(hdb);
2392 hdb = MsiGetActiveDatabase(hpkg);
2394 query = "CREATE TABLE `_Property` ( "
2395 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2396 r = run_query(hdb, query);
2397 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2399 MsiCloseHandle(hdb);
2400 MsiCloseHandle(hpkg);
2401 DeleteFileA(msifile);
2403 hdb = create_package_db();
2404 ok( hdb, "failed to create package\n");
2406 query = "CREATE TABLE `_Property` ( "
2407 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2408 r = run_query(hdb, query);
2409 ok(r == ERROR_SUCCESS, "failed to create table\n");
2411 query = "ALTER `_Property` ADD `foo` INTEGER";
2412 r = run_query(hdb, query);
2413 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2415 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2416 r = run_query(hdb, query);
2417 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2419 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2420 r = run_query(hdb, query);
2421 ok(r == ERROR_SUCCESS, "failed to add column\n");
2423 sprintf(package, "#%lu", hdb);
2424 r = MsiOpenPackageA(package, &hpkg);
2425 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2426 if (r == ERROR_SUCCESS)
2427 MsiCloseHandle(hpkg);
2429 r = MsiCloseHandle(hdb);
2430 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2432 hdb = create_package_db();
2433 ok (hdb, "failed to create package database\n");
2435 create_property_table(hdb);
2436 add_property_entry(hdb, "'prop', 'val'");
2438 create_custom_action_table(hdb);
2439 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2441 r = package_from_db(hdb, &hpkg);
2442 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2444 MsiCloseHandle(hdb);
2446 sz = MAX_PATH;
2447 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2449 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2451 hdb = MsiGetActiveDatabase(hpkg);
2453 found = find_prop_in_property(hdb, "prop", "val", -1);
2454 ok(found, "prop should be in the _Property table\n");
2456 add_property_entry(hdb, "'dantes', 'mercedes'");
2458 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2459 r = do_query(hdb, query, &hrec);
2460 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2462 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2463 ok(found == FALSE, "dantes should not be in the _Property table\n");
2465 sz = MAX_PATH;
2466 lstrcpyA(buffer, "aaa");
2467 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2469 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2471 r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2475 ok(found == TRUE, "dantes should be in the _Property table\n");
2477 r = MsiDoActionA( hpkg, "EmbedNull" );
2478 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2480 sz = MAX_PATH;
2481 memset( buffer, 'a', sizeof(buffer) );
2482 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2483 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2484 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2485 ok( sz == sizeof("\0np") - 1, "got %lu\n", sz );
2487 found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2488 ok(found == TRUE, "prop2 should be in the _Property table\n");
2490 MsiCloseHandle(hdb);
2491 MsiCloseHandle(hpkg);
2492 DeleteFileA(msifile);
2495 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2497 MSIHANDLE htab = 0;
2498 UINT res;
2500 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2501 if( res == ERROR_SUCCESS )
2503 UINT r;
2505 r = MsiViewExecute( htab, hrec );
2506 if( r != ERROR_SUCCESS )
2508 res = r;
2509 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2512 r = MsiViewClose( htab );
2513 if( r != ERROR_SUCCESS )
2514 res = r;
2516 r = MsiCloseHandle( htab );
2517 if( r != ERROR_SUCCESS )
2518 res = r;
2520 return res;
2523 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2525 return try_query_param( hdb, szQuery, 0 );
2528 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2530 MSIHANDLE summary;
2531 UINT r;
2533 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2536 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2539 r = MsiSummaryInfoPersist(summary);
2540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2542 MsiCloseHandle(summary);
2545 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2547 MSIHANDLE summary;
2548 UINT r;
2550 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2553 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2556 r = MsiSummaryInfoPersist(summary);
2557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2559 MsiCloseHandle(summary);
2562 static void test_msipackage(void)
2564 MSIHANDLE hdb = 0, hpack = 100;
2565 UINT r;
2566 const char *query;
2567 char name[10];
2569 /* NULL szPackagePath */
2570 r = MsiOpenPackageA(NULL, &hpack);
2571 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2573 /* empty szPackagePath */
2574 r = MsiOpenPackageA("", &hpack);
2575 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2577 skip("Not enough rights to perform tests\n");
2578 return;
2580 todo_wine
2582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2585 if (r == ERROR_SUCCESS)
2586 MsiCloseHandle(hpack);
2588 /* nonexistent szPackagePath */
2589 r = MsiOpenPackageA("nonexistent", &hpack);
2590 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2592 /* NULL hProduct */
2593 r = MsiOpenPackageA(msifile, NULL);
2594 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2596 name[0]='#';
2597 name[1]=0;
2598 r = MsiOpenPackageA(name, &hpack);
2599 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2601 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2604 /* database exists, but is empty */
2605 sprintf(name, "#%lu", hdb);
2606 r = MsiOpenPackageA(name, &hpack);
2607 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2608 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2610 query = "CREATE TABLE `Property` ( "
2611 "`Property` CHAR(72), `Value` CHAR(0) "
2612 "PRIMARY KEY `Property`)";
2613 r = try_query(hdb, query);
2614 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2616 query = "CREATE TABLE `InstallExecuteSequence` ("
2617 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2618 "PRIMARY KEY `Action`)";
2619 r = try_query(hdb, query);
2620 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2622 /* a few key tables exist */
2623 sprintf(name, "#%lu", hdb);
2624 r = MsiOpenPackageA(name, &hpack);
2625 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2626 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2628 MsiCloseHandle(hdb);
2629 DeleteFileA(msifile);
2631 /* start with a clean database to show what constitutes a valid package */
2632 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2635 sprintf(name, "#%lu", hdb);
2637 /* The following summary information props must exist:
2638 * - PID_REVNUMBER
2639 * - PID_PAGECOUNT
2642 set_summary_dword(hdb, PID_PAGECOUNT, 100);
2643 r = MsiOpenPackageA(name, &hpack);
2644 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2645 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2647 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2648 r = MsiOpenPackageA(name, &hpack);
2649 ok(r == ERROR_SUCCESS,
2650 "Expected ERROR_SUCCESS, got %d\n", r);
2652 MsiCloseHandle(hpack);
2653 MsiCloseHandle(hdb);
2654 DeleteFileA(msifile);
2657 static void test_formatrecord2(void)
2659 MSIHANDLE hpkg, hrec ;
2660 char buffer[0x100];
2661 DWORD sz;
2662 UINT r;
2664 r = package_from_db(create_package_db(), &hpkg);
2665 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2667 skip("Not enough rights to perform tests\n");
2668 DeleteFileA(msifile);
2669 return;
2671 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2673 r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2674 ok( r == ERROR_SUCCESS, "set property failed\n");
2676 hrec = MsiCreateRecord(2);
2677 ok(hrec, "create record failed\n");
2679 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2680 ok( r == ERROR_SUCCESS, "format record failed\n");
2682 buffer[0] = 0;
2683 sz = sizeof buffer;
2684 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2685 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2687 r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2688 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2689 r = MsiRecordSetStringA(hrec, 1, "hoo");
2690 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2691 sz = sizeof buffer;
2692 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2693 ok( sz == 3, "size wrong\n");
2694 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2695 ok( r == ERROR_SUCCESS, "format failed\n");
2697 r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2698 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2699 sz = sizeof buffer;
2700 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2701 ok( sz == 3, "size wrong\n");
2702 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2703 ok( r == ERROR_SUCCESS, "format failed\n");
2705 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2706 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2707 r = MsiRecordSetStringA(hrec, 1, "hoo");
2708 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2709 sz = sizeof buffer;
2710 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2711 ok( sz == 3, "size wrong\n");
2712 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2713 ok( r == ERROR_SUCCESS, "format failed\n");
2715 r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2716 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2717 sz = sizeof buffer;
2718 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2719 ok( sz == 1, "size wrong\n");
2720 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2721 ok( r == ERROR_SUCCESS, "format failed\n");
2723 SetEnvironmentVariableA("FOO", "BAR");
2724 r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2725 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2726 sz = sizeof buffer;
2727 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2728 ok( sz == 3, "size wrong\n");
2729 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2730 ok( r == ERROR_SUCCESS, "format failed\n");
2732 r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2733 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2734 r = MsiRecordSetStringA(hrec, 1, "%FOO");
2735 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2736 sz = sizeof buffer;
2737 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2738 ok( sz == 3, "size wrong\n");
2739 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2740 ok( r == ERROR_SUCCESS, "format failed\n");
2742 MsiCloseHandle( hrec );
2743 MsiCloseHandle( hpkg );
2744 DeleteFileA(msifile);
2747 static void test_formatrecord_tables(void)
2749 MSIHANDLE hdb, hrec, hpkg = 0;
2750 CHAR buf[MAX_PATH + 41];
2751 CHAR curr_dir[MAX_PATH];
2752 CHAR expected[MAX_PATH + 45];
2753 CHAR root[MAX_PATH];
2754 DWORD size;
2755 UINT r;
2757 GetCurrentDirectoryA( MAX_PATH, curr_dir );
2759 hdb = create_package_db();
2760 ok ( hdb, "failed to create package database\n");
2762 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2763 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2764 "'I am a really long directory'" );
2766 create_feature_table( hdb );
2767 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2769 create_component_table( hdb );
2770 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2771 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2772 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2774 create_feature_components_table( hdb );
2775 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2776 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2777 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2779 create_file_table( hdb );
2780 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2781 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2782 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2784 create_custom_action_table( hdb );
2785 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2786 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2787 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2788 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2789 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2791 r = package_from_db( hdb, &hpkg );
2792 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2794 skip("Not enough rights to perform tests\n");
2795 MsiCloseHandle( hdb );
2796 DeleteFileA( msifile );
2797 return;
2799 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2801 MsiCloseHandle( hdb );
2803 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2804 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2806 hrec = MsiCreateRecord( 1 );
2808 /* property doesn't exist */
2809 size = MAX_PATH;
2810 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2811 MsiRecordSetStringA( hrec, 1, "[idontexist]" );
2812 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2813 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2814 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2816 /* property exists */
2817 size = MAX_PATH;
2818 MsiRecordSetStringA( hrec, 1, "[imaprop]" );
2819 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2820 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2821 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2823 size = MAX_PATH;
2824 MsiRecordSetStringA( hrec, 0, "1: [1] " );
2825 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2826 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2827 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2829 /* environment variable doesn't exist */
2830 size = MAX_PATH;
2831 MsiRecordSetStringA( hrec, 1, "[%idontexist]" );
2832 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2833 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2834 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2836 /* environment variable exists */
2837 size = MAX_PATH;
2838 SetEnvironmentVariableA( "crazyvar", "crazyval" );
2839 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" );
2840 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2841 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2842 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2844 /* file key before CostInitialize */
2845 size = MAX_PATH;
2846 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2847 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2848 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2849 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2851 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2853 r = MsiDoActionA(hpkg, "CostInitialize");
2854 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2856 r = MsiDoActionA(hpkg, "FileCost");
2857 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2859 r = MsiDoActionA(hpkg, "CostFinalize");
2860 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2862 size = MAX_PATH;
2863 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size );
2865 sprintf( expected, "1: %sfrontal.txt ", root);
2867 /* frontal full file key */
2868 size = MAX_PATH;
2869 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2870 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2871 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2872 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2874 /* frontal short file key */
2875 size = MAX_PATH;
2876 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" );
2877 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2878 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2879 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2881 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2883 /* temporal full file key */
2884 size = MAX_PATH;
2885 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" );
2886 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2887 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2888 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2890 /* temporal short file key */
2891 size = MAX_PATH;
2892 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" );
2893 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2894 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2895 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2897 /* custom action 51, files don't exist */
2898 r = MsiDoActionA( hpkg, "MyCustom" );
2899 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2901 sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2903 size = MAX_PATH;
2904 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2905 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2906 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2908 sprintf( buf, "%sI am a really long directory", root );
2909 CreateDirectoryA( buf, NULL );
2911 lstrcatA( buf, "\\temporal.txt" );
2912 create_test_file( buf );
2914 /* custom action 51, files exist */
2915 r = MsiDoActionA( hpkg, "MyCustom" );
2916 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2918 size = MAX_PATH;
2919 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2920 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2921 todo_wine
2923 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2926 /* custom action 51, escaped text 1 */
2927 r = MsiDoActionA( hpkg, "EscapeIt1" );
2928 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2930 size = MAX_PATH;
2931 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2932 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2933 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2935 /* custom action 51, escaped text 2 */
2936 r = MsiDoActionA( hpkg, "EscapeIt2" );
2937 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2939 size = MAX_PATH;
2940 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2941 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2942 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf);
2944 /* custom action 51, escaped text 3 */
2945 r = MsiDoActionA( hpkg, "EscapeIt3" );
2946 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2948 size = MAX_PATH;
2949 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2950 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2951 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf);
2953 /* custom action 51, embedded null */
2954 r = MsiDoActionA( hpkg, "EmbedNull" );
2955 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2957 size = MAX_PATH;
2958 memset( buf, 'a', sizeof(buf) );
2959 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2960 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2961 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
2962 ok( size == sizeof("\0np") - 1, "got %lu\n", size );
2964 r = MsiSetPropertyA( hpkg, "prop", "[~]np" );
2965 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2967 size = MAX_PATH;
2968 memset( buf, 'a', sizeof(buf) );
2969 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2970 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2971 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2973 sprintf( expected, "1: %sI am a really long directory\\ ", root);
2975 /* component with INSTALLSTATE_LOCAL */
2976 size = MAX_PATH;
2977 MsiRecordSetStringA( hrec, 1, "[$temporal]" );
2978 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2979 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2980 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2982 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE );
2983 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2985 /* component with INSTALLSTATE_SOURCE */
2986 lstrcpyA( expected, "1: " );
2987 lstrcatA( expected, curr_dir );
2988 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" );
2989 lstrcatA( expected, " " );
2990 size = MAX_PATH;
2991 MsiRecordSetStringA( hrec, 1, "[$parietal]" );
2992 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2993 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2994 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2996 sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2997 DeleteFileA( buf );
2999 sprintf( buf, "%sI am a really long directory", root );
3000 RemoveDirectoryA( buf );
3002 MsiCloseHandle( hrec );
3003 MsiCloseHandle( hpkg );
3004 DeleteFileA( msifile );
3007 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
3008 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3010 UINT r;
3011 INSTALLSTATE state = 0xdeadbee;
3012 INSTALLSTATE action = 0xdeadbee;
3014 r = MsiGetFeatureStateA( package, feature, &state, &action );
3015 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3016 if (r == ERROR_SUCCESS)
3018 ok( state == expected_state, "%u: expected state %d got %d\n",
3019 line, expected_state, state );
3020 todo_wine_if (todo)
3021 ok( action == expected_action, "%u: expected action %d got %d\n",
3022 line, expected_action, action );
3024 else
3026 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
3027 todo_wine_if (todo)
3028 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
3033 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
3034 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3036 UINT r;
3037 INSTALLSTATE state = 0xdeadbee;
3038 INSTALLSTATE action = 0xdeadbee;
3040 r = MsiGetComponentStateA( package, component, &state, &action );
3041 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3042 if (r == ERROR_SUCCESS)
3044 ok( state == expected_state, "%u: expected state %d got %d\n",
3045 line, expected_state, state );
3046 todo_wine_if (todo)
3047 ok( action == expected_action, "%u: expected action %d got %d\n",
3048 line, expected_action, action );
3050 else
3052 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
3053 line, state );
3054 todo_wine_if (todo)
3055 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
3056 line, action );
3060 static void test_states(void)
3062 static const char msifile2[] = "winetest2-package.msi";
3063 static const char msifile3[] = "winetest3-package.msi";
3064 static const char msifile4[] = "winetest4-package.msi";
3065 static const WCHAR msifile2W[] = L"winetest2-package.msi";
3066 static const WCHAR msifile3W[] = L"winetest3-package.msi";
3067 static const WCHAR msifile4W[] = L"winetest4-package.msi";
3068 char msi_cache_file[MAX_PATH];
3069 DWORD cache_file_name_len;
3070 INSTALLSTATE state;
3071 MSIHANDLE hpkg, hprod;
3072 UINT r;
3073 MSIHANDLE hdb;
3074 BOOL is_broken;
3075 char value[MAX_PATH];
3076 DWORD size;
3078 if (is_process_limited())
3080 skip("process is limited\n");
3081 return;
3084 hdb = create_package_db();
3085 ok ( hdb, "failed to create package database\n" );
3087 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3089 create_property_table( hdb );
3090 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
3091 add_property_entry( hdb, "'ProductLanguage', '1033'" );
3092 add_property_entry( hdb, "'ProductName', 'MSITEST'" );
3093 add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
3094 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
3095 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
3097 create_install_execute_sequence_table( hdb );
3098 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
3099 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
3100 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
3101 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
3102 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
3103 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
3104 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
3105 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
3106 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
3107 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
3108 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
3110 create_media_table( hdb );
3111 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
3113 create_feature_table( hdb );
3115 create_component_table( hdb );
3117 /* msidbFeatureAttributesFavorLocal */
3118 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3120 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
3121 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
3123 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
3124 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
3126 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
3127 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
3129 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
3130 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
3132 /* msidbFeatureAttributesFavorSource */
3133 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
3135 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
3136 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
3138 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3139 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
3141 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
3142 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
3144 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
3145 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
3147 /* msidbFeatureAttributesFavorSource */
3148 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
3150 /* msidbFeatureAttributesFavorLocal */
3151 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
3153 /* disabled */
3154 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
3156 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3157 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3159 /* no feature parent:msidbComponentAttributesLocalOnly */
3160 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3162 /* msidbFeatureAttributesFavorLocal:removed */
3163 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
3165 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3166 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3168 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3169 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3171 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3172 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3174 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3175 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3177 /* msidbFeatureAttributesFavorSource:removed */
3178 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
3180 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3181 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3183 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3184 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3186 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3187 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3189 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3190 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3192 /* msidbFeatureAttributesFavorLocal */
3193 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
3195 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3197 /* msidbFeatureAttributesFavorSource */
3198 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
3200 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3202 /* msidbFeatureAttributesFavorAdvertise */
3203 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
3205 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3207 /* msidbFeatureAttributesUIDisallowAbsent */
3208 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
3210 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3212 /* high install level */
3213 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
3215 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3217 /* msidbFeatureAttributesFollowParent */
3218 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
3220 create_feature_components_table( hdb );
3221 add_feature_components_entry( hdb, "'one', 'alpha'" );
3222 add_feature_components_entry( hdb, "'one', 'beta'" );
3223 add_feature_components_entry( hdb, "'one', 'gamma'" );
3224 add_feature_components_entry( hdb, "'one', 'theta'" );
3225 add_feature_components_entry( hdb, "'two', 'delta'" );
3226 add_feature_components_entry( hdb, "'two', 'epsilon'" );
3227 add_feature_components_entry( hdb, "'two', 'zeta'" );
3228 add_feature_components_entry( hdb, "'two', 'iota'" );
3229 add_feature_components_entry( hdb, "'three', 'eta'" );
3230 add_feature_components_entry( hdb, "'four', 'eta'" );
3231 add_feature_components_entry( hdb, "'five', 'eta'" );
3232 add_feature_components_entry( hdb, "'six', 'lambda'" );
3233 add_feature_components_entry( hdb, "'six', 'mu'" );
3234 add_feature_components_entry( hdb, "'six', 'nu'" );
3235 add_feature_components_entry( hdb, "'six', 'xi'" );
3236 add_feature_components_entry( hdb, "'seven', 'omicron'" );
3237 add_feature_components_entry( hdb, "'seven', 'pi'" );
3238 add_feature_components_entry( hdb, "'seven', 'rho'" );
3239 add_feature_components_entry( hdb, "'seven', 'sigma'" );
3240 add_feature_components_entry( hdb, "'eight', 'tau'" );
3241 add_feature_components_entry( hdb, "'nine', 'phi'" );
3242 add_feature_components_entry( hdb, "'ten', 'chi'" );
3243 add_feature_components_entry( hdb, "'eleven', 'psi'" );
3244 add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3245 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3247 create_file_table( hdb );
3248 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3249 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3250 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3251 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3252 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3253 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3254 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3255 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3257 /* compressed file */
3258 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3260 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3261 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3262 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3263 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3264 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3265 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3266 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3267 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3268 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3269 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3270 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3271 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3272 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3273 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3275 r = MsiDatabaseCommit(hdb);
3276 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
3278 /* these properties must not be in the saved msi file */
3279 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3280 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3281 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3282 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3283 add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3285 r = package_from_db( hdb, &hpkg );
3286 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3288 skip("Not enough rights to perform tests\n");
3289 DeleteFileA(msifile);
3290 return;
3292 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3294 MsiCloseHandle(hdb);
3296 CopyFileA(msifile, msifile2, FALSE);
3297 CopyFileA(msifile, msifile3, FALSE);
3298 CopyFileA(msifile, msifile4, FALSE);
3300 size = sizeof(value);
3301 memset(value, 0, sizeof(value));
3302 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3303 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3304 ok(!value[0], "ProductToBeRegistered = %s\n", value);
3306 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3307 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3309 r = MsiDoActionA( hpkg, "CostInitialize");
3310 ok( r == ERROR_SUCCESS, "cost init failed\n");
3312 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3313 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3315 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3317 r = MsiDoActionA( hpkg, "FileCost");
3318 ok( r == ERROR_SUCCESS, "file cost failed\n");
3320 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3321 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3323 r = MsiDoActionA( hpkg, "CostFinalize");
3324 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3326 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3327 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3328 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3329 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3330 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3331 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3332 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3333 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3334 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3335 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3336 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3337 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3338 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3340 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3341 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3342 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3343 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3344 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3345 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3346 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3347 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3348 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3349 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3350 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3351 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3352 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3353 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3354 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3355 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3356 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3357 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3358 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3359 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3360 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3361 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3362 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3364 MsiCloseHandle( hpkg );
3366 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3368 /* publish the features and components */
3369 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
3373 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3375 /* these properties must not be in the saved msi file */
3376 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3377 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3378 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3379 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3381 r = package_from_db( hdb, &hpkg );
3382 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3384 MsiCloseHandle(hdb);
3386 size = sizeof(value);
3387 memset(value, 0, sizeof(value));
3388 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3389 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3390 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value);
3392 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3393 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3395 r = MsiDoActionA( hpkg, "CostInitialize");
3396 ok( r == ERROR_SUCCESS, "cost init failed\n");
3398 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3399 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3401 r = MsiDoActionA( hpkg, "FileCost");
3402 ok( r == ERROR_SUCCESS, "file cost failed\n");
3404 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3405 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3407 r = MsiDoActionA( hpkg, "CostFinalize");
3408 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3410 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3411 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3412 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3413 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3414 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3415 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3416 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3417 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3418 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3419 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3420 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3421 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3422 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3424 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3425 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3426 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3427 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3428 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3429 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3430 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3431 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3432 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3433 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3434 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3435 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3436 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3437 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3438 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3439 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3440 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3441 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3442 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3443 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3444 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3445 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3446 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3448 MsiCloseHandle(hpkg);
3450 /* uninstall the product */
3451 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3454 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3455 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3456 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3457 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3459 /* all features installed locally */
3460 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3463 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3464 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3466 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3468 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb);
3469 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3471 /* these properties must not be in the saved msi file */
3472 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3474 r = package_from_db( hdb, &hpkg );
3475 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3477 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3478 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3480 r = MsiDoActionA( hpkg, "CostInitialize");
3481 ok( r == ERROR_SUCCESS, "cost init failed\n");
3483 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3484 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3486 r = MsiDoActionA( hpkg, "CostFinalize");
3487 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3489 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3490 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3491 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3492 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3493 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3494 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3495 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3496 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3497 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3498 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3499 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3500 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3501 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3503 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3504 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3505 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3506 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3507 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3508 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3509 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3510 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3511 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3512 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3513 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3514 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3515 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3516 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3517 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3518 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3519 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3520 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3521 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3522 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3523 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3524 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3525 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3527 MsiCloseHandle(hpkg);
3529 /* uninstall the product */
3530 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3533 /* all features installed from source */
3534 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3537 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3538 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3539 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3540 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3542 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3543 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3545 /* this property must not be in the saved msi file */
3546 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3548 r = package_from_db( hdb, &hpkg );
3549 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3551 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3552 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3554 r = MsiDoActionA( hpkg, "CostInitialize");
3555 ok( r == ERROR_SUCCESS, "cost init failed\n");
3557 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3558 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3560 r = MsiDoActionA( hpkg, "FileCost");
3561 ok( r == ERROR_SUCCESS, "file cost failed\n");
3563 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3564 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3566 r = MsiDoActionA( hpkg, "CostFinalize");
3567 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3569 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3570 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3571 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3572 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3573 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3574 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3575 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3576 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3577 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3578 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3579 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3580 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3581 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3583 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3584 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3585 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3586 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3587 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3588 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3589 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3590 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3591 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3592 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3593 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3594 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3595 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3596 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3597 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3598 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3599 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3600 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3601 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3602 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3603 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3604 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3605 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3607 MsiCloseHandle(hpkg);
3609 /* reinstall the product */
3610 r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3611 is_broken = (r == ERROR_INSTALL_FAILURE);
3612 ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r);
3614 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3615 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3616 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3617 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3619 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3620 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3622 /* this property must not be in the saved msi file */
3623 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3625 r = package_from_db( hdb, &hpkg );
3626 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3628 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3629 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3631 r = MsiDoActionA( hpkg, "CostInitialize");
3632 ok( r == ERROR_SUCCESS, "cost init failed\n");
3634 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3635 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3637 r = MsiDoActionA( hpkg, "FileCost");
3638 ok( r == ERROR_SUCCESS, "file cost failed\n");
3640 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3641 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3643 r = MsiDoActionA( hpkg, "CostFinalize");
3644 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3646 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3647 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3648 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3649 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3650 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3651 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3652 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3653 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3654 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3655 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3656 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3657 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3658 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3660 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3661 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3662 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3663 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3664 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3665 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3666 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3667 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3668 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3669 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3670 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3671 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3672 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3673 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3674 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3675 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3676 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3677 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3678 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3679 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3680 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3681 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3682 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3684 MsiCloseHandle(hpkg);
3686 /* test source only install */
3687 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3688 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3689 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3690 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3691 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3692 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3694 r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3696 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3697 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3698 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3699 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3701 /* no arguments test */
3702 cache_file_name_len = sizeof(msi_cache_file);
3703 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3704 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3707 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3709 create_custom_action_table( hdb );
3710 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3711 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3712 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3713 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3714 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3715 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3716 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3717 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3718 add_custom_action_entry( hdb,
3719 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3721 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3722 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3723 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3724 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3725 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3726 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3727 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3728 /* Add "one" feature action tests */
3729 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3730 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3731 r = MsiDatabaseCommit(hdb);
3732 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3733 r = package_from_db( hdb, &hpkg );
3734 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3735 MsiCloseHandle(hdb);
3737 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3738 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3739 r = MsiDoActionA( hpkg, "CostInitialize");
3740 ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3741 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3742 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3744 r = MsiDoActionA( hpkg, "FileCost");
3745 ok( r == ERROR_SUCCESS, "FileCost failed\n");
3746 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3747 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3749 r = MsiDoActionA( hpkg, "CostFinalize");
3750 ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3751 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3752 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3753 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3754 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3755 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3756 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3757 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3758 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3759 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3760 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3761 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3762 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3763 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3764 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3765 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3766 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3767 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3768 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3769 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3770 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3771 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3772 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3773 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3774 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3775 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3777 r = MsiDoActionA( hpkg, "InstallValidate");
3778 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3779 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3780 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3781 MsiCloseHandle( hpkg );
3783 r = MsiInstallProductA(msifile, "");
3784 ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */,
3785 "Expected ERROR_SUCCESS, got %d\n", r);
3786 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3787 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3788 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3789 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3790 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3791 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3793 /* minor upgrade test with no REINSTALL argument */
3794 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3796 size = MAX_PATH;
3797 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3799 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
3800 MsiCloseHandle(hprod);
3802 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3803 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3804 update_ProductVersion_property( hdb, "1.1.2" );
3805 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3806 r = MsiDatabaseCommit(hdb);
3807 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3808 MsiCloseHandle(hdb);
3810 r = MsiInstallProductA(msifile2, "");
3811 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
3813 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3816 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3818 size = MAX_PATH;
3819 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3822 MsiCloseHandle(hprod);
3824 /* major upgrade test */
3825 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3826 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3827 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3828 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3829 create_upgrade_table( hdb );
3830 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3831 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3832 update_ProductVersion_property( hdb, "1.1.3" );
3833 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3834 r = MsiDatabaseCommit(hdb);
3835 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3836 MsiCloseHandle(hdb);
3838 r = MsiInstallProductA(msifile2, "");
3839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3841 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3842 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3843 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
3844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3845 size = MAX_PATH;
3846 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3848 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
3849 MsiCloseHandle(hprod);
3851 /* uninstall the product */
3852 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3855 DeleteFileA(msifile);
3856 DeleteFileA(msifile2);
3857 DeleteFileA(msifile3);
3858 DeleteFileA(msifile4);
3861 static void test_removefiles(void)
3863 MSIHANDLE hpkg;
3864 UINT r;
3865 MSIHANDLE hdb;
3866 INSTALLSTATE installed, action;
3868 hdb = create_package_db();
3869 ok ( hdb, "failed to create package database\n" );
3871 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3873 create_feature_table( hdb );
3874 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3876 create_component_table( hdb );
3877 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3878 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3879 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3880 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3881 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3882 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3883 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3885 create_feature_components_table( hdb );
3886 add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3887 add_feature_components_entry( hdb, "'one', 'helium'" );
3888 add_feature_components_entry( hdb, "'one', 'lithium'" );
3889 add_feature_components_entry( hdb, "'one', 'beryllium'" );
3890 add_feature_components_entry( hdb, "'one', 'boron'" );
3891 add_feature_components_entry( hdb, "'one', 'carbon'" );
3892 add_feature_components_entry( hdb, "'one', 'oxygen'" );
3894 create_file_table( hdb );
3895 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3896 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3897 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3898 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3899 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3900 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3901 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3903 create_remove_file_table( hdb );
3905 r = package_from_db( hdb, &hpkg );
3906 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3908 skip("Not enough rights to perform tests\n");
3909 DeleteFileA(msifile);
3910 return;
3912 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3914 MsiCloseHandle( hdb );
3916 create_test_file( "hydrogen.txt" );
3917 create_test_file( "helium.txt" );
3918 create_test_file( "lithium.txt" );
3919 create_test_file( "beryllium.txt" );
3920 create_test_file( "boron.txt" );
3921 create_test_file( "carbon.txt" );
3922 create_test_file( "oxygen.txt" );
3924 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3925 ok( r == ERROR_SUCCESS, "set property failed\n");
3927 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3929 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3930 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3932 r = MsiDoActionA( hpkg, "CostInitialize");
3933 ok( r == ERROR_SUCCESS, "cost init failed\n");
3935 r = MsiDoActionA( hpkg, "FileCost");
3936 ok( r == ERROR_SUCCESS, "file cost failed\n");
3938 installed = action = 0xdeadbeef;
3939 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3940 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3941 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3942 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3944 r = MsiDoActionA( hpkg, "CostFinalize");
3945 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3947 r = MsiDoActionA( hpkg, "InstallValidate");
3948 ok( r == ERROR_SUCCESS, "install validate failed\n");
3950 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3951 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3953 installed = action = 0xdeadbeef;
3954 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3955 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3956 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3957 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3959 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3960 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3962 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3963 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3965 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3966 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3968 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3969 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3971 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3972 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3974 installed = action = 0xdeadbeef;
3975 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3976 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3977 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3978 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3980 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3981 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3983 installed = action = 0xdeadbeef;
3984 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3985 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3986 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3987 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3989 r = MsiDoActionA( hpkg, "RemoveFiles");
3990 ok( r == ERROR_SUCCESS, "remove files failed\n");
3992 installed = action = 0xdeadbeef;
3993 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3994 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3995 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3996 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3998 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3999 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
4000 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
4001 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
4002 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
4003 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
4004 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
4006 MsiCloseHandle( hpkg );
4007 DeleteFileA(msifile);
4010 static void test_appsearch(void)
4012 MSIHANDLE hpkg;
4013 UINT r;
4014 MSIHANDLE hdb;
4015 CHAR prop[MAX_PATH];
4016 DWORD size;
4017 HKEY hkey;
4018 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
4020 hdb = create_package_db();
4021 ok ( hdb, "failed to create package database\n" );
4023 create_appsearch_table( hdb );
4024 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
4025 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
4026 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
4027 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
4028 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
4030 create_reglocator_table( hdb );
4031 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
4033 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
4034 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4035 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
4036 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4037 RegCloseKey(hkey);
4038 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4040 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
4041 NULL, &hkey, NULL);
4042 if (r == ERROR_ACCESS_DENIED)
4044 skip("insufficient rights\n");
4045 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4046 MsiCloseHandle(hdb);
4047 DeleteFileA(msifile);
4048 return;
4050 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4052 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4053 sizeof("c:\\windows\\system32\\notepad.exe"));
4054 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4055 RegCloseKey(hkey);
4056 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4058 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
4059 NULL, &hkey, NULL);
4060 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4061 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4062 sizeof("c:\\windows\\system32\\notepad.exe"));
4063 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4064 RegCloseKey(hkey);
4065 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
4066 msidbLocatorTypeFileName|msidbLocatorType64bit );
4068 create_drlocator_table( hdb );
4069 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
4071 create_signature_table( hdb );
4072 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
4073 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4074 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4075 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4076 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4078 r = package_from_db( hdb, &hpkg );
4079 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4081 skip("Not enough rights to perform tests\n");
4082 DeleteFileA(msifile);
4083 return;
4085 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
4086 MsiCloseHandle( hdb );
4087 if (r != ERROR_SUCCESS)
4088 goto done;
4090 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4092 r = MsiDoActionA( hpkg, "AppSearch" );
4093 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
4095 size = sizeof(prop);
4096 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
4097 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4098 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4100 size = sizeof(prop);
4101 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
4102 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4104 size = sizeof(prop);
4105 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
4106 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4107 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4109 size = sizeof(prop);
4110 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
4111 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4112 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4114 size = sizeof(prop);
4115 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
4116 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4117 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4119 done:
4120 MsiCloseHandle( hpkg );
4121 DeleteFileA(msifile);
4122 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4123 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY);
4124 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY);
4127 static void test_appsearch_complocator(void)
4129 MSIHANDLE hpkg, hdb;
4130 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
4131 LPSTR usersid;
4132 DWORD size;
4133 UINT r;
4135 if (!(usersid = get_user_sid()))
4136 return;
4138 if (is_process_limited())
4140 skip("process is limited\n");
4141 return;
4144 create_test_file("FileName1");
4145 create_test_file("FileName4");
4146 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
4147 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
4149 create_test_file("FileName2");
4150 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
4151 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4153 create_test_file("FileName3");
4154 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
4155 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4157 create_test_file("FileName5");
4158 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
4159 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4161 create_test_file("FileName6");
4162 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
4163 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4165 create_test_file("FileName7");
4166 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
4167 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4169 /* dir is FALSE, but we're pretending it's a directory */
4170 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
4171 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4173 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4174 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
4175 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4177 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4178 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
4179 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4181 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4182 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
4183 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4185 hdb = create_package_db();
4186 ok(hdb, "Expected a valid database handle\n");
4188 create_appsearch_table(hdb);
4189 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4190 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4191 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4192 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4193 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4194 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4195 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4196 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4197 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4198 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4199 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4200 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4202 create_complocator_table(hdb);
4204 /* published component, machine, file, signature, misdbLocatorTypeFile */
4205 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4207 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4208 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4210 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4211 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4213 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4214 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4216 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4217 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4219 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4220 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4222 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4223 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4225 /* unpublished component, no signature, misdbLocatorTypeDir */
4226 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4228 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4229 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4231 /* published component, signature w/ ver, misdbLocatorTypeFile */
4232 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4234 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4235 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4237 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4238 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4240 create_signature_table(hdb);
4241 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4242 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4243 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4244 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4245 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4246 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4247 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4248 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4250 r = package_from_db(hdb, &hpkg);
4251 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4253 skip("Not enough rights to perform tests\n");
4254 goto error;
4256 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4258 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4261 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4263 r = MsiDoActionA(hpkg, "AppSearch");
4264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4266 strcpy(expected, CURR_DIR);
4267 if (is_root(CURR_DIR)) expected[2] = 0;
4269 size = MAX_PATH;
4270 sprintf(path, "%s\\FileName1", expected);
4271 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4273 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4275 size = MAX_PATH;
4276 sprintf(path, "%s\\FileName2", expected);
4277 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4279 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4281 size = MAX_PATH;
4282 sprintf(path, "%s\\FileName3", expected);
4283 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4285 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4287 size = MAX_PATH;
4288 sprintf(path, "%s\\FileName4", expected);
4289 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4291 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4293 size = MAX_PATH;
4294 sprintf(path, "%s\\FileName5", expected);
4295 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4297 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4299 size = MAX_PATH;
4300 sprintf(path, "%s\\", expected);
4301 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4303 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4305 size = MAX_PATH;
4306 sprintf(path, "%s\\", expected);
4307 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4309 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4311 size = MAX_PATH;
4312 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4314 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4316 size = MAX_PATH;
4317 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4319 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4321 size = MAX_PATH;
4322 sprintf(path, "%s\\FileName8.dll", expected);
4323 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4325 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4327 size = MAX_PATH;
4328 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4330 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4332 size = MAX_PATH;
4333 sprintf(path, "%s\\FileName10.dll", expected);
4334 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4336 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4338 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4339 MSIINSTALLCONTEXT_MACHINE, NULL);
4340 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4341 MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
4342 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4343 MSIINSTALLCONTEXT_USERMANAGED, usersid);
4344 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4345 MSIINSTALLCONTEXT_MACHINE, NULL);
4346 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4347 MSIINSTALLCONTEXT_MACHINE, NULL);
4348 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4349 MSIINSTALLCONTEXT_MACHINE, NULL);
4350 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4351 MSIINSTALLCONTEXT_MACHINE, NULL);
4352 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4353 MSIINSTALLCONTEXT_MACHINE, NULL);
4354 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4355 MSIINSTALLCONTEXT_MACHINE, NULL);
4356 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4357 MSIINSTALLCONTEXT_MACHINE, NULL);
4359 MsiCloseHandle(hpkg);
4361 error:
4362 DeleteFileA("FileName1");
4363 DeleteFileA("FileName2");
4364 DeleteFileA("FileName3");
4365 DeleteFileA("FileName4");
4366 DeleteFileA("FileName5");
4367 DeleteFileA("FileName6");
4368 DeleteFileA("FileName7");
4369 DeleteFileA("FileName8.dll");
4370 DeleteFileA("FileName9.dll");
4371 DeleteFileA("FileName10.dll");
4372 DeleteFileA(msifile);
4373 LocalFree(usersid);
4376 static void test_appsearch_reglocator(void)
4378 MSIHANDLE hpkg, hdb;
4379 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4380 DWORD binary[2], size, val;
4381 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4382 HKEY hklm, classes, hkcu, users;
4383 LPSTR pathdata, pathvar, ptr;
4384 LONG res;
4385 UINT r, type = 0;
4386 SYSTEM_INFO si;
4388 version = TRUE;
4389 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4390 version = FALSE;
4392 DeleteFileA("test.dll");
4394 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4395 if (res == ERROR_ACCESS_DENIED)
4397 skip("Not enough rights to perform tests\n");
4398 return;
4400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4402 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4403 (const BYTE *)"regszdata", 10);
4404 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4406 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4409 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4410 (const BYTE *)"regszdata", 10);
4411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4413 users = 0;
4414 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4415 ok(res == ERROR_SUCCESS ||
4416 broken(res == ERROR_INVALID_PARAMETER),
4417 "Expected ERROR_SUCCESS, got %ld\n", res);
4419 if (res == ERROR_SUCCESS)
4421 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4422 (const BYTE *)"regszdata", 10);
4423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4426 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4429 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4432 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4433 (const BYTE *)"regszdata", 10);
4434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4436 val = 42;
4437 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4438 (const BYTE *)&val, sizeof(DWORD));
4439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4441 val = -42;
4442 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4443 (const BYTE *)&val, sizeof(DWORD));
4444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4446 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4447 (const BYTE *)"%PATH%", 7);
4448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4450 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4451 (const BYTE *)"my%NOVAR%", 10);
4452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4454 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4455 (const BYTE *)"one\0two\0", 9);
4456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4458 binary[0] = 0x1234abcd;
4459 binary[1] = 0x567890ef;
4460 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4461 (const BYTE *)binary, sizeof(binary));
4462 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4464 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4465 (const BYTE *)"#regszdata", 11);
4466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4468 strcpy(expected, CURR_DIR);
4469 if (is_root(CURR_DIR)) expected[2] = 0;
4471 create_test_file("FileName1");
4472 sprintf(path, "%s\\FileName1", expected);
4473 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4474 (const BYTE *)path, lstrlenA(path) + 1);
4475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4477 sprintf(path, "%s\\FileName2", expected);
4478 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4479 (const BYTE *)path, lstrlenA(path) + 1);
4480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4482 lstrcpyA(path, expected);
4483 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4484 (const BYTE *)path, lstrlenA(path) + 1);
4485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4487 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4488 (const BYTE *)"", 1);
4489 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4491 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4492 sprintf(path, "%s\\FileName3.dll", expected);
4493 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4494 (const BYTE *)path, lstrlenA(path) + 1);
4495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4497 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4498 sprintf(path, "%s\\FileName4.dll", expected);
4499 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4500 (const BYTE *)path, lstrlenA(path) + 1);
4501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4503 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4504 sprintf(path, "%s\\FileName5.dll", expected);
4505 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4506 (const BYTE *)path, lstrlenA(path) + 1);
4507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4509 sprintf(path, "\"%s\\FileName1\" -option", expected);
4510 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4511 (const BYTE *)path, lstrlenA(path) + 1);
4512 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4514 space = strchr(expected, ' ') != NULL;
4515 sprintf(path, "%s\\FileName1 -option", expected);
4516 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4517 (const BYTE *)path, lstrlenA(path) + 1);
4518 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4520 hdb = create_package_db();
4521 ok(hdb, "Expected a valid database handle\n");
4523 create_appsearch_table(hdb);
4524 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4525 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4526 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4527 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4528 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4529 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4530 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4531 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4532 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4533 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4534 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4535 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4536 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4537 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4538 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4539 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4540 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4541 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4542 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4543 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4544 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4545 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4546 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4547 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4548 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4549 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4550 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4551 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4552 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4553 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4555 create_reglocator_table(hdb);
4557 type = msidbLocatorTypeRawValue;
4558 if (is_64bit)
4559 type |= msidbLocatorType64bit;
4561 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4562 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4564 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4565 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4567 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4568 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4570 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4571 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4573 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4574 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4576 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4577 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4579 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4580 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4582 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4583 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4585 type = msidbLocatorTypeFileName;
4586 if (is_64bit)
4587 type |= msidbLocatorType64bit;
4589 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4590 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4592 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4593 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4595 /* HKLM, msidbLocatorTypeFileName, no signature */
4596 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4598 type = msidbLocatorTypeDirectory;
4599 if (is_64bit)
4600 type |= msidbLocatorType64bit;
4602 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4603 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4605 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4606 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4608 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4609 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4611 type = msidbLocatorTypeRawValue;
4612 if (is_64bit)
4613 type |= msidbLocatorType64bit;
4615 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4616 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4618 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4619 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4621 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4622 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4624 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4625 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4627 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4628 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4630 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4631 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4633 type = msidbLocatorTypeFileName;
4634 if (is_64bit)
4635 type |= msidbLocatorType64bit;
4637 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4638 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4640 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4641 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4643 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4644 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4646 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4647 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4649 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4650 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4652 type = msidbLocatorTypeDirectory;
4653 if (is_64bit)
4654 type |= msidbLocatorType64bit;
4656 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4657 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4659 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4660 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4662 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4663 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4665 type = msidbLocatorTypeFileName;
4666 if (is_64bit)
4667 type |= msidbLocatorType64bit;
4669 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4670 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4672 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4673 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4675 create_signature_table(hdb);
4676 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4677 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4678 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4679 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4680 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4681 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4683 if (!is_root(CURR_DIR))
4685 ptr = strrchr(expected, '\\') + 1;
4686 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4687 add_signature_entry(hdb, path);
4689 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4690 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4691 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4693 r = package_from_db(hdb, &hpkg);
4694 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4696 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4698 r = MsiDoActionA(hpkg, "AppSearch");
4699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4701 size = MAX_PATH;
4702 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4704 ok(!lstrcmpA(prop, "regszdata"),
4705 "Expected \"regszdata\", got \"%s\"\n", prop);
4707 size = MAX_PATH;
4708 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4710 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4712 size = MAX_PATH;
4713 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4715 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4717 memset(&si, 0, sizeof(si));
4718 GetNativeSystemInfo(&si);
4720 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4722 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4723 pathvar = malloc(size);
4724 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4726 size = 0;
4727 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730 pathdata = malloc(++size);
4731 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4733 ok(!lstrcmpA(pathdata, pathvar),
4734 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4736 free(pathvar);
4737 free(pathdata);
4740 size = MAX_PATH;
4741 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743 ok(!lstrcmpA(prop,
4744 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4746 size = MAX_PATH;
4747 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749 todo_wine
4751 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4752 "Expected \"\\0one\\0two\\0\\0\"\n");
4755 size = MAX_PATH;
4756 lstrcpyA(path, "#xCDAB3412EF907856");
4757 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4759 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4761 size = MAX_PATH;
4762 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4764 ok(!lstrcmpA(prop, "##regszdata"),
4765 "Expected \"##regszdata\", got \"%s\"\n", prop);
4767 size = MAX_PATH;
4768 sprintf(path, "%s\\FileName1", expected);
4769 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4771 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4773 size = MAX_PATH;
4774 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4778 size = MAX_PATH;
4779 sprintf(path, "%s\\", expected);
4780 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4782 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4784 size = MAX_PATH;
4785 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4787 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4789 size = MAX_PATH;
4790 sprintf(path, "%s\\", expected);
4791 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4793 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4795 size = MAX_PATH;
4796 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4798 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4800 size = MAX_PATH;
4801 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4803 ok(!lstrcmpA(prop, "regszdata"),
4804 "Expected \"regszdata\", got \"%s\"\n", prop);
4806 size = MAX_PATH;
4807 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4809 ok(!lstrcmpA(prop, "regszdata"),
4810 "Expected \"regszdata\", got \"%s\"\n", prop);
4812 if (users)
4814 size = MAX_PATH;
4815 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4817 ok(!lstrcmpA(prop, "regszdata"),
4818 "Expected \"regszdata\", got \"%s\"\n", prop);
4821 size = MAX_PATH;
4822 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4824 ok(!lstrcmpA(prop, "defvalue"),
4825 "Expected \"defvalue\", got \"%s\"\n", prop);
4827 size = MAX_PATH;
4828 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4830 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4832 size = MAX_PATH;
4833 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4835 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4837 if (version)
4839 size = MAX_PATH;
4840 sprintf(path, "%s\\FileName3.dll", expected);
4841 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4843 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4845 size = MAX_PATH;
4846 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4848 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4850 size = MAX_PATH;
4851 sprintf(path, "%s\\FileName5.dll", expected);
4852 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4854 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4857 if (!is_root(CURR_DIR))
4859 size = MAX_PATH;
4860 lstrcpyA(path, expected);
4861 ptr = strrchr(path, '\\') + 1;
4862 *ptr = '\0';
4863 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4865 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4867 size = MAX_PATH;
4868 sprintf(path, "%s\\", expected);
4869 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4870 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4871 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4873 size = MAX_PATH;
4874 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4876 if (is_root(CURR_DIR))
4877 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4878 else
4879 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4881 size = MAX_PATH;
4882 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4884 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4886 size = MAX_PATH;
4887 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4889 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4891 size = MAX_PATH;
4892 sprintf(path, "%s\\FileName1", expected);
4893 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4897 size = MAX_PATH;
4898 sprintf(path, "%s\\FileName1", expected);
4899 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4901 if (space)
4902 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4903 else
4904 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4906 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4907 RegDeleteValueA(hklm, "Value1");
4908 RegDeleteValueA(hklm, "Value2");
4909 RegDeleteValueA(hklm, "Value3");
4910 RegDeleteValueA(hklm, "Value4");
4911 RegDeleteValueA(hklm, "Value5");
4912 RegDeleteValueA(hklm, "Value6");
4913 RegDeleteValueA(hklm, "Value7");
4914 RegDeleteValueA(hklm, "Value8");
4915 RegDeleteValueA(hklm, "Value9");
4916 RegDeleteValueA(hklm, "Value10");
4917 RegDeleteValueA(hklm, "Value11");
4918 RegDeleteValueA(hklm, "Value12");
4919 RegDeleteValueA(hklm, "Value13");
4920 RegDeleteValueA(hklm, "Value14");
4921 RegDeleteValueA(hklm, "Value15");
4922 RegDeleteValueA(hklm, "Value16");
4923 RegDeleteValueA(hklm, "Value17");
4924 RegDeleteKeyA(hklm, "");
4925 RegCloseKey(hklm);
4927 RegDeleteValueA(classes, "Value1");
4928 RegDeleteKeyA(classes, "");
4929 RegCloseKey(classes);
4931 RegDeleteValueA(hkcu, "Value1");
4932 RegDeleteKeyA(hkcu, "");
4933 RegCloseKey(hkcu);
4935 RegDeleteValueA(users, "Value1");
4936 RegDeleteKeyA(users, "");
4937 RegCloseKey(users);
4939 DeleteFileA("FileName1");
4940 DeleteFileA("FileName3.dll");
4941 DeleteFileA("FileName4.dll");
4942 DeleteFileA("FileName5.dll");
4943 MsiCloseHandle(hpkg);
4944 DeleteFileA(msifile);
4947 static void delete_win_ini(LPCSTR file)
4949 CHAR path[MAX_PATH];
4951 GetWindowsDirectoryA(path, MAX_PATH);
4952 lstrcatA(path, "\\");
4953 lstrcatA(path, file);
4955 DeleteFileA(path);
4958 static void test_appsearch_inilocator(void)
4960 MSIHANDLE hpkg, hdb;
4961 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4962 BOOL version;
4963 LPSTR ptr;
4964 DWORD size;
4965 UINT r;
4967 version = TRUE;
4968 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4969 version = FALSE;
4971 DeleteFileA("test.dll");
4973 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4975 strcpy(expected, CURR_DIR);
4976 if (is_root(CURR_DIR)) expected[2] = 0;
4978 create_test_file("FileName1");
4979 sprintf(path, "%s\\FileName1", expected);
4980 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4982 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4984 sprintf(path, "%s\\IDontExist", expected);
4985 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4987 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4988 sprintf(path, "%s\\FileName2.dll", expected);
4989 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4991 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4992 sprintf(path, "%s\\FileName3.dll", expected);
4993 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4995 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4996 sprintf(path, "%s\\FileName4.dll", expected);
4997 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4999 hdb = create_package_db();
5000 ok(hdb, "Expected a valid database handle\n");
5002 create_appsearch_table(hdb);
5003 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5004 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5005 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5006 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5007 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5008 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5009 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5010 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5011 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5012 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5013 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5014 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
5016 create_inilocator_table(hdb);
5018 /* msidbLocatorTypeRawValue, field 1 */
5019 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
5021 /* msidbLocatorTypeRawValue, field 2 */
5022 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
5024 /* msidbLocatorTypeRawValue, entire field */
5025 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
5027 /* msidbLocatorTypeFile */
5028 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5030 /* msidbLocatorTypeDirectory, file */
5031 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
5033 /* msidbLocatorTypeDirectory, directory */
5034 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
5036 /* msidbLocatorTypeFile, file, no signature */
5037 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5039 /* msidbLocatorTypeFile, dir, no signature */
5040 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
5042 /* msidbLocatorTypeFile, file does not exist */
5043 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
5045 /* msidbLocatorTypeFile, signature with version */
5046 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
5048 /* msidbLocatorTypeFile, signature with version, ver > max */
5049 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
5051 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
5052 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
5054 create_signature_table(hdb);
5055 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
5056 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
5057 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5058 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5059 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5061 r = package_from_db(hdb, &hpkg);
5062 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5064 skip("Not enough rights to perform tests\n");
5065 goto error;
5067 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5069 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5071 r = MsiDoActionA(hpkg, "AppSearch");
5072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5074 size = MAX_PATH;
5075 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5077 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
5079 size = MAX_PATH;
5080 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
5084 size = MAX_PATH;
5085 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5087 ok(!lstrcmpA(prop, "keydata,field2"),
5088 "Expected \"keydata,field2\", got \"%s\"\n", prop);
5090 size = MAX_PATH;
5091 sprintf(path, "%s\\FileName1", expected);
5092 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5094 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5096 size = MAX_PATH;
5097 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5099 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5101 size = MAX_PATH;
5102 sprintf(path, "%s\\", expected);
5103 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5105 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5107 size = MAX_PATH;
5108 sprintf(path, "%s\\", expected);
5109 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5111 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5113 if (!is_root(CURR_DIR))
5115 size = MAX_PATH;
5116 lstrcpyA(path, expected);
5117 ptr = strrchr(path, '\\');
5118 *(ptr + 1) = 0;
5119 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5121 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5123 size = MAX_PATH;
5124 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5126 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5128 if (version)
5130 size = MAX_PATH;
5131 sprintf(path, "%s\\FileName2.dll", expected);
5132 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5134 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5136 size = MAX_PATH;
5137 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5139 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5141 size = MAX_PATH;
5142 sprintf(path, "%s\\FileName4.dll", expected);
5143 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
5144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5145 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5148 MsiCloseHandle(hpkg);
5150 error:
5151 delete_win_ini("IniFile.ini");
5152 DeleteFileA("FileName1");
5153 DeleteFileA("FileName2.dll");
5154 DeleteFileA("FileName3.dll");
5155 DeleteFileA("FileName4.dll");
5156 DeleteFileA(msifile);
5160 * MSI AppSearch action on DrLocator table always returns absolute paths.
5161 * If a relative path was set, it returns the first absolute path that
5162 * matches or an empty string if it didn't find anything.
5163 * This helper function replicates this behaviour.
5165 static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5167 int i, size;
5168 DWORD attr, drives;
5170 size = lstrlenA(relative);
5171 drives = GetLogicalDrives();
5172 lstrcpyA(absolute, "A:\\");
5173 for (i = 0; i < 26; absolute[0] = '\0', i++)
5175 if (!(drives & (1 << i)))
5176 continue;
5178 absolute[0] = 'A' + i;
5179 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5180 continue;
5182 lstrcpynA(absolute + 3, relative, size + 1);
5183 attr = GetFileAttributesA(absolute);
5184 if (attr != INVALID_FILE_ATTRIBUTES &&
5185 (attr & FILE_ATTRIBUTE_DIRECTORY))
5187 if (absolute[3 + size - 1] != '\\')
5188 lstrcatA(absolute, "\\");
5189 break;
5191 absolute[3] = '\0';
5195 static void test_appsearch_drlocator(void)
5197 MSIHANDLE hpkg, hdb;
5198 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5199 BOOL version;
5200 DWORD size;
5201 UINT r;
5203 version = TRUE;
5204 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5205 version = FALSE;
5207 DeleteFileA("test.dll");
5209 create_test_file("FileName1");
5210 CreateDirectoryA("one", NULL);
5211 CreateDirectoryA("one\\two", NULL);
5212 CreateDirectoryA("one\\two\\three", NULL);
5213 create_test_file("one\\two\\three\\FileName2");
5214 CreateDirectoryA("another", NULL);
5215 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5216 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5217 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5219 hdb = create_package_db();
5220 ok(hdb, "Expected a valid database handle\n");
5222 create_appsearch_table(hdb);
5223 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5224 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5225 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5226 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5227 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5228 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5229 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5230 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5231 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5232 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5233 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5234 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5236 create_drlocator_table(hdb);
5238 strcpy(expected, CURR_DIR);
5239 if (is_root(CURR_DIR)) expected[2] = 0;
5241 /* no parent, full path, depth 0, signature */
5242 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5243 add_drlocator_entry(hdb, path);
5245 /* no parent, full path, depth 0, no signature */
5246 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5247 add_drlocator_entry(hdb, path);
5249 /* no parent, relative path, depth 0, no signature */
5250 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5251 add_drlocator_entry(hdb, path);
5253 /* no parent, full path, depth 2, signature */
5254 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5255 add_drlocator_entry(hdb, path);
5257 /* no parent, full path, depth 3, signature */
5258 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5259 add_drlocator_entry(hdb, path);
5261 /* no parent, full path, depth 1, signature is dir */
5262 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5263 add_drlocator_entry(hdb, path);
5265 /* parent is in DrLocator, relative path, depth 0, signature */
5266 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5267 add_drlocator_entry(hdb, path);
5269 /* no parent, full path, depth 0, signature w/ version */
5270 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5271 add_drlocator_entry(hdb, path);
5273 /* no parent, full path, depth 0, signature w/ version, ver > max */
5274 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5275 add_drlocator_entry(hdb, path);
5277 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5278 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5279 add_drlocator_entry(hdb, path);
5281 /* no parent, relative empty path, depth 0, no signature */
5282 sprintf(path, "'NewSignature11', '', '', 0");
5283 add_drlocator_entry(hdb, path);
5285 create_reglocator_table(hdb);
5287 /* parent */
5288 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5290 /* parent is in RegLocator, no path, depth 0, no signature */
5291 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5292 add_drlocator_entry(hdb, path);
5294 create_signature_table(hdb);
5295 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5296 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5297 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5298 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5299 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5300 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5301 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5302 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5304 r = package_from_db(hdb, &hpkg);
5305 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5307 skip("Not enough rights to perform tests\n");
5308 goto error;
5310 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5312 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5314 r = MsiDoActionA(hpkg, "AppSearch");
5315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5317 size = MAX_PATH;
5318 sprintf(path, "%s\\FileName1", expected);
5319 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5321 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5323 size = MAX_PATH;
5324 sprintf(path, "%s\\", expected);
5325 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5327 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5329 size = MAX_PATH;
5330 search_absolute_directory(path, expected + 3);
5331 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5333 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5335 size = MAX_PATH;
5336 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5338 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5340 size = MAX_PATH;
5341 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5342 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5344 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5346 size = MAX_PATH;
5347 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5349 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5351 size = MAX_PATH;
5352 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5353 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5355 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5357 if (version)
5359 size = MAX_PATH;
5360 sprintf(path, "%s\\FileName3.dll", expected);
5361 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5363 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5365 size = MAX_PATH;
5366 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5368 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5370 size = MAX_PATH;
5371 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5373 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5376 size = MAX_PATH;
5377 search_absolute_directory(path, "");
5378 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5380 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5382 size = MAX_PATH;
5383 strcpy(path, "c:\\");
5384 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5386 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5388 MsiCloseHandle(hpkg);
5390 error:
5391 DeleteFileA("FileName1");
5392 DeleteFileA("FileName3.dll");
5393 DeleteFileA("FileName4.dll");
5394 DeleteFileA("FileName5.dll");
5395 DeleteFileA("one\\two\\three\\FileName2");
5396 RemoveDirectoryA("one\\two\\three");
5397 RemoveDirectoryA("one\\two");
5398 RemoveDirectoryA("one");
5399 RemoveDirectoryA("another");
5400 DeleteFileA(msifile);
5403 static void test_featureparents(void)
5405 MSIHANDLE hpkg;
5406 UINT r;
5407 MSIHANDLE hdb;
5409 hdb = create_package_db();
5410 ok ( hdb, "failed to create package database\n" );
5412 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5414 create_feature_table( hdb );
5415 create_component_table( hdb );
5416 create_feature_components_table( hdb );
5417 create_file_table( hdb );
5419 /* msidbFeatureAttributesFavorLocal */
5420 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5422 /* msidbFeatureAttributesFavorSource */
5423 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5425 /* msidbFeatureAttributesFavorLocal */
5426 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5428 /* msidbFeatureAttributesUIDisallowAbsent */
5429 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5431 /* disabled because of install level */
5432 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5434 /* child feature of disabled feature */
5435 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5437 /* component of disabled feature (install level) */
5438 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5440 /* component of disabled child feature (install level) */
5441 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5443 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5444 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5446 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5447 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5449 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5450 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5452 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5453 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5455 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5456 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5458 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5459 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5461 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5462 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5464 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5465 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5467 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5468 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5470 add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5471 add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5472 add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5473 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5474 add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5475 add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5476 add_feature_components_entry( hdb, "'orion', 'leo'" );
5477 add_feature_components_entry( hdb, "'orion', 'virgo'" );
5478 add_feature_components_entry( hdb, "'orion', 'libra'" );
5479 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5480 add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5481 add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5482 add_feature_components_entry( hdb, "'orion', 'canis'" );
5483 add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5484 add_feature_components_entry( hdb, "'orion', 'lepus'" );
5485 add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5486 add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5488 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5489 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5490 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5491 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5492 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5493 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5494 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5495 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5496 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5497 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5498 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5500 r = package_from_db( hdb, &hpkg );
5501 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5503 skip("Not enough rights to perform tests\n");
5504 DeleteFileA(msifile);
5505 return;
5507 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5509 MsiCloseHandle( hdb );
5511 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5513 r = MsiDoActionA( hpkg, "CostInitialize");
5514 ok( r == ERROR_SUCCESS, "cost init failed\n");
5516 r = MsiDoActionA( hpkg, "FileCost");
5517 ok( r == ERROR_SUCCESS, "file cost failed\n");
5519 r = MsiDoActionA( hpkg, "CostFinalize");
5520 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5522 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5523 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5524 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5525 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5526 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5527 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5529 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5530 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5531 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5532 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5533 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5534 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5535 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5536 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5537 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5538 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5539 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5541 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5542 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5544 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5545 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5547 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5548 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5550 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5551 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5552 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5553 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5554 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5555 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5557 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5558 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5559 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5560 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5561 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5562 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5563 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5564 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5565 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5566 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5567 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5569 MsiCloseHandle(hpkg);
5570 DeleteFileA(msifile);
5573 static void test_installprops(void)
5575 MSIHANDLE hpkg, hdb;
5576 CHAR path[MAX_PATH], buf[MAX_PATH];
5577 DWORD size, type;
5578 LANGID langid;
5579 HKEY hkey1, hkey2, pathkey;
5580 int res;
5581 UINT r;
5582 REGSAM access = KEY_ALL_ACCESS;
5583 SYSTEM_INFO si;
5584 INSTALLUILEVEL uilevel;
5586 if (is_wow64)
5587 access |= KEY_WOW64_64KEY;
5589 lstrcpyA(path, CURR_DIR);
5590 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5591 lstrcatA(path, msifile);
5593 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5595 hdb = create_package_db();
5596 ok( hdb, "failed to create database\n");
5598 r = package_from_db(hdb, &hpkg);
5599 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5601 skip("Not enough rights to perform tests\n");
5602 MsiSetInternalUI(uilevel, NULL);
5603 DeleteFileA(msifile);
5604 return;
5606 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5608 MsiCloseHandle(hdb);
5610 buf[0] = 0;
5611 size = MAX_PATH;
5612 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5613 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5614 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5616 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5618 buf[0] = 0;
5619 size = MAX_PATH;
5620 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5621 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5622 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5624 buf[0] = 0;
5625 size = MAX_PATH;
5626 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5627 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5628 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5630 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5631 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5632 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5633 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5635 size = MAX_PATH;
5636 type = REG_SZ;
5637 *path = '\0';
5638 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5640 size = MAX_PATH;
5641 type = REG_SZ;
5642 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5645 buf[0] = 0;
5646 size = MAX_PATH;
5647 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5648 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5649 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5651 size = MAX_PATH;
5652 type = REG_SZ;
5653 *path = '\0';
5654 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5656 size = MAX_PATH;
5657 type = REG_SZ;
5658 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5661 if (*path)
5663 buf[0] = 0;
5664 size = MAX_PATH;
5665 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5666 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5667 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5670 buf[0] = 0;
5671 size = MAX_PATH;
5672 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5673 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5674 trace("VersionDatabase = %s\n", buf);
5676 buf[0] = 0;
5677 size = MAX_PATH;
5678 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5679 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5680 trace("VersionMsi = %s\n", buf);
5682 buf[0] = 0;
5683 size = MAX_PATH;
5684 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5685 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5686 trace("Date = %s\n", buf);
5688 buf[0] = 0;
5689 size = MAX_PATH;
5690 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5691 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5692 trace("Time = %s\n", buf);
5694 buf[0] = 0;
5695 size = MAX_PATH;
5696 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5697 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5698 trace("PackageCode = %s\n", buf);
5700 buf[0] = 0;
5701 size = MAX_PATH;
5702 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5703 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5704 trace("ComputerName = %s\n", buf);
5706 langid = GetUserDefaultLangID();
5707 sprintf(path, "%d", langid);
5709 buf[0] = 0;
5710 size = MAX_PATH;
5711 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5712 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5713 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5715 res = GetSystemMetrics(SM_CXSCREEN);
5716 buf[0] = 0;
5717 size = MAX_PATH;
5718 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5719 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5720 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5722 res = GetSystemMetrics(SM_CYSCREEN);
5723 buf[0] = 0;
5724 size = MAX_PATH;
5725 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5726 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5727 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5729 buf[0] = 0;
5730 size = MAX_PATH;
5731 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
5732 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
5734 GetNativeSystemInfo(&si);
5736 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5737 check_prop(hpkg, "VersionNT", buf, 1, 1);
5739 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5741 sprintf(buf, "%d", si.wProcessorLevel);
5742 check_prop(hpkg, "Intel", buf, 1, 0);
5743 check_prop(hpkg, "MsiAMD64", buf, 1, 0);
5744 check_prop(hpkg, "Msix64", buf, 1, 0);
5745 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5746 check_prop(hpkg, "VersionNT64", buf, 1, 1);
5748 GetSystemDirectoryA(path, MAX_PATH);
5749 strcat(path, "\\");
5750 check_prop(hpkg, "System64Folder", path, 0, 0);
5752 GetSystemWow64DirectoryA(path, MAX_PATH);
5753 strcat(path, "\\");
5754 check_prop(hpkg, "SystemFolder", path, 0, 0);
5756 size = MAX_PATH;
5757 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5758 strcat(path, "\\");
5759 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5761 size = MAX_PATH;
5762 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5763 strcat(path, "\\");
5764 check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0);
5766 size = MAX_PATH;
5767 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5768 strcat(path, "\\");
5769 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5771 size = MAX_PATH;
5772 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5773 strcat(path, "\\");
5774 check_prop(hpkg, "CommonFiles64Folder", path, 0, 0);
5776 else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5778 sprintf(buf, "%d", si.wProcessorLevel);
5779 check_prop(hpkg, "Intel", buf, 1, 0);
5781 GetSystemDirectoryA(path, MAX_PATH);
5782 strcat(path, "\\");
5783 check_prop(hpkg, "SystemFolder", path, 0, 0);
5785 size = MAX_PATH;
5786 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5787 strcat(path, "\\");
5788 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5790 size = MAX_PATH;
5791 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5792 strcat(path, "\\");
5793 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5795 check_prop(hpkg, "MsiAMD64", "", 1, 0);
5796 check_prop(hpkg, "Msix64", "", 1, 0);
5797 check_prop(hpkg, "VersionNT64", "", 1, 0);
5798 check_prop(hpkg, "System64Folder", "", 0, 0);
5799 check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0);
5800 check_prop(hpkg, "CommonFiles64Dir", "", 0, 0);
5803 CloseHandle(hkey1);
5804 CloseHandle(hkey2);
5805 RegCloseKey(pathkey);
5806 MsiCloseHandle(hpkg);
5807 DeleteFileA(msifile);
5808 MsiSetInternalUI(uilevel, NULL);
5811 static void test_launchconditions(void)
5813 MSIHANDLE hpkg;
5814 MSIHANDLE hdb;
5815 UINT r;
5817 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5819 hdb = create_package_db();
5820 ok( hdb, "failed to create package database\n" );
5822 create_launchcondition_table( hdb );
5824 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5826 /* invalid condition */
5827 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5829 r = package_from_db( hdb, &hpkg );
5830 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5832 skip("Not enough rights to perform tests\n");
5833 DeleteFileA(msifile);
5834 return;
5836 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5838 MsiCloseHandle( hdb );
5840 r = MsiSetPropertyA( hpkg, "X", "1" );
5841 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5843 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5845 /* invalid conditions are ignored */
5846 r = MsiDoActionA( hpkg, "LaunchConditions" );
5847 ok( r == ERROR_SUCCESS, "cost init failed\n" );
5849 /* verify LaunchConditions still does some verification */
5850 r = MsiSetPropertyA( hpkg, "X", "2" );
5851 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5853 r = MsiDoActionA( hpkg, "LaunchConditions" );
5854 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5856 MsiCloseHandle( hpkg );
5857 DeleteFileA( msifile );
5860 static void test_ccpsearch(void)
5862 MSIHANDLE hdb, hpkg;
5863 CHAR prop[MAX_PATH];
5864 DWORD size = MAX_PATH;
5865 UINT r;
5867 hdb = create_package_db();
5868 ok(hdb, "failed to create package database\n");
5870 create_ccpsearch_table(hdb);
5871 add_ccpsearch_entry(hdb, "'CCP_random'");
5872 add_ccpsearch_entry(hdb, "'RMCCP_random'");
5874 create_reglocator_table(hdb);
5875 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5877 create_drlocator_table(hdb);
5878 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5880 create_signature_table(hdb);
5882 r = package_from_db(hdb, &hpkg);
5883 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5885 skip("Not enough rights to perform tests\n");
5886 DeleteFileA(msifile);
5887 return;
5889 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5891 MsiCloseHandle(hdb);
5893 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5895 r = MsiDoActionA(hpkg, "CCPSearch");
5896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5898 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5900 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5902 MsiCloseHandle(hpkg);
5903 DeleteFileA(msifile);
5906 static void test_complocator(void)
5908 MSIHANDLE hdb, hpkg;
5909 UINT r;
5910 CHAR prop[MAX_PATH];
5911 CHAR expected[MAX_PATH];
5912 DWORD size = MAX_PATH;
5914 hdb = create_package_db();
5915 ok(hdb, "failed to create package database\n");
5917 create_appsearch_table(hdb);
5918 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5919 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5920 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5921 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5922 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5923 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5924 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5925 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5926 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5927 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5928 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5929 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5930 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5931 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5932 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5933 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5935 create_complocator_table(hdb);
5936 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5937 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5938 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5939 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5940 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5941 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5942 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5943 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5944 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5945 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5946 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5947 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5948 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5949 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5950 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5951 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5953 create_signature_table(hdb);
5954 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5955 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5956 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5957 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5958 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5959 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5960 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5961 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5963 r = package_from_db(hdb, &hpkg);
5964 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5966 skip("Not enough rights to perform tests\n");
5967 DeleteFileA(msifile);
5968 return;
5970 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5972 MsiCloseHandle(hdb);
5974 create_test_file("abelisaurus");
5975 create_test_file("bactrosaurus");
5976 create_test_file("camelotia");
5977 create_test_file("diclonius");
5978 create_test_file("echinodon");
5979 create_test_file("falcarius");
5980 create_test_file("gallimimus");
5981 create_test_file("hagryphus");
5982 CreateDirectoryA("iguanodon", NULL);
5983 CreateDirectoryA("jobaria", NULL);
5984 CreateDirectoryA("kakuru", NULL);
5985 CreateDirectoryA("labocania", NULL);
5986 CreateDirectoryA("megaraptor", NULL);
5987 CreateDirectoryA("neosodon", NULL);
5988 CreateDirectoryA("olorotitan", NULL);
5989 CreateDirectoryA("pantydraco", NULL);
5991 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
5992 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5993 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
5994 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5995 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
5996 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5997 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
5998 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
5999 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
6000 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
6001 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
6002 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
6003 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
6004 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
6005 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
6006 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
6008 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6010 r = MsiDoActionA(hpkg, "AppSearch");
6011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6013 size = MAX_PATH;
6014 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
6015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6017 lstrcpyA(expected, CURR_DIR);
6018 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6019 lstrcatA(expected, "abelisaurus");
6020 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6021 "Expected %s or empty string, got %s\n", expected, prop);
6023 size = MAX_PATH;
6024 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
6025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6026 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6028 size = MAX_PATH;
6029 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
6030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6031 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6033 size = MAX_PATH;
6034 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
6035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6036 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6038 size = MAX_PATH;
6039 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
6040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6042 lstrcpyA(expected, CURR_DIR);
6043 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6044 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6045 "Expected %s or empty string, got %s\n", expected, prop);
6047 size = MAX_PATH;
6048 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
6049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6050 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6052 size = MAX_PATH;
6053 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
6054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6055 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6057 size = MAX_PATH;
6058 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
6059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6060 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6062 size = MAX_PATH;
6063 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
6064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6065 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6067 size = MAX_PATH;
6068 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
6069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6070 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6072 size = MAX_PATH;
6073 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
6074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6075 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6077 size = MAX_PATH;
6078 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
6079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6080 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6082 size = MAX_PATH;
6083 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
6084 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6086 lstrcpyA(expected, CURR_DIR);
6087 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6088 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6089 "Expected %s or empty string, got %s\n", expected, prop);
6091 size = MAX_PATH;
6092 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
6093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6095 lstrcpyA(expected, CURR_DIR);
6096 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6097 lstrcatA(expected, "neosodon\\");
6098 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6099 "Expected %s or empty string, got %s\n", expected, prop);
6101 size = MAX_PATH;
6102 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6104 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6106 size = MAX_PATH;
6107 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6109 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6111 MsiCloseHandle(hpkg);
6112 DeleteFileA("abelisaurus");
6113 DeleteFileA("bactrosaurus");
6114 DeleteFileA("camelotia");
6115 DeleteFileA("diclonius");
6116 DeleteFileA("echinodon");
6117 DeleteFileA("falcarius");
6118 DeleteFileA("gallimimus");
6119 DeleteFileA("hagryphus");
6120 RemoveDirectoryA("iguanodon");
6121 RemoveDirectoryA("jobaria");
6122 RemoveDirectoryA("kakuru");
6123 RemoveDirectoryA("labocania");
6124 RemoveDirectoryA("megaraptor");
6125 RemoveDirectoryA("neosodon");
6126 RemoveDirectoryA("olorotitan");
6127 RemoveDirectoryA("pantydraco");
6128 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6129 MSIINSTALLCONTEXT_MACHINE, NULL);
6130 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6131 MSIINSTALLCONTEXT_MACHINE, NULL);
6132 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6133 MSIINSTALLCONTEXT_MACHINE, NULL);
6134 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6135 MSIINSTALLCONTEXT_MACHINE, NULL);
6136 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6137 MSIINSTALLCONTEXT_MACHINE, NULL);
6138 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6139 MSIINSTALLCONTEXT_MACHINE, NULL);
6140 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6141 MSIINSTALLCONTEXT_MACHINE, NULL);
6142 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6143 MSIINSTALLCONTEXT_MACHINE, NULL);
6144 DeleteFileA(msifile);
6147 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6149 MSIHANDLE summary;
6150 UINT r;
6152 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6155 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6158 r = MsiSummaryInfoPersist(summary);
6159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6161 MsiCloseHandle(summary);
6164 static void test_MsiGetSourcePath(void)
6166 MSIHANDLE hdb, hpkg;
6167 CHAR path[MAX_PATH];
6168 CHAR cwd[MAX_PATH];
6169 CHAR subsrc[MAX_PATH];
6170 CHAR sub2[MAX_PATH];
6171 DWORD size;
6172 UINT r;
6174 lstrcpyA(cwd, CURR_DIR);
6175 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6177 lstrcpyA(subsrc, cwd);
6178 lstrcatA(subsrc, "subsource");
6179 lstrcatA(subsrc, "\\");
6181 lstrcpyA(sub2, subsrc);
6182 lstrcatA(sub2, "sub2");
6183 lstrcatA(sub2, "\\");
6185 /* uncompressed source */
6187 hdb = create_package_db();
6188 ok( hdb, "failed to create database\n");
6190 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6192 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6193 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6194 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6196 r = MsiDatabaseCommit(hdb);
6197 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6199 r = package_from_db(hdb, &hpkg);
6200 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6202 skip("Not enough rights to perform tests\n");
6203 DeleteFileA(msifile);
6204 return;
6206 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6208 MsiCloseHandle(hdb);
6210 /* invalid database handle */
6211 size = MAX_PATH;
6212 lstrcpyA(path, "kiwi");
6213 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6214 ok(r == ERROR_INVALID_HANDLE,
6215 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6216 ok(!lstrcmpA(path, "kiwi"),
6217 "Expected path to be unchanged, got \"%s\"\n", path);
6218 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6220 /* NULL szFolder */
6221 size = MAX_PATH;
6222 lstrcpyA(path, "kiwi");
6223 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6224 ok(r == ERROR_INVALID_PARAMETER,
6225 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6226 ok(!lstrcmpA(path, "kiwi"),
6227 "Expected path to be unchanged, got \"%s\"\n", path);
6228 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6230 /* empty szFolder */
6231 size = MAX_PATH;
6232 lstrcpyA(path, "kiwi");
6233 r = MsiGetSourcePathA(hpkg, "", path, &size);
6234 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6235 ok(!lstrcmpA(path, "kiwi"),
6236 "Expected path to be unchanged, got \"%s\"\n", path);
6237 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6239 /* try TARGETDIR */
6240 size = MAX_PATH;
6241 lstrcpyA(path, "kiwi");
6242 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6243 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6244 ok(!lstrcmpA(path, "kiwi"),
6245 "Expected path to be unchanged, got \"%s\"\n", path);
6246 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6248 size = MAX_PATH;
6249 lstrcpyA(path, "kiwi");
6250 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6252 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6253 ok(size == 0, "Expected 0, got %lu\n", size);
6255 size = MAX_PATH;
6256 lstrcpyA(path, "kiwi");
6257 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6259 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6260 ok(size == 0, "Expected 0, got %lu\n", size);
6262 /* try SourceDir */
6263 size = MAX_PATH;
6264 lstrcpyA(path, "kiwi");
6265 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6266 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6267 ok(!lstrcmpA(path, "kiwi"),
6268 "Expected path to be unchanged, got \"%s\"\n", path);
6269 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6271 /* try SOURCEDIR */
6272 size = MAX_PATH;
6273 lstrcpyA(path, "kiwi");
6274 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6275 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6276 ok(!lstrcmpA(path, "kiwi"),
6277 "Expected path to be unchanged, got \"%s\"\n", path);
6278 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6280 /* source path does not exist, but the property exists */
6281 size = MAX_PATH;
6282 lstrcpyA(path, "kiwi");
6283 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6285 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6286 ok(size == 0, "Expected 0, got %lu\n", size);
6288 size = MAX_PATH;
6289 lstrcpyA(path, "kiwi");
6290 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6292 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6293 ok(size == 0, "Expected 0, got %lu\n", size);
6295 /* try SubDir */
6296 size = MAX_PATH;
6297 lstrcpyA(path, "kiwi");
6298 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6299 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6300 ok(!lstrcmpA(path, "kiwi"),
6301 "Expected path to be unchanged, got \"%s\"\n", path);
6302 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6304 /* try SubDir2 */
6305 size = MAX_PATH;
6306 lstrcpyA(path, "kiwi");
6307 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6308 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6309 ok(!lstrcmpA(path, "kiwi"),
6310 "Expected path to be unchanged, got \"%s\"\n", path);
6311 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6313 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6315 r = MsiDoActionA(hpkg, "CostInitialize");
6316 ok(r == ERROR_SUCCESS, "cost init failed\n");
6318 /* try TARGETDIR after CostInitialize */
6319 size = MAX_PATH;
6320 lstrcpyA(path, "kiwi");
6321 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6323 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6324 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6326 /* try SourceDir after CostInitialize */
6327 size = MAX_PATH;
6328 lstrcpyA(path, "kiwi");
6329 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6331 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6332 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6334 /* try SOURCEDIR after CostInitialize */
6335 size = MAX_PATH;
6336 lstrcpyA(path, "kiwi");
6337 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6338 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6339 ok(!lstrcmpA(path, "kiwi"),
6340 "Expected path to be unchanged, got \"%s\"\n", path);
6341 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6343 /* source path does not exist, but the property exists */
6344 size = MAX_PATH;
6345 lstrcpyA(path, "kiwi");
6346 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6348 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6349 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6351 size = MAX_PATH;
6352 lstrcpyA(path, "kiwi");
6353 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6355 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6356 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6358 /* try SubDir after CostInitialize */
6359 size = MAX_PATH;
6360 lstrcpyA(path, "kiwi");
6361 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6363 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6364 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6366 /* try SubDir2 after CostInitialize */
6367 size = MAX_PATH;
6368 lstrcpyA(path, "kiwi");
6369 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6371 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6372 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6374 r = MsiDoActionA(hpkg, "ResolveSource");
6375 ok(r == ERROR_SUCCESS, "file cost failed\n");
6377 /* try TARGETDIR after ResolveSource */
6378 size = MAX_PATH;
6379 lstrcpyA(path, "kiwi");
6380 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6383 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6385 /* try SourceDir after ResolveSource */
6386 size = MAX_PATH;
6387 lstrcpyA(path, "kiwi");
6388 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6390 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6391 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6393 /* try SOURCEDIR after ResolveSource */
6394 size = MAX_PATH;
6395 lstrcpyA(path, "kiwi");
6396 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6397 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6398 ok(!lstrcmpA(path, "kiwi"),
6399 "Expected path to be unchanged, got \"%s\"\n", path);
6400 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6402 /* source path does not exist, but the property exists */
6403 size = MAX_PATH;
6404 lstrcpyA(path, "kiwi");
6405 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6407 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6408 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6410 size = MAX_PATH;
6411 lstrcpyA(path, "kiwi");
6412 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6414 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6415 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6417 /* try SubDir after ResolveSource */
6418 size = MAX_PATH;
6419 lstrcpyA(path, "kiwi");
6420 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6422 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6423 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6425 /* try SubDir2 after ResolveSource */
6426 size = MAX_PATH;
6427 lstrcpyA(path, "kiwi");
6428 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6430 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6431 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6433 r = MsiDoActionA(hpkg, "FileCost");
6434 ok(r == ERROR_SUCCESS, "file cost failed\n");
6436 /* try TARGETDIR after FileCost */
6437 size = MAX_PATH;
6438 lstrcpyA(path, "kiwi");
6439 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6441 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6442 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6444 /* try SourceDir after FileCost */
6445 size = MAX_PATH;
6446 lstrcpyA(path, "kiwi");
6447 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6449 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6450 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6452 /* try SOURCEDIR after FileCost */
6453 size = MAX_PATH;
6454 lstrcpyA(path, "kiwi");
6455 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6456 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6457 ok(!lstrcmpA(path, "kiwi"),
6458 "Expected path to be unchanged, got \"%s\"\n", path);
6459 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6461 /* source path does not exist, but the property exists */
6462 size = MAX_PATH;
6463 lstrcpyA(path, "kiwi");
6464 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6466 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6467 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6469 size = MAX_PATH;
6470 lstrcpyA(path, "kiwi");
6471 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6473 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6474 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6476 /* try SubDir after FileCost */
6477 size = MAX_PATH;
6478 lstrcpyA(path, "kiwi");
6479 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6481 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6482 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6484 /* try SubDir2 after FileCost */
6485 size = MAX_PATH;
6486 lstrcpyA(path, "kiwi");
6487 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6489 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6490 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6492 r = MsiDoActionA(hpkg, "CostFinalize");
6493 ok(r == ERROR_SUCCESS, "file cost failed\n");
6495 /* try TARGETDIR after CostFinalize */
6496 size = MAX_PATH;
6497 lstrcpyA(path, "kiwi");
6498 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6500 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6501 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6503 /* try SourceDir after CostFinalize */
6504 size = MAX_PATH;
6505 lstrcpyA(path, "kiwi");
6506 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6508 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6509 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6511 /* try SOURCEDIR after CostFinalize */
6512 size = MAX_PATH;
6513 lstrcpyA(path, "kiwi");
6514 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6515 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6516 ok(!lstrcmpA(path, "kiwi"),
6517 "Expected path to be unchanged, got \"%s\"\n", path);
6518 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6520 /* source path does not exist, but the property exists */
6521 size = MAX_PATH;
6522 lstrcpyA(path, "kiwi");
6523 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6525 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6526 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6528 size = MAX_PATH;
6529 lstrcpyA(path, "kiwi");
6530 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6532 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6533 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6535 /* try SubDir after CostFinalize */
6536 size = MAX_PATH;
6537 lstrcpyA(path, "kiwi");
6538 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6540 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6541 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6543 /* try SubDir2 after CostFinalize */
6544 size = MAX_PATH;
6545 lstrcpyA(path, "kiwi");
6546 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6548 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6549 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6551 /* nonexistent directory */
6552 size = MAX_PATH;
6553 lstrcpyA(path, "kiwi");
6554 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6555 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6556 ok(!lstrcmpA(path, "kiwi"),
6557 "Expected path to be unchanged, got \"%s\"\n", path);
6558 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6560 /* NULL szPathBuf */
6561 size = MAX_PATH;
6562 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6564 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6566 /* NULL pcchPathBuf */
6567 lstrcpyA(path, "kiwi");
6568 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6569 ok(r == ERROR_INVALID_PARAMETER,
6570 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6571 ok(!lstrcmpA(path, "kiwi"),
6572 "Expected path to be unchanged, got \"%s\"\n", path);
6574 /* pcchPathBuf is 0 */
6575 size = 0;
6576 lstrcpyA(path, "kiwi");
6577 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6578 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6579 ok(!lstrcmpA(path, "kiwi"),
6580 "Expected path to be unchanged, got \"%s\"\n", path);
6581 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6583 /* pcchPathBuf does not have room for NULL terminator */
6584 size = lstrlenA(cwd);
6585 lstrcpyA(path, "kiwi");
6586 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6587 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6588 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6589 "Expected path with no backslash, got \"%s\"\n", path);
6590 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6592 /* pcchPathBuf has room for NULL terminator */
6593 size = lstrlenA(cwd) + 1;
6594 lstrcpyA(path, "kiwi");
6595 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6597 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6598 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6600 /* remove property */
6601 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6604 /* try SourceDir again */
6605 size = MAX_PATH;
6606 lstrcpyA(path, "kiwi");
6607 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6609 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6610 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6612 /* set property to a valid directory */
6613 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6616 /* try SOURCEDIR again */
6617 size = MAX_PATH;
6618 lstrcpyA(path, "kiwi");
6619 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6620 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6621 ok(!lstrcmpA(path, "kiwi"),
6622 "Expected path to be unchanged, got \"%s\"\n", path);
6623 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6625 MsiCloseHandle(hpkg);
6627 /* compressed source */
6629 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6632 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
6634 r = package_from_db(hdb, &hpkg);
6635 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6637 /* try TARGETDIR */
6638 size = MAX_PATH;
6639 lstrcpyA(path, "kiwi");
6640 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6641 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6642 ok(!lstrcmpA(path, "kiwi"),
6643 "Expected path to be unchanged, got \"%s\"\n", path);
6644 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6646 /* try SourceDir */
6647 size = MAX_PATH;
6648 lstrcpyA(path, "kiwi");
6649 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6650 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6651 ok(!lstrcmpA(path, "kiwi"),
6652 "Expected path to be unchanged, got \"%s\"\n", path);
6653 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6655 /* try SOURCEDIR */
6656 size = MAX_PATH;
6657 lstrcpyA(path, "kiwi");
6658 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6659 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6660 ok(!lstrcmpA(path, "kiwi"),
6661 "Expected path to be unchanged, got \"%s\"\n", path);
6662 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6664 /* source path nor the property exist */
6665 size = MAX_PATH;
6666 lstrcpyA(path, "kiwi");
6667 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6670 ok(size == 0, "Expected 0, got %lu\n", size);
6672 size = MAX_PATH;
6673 lstrcpyA(path, "kiwi");
6674 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6676 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6677 ok(size == 0, "Expected 0, got %lu\n", size);
6679 /* try SubDir */
6680 size = MAX_PATH;
6681 lstrcpyA(path, "kiwi");
6682 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6683 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6684 ok(!lstrcmpA(path, "kiwi"),
6685 "Expected path to be unchanged, got \"%s\"\n", path);
6686 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6688 /* try SubDir2 */
6689 size = MAX_PATH;
6690 lstrcpyA(path, "kiwi");
6691 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6692 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6693 ok(!lstrcmpA(path, "kiwi"),
6694 "Expected path to be unchanged, got \"%s\"\n", path);
6695 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6697 r = MsiDoActionA(hpkg, "CostInitialize");
6698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6700 /* try TARGETDIR after CostInitialize */
6701 size = MAX_PATH;
6702 lstrcpyA(path, "kiwi");
6703 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6705 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6706 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6708 /* try SourceDir after CostInitialize */
6709 size = MAX_PATH;
6710 lstrcpyA(path, "kiwi");
6711 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6713 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6714 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6716 /* try SOURCEDIR after CostInitialize */
6717 size = MAX_PATH;
6718 lstrcpyA(path, "kiwi");
6719 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6720 todo_wine
6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6724 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6727 /* source path does not exist, but the property exists */
6728 size = MAX_PATH;
6729 lstrcpyA(path, "kiwi");
6730 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6732 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6733 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6735 size = MAX_PATH;
6736 lstrcpyA(path, "kiwi");
6737 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6739 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6740 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6742 /* try SubDir after CostInitialize */
6743 size = MAX_PATH;
6744 lstrcpyA(path, "kiwi");
6745 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6747 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6748 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6750 /* try SubDir2 after CostInitialize */
6751 size = MAX_PATH;
6752 lstrcpyA(path, "kiwi");
6753 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6755 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6756 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6758 r = MsiDoActionA(hpkg, "ResolveSource");
6759 ok(r == ERROR_SUCCESS, "file cost failed\n");
6761 /* try TARGETDIR after ResolveSource */
6762 size = MAX_PATH;
6763 lstrcpyA(path, "kiwi");
6764 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6766 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6767 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6769 /* try SourceDir after ResolveSource */
6770 size = MAX_PATH;
6771 lstrcpyA(path, "kiwi");
6772 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6774 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6775 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6777 /* try SOURCEDIR after ResolveSource */
6778 size = MAX_PATH;
6779 lstrcpyA(path, "kiwi");
6780 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6781 todo_wine
6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6784 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6785 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6788 /* source path and the property exist */
6789 size = MAX_PATH;
6790 lstrcpyA(path, "kiwi");
6791 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6793 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6794 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6796 size = MAX_PATH;
6797 lstrcpyA(path, "kiwi");
6798 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6800 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6801 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6803 /* try SubDir after ResolveSource */
6804 size = MAX_PATH;
6805 lstrcpyA(path, "kiwi");
6806 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6808 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6809 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6811 /* try SubDir2 after ResolveSource */
6812 size = MAX_PATH;
6813 lstrcpyA(path, "kiwi");
6814 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6816 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6817 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6819 r = MsiDoActionA(hpkg, "FileCost");
6820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6822 /* try TARGETDIR after CostFinalize */
6823 size = MAX_PATH;
6824 lstrcpyA(path, "kiwi");
6825 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6827 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6828 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6830 /* try SourceDir after CostFinalize */
6831 size = MAX_PATH;
6832 lstrcpyA(path, "kiwi");
6833 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6835 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6836 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6838 /* try SOURCEDIR after CostFinalize */
6839 size = MAX_PATH;
6840 lstrcpyA(path, "kiwi");
6841 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6842 todo_wine
6844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6845 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6846 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6849 /* source path and the property exist */
6850 size = MAX_PATH;
6851 lstrcpyA(path, "kiwi");
6852 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6854 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6855 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6857 size = MAX_PATH;
6858 lstrcpyA(path, "kiwi");
6859 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6861 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6862 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6864 /* try SubDir after CostFinalize */
6865 size = MAX_PATH;
6866 lstrcpyA(path, "kiwi");
6867 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6869 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6870 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6872 /* try SubDir2 after CostFinalize */
6873 size = MAX_PATH;
6874 lstrcpyA(path, "kiwi");
6875 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6877 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6878 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6880 r = MsiDoActionA(hpkg, "CostFinalize");
6881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6883 /* try TARGETDIR after CostFinalize */
6884 size = MAX_PATH;
6885 lstrcpyA(path, "kiwi");
6886 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6889 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6891 /* try SourceDir after CostFinalize */
6892 size = MAX_PATH;
6893 lstrcpyA(path, "kiwi");
6894 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6896 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6897 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6899 /* try SOURCEDIR after CostFinalize */
6900 size = MAX_PATH;
6901 lstrcpyA(path, "kiwi");
6902 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6903 todo_wine
6905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6906 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6907 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6910 /* source path and the property exist */
6911 size = MAX_PATH;
6912 lstrcpyA(path, "kiwi");
6913 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6915 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6916 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6918 size = MAX_PATH;
6919 lstrcpyA(path, "kiwi");
6920 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6922 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6923 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6925 /* try SubDir after CostFinalize */
6926 size = MAX_PATH;
6927 lstrcpyA(path, "kiwi");
6928 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6930 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6931 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6933 /* try SubDir2 after CostFinalize */
6934 size = MAX_PATH;
6935 lstrcpyA(path, "kiwi");
6936 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6938 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6939 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6941 MsiCloseHandle(hpkg);
6942 DeleteFileA(msifile);
6945 static void test_shortlongsource(void)
6947 MSIHANDLE hdb, hpkg;
6948 CHAR path[MAX_PATH];
6949 CHAR cwd[MAX_PATH];
6950 CHAR subsrc[MAX_PATH];
6951 DWORD size;
6952 UINT r;
6954 lstrcpyA(cwd, CURR_DIR);
6955 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6957 lstrcpyA(subsrc, cwd);
6958 lstrcatA(subsrc, "long");
6959 lstrcatA(subsrc, "\\");
6961 /* long file names */
6963 hdb = create_package_db();
6964 ok( hdb, "failed to create database\n");
6966 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6968 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6969 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6971 /* CostInitialize:short */
6972 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6974 /* CostInitialize:long */
6975 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6977 /* FileCost:short */
6978 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6980 /* FileCost:long */
6981 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6983 /* CostFinalize:short */
6984 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6986 /* CostFinalize:long */
6987 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6989 r = MsiDatabaseCommit(hdb);
6990 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6992 r = package_from_db(hdb, &hpkg);
6993 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6995 skip("Not enough rights to perform tests\n");
6996 DeleteFileA(msifile);
6997 return;
6999 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7001 MsiCloseHandle(hdb);
7003 CreateDirectoryA("one", NULL);
7004 CreateDirectoryA("four", NULL);
7006 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7008 r = MsiDoActionA(hpkg, "CostInitialize");
7009 ok(r == ERROR_SUCCESS, "file cost failed\n");
7011 CreateDirectoryA("five", NULL);
7012 CreateDirectoryA("eight", NULL);
7014 r = MsiDoActionA(hpkg, "FileCost");
7015 ok(r == ERROR_SUCCESS, "file cost failed\n");
7017 CreateDirectoryA("nine", NULL);
7018 CreateDirectoryA("twelve", NULL);
7020 r = MsiDoActionA(hpkg, "CostFinalize");
7021 ok(r == ERROR_SUCCESS, "file cost failed\n");
7023 /* neither short nor long source directories exist */
7024 size = MAX_PATH;
7025 lstrcpyA(path, "kiwi");
7026 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7028 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7029 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7031 CreateDirectoryA("short", NULL);
7033 /* short source directory exists */
7034 size = MAX_PATH;
7035 lstrcpyA(path, "kiwi");
7036 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7038 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7039 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7041 CreateDirectoryA("long", NULL);
7043 /* both short and long source directories exist */
7044 size = MAX_PATH;
7045 lstrcpyA(path, "kiwi");
7046 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7048 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7049 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7051 lstrcpyA(subsrc, cwd);
7052 lstrcatA(subsrc, "two");
7053 lstrcatA(subsrc, "\\");
7055 /* short dir exists before CostInitialize */
7056 size = MAX_PATH;
7057 lstrcpyA(path, "kiwi");
7058 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7060 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7061 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7063 lstrcpyA(subsrc, cwd);
7064 lstrcatA(subsrc, "four");
7065 lstrcatA(subsrc, "\\");
7067 /* long dir exists before CostInitialize */
7068 size = MAX_PATH;
7069 lstrcpyA(path, "kiwi");
7070 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7071 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7072 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7073 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7075 lstrcpyA(subsrc, cwd);
7076 lstrcatA(subsrc, "six");
7077 lstrcatA(subsrc, "\\");
7079 /* short dir exists before FileCost */
7080 size = MAX_PATH;
7081 lstrcpyA(path, "kiwi");
7082 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7084 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7085 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7087 lstrcpyA(subsrc, cwd);
7088 lstrcatA(subsrc, "eight");
7089 lstrcatA(subsrc, "\\");
7091 /* long dir exists before FileCost */
7092 size = MAX_PATH;
7093 lstrcpyA(path, "kiwi");
7094 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7096 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7097 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7099 lstrcpyA(subsrc, cwd);
7100 lstrcatA(subsrc, "ten");
7101 lstrcatA(subsrc, "\\");
7103 /* short dir exists before CostFinalize */
7104 size = MAX_PATH;
7105 lstrcpyA(path, "kiwi");
7106 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7108 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7109 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7111 lstrcpyA(subsrc, cwd);
7112 lstrcatA(subsrc, "twelve");
7113 lstrcatA(subsrc, "\\");
7115 /* long dir exists before CostFinalize */
7116 size = MAX_PATH;
7117 lstrcpyA(path, "kiwi");
7118 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7120 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7121 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7123 MsiCloseHandle(hpkg);
7124 RemoveDirectoryA("short");
7125 RemoveDirectoryA("long");
7126 RemoveDirectoryA("one");
7127 RemoveDirectoryA("four");
7128 RemoveDirectoryA("five");
7129 RemoveDirectoryA("eight");
7130 RemoveDirectoryA("nine");
7131 RemoveDirectoryA("twelve");
7133 /* short file names */
7135 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
7136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7138 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7140 r = package_from_db(hdb, &hpkg);
7141 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7143 MsiCloseHandle(hdb);
7145 CreateDirectoryA("one", NULL);
7146 CreateDirectoryA("four", NULL);
7148 r = MsiDoActionA(hpkg, "CostInitialize");
7149 ok(r == ERROR_SUCCESS, "file cost failed\n");
7151 CreateDirectoryA("five", NULL);
7152 CreateDirectoryA("eight", NULL);
7154 r = MsiDoActionA(hpkg, "FileCost");
7155 ok(r == ERROR_SUCCESS, "file cost failed\n");
7157 CreateDirectoryA("nine", NULL);
7158 CreateDirectoryA("twelve", NULL);
7160 r = MsiDoActionA(hpkg, "CostFinalize");
7161 ok(r == ERROR_SUCCESS, "file cost failed\n");
7163 lstrcpyA(subsrc, cwd);
7164 lstrcatA(subsrc, "short");
7165 lstrcatA(subsrc, "\\");
7167 /* neither short nor long source directories exist */
7168 size = MAX_PATH;
7169 lstrcpyA(path, "kiwi");
7170 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7172 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7173 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7175 CreateDirectoryA("short", NULL);
7177 /* short source directory exists */
7178 size = MAX_PATH;
7179 lstrcpyA(path, "kiwi");
7180 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7182 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7183 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7185 CreateDirectoryA("long", NULL);
7187 /* both short and long source directories exist */
7188 size = MAX_PATH;
7189 lstrcpyA(path, "kiwi");
7190 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7192 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7193 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7195 lstrcpyA(subsrc, cwd);
7196 lstrcatA(subsrc, "one");
7197 lstrcatA(subsrc, "\\");
7199 /* short dir exists before CostInitialize */
7200 size = MAX_PATH;
7201 lstrcpyA(path, "kiwi");
7202 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7204 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7205 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7207 lstrcpyA(subsrc, cwd);
7208 lstrcatA(subsrc, "three");
7209 lstrcatA(subsrc, "\\");
7211 /* long dir exists before CostInitialize */
7212 size = MAX_PATH;
7213 lstrcpyA(path, "kiwi");
7214 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7216 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7217 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7219 lstrcpyA(subsrc, cwd);
7220 lstrcatA(subsrc, "five");
7221 lstrcatA(subsrc, "\\");
7223 /* short dir exists before FileCost */
7224 size = MAX_PATH;
7225 lstrcpyA(path, "kiwi");
7226 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7228 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7229 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7231 lstrcpyA(subsrc, cwd);
7232 lstrcatA(subsrc, "seven");
7233 lstrcatA(subsrc, "\\");
7235 /* long dir exists before FileCost */
7236 size = MAX_PATH;
7237 lstrcpyA(path, "kiwi");
7238 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7240 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7241 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7243 lstrcpyA(subsrc, cwd);
7244 lstrcatA(subsrc, "nine");
7245 lstrcatA(subsrc, "\\");
7247 /* short dir exists before CostFinalize */
7248 size = MAX_PATH;
7249 lstrcpyA(path, "kiwi");
7250 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7252 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7253 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7255 lstrcpyA(subsrc, cwd);
7256 lstrcatA(subsrc, "eleven");
7257 lstrcatA(subsrc, "\\");
7259 /* long dir exists before CostFinalize */
7260 size = MAX_PATH;
7261 lstrcpyA(path, "kiwi");
7262 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7264 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7265 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7267 MsiCloseHandle(hpkg);
7268 RemoveDirectoryA("short");
7269 RemoveDirectoryA("long");
7270 RemoveDirectoryA("one");
7271 RemoveDirectoryA("four");
7272 RemoveDirectoryA("five");
7273 RemoveDirectoryA("eight");
7274 RemoveDirectoryA("nine");
7275 RemoveDirectoryA("twelve");
7276 DeleteFileA(msifile);
7279 static void test_sourcedir(void)
7281 MSIHANDLE hdb, hpkg;
7282 CHAR package[12];
7283 CHAR path[MAX_PATH];
7284 CHAR cwd[MAX_PATH];
7285 CHAR subsrc[MAX_PATH];
7286 DWORD size;
7287 UINT r;
7289 lstrcpyA(cwd, CURR_DIR);
7290 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7292 lstrcpyA(subsrc, cwd);
7293 lstrcatA(subsrc, "long");
7294 lstrcatA(subsrc, "\\");
7296 hdb = create_package_db();
7297 ok( hdb, "failed to create database\n");
7299 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7301 sprintf(package, "#%lu", hdb);
7302 r = MsiOpenPackageA(package, &hpkg);
7303 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7305 skip("Not enough rights to perform tests\n");
7306 goto error;
7308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7310 /* properties only */
7312 /* SourceDir prop */
7313 size = MAX_PATH;
7314 lstrcpyA(path, "kiwi");
7315 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7317 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7318 ok(size == 0, "Expected 0, got %lu\n", size);
7320 /* SOURCEDIR prop */
7321 size = MAX_PATH;
7322 lstrcpyA(path, "kiwi");
7323 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7325 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7326 ok(size == 0, "Expected 0, got %lu\n", size);
7328 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7330 r = MsiDoActionA(hpkg, "CostInitialize");
7331 ok(r == ERROR_SUCCESS, "file cost failed\n");
7333 /* SourceDir after CostInitialize */
7334 size = MAX_PATH;
7335 lstrcpyA(path, "kiwi");
7336 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7338 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7339 ok(size == 0, "Expected 0, got %lu\n", size);
7341 /* SOURCEDIR after CostInitialize */
7342 size = MAX_PATH;
7343 lstrcpyA(path, "kiwi");
7344 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7346 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7347 ok(size == 0, "Expected 0, got %lu\n", size);
7349 r = MsiDoActionA(hpkg, "FileCost");
7350 ok(r == ERROR_SUCCESS, "file cost failed\n");
7352 /* SourceDir after FileCost */
7353 size = MAX_PATH;
7354 lstrcpyA(path, "kiwi");
7355 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7357 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7358 ok(size == 0, "Expected 0, got %lu\n", size);
7360 /* SOURCEDIR after FileCost */
7361 size = MAX_PATH;
7362 lstrcpyA(path, "kiwi");
7363 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7365 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7366 ok(size == 0, "Expected 0, got %lu\n", size);
7368 r = MsiDoActionA(hpkg, "CostFinalize");
7369 ok(r == ERROR_SUCCESS, "file cost failed\n");
7371 /* SourceDir after CostFinalize */
7372 size = MAX_PATH;
7373 lstrcpyA(path, "kiwi");
7374 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7376 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7377 ok(size == 0, "Expected 0, got %lu\n", size);
7379 /* SOURCEDIR after CostFinalize */
7380 size = MAX_PATH;
7381 lstrcpyA(path, "kiwi");
7382 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7384 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7385 ok(size == 0, "Expected 0, got %lu\n", size);
7387 size = MAX_PATH;
7388 lstrcpyA(path, "kiwi");
7389 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7390 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7391 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7392 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
7394 /* SOURCEDIR after calling MsiGetSourcePath */
7395 size = MAX_PATH;
7396 lstrcpyA(path, "kiwi");
7397 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7399 todo_wine {
7400 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7401 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7404 r = MsiDoActionA(hpkg, "ResolveSource");
7405 ok(r == ERROR_SUCCESS, "file cost failed\n");
7407 /* SourceDir after ResolveSource */
7408 size = MAX_PATH;
7409 lstrcpyA(path, "kiwi");
7410 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7412 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7413 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7415 /* SOURCEDIR after ResolveSource */
7416 size = MAX_PATH;
7417 lstrcpyA(path, "kiwi");
7418 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7420 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7421 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7423 /* random casing */
7424 size = MAX_PATH;
7425 lstrcpyA(path, "kiwi");
7426 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7428 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7429 ok(size == 0, "Expected 0, got %lu\n", size);
7431 MsiCloseHandle(hpkg);
7433 /* reset the package state */
7434 sprintf(package, "#%lu", hdb);
7435 r = MsiOpenPackageA(package, &hpkg);
7436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7438 /* test how MsiGetSourcePath affects the properties */
7440 /* SourceDir prop */
7441 size = MAX_PATH;
7442 lstrcpyA(path, "kiwi");
7443 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7444 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7445 todo_wine
7447 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7448 ok(size == 0, "Expected 0, got %lu\n", size);
7451 size = MAX_PATH;
7452 lstrcpyA(path, "kiwi");
7453 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7454 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7455 ok(!lstrcmpA(path, "kiwi"),
7456 "Expected path to be unchanged, got \"%s\"\n", path);
7457 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7459 /* SourceDir after MsiGetSourcePath */
7460 size = MAX_PATH;
7461 lstrcpyA(path, "kiwi");
7462 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7464 todo_wine
7466 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7467 ok(size == 0, "Expected 0, got %lu\n", size);
7470 /* SOURCEDIR prop */
7471 size = MAX_PATH;
7472 lstrcpyA(path, "kiwi");
7473 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7475 todo_wine
7477 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7478 ok(size == 0, "Expected 0, got %lu\n", size);
7481 size = MAX_PATH;
7482 lstrcpyA(path, "kiwi");
7483 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7484 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7485 ok(!lstrcmpA(path, "kiwi"),
7486 "Expected path to be unchanged, got \"%s\"\n", path);
7487 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7489 /* SOURCEDIR prop after MsiGetSourcePath */
7490 size = MAX_PATH;
7491 lstrcpyA(path, "kiwi");
7492 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7494 todo_wine
7496 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7497 ok(size == 0, "Expected 0, got %lu\n", size);
7500 r = MsiDoActionA(hpkg, "CostInitialize");
7501 ok(r == ERROR_SUCCESS, "file cost failed\n");
7503 /* SourceDir after CostInitialize */
7504 size = MAX_PATH;
7505 lstrcpyA(path, "kiwi");
7506 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7508 todo_wine
7510 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7511 ok(size == 0, "Expected 0, got %lu\n", size);
7514 size = MAX_PATH;
7515 lstrcpyA(path, "kiwi");
7516 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7518 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7519 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7521 /* SourceDir after MsiGetSourcePath */
7522 size = MAX_PATH;
7523 lstrcpyA(path, "kiwi");
7524 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7526 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7527 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7529 /* SOURCEDIR after CostInitialize */
7530 size = MAX_PATH;
7531 lstrcpyA(path, "kiwi");
7532 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7534 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7535 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7537 /* SOURCEDIR source path still does not exist */
7538 size = MAX_PATH;
7539 lstrcpyA(path, "kiwi");
7540 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7541 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7542 ok(!lstrcmpA(path, "kiwi"),
7543 "Expected path to be unchanged, got \"%s\"\n", path);
7544 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7546 r = MsiDoActionA(hpkg, "FileCost");
7547 ok(r == ERROR_SUCCESS, "file cost failed\n");
7549 /* SourceDir after FileCost */
7550 size = MAX_PATH;
7551 lstrcpyA(path, "kiwi");
7552 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7554 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7555 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7557 /* SOURCEDIR after FileCost */
7558 size = MAX_PATH;
7559 lstrcpyA(path, "kiwi");
7560 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7562 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7563 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7565 /* SOURCEDIR source path still does not exist */
7566 size = MAX_PATH;
7567 lstrcpyA(path, "kiwi");
7568 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7569 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7570 ok(!lstrcmpA(path, "kiwi"),
7571 "Expected path to be unchanged, got \"%s\"\n", path);
7572 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7574 r = MsiDoActionA(hpkg, "CostFinalize");
7575 ok(r == ERROR_SUCCESS, "file cost failed\n");
7577 /* SourceDir after CostFinalize */
7578 size = MAX_PATH;
7579 lstrcpyA(path, "kiwi");
7580 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7582 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7583 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7585 /* SOURCEDIR after CostFinalize */
7586 size = MAX_PATH;
7587 lstrcpyA(path, "kiwi");
7588 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7590 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7591 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7593 /* SOURCEDIR source path still does not exist */
7594 size = MAX_PATH;
7595 lstrcpyA(path, "kiwi");
7596 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7597 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7598 ok(!lstrcmpA(path, "kiwi"),
7599 "Expected path to be unchanged, got \"%s\"\n", path);
7600 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7602 r = MsiDoActionA(hpkg, "ResolveSource");
7603 ok(r == ERROR_SUCCESS, "file cost failed\n");
7605 /* SourceDir after ResolveSource */
7606 size = MAX_PATH;
7607 lstrcpyA(path, "kiwi");
7608 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7610 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7611 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7613 /* SOURCEDIR after ResolveSource */
7614 size = MAX_PATH;
7615 lstrcpyA(path, "kiwi");
7616 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7618 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7619 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7621 /* SOURCEDIR source path still does not exist */
7622 size = MAX_PATH;
7623 lstrcpyA(path, "kiwi");
7624 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7625 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7626 ok(!lstrcmpA(path, "kiwi"),
7627 "Expected path to be unchanged, got \"%s\"\n", path);
7628 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7630 MsiCloseHandle(hpkg);
7632 error:
7633 MsiCloseHandle(hdb);
7634 DeleteFileA(msifile);
7637 struct access_res
7639 BOOL gothandle;
7640 DWORD lasterr;
7641 BOOL ignore;
7644 static const struct access_res create[16] =
7646 { TRUE, ERROR_SUCCESS, TRUE },
7647 { TRUE, ERROR_SUCCESS, TRUE },
7648 { TRUE, ERROR_SUCCESS, FALSE },
7649 { TRUE, ERROR_SUCCESS, FALSE },
7650 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7651 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7652 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7653 { TRUE, ERROR_SUCCESS, FALSE },
7654 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7655 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7656 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7657 { TRUE, ERROR_SUCCESS, TRUE },
7658 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7659 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7660 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7661 { TRUE, ERROR_SUCCESS, TRUE }
7664 static const struct access_res create_commit[16] =
7666 { TRUE, ERROR_SUCCESS, TRUE },
7667 { TRUE, ERROR_SUCCESS, TRUE },
7668 { TRUE, ERROR_SUCCESS, FALSE },
7669 { TRUE, ERROR_SUCCESS, FALSE },
7670 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7671 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7672 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7673 { TRUE, ERROR_SUCCESS, FALSE },
7674 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7675 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7676 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7677 { TRUE, ERROR_SUCCESS, TRUE },
7678 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7679 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7680 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7681 { TRUE, ERROR_SUCCESS, TRUE }
7684 static const struct access_res create_close[16] =
7686 { TRUE, ERROR_SUCCESS, FALSE },
7687 { TRUE, ERROR_SUCCESS, FALSE },
7688 { TRUE, ERROR_SUCCESS, FALSE },
7689 { TRUE, ERROR_SUCCESS, FALSE },
7690 { TRUE, ERROR_SUCCESS, FALSE },
7691 { TRUE, ERROR_SUCCESS, FALSE },
7692 { TRUE, ERROR_SUCCESS, FALSE },
7693 { TRUE, ERROR_SUCCESS, FALSE },
7694 { TRUE, ERROR_SUCCESS, FALSE },
7695 { TRUE, ERROR_SUCCESS, FALSE },
7696 { TRUE, ERROR_SUCCESS, FALSE },
7697 { TRUE, ERROR_SUCCESS, FALSE },
7698 { TRUE, ERROR_SUCCESS, FALSE },
7699 { TRUE, ERROR_SUCCESS, FALSE },
7700 { TRUE, ERROR_SUCCESS, FALSE },
7701 { TRUE, ERROR_SUCCESS }
7704 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7706 DWORD access = 0, share = 0;
7707 DWORD lasterr;
7708 HANDLE hfile;
7709 int i, j, idx = 0;
7711 for (i = 0; i < 4; i++)
7713 if (i == 0) access = 0;
7714 if (i == 1) access = GENERIC_READ;
7715 if (i == 2) access = GENERIC_WRITE;
7716 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7718 for (j = 0; j < 4; j++)
7720 if (ares[idx].ignore)
7721 continue;
7723 if (j == 0) share = 0;
7724 if (j == 1) share = FILE_SHARE_READ;
7725 if (j == 2) share = FILE_SHARE_WRITE;
7726 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7728 SetLastError(0xdeadbeef);
7729 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7730 FILE_ATTRIBUTE_NORMAL, 0);
7731 lasterr = GetLastError();
7733 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7734 "(%lu, handle, %d): Expected %d, got %d\n",
7735 line, idx, ares[idx].gothandle,
7736 (hfile != INVALID_HANDLE_VALUE));
7738 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n",
7739 line, idx, ares[idx].lasterr, lasterr);
7741 CloseHandle(hfile);
7742 idx++;
7747 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7749 static void test_access(void)
7751 MSIHANDLE hdb;
7752 UINT r;
7754 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7757 test_file_access(msifile, create);
7759 r = MsiDatabaseCommit(hdb);
7760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7762 test_file_access(msifile, create_commit);
7763 MsiCloseHandle(hdb);
7765 test_file_access(msifile, create_close);
7766 DeleteFileA(msifile);
7768 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7771 test_file_access(msifile, create);
7773 r = MsiDatabaseCommit(hdb);
7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7776 test_file_access(msifile, create_commit);
7777 MsiCloseHandle(hdb);
7779 test_file_access(msifile, create_close);
7780 DeleteFileA(msifile);
7783 static void test_emptypackage(void)
7785 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7786 MSIHANDLE hview = 0, hrec = 0;
7787 MSICONDITION condition;
7788 CHAR buffer[MAX_PATH];
7789 DWORD size;
7790 UINT r;
7792 r = MsiOpenPackageA("", &hpkg);
7793 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7795 skip("Not enough rights to perform tests\n");
7796 return;
7798 todo_wine
7800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7803 hdb = MsiGetActiveDatabase(hpkg);
7804 todo_wine
7806 ok(hdb != 0, "Expected a valid database handle\n");
7809 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7810 todo_wine
7812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7814 r = MsiViewExecute(hview, 0);
7815 todo_wine
7817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820 r = MsiViewFetch(hview, &hrec);
7821 todo_wine
7823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7826 buffer[0] = 0;
7827 size = MAX_PATH;
7828 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7829 todo_wine
7831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7832 ok(!lstrcmpA(buffer, "_Property"),
7833 "Expected \"_Property\", got \"%s\"\n", buffer);
7836 MsiCloseHandle(hrec);
7838 r = MsiViewFetch(hview, &hrec);
7839 todo_wine
7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7844 size = MAX_PATH;
7845 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7846 todo_wine
7848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7849 ok(!lstrcmpA(buffer, "#_FolderCache"),
7850 "Expected \"_Property\", got \"%s\"\n", buffer);
7853 MsiCloseHandle(hrec);
7854 MsiViewClose(hview);
7855 MsiCloseHandle(hview);
7857 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7858 todo_wine
7860 ok(condition == MSICONDITION_FALSE,
7861 "Expected MSICONDITION_FALSE, got %d\n", condition);
7864 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7865 todo_wine
7867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7869 r = MsiViewExecute(hview, 0);
7870 todo_wine
7872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7875 /* _Property table is not empty */
7876 r = MsiViewFetch(hview, &hrec);
7877 todo_wine
7879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7882 MsiCloseHandle(hrec);
7883 MsiViewClose(hview);
7884 MsiCloseHandle(hview);
7886 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7887 todo_wine
7889 ok(condition == MSICONDITION_FALSE,
7890 "Expected MSICONDITION_FALSE, got %d\n", condition);
7893 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7894 todo_wine
7896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7898 r = MsiViewExecute(hview, 0);
7899 todo_wine
7901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7904 /* #_FolderCache is not empty */
7905 r = MsiViewFetch(hview, &hrec);
7906 todo_wine
7908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7911 MsiCloseHandle(hrec);
7912 MsiViewClose(hview);
7913 MsiCloseHandle(hview);
7915 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7916 todo_wine
7918 ok(r == ERROR_BAD_QUERY_SYNTAX,
7919 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7922 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7923 todo_wine
7925 ok(r == ERROR_BAD_QUERY_SYNTAX,
7926 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7929 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7930 todo_wine
7932 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
7933 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7936 MsiCloseHandle(hsuminfo);
7938 r = MsiDatabaseCommit(hdb);
7939 todo_wine
7941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7944 MsiCloseHandle(hdb);
7945 MsiCloseHandle(hpkg);
7948 static void test_MsiGetProductProperty(void)
7950 WCHAR valW[MAX_PATH];
7951 MSIHANDLE hprod, hdb;
7952 CHAR val[MAX_PATH];
7953 CHAR path[MAX_PATH];
7954 CHAR query[MAX_PATH + 17];
7955 CHAR keypath[MAX_PATH*2];
7956 CHAR prodcode[MAX_PATH];
7957 WCHAR prodcodeW[MAX_PATH];
7958 CHAR prod_squashed[MAX_PATH];
7959 WCHAR prod_squashedW[MAX_PATH];
7960 HKEY prodkey, userkey, props;
7961 DWORD size;
7962 LONG res;
7963 UINT r;
7964 REGSAM access = KEY_ALL_ACCESS;
7966 GetCurrentDirectoryA(MAX_PATH, path);
7967 lstrcatA(path, "\\");
7969 create_test_guid(prodcode, prod_squashed);
7970 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7971 squash_guid(prodcodeW, prod_squashedW);
7973 if (is_wow64)
7974 access |= KEY_WOW64_64KEY;
7976 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7979 r = MsiDatabaseCommit(hdb);
7980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7982 r = set_summary_info(hdb);
7983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7985 r = run_query(hdb,
7986 "CREATE TABLE `Directory` ( "
7987 "`Directory` CHAR(255) NOT NULL, "
7988 "`Directory_Parent` CHAR(255), "
7989 "`DefaultDir` CHAR(255) NOT NULL "
7990 "PRIMARY KEY `Directory`)");
7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7993 create_property_table(hdb);
7995 sprintf(query, "'ProductCode', '%s'", prodcode);
7996 r = add_property_entry(hdb, query);
7998 r = MsiDatabaseCommit(hdb);
7999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8001 MsiCloseHandle(hdb);
8003 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8004 lstrcatA(keypath, prod_squashed);
8006 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8007 if (res == ERROR_ACCESS_DENIED)
8009 skip("Not enough rights to perform tests\n");
8010 DeleteFileA(msifile);
8011 return;
8013 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8015 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8016 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8017 lstrcatA(keypath, prod_squashed);
8019 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8020 if (res == ERROR_ACCESS_DENIED)
8022 skip("Not enough rights to perform tests\n");
8023 RegDeleteKeyA(prodkey, "");
8024 RegCloseKey(prodkey);
8025 return;
8027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8029 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8032 lstrcpyA(val, path);
8033 lstrcatA(val, "\\");
8034 lstrcatA(val, msifile);
8035 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8036 (const BYTE *)val, lstrlenA(val) + 1);
8037 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8039 hprod = 0xdeadbeef;
8040 r = MsiOpenProductA(prodcode, &hprod);
8041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8042 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8044 /* hProduct is invalid */
8045 size = MAX_PATH;
8046 lstrcpyA(val, "apple");
8047 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
8048 ok(r == ERROR_INVALID_HANDLE,
8049 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8050 ok(!lstrcmpA(val, "apple"),
8051 "Expected val to be unchanged, got \"%s\"\n", val);
8052 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8054 size = MAX_PATH;
8055 lstrcpyW(valW, L"apple");
8056 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
8057 ok(r == ERROR_INVALID_HANDLE,
8058 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8059 ok(!lstrcmpW(valW, L"apple"),
8060 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8061 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8063 /* szProperty is NULL */
8064 size = MAX_PATH;
8065 lstrcpyA(val, "apple");
8066 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
8067 ok(r == ERROR_INVALID_PARAMETER,
8068 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8069 ok(!lstrcmpA(val, "apple"),
8070 "Expected val to be unchanged, got \"%s\"\n", val);
8071 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8073 size = MAX_PATH;
8074 lstrcpyW(valW, L"apple");
8075 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
8076 ok(r == ERROR_INVALID_PARAMETER,
8077 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8078 ok(!lstrcmpW(valW, L"apple"),
8079 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8080 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8082 /* szProperty is empty */
8083 size = MAX_PATH;
8084 lstrcpyA(val, "apple");
8085 r = MsiGetProductPropertyA(hprod, "", val, &size);
8086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8087 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8088 ok(size == 0, "Expected 0, got %lu\n", size);
8090 size = MAX_PATH;
8091 lstrcpyW(valW, L"apple");
8092 r = MsiGetProductPropertyW(hprod, L"", valW, &size);
8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8095 ok(size == 0, "Expected 0, got %lu\n", size);
8097 /* get the property */
8098 size = MAX_PATH;
8099 lstrcpyA(val, "apple");
8100 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8102 ok(!lstrcmpA(val, prodcode),
8103 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8104 ok(size == lstrlenA(prodcode),
8105 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8107 size = MAX_PATH;
8108 lstrcpyW(valW, L"apple");
8109 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8111 ok(!lstrcmpW(valW, prodcodeW),
8112 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8113 ok(size == lstrlenW(prodcodeW),
8114 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8116 /* lpValueBuf is NULL */
8117 size = MAX_PATH;
8118 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8120 ok(size == lstrlenA(prodcode),
8121 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8123 size = MAX_PATH;
8124 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
8125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8126 ok(size == lstrlenW(prodcodeW),
8127 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8129 /* pcchValueBuf is NULL */
8130 lstrcpyA(val, "apple");
8131 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8132 ok(r == ERROR_INVALID_PARAMETER,
8133 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8134 ok(!lstrcmpA(val, "apple"),
8135 "Expected val to be unchanged, got \"%s\"\n", val);
8136 ok(size == lstrlenA(prodcode),
8137 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8139 lstrcpyW(valW, L"apple");
8140 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8141 ok(r == ERROR_INVALID_PARAMETER,
8142 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8143 ok(!lstrcmpW(valW, L"apple"),
8144 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8145 ok(size == lstrlenW(prodcodeW),
8146 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8148 /* pcchValueBuf is too small */
8149 size = 4;
8150 lstrcpyA(val, "apple");
8151 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8152 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8153 ok(!strncmp(val, prodcode, 3),
8154 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8155 ok(size == lstrlenA(prodcode),
8156 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8158 size = 4;
8159 lstrcpyW(valW, L"apple");
8160 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8161 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8162 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8163 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8164 ok(size == lstrlenW(prodcodeW),
8165 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8167 /* pcchValueBuf does not leave room for NULL terminator */
8168 size = lstrlenA(prodcode);
8169 lstrcpyA(val, "apple");
8170 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8171 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8172 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8173 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8174 ok(size == lstrlenA(prodcode),
8175 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8177 size = lstrlenW(prodcodeW);
8178 lstrcpyW(valW, L"apple");
8179 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8180 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8181 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8182 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8183 ok(size == lstrlenW(prodcodeW),
8184 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8186 /* pcchValueBuf has enough room for NULL terminator */
8187 size = lstrlenA(prodcode) + 1;
8188 lstrcpyA(val, "apple");
8189 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8191 ok(!lstrcmpA(val, prodcode),
8192 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8193 ok(size == lstrlenA(prodcode),
8194 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8196 size = lstrlenW(prodcodeW) + 1;
8197 lstrcpyW(valW, L"apple");
8198 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8200 ok(!lstrcmpW(valW, prodcodeW),
8201 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8202 ok(size == lstrlenW(prodcodeW),
8203 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8205 /* nonexistent property */
8206 size = MAX_PATH;
8207 lstrcpyA(val, "apple");
8208 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8210 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8211 ok(size == 0, "Expected 0, got %lu\n", size);
8213 size = MAX_PATH;
8214 lstrcpyW(valW, L"apple");
8215 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8217 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8218 ok(size == 0, "Expected 0, got %lu\n", size);
8220 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8223 /* non-product property set */
8224 size = MAX_PATH;
8225 lstrcpyA(val, "apple");
8226 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8228 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8229 ok(size == 0, "Expected 0, got %lu\n", size);
8231 size = MAX_PATH;
8232 lstrcpyW(valW, L"apple");
8233 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8235 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8236 ok(size == 0, "Expected 0, got %lu\n", size);
8238 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8241 /* non-product property that is also a product property set */
8242 size = MAX_PATH;
8243 lstrcpyA(val, "apple");
8244 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8246 ok(!lstrcmpA(val, prodcode),
8247 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8248 ok(size == lstrlenA(prodcode),
8249 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8251 size = MAX_PATH;
8252 lstrcpyW(valW, L"apple");
8253 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8255 ok(!lstrcmpW(valW, prodcodeW),
8256 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8257 ok(size == lstrlenW(prodcodeW),
8258 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8260 MsiCloseHandle(hprod);
8262 RegDeleteValueA(props, "LocalPackage");
8263 delete_key(props, "", access);
8264 RegCloseKey(props);
8265 delete_key(userkey, "", access);
8266 RegCloseKey(userkey);
8267 delete_key(prodkey, "", access);
8268 RegCloseKey(prodkey);
8269 DeleteFileA(msifile);
8272 static void test_MsiSetProperty(void)
8274 MSIHANDLE hpkg, hdb, hrec;
8275 CHAR buf[MAX_PATH];
8276 LPCSTR query;
8277 DWORD size;
8278 UINT r;
8280 r = package_from_db(create_package_db(), &hpkg);
8281 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8283 skip("Not enough rights to perform tests\n");
8284 DeleteFileA(msifile);
8285 return;
8287 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8289 /* invalid hInstall */
8290 r = MsiSetPropertyA(0, "Prop", "Val");
8291 ok(r == ERROR_INVALID_HANDLE,
8292 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8294 /* invalid hInstall */
8295 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8296 ok(r == ERROR_INVALID_HANDLE,
8297 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8299 /* szName is NULL */
8300 r = MsiSetPropertyA(hpkg, NULL, "Val");
8301 ok(r == ERROR_INVALID_PARAMETER,
8302 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8304 /* both szName and szValue are NULL */
8305 r = MsiSetPropertyA(hpkg, NULL, NULL);
8306 ok(r == ERROR_INVALID_PARAMETER,
8307 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8309 /* szName is empty */
8310 r = MsiSetPropertyA(hpkg, "", "Val");
8311 ok(r == ERROR_FUNCTION_FAILED,
8312 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8314 /* szName is empty and szValue is NULL */
8315 r = MsiSetPropertyA(hpkg, "", NULL);
8316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8318 /* set a property */
8319 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8322 /* get the property */
8323 size = MAX_PATH;
8324 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8326 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8327 ok(size == 3, "Expected 3, got %lu\n", size);
8329 /* update the property */
8330 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8333 /* get the property */
8334 size = MAX_PATH;
8335 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8337 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8338 ok(size == 4, "Expected 4, got %lu\n", size);
8340 hdb = MsiGetActiveDatabase(hpkg);
8341 ok(hdb != 0, "Expected a valid database handle\n");
8343 /* set prop is not in the _Property table */
8344 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8345 r = do_query(hdb, query, &hrec);
8346 ok(r == ERROR_BAD_QUERY_SYNTAX,
8347 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8349 /* set prop is not in the Property table */
8350 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8351 r = do_query(hdb, query, &hrec);
8352 ok(r == ERROR_BAD_QUERY_SYNTAX,
8353 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8355 MsiCloseHandle(hdb);
8357 /* szValue is an empty string */
8358 r = MsiSetPropertyA(hpkg, "Prop", "");
8359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8361 /* try to get the property */
8362 size = MAX_PATH;
8363 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8365 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8366 ok(size == 0, "Expected 0, got %lu\n", size);
8368 /* reset the property */
8369 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8372 /* delete the property */
8373 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8376 /* try to get the property */
8377 size = MAX_PATH;
8378 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8380 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8381 ok(size == 0, "Expected 0, got %lu\n", size);
8383 MsiCloseHandle(hpkg);
8384 DeleteFileA(msifile);
8387 static void test_MsiApplyMultiplePatches(void)
8389 UINT r, type = GetDriveTypeW(NULL);
8391 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
8392 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8394 r = MsiApplyMultiplePatchesA("", NULL, NULL);
8395 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8397 r = MsiApplyMultiplePatchesA(";", NULL, NULL);
8398 if (type == DRIVE_FIXED)
8399 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8400 else
8401 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8403 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL);
8404 if (type == DRIVE_FIXED)
8405 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8406 else
8407 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8409 r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
8410 if (type == DRIVE_FIXED)
8411 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8412 else
8413 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8415 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8416 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8418 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8419 if (type == DRIVE_FIXED)
8420 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8421 else
8422 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8424 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8425 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8427 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8428 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8431 static void test_MsiApplyPatch(void)
8433 UINT r;
8435 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8436 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8438 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL);
8439 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8442 static void test_costs(void)
8444 MSIHANDLE hdb, hpkg;
8445 char package[12], drive[3];
8446 DWORD len;
8447 UINT r;
8448 int cost, temp;
8450 hdb = create_package_db();
8451 ok( hdb, "failed to create database\n" );
8453 create_property_table( hdb );
8454 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8455 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8456 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8458 create_media_table( hdb );
8459 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8461 create_file_table( hdb );
8462 add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8464 create_component_table( hdb );
8465 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8466 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8468 create_feature_table( hdb );
8469 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8470 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8472 create_feature_components_table( hdb );
8473 add_feature_components_entry( hdb, "'one', 'one'" );
8474 add_feature_components_entry( hdb, "'two', 'two'" );
8476 create_install_execute_sequence_table( hdb );
8477 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8478 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8479 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8480 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8482 r = MsiDatabaseCommit( hdb );
8483 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8485 sprintf( package, "#%lu", hdb );
8486 r = MsiOpenPackageA( package, &hpkg );
8487 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8489 skip("Not enough rights to perform tests\n");
8490 goto error;
8492 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8494 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8495 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8497 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8498 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8500 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8501 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8503 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8504 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8506 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8507 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8509 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8510 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8512 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8513 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8515 len = sizeof(drive);
8516 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8517 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8519 len = sizeof(drive);
8520 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8521 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8523 len = sizeof(drive);
8524 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8525 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8527 len = sizeof(drive);
8528 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8529 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8531 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
8533 r = MsiDoActionA( hpkg, "CostInitialize" );
8534 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8536 r = MsiDoActionA( hpkg, "FileCost" );
8537 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8539 len = sizeof(drive);
8540 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8541 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8543 r = MsiDoActionA( hpkg, "CostFinalize" );
8544 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8546 /* contrary to what msdn says InstallValidate must be called too */
8547 len = sizeof(drive);
8548 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8549 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8551 r = MsiDoActionA( hpkg, "InstallValidate" );
8552 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8554 len = 0;
8555 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8556 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8558 len = 0;
8559 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8560 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8561 ok( len == 2, "expected len == 2, got %lu\n", len );
8563 len = 2;
8564 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8565 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8566 ok( len == 2, "expected len == 2, got %lu\n", len );
8568 len = 2;
8569 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8570 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8571 ok( len == 2, "expected len == 2, got %lu\n", len );
8573 /* install state doesn't seem to matter */
8574 len = sizeof(drive);
8575 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8576 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8578 len = sizeof(drive);
8579 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8580 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8582 len = sizeof(drive);
8583 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8584 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8586 len = sizeof(drive);
8587 drive[0] = 0;
8588 cost = temp = 0xdead;
8589 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8590 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8591 ok( len == 2, "expected len == 2, got %lu\n", len );
8592 ok( drive[0], "expected a drive\n" );
8593 ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
8594 ok( !temp, "expected temp == 0, got %d\n", temp );
8596 len = sizeof(drive);
8597 drive[0] = 0;
8598 cost = temp = 0xdead;
8599 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8600 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8601 ok( len == 2, "expected len == 2, got %lu\n", len );
8602 ok( drive[0], "expected a drive\n" );
8603 ok( !cost, "expected cost == 0, got %d\n", cost );
8604 ok( !temp, "expected temp == 0, got %d\n", temp );
8606 len = sizeof(drive);
8607 drive[0] = 0;
8608 cost = temp = 0xdead;
8609 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8610 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8611 ok( len == 2, "expected len == 2, got %lu\n", len );
8612 ok( drive[0], "expected a drive\n" );
8613 ok( !cost, "expected cost == 0, got %d\n", cost );
8614 ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8616 /* increased index */
8617 len = sizeof(drive);
8618 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8619 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8621 len = sizeof(drive);
8622 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8623 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8625 /* test MsiGetFeatureCost */
8626 cost = 0xdead;
8627 r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8628 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8629 ok( cost == 0xdead, "got %d\n", cost );
8631 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL );
8632 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8634 cost = 0xdead;
8635 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8636 ok( !r, "got %u\n", r);
8637 ok( cost == 8, "got %d\n", cost );
8639 MsiCloseHandle( hpkg );
8640 error:
8641 MsiCloseHandle( hdb );
8642 DeleteFileA( msifile );
8645 static void test_MsiDatabaseCommit(void)
8647 UINT r;
8648 MSIHANDLE hdb, hpkg = 0;
8649 char buf[32], package[12];
8650 DWORD sz;
8652 hdb = create_package_db();
8653 ok( hdb, "failed to create database\n" );
8655 create_property_table( hdb );
8657 sprintf( package, "#%lu", hdb );
8658 r = MsiOpenPackageA( package, &hpkg );
8659 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8661 skip("Not enough rights to perform tests\n");
8662 goto error;
8664 ok( r == ERROR_SUCCESS, "got %u\n", r );
8666 r = MsiSetPropertyA( hpkg, "PROP", "value" );
8667 ok( r == ERROR_SUCCESS, "got %u\n", r );
8669 buf[0] = 0;
8670 sz = sizeof(buf);
8671 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8672 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8673 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8675 r = MsiDatabaseCommit( hdb );
8676 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8678 buf[0] = 0;
8679 sz = sizeof(buf);
8680 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8681 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8682 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8684 MsiCloseHandle( hpkg );
8685 error:
8686 MsiCloseHandle( hdb );
8687 DeleteFileA( msifile );
8690 static int externalui_ran;
8692 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
8694 externalui_ran = 1;
8695 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8696 return 0;
8699 static int externalui_record_ran;
8701 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
8703 INT retval = context ? *((INT *)context) : 0;
8704 UINT r;
8705 externalui_record_ran = 1;
8706 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8707 r = MsiRecordGetFieldCount(hrecord);
8708 ok(r == 1, "expected 1, got %u\n", r);
8709 r = MsiRecordGetInteger(hrecord, 1);
8710 ok(r == 12345, "expected 12345, got %u\n", r);
8711 return retval;
8714 static void test_externalui(void)
8716 /* test that external UI handlers work correctly */
8718 INSTALLUI_HANDLERA prev;
8719 INSTALLUI_HANDLER_RECORD prev_record;
8720 MSIHANDLE hpkg, hrecord;
8721 UINT r;
8722 INT retval = 0;
8724 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8726 r = package_from_db(create_package_db(), &hpkg);
8727 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8729 skip("Not enough rights to perform tests\n");
8730 DeleteFileA(msifile);
8731 return;
8733 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8735 hrecord = MsiCreateRecord(1);
8736 ok(hrecord, "Expected a valid record\n");
8737 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
8738 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
8739 r = MsiRecordSetInteger(hrecord, 1, 12345);
8740 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
8742 externalui_ran = 0;
8743 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8744 ok(r == 0, "expected 0, got %u\n", r);
8745 ok(externalui_ran == 1, "external UI callback did not run\n");
8747 prev = MsiSetExternalUIA(prev, 0, NULL);
8748 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
8749 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record);
8750 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8752 externalui_ran = externalui_record_ran = 0;
8753 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8754 ok(r == 0, "expected 0, got %u\n", r);
8755 ok(externalui_ran == 0, "external UI callback should not have run\n");
8756 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8758 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8760 externalui_ran = externalui_record_ran = 0;
8761 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8762 ok(r == 0, "expected 0, got %u\n", r);
8763 ok(externalui_ran == 1, "external UI callback did not run\n");
8764 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8766 retval = 1;
8767 externalui_ran = externalui_record_ran = 0;
8768 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8769 ok(r == 1, "expected 1, got %u\n", r);
8770 ok(externalui_ran == 0, "external UI callback should not have run\n");
8771 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8773 /* filter and context should be kept separately */
8774 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record);
8775 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8777 externalui_ran = externalui_record_ran = 0;
8778 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8779 ok(r == 0, "expected 0, got %u\n", r);
8780 ok(externalui_ran == 1, "external UI callback did not run\n");
8781 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
8783 MsiCloseHandle(hpkg);
8784 DeleteFileA(msifile);
8787 struct externalui_message {
8788 UINT message;
8789 int field_count;
8790 char field[4][100];
8791 int match[4]; /* should we test for a match */
8792 int optional;
8795 static struct externalui_message *sequence;
8796 static int sequence_count, sequence_size;
8798 static void add_message(const struct externalui_message *msg)
8800 if (!sequence)
8802 sequence_size = 10;
8803 sequence = malloc(sequence_size * sizeof(*sequence));
8805 if (sequence_count == sequence_size)
8807 sequence_size *= 2;
8808 sequence = realloc(sequence, sequence_size * sizeof(*sequence));
8811 assert(sequence);
8812 sequence[sequence_count++] = *msg;
8815 static void flush_sequence(void)
8817 free(sequence);
8818 sequence = NULL;
8819 sequence_count = sequence_size = 0;
8822 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
8823 const char *file, int line)
8825 static const struct externalui_message end_of_sequence = {0};
8826 const struct externalui_message *actual;
8827 int failcount = 0;
8828 int i;
8830 add_message(&end_of_sequence);
8832 actual = sequence;
8834 while (expected->message && actual->message)
8836 if (expected->message == actual->message)
8838 if (expected->field_count < actual->field_count)
8840 todo_wine_if (todo)
8841 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
8842 context, expected->message, expected->field_count, actual->field_count);
8843 failcount++;
8846 for (i = 0; i <= actual->field_count; i++)
8848 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
8850 todo_wine_if (todo)
8851 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8852 context, expected->message, i, expected->field[i], actual->field[i]);
8853 failcount++;
8857 expected++;
8858 actual++;
8860 else if (expected->optional)
8862 expected++;
8864 else
8866 todo_wine_if (todo)
8867 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8868 context, expected->message, actual->message);
8869 failcount++;
8870 if (todo)
8871 goto done;
8872 expected++;
8873 actual++;
8877 if (expected->message || actual->message)
8879 todo_wine_if (todo)
8880 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8881 context, expected->message, actual->message);
8882 failcount++;
8885 if(todo && !failcount) /* succeeded yet marked todo */
8887 todo_wine
8888 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
8891 done:
8892 flush_sequence();
8895 #define ok_sequence(exp, contx, todo) \
8896 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8898 /* don't use PROGRESS, which is timing-dependent,
8899 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8900 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE =
8901 INSTALLLOGMODE_FATALEXIT |
8902 INSTALLLOGMODE_ERROR |
8903 INSTALLLOGMODE_WARNING |
8904 INSTALLLOGMODE_USER |
8905 INSTALLLOGMODE_INFO |
8906 INSTALLLOGMODE_FILESINUSE |
8907 INSTALLLOGMODE_RESOLVESOURCE |
8908 INSTALLLOGMODE_OUTOFDISKSPACE |
8909 INSTALLLOGMODE_ACTIONSTART |
8910 INSTALLLOGMODE_ACTIONDATA |
8911 INSTALLLOGMODE_COMMONDATA |
8912 INSTALLLOGMODE_INITIALIZE |
8913 INSTALLLOGMODE_TERMINATE |
8914 INSTALLLOGMODE_RMFILESINUSE |
8915 INSTALLLOGMODE_INSTALLSTART |
8916 INSTALLLOGMODE_INSTALLEND;
8918 static const struct externalui_message empty_sequence[] = {
8922 static const struct externalui_message openpackage_nonexistent_sequence[] = {
8923 {INSTALLMESSAGE_INITIALIZE, -1},
8924 {INSTALLMESSAGE_TERMINATE, -1},
8928 static const struct externalui_message openpackage_sequence[] = {
8929 {INSTALLMESSAGE_INITIALIZE, -1},
8930 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8931 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
8932 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8933 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8937 static const struct externalui_message processmessage_info_sequence[] = {
8938 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8942 static const struct externalui_message processmessage_actionstart_sequence[] = {
8943 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8947 static const struct externalui_message processmessage_actiondata_sequence[] = {
8948 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8952 static const struct externalui_message processmessage_error_sequence[] = {
8953 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8957 static const struct externalui_message processmessage_internal_error_sequence[] = {
8958 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8959 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8963 static const struct externalui_message processmessage_error_format_sequence[] = {
8964 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8968 static const struct externalui_message doaction_costinitialize_sequence[] = {
8969 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8970 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8971 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8975 static const struct externalui_message doaction_custom_sequence[] = {
8976 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8977 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8978 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8982 static const struct externalui_message doaction_custom_fullui_sequence[] = {
8983 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8984 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
8985 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8986 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8990 static const struct externalui_message doaction_custom_cancel_sequence[] = {
8991 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8995 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
8996 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8997 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8998 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8999 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
9000 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
9001 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
9005 static const struct externalui_message doaction_dialog_sequence[] = {
9006 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9007 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9008 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9009 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
9010 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
9014 static const struct externalui_message doaction_dialog_error_sequence[] = {
9015 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
9016 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
9017 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
9021 static const struct externalui_message doaction_dialog_3_sequence[] = {
9022 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9023 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9024 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9025 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9029 static const struct externalui_message doaction_dialog_12345_sequence[] = {
9030 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9031 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9032 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9033 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
9037 static const struct externalui_message closehandle_sequence[] = {
9038 {INSTALLMESSAGE_TERMINATE, -1},
9042 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
9044 INT retval = context ? *((INT *)context) : 0;
9045 struct externalui_message msg;
9047 msg.message = message;
9048 msg.field_count = 0;
9049 strcpy(msg.field[0], string);
9050 add_message(&msg);
9052 return retval;
9055 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
9057 INT retval = context ? *((INT *)context) : 0;
9058 struct externalui_message msg;
9059 char buffer[256];
9060 DWORD length;
9061 UINT r;
9062 int i;
9064 msg.message = message;
9065 if (message == INSTALLMESSAGE_TERMINATE)
9067 /* trying to access the record seems to hang on some versions of Windows */
9068 msg.field_count = -1;
9069 add_message(&msg);
9070 return 1;
9072 msg.field_count = MsiRecordGetFieldCount(hrecord);
9073 for (i = 0; i <= msg.field_count; i++)
9075 length = sizeof(buffer);
9076 r = MsiRecordGetStringA(hrecord, i, buffer, &length);
9077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9078 memcpy(msg.field[i], buffer, min(100, length+1));
9081 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
9082 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
9083 return retval;
9085 add_message(&msg);
9087 return retval;
9090 static void test_externalui_message(void)
9092 /* test that events trigger the correct sequence of messages */
9094 INSTALLUI_HANDLER_RECORD prev;
9095 MSIHANDLE hdb, hpkg, hrecord;
9096 INT retval = 1;
9097 UINT r;
9099 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9101 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval);
9102 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev);
9104 flush_sequence();
9106 CoInitialize(NULL);
9108 hdb = create_package_db();
9109 ok(hdb, "failed to create database\n");
9111 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9112 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9115 r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9116 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
9117 r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9118 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
9120 create_actiontext_table(hdb);
9121 add_actiontext_entry(hdb, "'custom', 'description', 'template'");
9122 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
9124 r = MsiOpenPackageA(NULL, &hpkg);
9125 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9126 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
9128 r = MsiOpenPackageA("nonexistent", &hpkg);
9129 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9130 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9132 r = package_from_db(hdb, &hpkg);
9133 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9135 skip("Not enough rights to perform tests\n");
9136 DeleteFileA(msifile);
9137 return;
9139 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9140 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9142 /* Test MsiProcessMessage */
9143 hrecord = MsiCreateRecord(3);
9144 ok(hrecord, "failed to create record\n");
9146 MsiRecordSetStringA(hrecord, 0, "zero");
9147 MsiRecordSetStringA(hrecord, 1, "one");
9148 MsiRecordSetStringA(hrecord, 2, "two");
9149 MsiRecordSetStringA(hrecord, 3, "three");
9150 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9151 ok(r == 1, "Expected 1, got %d\n", r);
9152 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9154 MsiRecordSetStringA(hrecord, 1, "name");
9155 MsiRecordSetStringA(hrecord, 2, "description");
9156 MsiRecordSetStringA(hrecord, 3, "template");
9157 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord);
9158 ok(r == 1, "Expected 1, got %d\n", r);
9159 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9161 MsiRecordSetStringA(hrecord, 0, "apple");
9162 MsiRecordSetStringA(hrecord, 1, "cherry");
9163 MsiRecordSetStringA(hrecord, 2, "banana");
9164 MsiRecordSetStringA(hrecord, 3, "guava");
9165 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord);
9166 ok(r == 1, "Expected 1, got %d\n", r);
9167 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9169 /* non-internal error */
9170 MsiRecordSetStringA(hrecord, 0, NULL);
9171 MsiRecordSetInteger(hrecord, 1, 1311);
9172 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9173 ok(r == 1, "Expected 1, got %d\n", r);
9174 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9176 /* internal error */
9177 MsiRecordSetStringA(hrecord, 0, NULL);
9178 MsiRecordSetInteger(hrecord, 1, 2726);
9179 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9180 ok(r == 0, "Expected 0, got %d\n", r);
9181 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9183 /* with format field */
9184 MsiRecordSetStringA(hrecord, 0, "starfruit");
9185 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9186 ok(r == 1, "Expected 1, got %d\n", r);
9187 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9189 /* Test a standard action */
9190 r = MsiDoActionA(hpkg, "CostInitialize");
9191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9192 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9194 /* Test a custom action */
9195 r = MsiDoActionA(hpkg, "custom");
9196 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9197 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9199 /* close the package */
9200 MsiCloseHandle(hpkg);
9201 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9203 /* Test dialogs */
9204 hdb = create_package_db();
9205 ok(hdb, "failed to create database\n");
9207 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9210 create_dialog_table(hdb);
9211 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9213 create_control_table(hdb);
9214 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9216 r = package_from_db(hdb, &hpkg);
9217 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9218 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9220 /* Test a custom action */
9221 r = MsiDoActionA(hpkg, "custom");
9222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9223 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9225 retval = 2;
9226 r = MsiDoActionA(hpkg, "custom");
9227 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9228 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9230 retval = 0;
9231 r = MsiDoActionA(hpkg, "custom");
9232 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9233 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9235 r = MsiDoActionA(hpkg, "dialog");
9236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9237 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9239 retval = -1;
9240 r = MsiDoActionA(hpkg, "error");
9241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9242 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9244 r = MsiDoActionA(hpkg, "error");
9245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9246 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9248 retval = -2;
9249 r = MsiDoActionA(hpkg, "custom");
9250 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9251 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9253 retval = 3;
9254 r = MsiDoActionA(hpkg, "dialog");
9255 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9256 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9258 retval = 12345;
9259 r = MsiDoActionA(hpkg, "dialog");
9260 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9261 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9263 MsiCloseHandle(hpkg);
9264 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9266 MsiCloseHandle(hrecord);
9267 CoUninitialize();
9268 DeleteFileA(msifile);
9269 DeleteFileA("forcecodepage.idt");
9272 static const struct externalui_message controlevent_spawn_sequence[] = {
9273 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9274 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9275 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9276 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9278 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9279 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9280 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9282 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9284 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9288 static const struct externalui_message controlevent_spawn2_sequence[] = {
9289 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9290 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9291 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9292 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9294 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9295 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9296 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9298 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9300 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9304 static void test_controlevent(void)
9306 INSTALLUI_HANDLER_RECORD prev;
9307 MSIHANDLE hdb, hpkg;
9308 UINT r;
9310 if (!winetest_interactive)
9312 skip("interactive ControlEvent tests\n");
9313 return;
9316 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9318 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9319 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9321 flush_sequence();
9323 CoInitialize(NULL);
9325 hdb = create_package_db();
9326 ok(hdb, "failed to create database\n");
9328 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9329 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9332 create_dialog_table(hdb);
9333 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9334 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9335 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9336 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9338 create_control_table(hdb);
9339 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9340 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9341 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9342 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9344 create_controlevent_table(hdb);
9345 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9346 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9348 create_custom_action_table(hdb);
9349 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9351 /* SpawnDialog and EndDialog should trigger after all other events */
9352 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9353 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9355 /* Multiple dialog events cause only the last one to be triggered */
9356 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9357 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9358 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9360 r = package_from_db(hdb, &hpkg);
9361 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9362 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9364 r = MsiDoActionA(hpkg, "spawn");
9365 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9366 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9368 r = MsiDoActionA(hpkg, "spawn2");
9369 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9370 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9372 MsiCloseHandle(hpkg);
9373 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9375 CoUninitialize();
9376 DeleteFileA(msifile);
9377 DeleteFileA("forcecodepage.idt");
9380 static const struct externalui_message toplevel_install_sequence[] = {
9381 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9382 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9384 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9385 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9386 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9387 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9388 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9390 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9391 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9392 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9394 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9395 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9396 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9398 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9399 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9400 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9402 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9403 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9404 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9406 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9407 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9409 /* property dump */
9411 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9412 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9413 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9417 static const struct externalui_message toplevel_install_ui_sequence[] = {
9418 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9419 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9421 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9422 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9423 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9425 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9429 static const struct externalui_message toplevel_executeaction_install_sequence[] = {
9430 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9431 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9433 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9434 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9435 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9436 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9438 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9439 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9440 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9442 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9443 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9444 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9446 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9447 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9448 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9450 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9451 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9452 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9454 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9455 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9457 /* property dump */
9459 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9460 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9461 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9465 static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = {
9466 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9467 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9469 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9470 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9471 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9472 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9474 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9475 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9476 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9478 /* property dump */
9480 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9481 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9482 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9486 static const struct externalui_message toplevel_msiinstallproduct_sequence[] = {
9487 {INSTALLMESSAGE_INITIALIZE, -1},
9489 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9490 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9491 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9492 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9493 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9495 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9496 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9498 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9499 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9500 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9502 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9504 /* property dump */
9506 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9507 {INSTALLMESSAGE_TERMINATE, -1},
9511 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = {
9512 {INSTALLMESSAGE_INITIALIZE, -1},
9514 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9515 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9516 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9517 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9518 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9520 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9521 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9522 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9524 /* property dump */
9526 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9527 {INSTALLMESSAGE_TERMINATE, -1},
9531 /* tests involving top-level actions: INSTALL, ExecuteAction */
9532 static void test_top_level_action(void)
9534 INSTALLUI_HANDLER_RECORD prev;
9535 MSIHANDLE hdb, hpkg;
9536 UINT r;
9537 char msifile_absolute[MAX_PATH];
9539 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9541 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9542 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9544 flush_sequence();
9546 CoInitialize(NULL);
9548 hdb = create_package_db();
9549 ok(hdb, "failed to create database\n");
9551 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9552 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9555 create_property_table(hdb);
9556 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9558 create_install_execute_sequence_table(hdb);
9559 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9560 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9561 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9563 create_install_ui_sequence_table(hdb);
9564 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9566 MsiDatabaseCommit(hdb);
9568 /* for some reason we have to open the package from file using an absolute path */
9569 MsiCloseHandle(hdb);
9570 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9571 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9572 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9573 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9575 /* test INSTALL */
9576 r = MsiDoActionA(hpkg, "INSTALL");
9577 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9578 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9580 /* test INSTALL with reduced+ UI */
9581 /* for some reason we need to re-open the package to change the internal UI */
9582 MsiCloseHandle(hpkg);
9583 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9584 MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL);
9585 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9586 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9587 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9589 r = MsiDoActionA(hpkg, "INSTALL");
9590 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9591 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9593 /* test ExecuteAction with EXECUTEACTION property unset */
9594 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9595 r = MsiDoActionA(hpkg, "ExecuteAction");
9596 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9597 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9599 /* test ExecuteAction with EXECUTEACTION property set */
9600 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9601 r = MsiDoActionA(hpkg, "ExecuteAction");
9602 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9603 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9605 MsiCloseHandle(hpkg);
9606 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9608 /* test MsiInstallProduct() */
9609 r = MsiInstallProductA(msifile_absolute, NULL);
9610 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9611 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9613 r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9614 todo_wine
9615 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9616 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9618 CoUninitialize();
9619 DeleteFileA(msifile);
9620 DeleteFileA("forcecodepage.idt");
9623 START_TEST(package)
9625 char temp_path[MAX_PATH], prev_path[MAX_PATH];
9626 STATEMGRSTATUS status;
9627 BOOL ret = FALSE;
9628 DWORD len;
9630 init_functionpointers();
9632 if (pIsWow64Process)
9633 pIsWow64Process(GetCurrentProcess(), &is_wow64);
9635 GetCurrentDirectoryA(MAX_PATH, prev_path);
9636 GetTempPathA(MAX_PATH, temp_path);
9637 SetCurrentDirectoryA(temp_path);
9639 lstrcpyA(CURR_DIR, temp_path);
9640 len = lstrlenA(CURR_DIR);
9642 if (len && (CURR_DIR[len - 1] == '\\'))
9643 CURR_DIR[len - 1] = 0;
9645 /* Create a restore point ourselves so we circumvent the multitude of restore points
9646 * that would have been created by all the installation and removal tests.
9648 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
9649 * creation of restore points.
9651 if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
9653 memset(&status, 0, sizeof(status));
9654 ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9657 test_createpackage();
9658 test_doaction();
9659 test_gettargetpath_bad();
9660 test_settargetpath();
9661 test_props();
9662 test_property_table();
9663 test_condition();
9664 test_msipackage();
9665 test_formatrecord2();
9666 test_formatrecord_tables();
9667 test_states();
9668 test_removefiles();
9669 test_appsearch();
9670 test_appsearch_complocator();
9671 test_appsearch_reglocator();
9672 test_appsearch_inilocator();
9673 test_appsearch_drlocator();
9674 test_featureparents();
9675 test_installprops();
9676 test_launchconditions();
9677 test_ccpsearch();
9678 test_complocator();
9679 test_MsiGetSourcePath();
9680 test_shortlongsource();
9681 test_sourcedir();
9682 test_access();
9683 test_emptypackage();
9684 test_MsiGetProductProperty();
9685 test_MsiSetProperty();
9686 test_MsiApplyMultiplePatches();
9687 test_MsiApplyPatch();
9688 test_costs();
9689 test_MsiDatabaseCommit();
9690 test_externalui();
9691 test_externalui_message();
9692 test_controlevent();
9693 test_top_level_action();
9695 if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
9697 ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9698 if (ret)
9699 remove_restore_point(status.llSequenceNumber);
9702 SetCurrentDirectoryA(prev_path);