mf/session: Forward more events to the application.
[wine/zf.git] / dlls / msi / tests / package.c
blob3b98d9ef1110f9644288fe2bfea61b36aeba290a
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 = HeapAlloc(GetProcessHeap(), 0, size);
137 GetTokenInformation(token, TokenUser, user, size, &size);
138 ConvertSidToStringSidA(user->User.Sid, &usersid);
139 HeapFree(GetProcessHeap(), 0, 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 = HeapAlloc( GetProcessHeap(), 0, 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)
208 HeapFree(GetProcessHeap(), 0, lpszName);
209 if(lpszSubKey)
210 RegCloseKey(hSubKey);
211 return ret;
214 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
216 DWORD i,n=1;
217 GUID guid;
219 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
220 return FALSE;
222 for(i=0; i<8; i++)
223 out[7-i] = in[n++];
224 n++;
225 for(i=0; i<4; i++)
226 out[11-i] = in[n++];
227 n++;
228 for(i=0; i<4; i++)
229 out[15-i] = in[n++];
230 n++;
231 for(i=0; i<2; i++)
233 out[17+i*2] = in[n++];
234 out[16+i*2] = in[n++];
236 n++;
237 for( ; i<8; i++)
239 out[17+i*2] = in[n++];
240 out[16+i*2] = in[n++];
242 out[32]=0;
243 return TRUE;
246 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
248 WCHAR guidW[MAX_PATH];
249 WCHAR squashedW[MAX_PATH];
250 GUID guid;
251 HRESULT hr;
252 int size;
254 hr = CoCreateGuid(&guid);
255 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
257 size = StringFromGUID2(&guid, guidW, MAX_PATH);
258 ok(size == 39, "Expected 39, got %d\n", hr);
260 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
261 squash_guid(guidW, squashedW);
262 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
265 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
266 LPCSTR guid, LPSTR usersid, BOOL dir)
268 WCHAR guidW[MAX_PATH];
269 WCHAR squashedW[MAX_PATH];
270 CHAR squashed[MAX_PATH];
271 CHAR comppath[MAX_PATH + 81];
272 CHAR prodpath[MAX_PATH];
273 CHAR path[MAX_PATH];
274 LPCSTR prod = NULL;
275 HKEY hkey;
276 REGSAM access = KEY_ALL_ACCESS;
278 if (is_wow64)
279 access |= KEY_WOW64_64KEY;
281 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
282 squash_guid(guidW, squashedW);
283 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
285 if (context == MSIINSTALLCONTEXT_MACHINE)
287 prod = "3D0DAE300FACA1300AD792060BCDAA92";
288 sprintf(comppath,
289 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
290 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
291 lstrcpyA(prodpath,
292 "SOFTWARE\\Classes\\Installer\\"
293 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
295 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
297 prod = "7D2F387510109040002000060BECB6AB";
298 sprintf(comppath,
299 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
300 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
301 sprintf(prodpath,
302 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
303 "Installer\\%s\\Installer\\Products\\"
304 "7D2F387510109040002000060BECB6AB", usersid);
306 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
308 prod = "7D2F387510109040002000060BECB6AB";
309 sprintf(comppath,
310 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
311 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
312 sprintf(prodpath,
313 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
314 "Installer\\Managed\\%s\\Installer\\Products\\"
315 "7D2F387510109040002000060BECB6AB", usersid);
318 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
320 lstrcpyA(path, CURR_DIR);
321 lstrcatA(path, "\\");
322 if (!dir) lstrcatA(path, filename);
324 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
325 RegCloseKey(hkey);
327 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
328 RegCloseKey(hkey);
331 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
333 WCHAR guidW[MAX_PATH];
334 WCHAR squashedW[MAX_PATH];
335 WCHAR substrW[MAX_PATH];
336 CHAR squashed[MAX_PATH];
337 CHAR comppath[MAX_PATH + 81];
338 CHAR prodpath[MAX_PATH];
339 REGSAM access = KEY_ALL_ACCESS;
341 if (is_wow64)
342 access |= KEY_WOW64_64KEY;
344 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
345 squash_guid(guidW, squashedW);
346 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
348 if (context == MSIINSTALLCONTEXT_MACHINE)
350 sprintf(comppath,
351 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
352 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
353 lstrcpyA(prodpath,
354 "SOFTWARE\\Classes\\Installer\\"
355 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
357 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
359 sprintf(comppath,
360 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
361 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
362 sprintf(prodpath,
363 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
364 "Installer\\%s\\Installer\\Products\\"
365 "7D2F387510109040002000060BECB6AB", usersid);
367 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
369 sprintf(comppath,
370 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
371 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
372 sprintf(prodpath,
373 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
374 "Installer\\Managed\\%s\\Installer\\Products\\"
375 "7D2F387510109040002000060BECB6AB", usersid);
378 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
379 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
381 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
382 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
385 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
387 MSIHANDLE hview = 0;
388 UINT r, ret;
390 /* open a select query */
391 r = MsiDatabaseOpenViewA(hdb, query, &hview);
392 if (r != ERROR_SUCCESS)
393 return r;
394 r = MsiViewExecute(hview, 0);
395 if (r != ERROR_SUCCESS)
396 return r;
397 ret = MsiViewFetch(hview, phrec);
398 r = MsiViewClose(hview);
399 if (r != ERROR_SUCCESS)
400 return r;
401 r = MsiCloseHandle(hview);
402 if (r != ERROR_SUCCESS)
403 return r;
404 return ret;
407 static UINT run_query( MSIHANDLE hdb, const char *query )
409 MSIHANDLE hview = 0;
410 UINT r;
412 r = MsiDatabaseOpenViewA(hdb, query, &hview);
413 if( r != ERROR_SUCCESS )
414 return r;
416 r = MsiViewExecute(hview, 0);
417 if( r == ERROR_SUCCESS )
418 r = MsiViewClose(hview);
419 MsiCloseHandle(hview);
420 return r;
423 static UINT create_component_table( MSIHANDLE hdb )
425 UINT r = run_query( hdb,
426 "CREATE TABLE `Component` ( "
427 "`Component` CHAR(72) NOT NULL, "
428 "`ComponentId` CHAR(38), "
429 "`Directory_` CHAR(72) NOT NULL, "
430 "`Attributes` SHORT NOT NULL, "
431 "`Condition` CHAR(255), "
432 "`KeyPath` CHAR(72) "
433 "PRIMARY KEY `Component`)" );
434 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
435 return r;
438 static UINT create_feature_table( MSIHANDLE hdb )
440 UINT r = run_query( hdb,
441 "CREATE TABLE `Feature` ( "
442 "`Feature` CHAR(38) NOT NULL, "
443 "`Feature_Parent` CHAR(38), "
444 "`Title` CHAR(64), "
445 "`Description` CHAR(255), "
446 "`Display` SHORT NOT NULL, "
447 "`Level` SHORT NOT NULL, "
448 "`Directory_` CHAR(72), "
449 "`Attributes` SHORT NOT NULL "
450 "PRIMARY KEY `Feature`)" );
451 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r);
452 return r;
455 static UINT create_feature_components_table( MSIHANDLE hdb )
457 UINT r = run_query( hdb,
458 "CREATE TABLE `FeatureComponents` ( "
459 "`Feature_` CHAR(38) NOT NULL, "
460 "`Component_` CHAR(72) NOT NULL "
461 "PRIMARY KEY `Feature_`, `Component_` )" );
462 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
463 return r;
466 static UINT create_file_table( MSIHANDLE hdb )
468 UINT r = run_query( hdb,
469 "CREATE TABLE `File` ("
470 "`File` CHAR(72) NOT NULL, "
471 "`Component_` CHAR(72) NOT NULL, "
472 "`FileName` CHAR(255) NOT NULL, "
473 "`FileSize` LONG NOT NULL, "
474 "`Version` CHAR(72), "
475 "`Language` CHAR(20), "
476 "`Attributes` SHORT, "
477 "`Sequence` SHORT NOT NULL "
478 "PRIMARY KEY `File`)" );
479 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r);
480 return r;
483 static UINT create_remove_file_table( MSIHANDLE hdb )
485 UINT r = run_query( hdb,
486 "CREATE TABLE `RemoveFile` ("
487 "`FileKey` CHAR(72) NOT NULL, "
488 "`Component_` CHAR(72) NOT NULL, "
489 "`FileName` CHAR(255) LOCALIZABLE, "
490 "`DirProperty` CHAR(72) NOT NULL, "
491 "`InstallMode` SHORT NOT NULL "
492 "PRIMARY KEY `FileKey`)" );
493 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r);
494 return r;
497 static UINT create_appsearch_table( MSIHANDLE hdb )
499 UINT r = run_query( hdb,
500 "CREATE TABLE `AppSearch` ("
501 "`Property` CHAR(72) NOT NULL, "
502 "`Signature_` CHAR(72) NOT NULL "
503 "PRIMARY KEY `Property`, `Signature_`)" );
504 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r);
505 return r;
508 static UINT create_reglocator_table( MSIHANDLE hdb )
510 UINT r = run_query( hdb,
511 "CREATE TABLE `RegLocator` ("
512 "`Signature_` CHAR(72) NOT NULL, "
513 "`Root` SHORT NOT NULL, "
514 "`Key` CHAR(255) NOT NULL, "
515 "`Name` CHAR(255), "
516 "`Type` SHORT "
517 "PRIMARY KEY `Signature_`)" );
518 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r);
519 return r;
522 static UINT create_signature_table( MSIHANDLE hdb )
524 UINT r = run_query( hdb,
525 "CREATE TABLE `Signature` ("
526 "`Signature` CHAR(72) NOT NULL, "
527 "`FileName` CHAR(255) NOT NULL, "
528 "`MinVersion` CHAR(20), "
529 "`MaxVersion` CHAR(20), "
530 "`MinSize` LONG, "
531 "`MaxSize` LONG, "
532 "`MinDate` LONG, "
533 "`MaxDate` LONG, "
534 "`Languages` CHAR(255) "
535 "PRIMARY KEY `Signature`)" );
536 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r);
537 return r;
540 static UINT create_launchcondition_table( MSIHANDLE hdb )
542 UINT r = run_query( hdb,
543 "CREATE TABLE `LaunchCondition` ("
544 "`Condition` CHAR(255) NOT NULL, "
545 "`Description` CHAR(255) NOT NULL "
546 "PRIMARY KEY `Condition`)" );
547 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r);
548 return r;
551 static UINT create_property_table( MSIHANDLE hdb )
553 UINT r = run_query( hdb,
554 "CREATE TABLE `Property` ("
555 "`Property` CHAR(72) NOT NULL, "
556 "`Value` CHAR(0) "
557 "PRIMARY KEY `Property`)" );
558 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r);
559 return r;
562 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
564 UINT r = run_query( hdb,
565 "CREATE TABLE `InstallExecuteSequence` ("
566 "`Action` CHAR(72) NOT NULL, "
567 "`Condition` CHAR(255), "
568 "`Sequence` SHORT "
569 "PRIMARY KEY `Action`)" );
570 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r);
571 return r;
574 static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
576 UINT r = run_query( hdb,
577 "CREATE TABLE `InstallUISequence` ("
578 "`Action` CHAR(72) NOT NULL, "
579 "`Condition` CHAR(255), "
580 "`Sequence` SHORT "
581 "PRIMARY KEY `Action`)" );
582 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r);
583 return r;
586 static UINT create_media_table( MSIHANDLE hdb )
588 UINT r = run_query( hdb,
589 "CREATE TABLE `Media` ("
590 "`DiskId` SHORT NOT NULL, "
591 "`LastSequence` SHORT NOT NULL, "
592 "`DiskPrompt` CHAR(64), "
593 "`Cabinet` CHAR(255), "
594 "`VolumeLabel` CHAR(32), "
595 "`Source` CHAR(72) "
596 "PRIMARY KEY `DiskId`)" );
597 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r);
598 return r;
601 static UINT create_ccpsearch_table( MSIHANDLE hdb )
603 UINT r = run_query( hdb,
604 "CREATE TABLE `CCPSearch` ("
605 "`Signature_` CHAR(72) NOT NULL "
606 "PRIMARY KEY `Signature_`)" );
607 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r);
608 return r;
611 static UINT create_drlocator_table( MSIHANDLE hdb )
613 UINT r = run_query( hdb,
614 "CREATE TABLE `DrLocator` ("
615 "`Signature_` CHAR(72) NOT NULL, "
616 "`Parent` CHAR(72), "
617 "`Path` CHAR(255), "
618 "`Depth` SHORT "
619 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
620 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r);
621 return r;
624 static UINT create_complocator_table( MSIHANDLE hdb )
626 UINT r = run_query( hdb,
627 "CREATE TABLE `CompLocator` ("
628 "`Signature_` CHAR(72) NOT NULL, "
629 "`ComponentId` CHAR(38) NOT NULL, "
630 "`Type` SHORT "
631 "PRIMARY KEY `Signature_`)" );
632 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r);
633 return r;
636 static UINT create_inilocator_table( MSIHANDLE hdb )
638 UINT r = run_query( hdb,
639 "CREATE TABLE `IniLocator` ("
640 "`Signature_` CHAR(72) NOT NULL, "
641 "`FileName` CHAR(255) NOT NULL, "
642 "`Section` CHAR(96)NOT NULL, "
643 "`Key` CHAR(128)NOT NULL, "
644 "`Field` SHORT, "
645 "`Type` SHORT "
646 "PRIMARY KEY `Signature_`)" );
647 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r);
648 return r;
651 static UINT create_custom_action_table( MSIHANDLE hdb )
653 UINT r = run_query( hdb,
654 "CREATE TABLE `CustomAction` ("
655 "`Action` CHAR(72) NOT NULL, "
656 "`Type` SHORT NOT NULL, "
657 "`Source` CHAR(75), "
658 "`Target` CHAR(255) "
659 "PRIMARY KEY `Action`)" );
660 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
661 return r;
664 static UINT create_dialog_table( MSIHANDLE hdb )
666 UINT r = run_query(hdb,
667 "CREATE TABLE `Dialog` ("
668 "`Dialog` CHAR(72) NOT NULL, "
669 "`HCentering` SHORT NOT NULL, "
670 "`VCentering` SHORT NOT NULL, "
671 "`Width` SHORT NOT NULL, "
672 "`Height` SHORT NOT NULL, "
673 "`Attributes` LONG, "
674 "`Title` CHAR(128) LOCALIZABLE, "
675 "`Control_First` CHAR(50) NOT NULL, "
676 "`Control_Default` CHAR(50), "
677 "`Control_Cancel` CHAR(50) "
678 "PRIMARY KEY `Dialog`)");
679 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r);
680 return r;
683 static UINT create_control_table( MSIHANDLE hdb )
685 UINT r = run_query(hdb,
686 "CREATE TABLE `Control` ("
687 "`Dialog_` CHAR(72) NOT NULL, "
688 "`Control` CHAR(50) NOT NULL, "
689 "`Type` CHAR(20) NOT NULL, "
690 "`X` SHORT NOT NULL, "
691 "`Y` SHORT NOT NULL, "
692 "`Width` SHORT NOT NULL, "
693 "`Height` SHORT NOT NULL, "
694 "`Attributes` LONG, "
695 "`Property` CHAR(50), "
696 "`Text` CHAR(0) LOCALIZABLE, "
697 "`Control_Next` CHAR(50), "
698 "`Help` CHAR(255) LOCALIZABLE "
699 "PRIMARY KEY `Dialog_`, `Control`)");
700 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r);
701 return r;
704 static UINT create_controlevent_table( MSIHANDLE hdb )
706 UINT r = run_query(hdb,
707 "CREATE TABLE `ControlEvent` ("
708 "`Dialog_` CHAR(72) NOT NULL, "
709 "`Control_` CHAR(50) NOT NULL, "
710 "`Event` CHAR(50) NOT NULL, "
711 "`Argument` CHAR(255) NOT NULL, "
712 "`Condition` CHAR(255), "
713 "`Ordering` SHORT "
714 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
715 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r);
716 return r;
719 static UINT create_actiontext_table( MSIHANDLE hdb )
721 UINT r = run_query(hdb,
722 "CREATE TABLE `ActionText` ("
723 "`Action` CHAR(72) NOT NULL, "
724 "`Description` CHAR(64) LOCALIZABLE, "
725 "`Template` CHAR(128) LOCALIZABLE "
726 "PRIMARY KEY `Action`)");
727 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
728 return r;
731 static UINT create_upgrade_table( MSIHANDLE hdb )
733 UINT r = run_query( hdb,
734 "CREATE TABLE `Upgrade` ("
735 "`UpgradeCode` CHAR(38) NOT NULL, "
736 "`VersionMin` CHAR(20), "
737 "`VersionMax` CHAR(20), "
738 "`Language` CHAR(255), "
739 "`Attributes` SHORT, "
740 "`Remove` CHAR(255), "
741 "`ActionProperty` CHAR(72) NOT NULL "
742 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
743 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r);
744 return r;
747 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
749 char *query;
750 UINT sz, r;
752 sz = strlen(values) + strlen(insert) + 1;
753 query = HeapAlloc(GetProcessHeap(), 0, sz);
754 sprintf(query, insert, values);
755 r = run_query(hdb, query);
756 HeapFree(GetProcessHeap(), 0, query);
757 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
758 return r;
761 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
762 "INSERT INTO `Component` " \
763 "(`Component`, `ComponentId`, `Directory_`, " \
764 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
766 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
767 "INSERT INTO `Directory` " \
768 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
770 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
771 "INSERT INTO `Feature` " \
772 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
773 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
775 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
776 "INSERT INTO `FeatureComponents` " \
777 "(`Feature_`, `Component_`) VALUES( %s )")
779 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
780 "INSERT INTO `File` " \
781 "(`File`, `Component_`, `FileName`, `FileSize`, " \
782 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
784 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
785 "INSERT INTO `AppSearch` " \
786 "(`Property`, `Signature_`) VALUES( %s )")
788 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
789 "INSERT INTO `Signature` " \
790 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
791 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
792 "VALUES( %s )")
794 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
795 "INSERT INTO `LaunchCondition` " \
796 "(`Condition`, `Description`) VALUES( %s )")
798 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
799 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
801 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
802 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
804 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
805 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
807 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
808 "INSERT INTO `InstallExecuteSequence` " \
809 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
811 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
812 "INSERT INTO `InstallUISequence` " \
813 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
815 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
816 "INSERT INTO `Media` " \
817 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
818 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
820 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
821 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
823 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
824 "INSERT INTO `DrLocator` " \
825 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
827 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
828 "INSERT INTO `CompLocator` " \
829 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
831 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
832 "INSERT INTO `IniLocator` " \
833 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
834 "VALUES( %s )")
836 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
837 "INSERT INTO `CustomAction` " \
838 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
840 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
841 "INSERT INTO `Dialog` " \
842 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
844 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
845 "INSERT INTO `Control` " \
846 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
848 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
849 "INSERT INTO `ControlEvent` " \
850 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
852 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
853 "INSERT INTO `ActionText` " \
854 "(`Action`, `Description`, `Template`) VALUES( %s )");
856 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
857 "INSERT INTO `Upgrade` " \
858 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
860 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
861 const char *name, UINT type )
863 const char insert[] =
864 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
865 "VALUES( '%s', %u, '%s', '%s', %u )";
866 char *query;
867 UINT sz, r;
869 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
870 query = HeapAlloc( GetProcessHeap(), 0, sz );
871 sprintf( query, insert, sig, root, path, name, type );
872 r = run_query( hdb, query );
873 HeapFree( GetProcessHeap(), 0, query );
874 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
875 return r;
878 static UINT set_summary_info(MSIHANDLE hdb)
880 UINT res;
881 MSIHANDLE suminfo;
883 /* build summary info */
884 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
885 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
887 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL,
888 "Installation Database");
889 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
891 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL,
892 "Installation Database");
893 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
895 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL,
896 "Wine Hackers");
897 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
899 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL,
900 ";1033");
901 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
903 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL,
904 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
905 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
907 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
908 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
910 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
911 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
913 res = MsiSummaryInfoPersist(suminfo);
914 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
916 res = MsiCloseHandle( suminfo);
917 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
919 return res;
923 static MSIHANDLE create_package_db(void)
925 MSIHANDLE hdb = 0;
926 UINT res;
928 DeleteFileA(msifile);
930 /* create an empty database */
931 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb );
932 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
933 if( res != ERROR_SUCCESS )
934 return hdb;
936 res = MsiDatabaseCommit( hdb );
937 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
939 res = set_summary_info(hdb);
940 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
942 res = run_query( hdb,
943 "CREATE TABLE `Directory` ( "
944 "`Directory` CHAR(255) NOT NULL, "
945 "`Directory_Parent` CHAR(255), "
946 "`DefaultDir` CHAR(255) NOT NULL "
947 "PRIMARY KEY `Directory`)" );
948 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
950 return hdb;
953 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
955 UINT res;
956 CHAR szPackage[12];
957 MSIHANDLE hPackage;
959 sprintf(szPackage, "#%u", hdb);
960 res = MsiOpenPackageA(szPackage, &hPackage);
961 if (res != ERROR_SUCCESS)
963 MsiCloseHandle(hdb);
964 return res;
967 res = MsiCloseHandle(hdb);
968 if (res != ERROR_SUCCESS)
970 MsiCloseHandle(hPackage);
971 return res;
974 *handle = hPackage;
975 return ERROR_SUCCESS;
978 static void create_file_data(LPCSTR name, LPCSTR data)
980 HANDLE file;
981 DWORD written;
983 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
984 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
985 if (file == INVALID_HANDLE_VALUE)
986 return;
988 WriteFile(file, data, strlen(data), &written, NULL);
989 WriteFile(file, "\n", strlen("\n"), &written, NULL);
991 CloseHandle(file);
994 static void create_test_file(const CHAR *name)
996 create_file_data(name, name);
999 typedef struct _tagVS_VERSIONINFO
1001 WORD wLength;
1002 WORD wValueLength;
1003 WORD wType;
1004 WCHAR szKey[1];
1005 WORD wPadding1[1];
1006 VS_FIXEDFILEINFO Value;
1007 WORD wPadding2[1];
1008 WORD wChildren[1];
1009 } VS_VERSIONINFO;
1011 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
1012 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
1014 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
1016 VS_VERSIONINFO *pVerInfo;
1017 VS_FIXEDFILEINFO *pFixedInfo;
1018 LPBYTE buffer, ofs;
1019 CHAR path[MAX_PATH];
1020 DWORD handle, size;
1021 HANDLE resource;
1022 BOOL ret = FALSE;
1024 GetSystemDirectoryA(path, MAX_PATH);
1025 /* Some dlls can't be updated on Vista/W2K8 */
1026 lstrcatA(path, "\\version.dll");
1028 CopyFileA(path, name, FALSE);
1030 size = GetFileVersionInfoSizeA(path, &handle);
1031 buffer = HeapAlloc(GetProcessHeap(), 0, size);
1033 GetFileVersionInfoA(path, 0, size, buffer);
1035 pVerInfo = (VS_VERSIONINFO *)buffer;
1036 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
1037 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
1039 pFixedInfo->dwFileVersionMS = ms;
1040 pFixedInfo->dwFileVersionLS = ls;
1041 pFixedInfo->dwProductVersionMS = ms;
1042 pFixedInfo->dwProductVersionLS = ls;
1044 resource = BeginUpdateResourceA(name, FALSE);
1045 if (!resource)
1046 goto done;
1048 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO),
1049 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
1050 goto done;
1052 if (!EndUpdateResourceA(resource, FALSE))
1053 goto done;
1055 ret = TRUE;
1057 done:
1058 HeapFree(GetProcessHeap(), 0, buffer);
1059 return ret;
1062 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
1064 RESTOREPOINTINFOA spec;
1066 spec.dwEventType = event_type;
1067 spec.dwRestorePtType = APPLICATION_INSTALL;
1068 spec.llSequenceNumber = status->llSequenceNumber;
1069 lstrcpyA(spec.szDescription, "msitest restore point");
1071 return pSRSetRestorePointA(&spec, status);
1074 static void remove_restore_point(DWORD seq_number)
1076 DWORD res;
1078 res = pSRRemoveRestorePoint(seq_number);
1079 if (res != ERROR_SUCCESS)
1080 trace("Failed to remove the restore point : %08x\n", res);
1083 static BOOL is_root(const char *path)
1085 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
1088 static void test_createpackage(void)
1090 MSIHANDLE hPackage = 0;
1091 UINT res;
1093 res = package_from_db(create_package_db(), &hPackage);
1094 if (res == ERROR_INSTALL_PACKAGE_REJECTED)
1096 skip("Not enough rights to perform tests\n");
1097 DeleteFileA(msifile);
1098 return;
1100 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
1102 res = MsiCloseHandle( hPackage);
1103 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
1104 DeleteFileA(msifile);
1107 static void test_doaction( void )
1109 MSIHANDLE hpkg;
1110 UINT r;
1112 r = MsiDoActionA( -1, NULL );
1113 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1115 r = package_from_db(create_package_db(), &hpkg);
1116 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1118 skip("Not enough rights to perform tests\n");
1119 DeleteFileA(msifile);
1120 return;
1122 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1124 r = MsiDoActionA(hpkg, NULL);
1125 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1127 r = MsiDoActionA(0, "boo");
1128 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1130 r = MsiDoActionA(hpkg, "boo");
1131 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
1133 MsiCloseHandle( hpkg );
1134 DeleteFileA(msifile);
1137 static void test_gettargetpath_bad(void)
1139 char buffer[0x80];
1140 WCHAR bufferW[0x80];
1141 MSIHANDLE hpkg;
1142 DWORD sz;
1143 UINT r;
1145 r = package_from_db(create_package_db(), &hpkg);
1146 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1148 skip("Not enough rights to perform tests\n");
1149 DeleteFileA(msifile);
1150 return;
1152 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1154 r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1155 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1157 r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1158 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1160 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1161 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1163 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1164 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1166 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1167 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1169 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1170 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1172 sz = 0;
1173 r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1174 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1176 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1177 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1179 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1180 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1182 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1183 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1185 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1186 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1188 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL );
1189 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1191 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL );
1192 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1194 sz = 0;
1195 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz );
1196 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1198 MsiCloseHandle( hpkg );
1199 DeleteFileA(msifile);
1202 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1204 UINT r;
1205 DWORD size;
1206 MSIHANDLE rec;
1208 rec = MsiCreateRecord( 1 );
1209 ok(rec, "MsiCreate record failed\n");
1211 r = MsiRecordSetStringA( rec, 0, file );
1212 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1214 size = MAX_PATH;
1215 r = MsiFormatRecordA( hpkg, rec, buff, &size );
1216 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1218 MsiCloseHandle( rec );
1221 static void test_settargetpath(void)
1223 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20];
1224 DWORD sz;
1225 MSIHANDLE hpkg;
1226 UINT r;
1227 MSIHANDLE hdb;
1229 hdb = create_package_db();
1230 ok ( hdb, "failed to create package database\n" );
1232 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1234 create_component_table( hdb );
1235 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1236 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1238 create_feature_table( hdb );
1239 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1241 create_feature_components_table( hdb );
1242 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1243 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1245 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1246 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1248 create_file_table( hdb );
1249 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1250 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1252 r = package_from_db( hdb, &hpkg );
1253 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1255 skip("Not enough rights to perform tests\n");
1256 DeleteFileA(msifile);
1257 return;
1259 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1261 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1263 r = MsiDoActionA( hpkg, "CostInitialize");
1264 ok( r == ERROR_SUCCESS, "cost init failed\n");
1266 r = MsiDoActionA( hpkg, "FileCost");
1267 ok( r == ERROR_SUCCESS, "file cost failed\n");
1269 r = MsiDoActionA( hpkg, "CostFinalize");
1270 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1272 buffer[0] = 0;
1273 sz = sizeof(buffer);
1274 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1275 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1276 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1278 r = MsiSetTargetPathA( 0, NULL, NULL );
1279 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1281 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1282 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1284 r = MsiSetTargetPathA( hpkg, "boo", NULL );
1285 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1287 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1288 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1290 sz = sizeof tempdir - 1;
1291 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1292 sprintf( file, "%srootfile.txt", tempdir );
1293 buffer[0] = 0;
1294 query_file_path( hpkg, "[#RootFile]", buffer );
1295 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1296 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1298 GetTempFileNameA( tempdir, "_wt", 0, buffer );
1299 sprintf( tempdir, "%s\\subdir", buffer );
1301 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1302 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1303 "MsiSetTargetPath on file returned %d\n", r );
1305 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1306 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1307 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1309 DeleteFileA( buffer );
1311 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1312 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1314 r = GetFileAttributesA( buffer );
1315 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1317 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1318 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1320 buffer[0] = 0;
1321 sz = sizeof buffer - 1;
1322 lstrcatA( tempdir, "\\" );
1323 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1324 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1325 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1327 sprintf( file, "%srootfile.txt", tempdir );
1328 query_file_path( hpkg, "[#RootFile]", buffer );
1329 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1331 buffer[0] = 0;
1332 sz = sizeof(buffer);
1333 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1334 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1335 lstrcatA( tempdir, "TestParent\\" );
1336 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1338 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1339 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1341 buffer[0] = 0;
1342 sz = sizeof(buffer);
1343 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1344 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1345 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1346 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1348 buffer[0] = 0;
1349 query_file_path( hpkg, "[#TestFile]", buffer );
1350 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1351 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1353 buffer[0] = 0;
1354 sz = sizeof buffer - 1;
1355 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1356 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1357 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1359 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1360 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1362 buffer[0] = 0;
1363 sz = sizeof buffer - 1;
1364 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1365 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1366 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1368 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " );
1369 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1371 buffer[0] = 0;
1372 sz = sizeof buffer - 1;
1373 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1374 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1375 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1377 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1378 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1380 buffer[0] = 0;
1381 sz = sizeof buffer - 1;
1382 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1383 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1384 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1386 MsiCloseHandle( hpkg );
1389 static void test_condition(void)
1391 MSICONDITION r;
1392 MSIHANDLE hpkg;
1394 r = package_from_db(create_package_db(), &hpkg);
1395 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1397 skip("Not enough rights to perform tests\n");
1398 DeleteFileA(msifile);
1399 return;
1401 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1403 r = MsiEvaluateConditionA(0, NULL);
1404 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1406 r = MsiEvaluateConditionA(hpkg, NULL);
1407 ok( r == MSICONDITION_NONE, "wrong return val\n");
1409 r = MsiEvaluateConditionA(hpkg, "");
1410 ok( r == MSICONDITION_NONE, "wrong return val\n");
1412 r = MsiEvaluateConditionA(hpkg, "1");
1413 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1415 r = MsiEvaluateConditionA(hpkg, "0");
1416 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1418 r = MsiEvaluateConditionA(hpkg, "-1");
1419 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1421 r = MsiEvaluateConditionA(hpkg, "0 = 0");
1422 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1424 r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1425 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1427 r = MsiEvaluateConditionA(hpkg, "0 = 1");
1428 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1430 r = MsiEvaluateConditionA(hpkg, "0 > 1");
1431 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1433 r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1434 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1436 r = MsiEvaluateConditionA(hpkg, "1 > 1");
1437 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1439 r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1440 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1442 r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1443 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1445 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1446 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1448 r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1449 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1451 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1452 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1454 r = MsiEvaluateConditionA(hpkg, "0 < 1");
1455 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1457 r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1458 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1460 r = MsiEvaluateConditionA(hpkg, "1 < 1");
1461 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1463 r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1464 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1466 r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1467 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1469 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1470 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1472 r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1473 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1475 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1476 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1478 r = MsiEvaluateConditionA(hpkg, "0 >=");
1479 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1481 r = MsiEvaluateConditionA(hpkg, " ");
1482 ok( r == MSICONDITION_NONE, "wrong return val\n");
1484 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1485 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1487 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1488 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1490 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1491 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1493 r = MsiEvaluateConditionA(hpkg, "not 0");
1494 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1496 r = MsiEvaluateConditionA(hpkg, "not LicView");
1497 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1499 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1500 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1502 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1503 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1505 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1506 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1508 r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1509 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1511 r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1512 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1514 r = MsiEvaluateConditionA(hpkg, "\"0\"");
1515 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1517 r = MsiEvaluateConditionA(hpkg, "1 and 2");
1518 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1520 r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1521 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1523 r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1524 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1526 r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1527 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1529 r = MsiEvaluateConditionA(hpkg, "(0)");
1530 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1532 r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1533 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1535 r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1536 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1538 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1539 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1541 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1542 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1544 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1545 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1547 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1548 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1550 r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1551 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1553 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1554 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1556 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1557 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1559 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1560 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1562 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1563 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1565 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1566 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1568 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1569 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1571 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1572 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1574 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1575 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1577 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1578 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1580 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1581 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1583 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1584 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1586 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1587 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1589 r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1590 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1592 r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1593 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1595 r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1596 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1598 r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1599 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1601 r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1602 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1604 r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1605 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1607 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1608 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1610 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1611 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1613 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1614 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1616 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1617 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1619 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1620 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1622 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1623 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1625 MsiSetPropertyA(hpkg, "mm", "5" );
1627 r = MsiEvaluateConditionA(hpkg, "mm = 5");
1628 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1630 r = MsiEvaluateConditionA(hpkg, "mm < 6");
1631 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1633 r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1634 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1636 r = MsiEvaluateConditionA(hpkg, "mm > 4");
1637 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1639 r = MsiEvaluateConditionA(hpkg, "mm < 12");
1640 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1642 r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1643 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1645 r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1646 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1648 r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1649 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1651 r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1652 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1654 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1655 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1657 r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1658 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1660 r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1661 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1663 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1664 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1666 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1667 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1669 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1670 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1672 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1673 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1675 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1676 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1678 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1679 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1681 r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1682 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1684 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1685 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1687 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1688 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1690 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1691 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1693 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1694 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1696 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1697 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1699 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1700 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1702 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1703 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1705 r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1706 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1708 r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1709 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1711 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1712 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1714 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1715 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1717 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1718 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1720 MsiSetPropertyA(hpkg, "bandalmael", "0" );
1721 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1722 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1724 MsiSetPropertyA(hpkg, "bandalmael", "" );
1725 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1726 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1728 MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1729 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1730 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1732 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1733 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1734 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1736 MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1737 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1738 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1740 MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1741 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1742 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1744 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1745 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1746 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1748 MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1749 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1750 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1752 MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1753 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1754 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1756 MsiSetPropertyA(hpkg, "bandalmael", "-" );
1757 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1758 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1760 MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1761 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1762 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1764 MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1765 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1766 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1767 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1768 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1770 MsiSetPropertyA(hpkg, "one", "hi");
1771 MsiSetPropertyA(hpkg, "two", "hithere");
1772 r = MsiEvaluateConditionA(hpkg, "one >< two");
1773 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1775 MsiSetPropertyA(hpkg, "one", "hithere");
1776 MsiSetPropertyA(hpkg, "two", "hi");
1777 r = MsiEvaluateConditionA(hpkg, "one >< two");
1778 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1780 MsiSetPropertyA(hpkg, "one", "hello");
1781 MsiSetPropertyA(hpkg, "two", "hi");
1782 r = MsiEvaluateConditionA(hpkg, "one >< two");
1783 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1785 MsiSetPropertyA(hpkg, "one", "hellohithere");
1786 MsiSetPropertyA(hpkg, "two", "hi");
1787 r = MsiEvaluateConditionA(hpkg, "one >< two");
1788 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1790 MsiSetPropertyA(hpkg, "one", "");
1791 MsiSetPropertyA(hpkg, "two", "hi");
1792 r = MsiEvaluateConditionA(hpkg, "one >< two");
1793 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1795 MsiSetPropertyA(hpkg, "one", "hi");
1796 MsiSetPropertyA(hpkg, "two", "");
1797 r = MsiEvaluateConditionA(hpkg, "one >< two");
1798 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1800 MsiSetPropertyA(hpkg, "one", "");
1801 MsiSetPropertyA(hpkg, "two", "");
1802 r = MsiEvaluateConditionA(hpkg, "one >< two");
1803 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1805 MsiSetPropertyA(hpkg, "one", "1234");
1806 MsiSetPropertyA(hpkg, "two", "1");
1807 r = MsiEvaluateConditionA(hpkg, "one >< two");
1808 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1810 MsiSetPropertyA(hpkg, "one", "one 1234");
1811 MsiSetPropertyA(hpkg, "two", "1");
1812 r = MsiEvaluateConditionA(hpkg, "one >< two");
1813 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1815 MsiSetPropertyA(hpkg, "one", "hithere");
1816 MsiSetPropertyA(hpkg, "two", "hi");
1817 r = MsiEvaluateConditionA(hpkg, "one << two");
1818 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1820 MsiSetPropertyA(hpkg, "one", "hi");
1821 MsiSetPropertyA(hpkg, "two", "hithere");
1822 r = MsiEvaluateConditionA(hpkg, "one << two");
1823 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1825 MsiSetPropertyA(hpkg, "one", "hi");
1826 MsiSetPropertyA(hpkg, "two", "hi");
1827 r = MsiEvaluateConditionA(hpkg, "one << two");
1828 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1830 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1831 MsiSetPropertyA(hpkg, "two", "hi");
1832 r = MsiEvaluateConditionA(hpkg, "one << two");
1833 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1835 MsiSetPropertyA(hpkg, "one", "");
1836 MsiSetPropertyA(hpkg, "two", "hi");
1837 r = MsiEvaluateConditionA(hpkg, "one << two");
1838 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1840 MsiSetPropertyA(hpkg, "one", "hithere");
1841 MsiSetPropertyA(hpkg, "two", "");
1842 r = MsiEvaluateConditionA(hpkg, "one << two");
1843 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1845 MsiSetPropertyA(hpkg, "one", "");
1846 MsiSetPropertyA(hpkg, "two", "");
1847 r = MsiEvaluateConditionA(hpkg, "one << two");
1848 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1850 MsiSetPropertyA(hpkg, "one", "1234");
1851 MsiSetPropertyA(hpkg, "two", "1");
1852 r = MsiEvaluateConditionA(hpkg, "one << two");
1853 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1855 MsiSetPropertyA(hpkg, "one", "1234 one");
1856 MsiSetPropertyA(hpkg, "two", "1");
1857 r = MsiEvaluateConditionA(hpkg, "one << two");
1858 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1860 MsiSetPropertyA(hpkg, "one", "hithere");
1861 MsiSetPropertyA(hpkg, "two", "there");
1862 r = MsiEvaluateConditionA(hpkg, "one >> two");
1863 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1865 MsiSetPropertyA(hpkg, "one", "hithere");
1866 MsiSetPropertyA(hpkg, "two", "hi");
1867 r = MsiEvaluateConditionA(hpkg, "one >> two");
1868 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1870 MsiSetPropertyA(hpkg, "one", "there");
1871 MsiSetPropertyA(hpkg, "two", "hithere");
1872 r = MsiEvaluateConditionA(hpkg, "one >> two");
1873 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1875 MsiSetPropertyA(hpkg, "one", "there");
1876 MsiSetPropertyA(hpkg, "two", "there");
1877 r = MsiEvaluateConditionA(hpkg, "one >> two");
1878 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1880 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1881 MsiSetPropertyA(hpkg, "two", "hi");
1882 r = MsiEvaluateConditionA(hpkg, "one >> two");
1883 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1885 MsiSetPropertyA(hpkg, "one", "");
1886 MsiSetPropertyA(hpkg, "two", "there");
1887 r = MsiEvaluateConditionA(hpkg, "one >> two");
1888 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1890 MsiSetPropertyA(hpkg, "one", "there");
1891 MsiSetPropertyA(hpkg, "two", "");
1892 r = MsiEvaluateConditionA(hpkg, "one >> two");
1893 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1895 MsiSetPropertyA(hpkg, "one", "");
1896 MsiSetPropertyA(hpkg, "two", "");
1897 r = MsiEvaluateConditionA(hpkg, "one >> two");
1898 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1900 MsiSetPropertyA(hpkg, "one", "1234");
1901 MsiSetPropertyA(hpkg, "two", "4");
1902 r = MsiEvaluateConditionA(hpkg, "one >> two");
1903 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1905 MsiSetPropertyA(hpkg, "one", "one 1234");
1906 MsiSetPropertyA(hpkg, "two", "4");
1907 r = MsiEvaluateConditionA(hpkg, "one >> two");
1908 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1910 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1912 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1913 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1915 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1916 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1918 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1919 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1921 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1922 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1924 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1925 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1927 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1928 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1930 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1931 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1933 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1934 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1936 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1937 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1939 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1940 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1942 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1943 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1945 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1946 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1948 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1949 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1951 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1952 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1954 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1955 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1957 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1958 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1960 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1961 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1963 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1964 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1966 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1967 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1969 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1970 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1972 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1973 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1975 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1976 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1978 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1979 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1981 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1982 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1984 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1985 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1987 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1988 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1990 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1991 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1993 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1994 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1996 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1997 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1999 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
2000 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2002 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
2003 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2005 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
2006 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2008 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
2009 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2011 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
2012 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2014 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
2015 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2017 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
2018 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2020 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
2021 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2023 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
2024 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
2025 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2027 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
2028 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2030 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
2031 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2033 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
2034 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2036 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
2037 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2039 MsiSetPropertyA(hpkg, "one", "1");
2040 r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
2041 ok( r == MSICONDITION_FALSE, "wrong return val\n");
2043 MsiSetPropertyA(hpkg, "X", "5.0");
2045 r = MsiEvaluateConditionA(hpkg, "X != \"\"");
2046 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2048 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
2049 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2051 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
2052 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2054 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
2055 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2057 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
2058 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2060 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2061 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2063 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2064 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2066 /* feature doesn't exist */
2067 r = MsiEvaluateConditionA(hpkg, "&nofeature");
2068 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2069 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\"");
2070 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2071 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3");
2072 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2073 r = MsiEvaluateConditionA(hpkg, "\"\"<>3");
2074 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2075 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\"");
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);
2079 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\"");
2080 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2082 MsiSetPropertyA(hpkg, "A", "2");
2083 MsiSetPropertyA(hpkg, "X", "50");
2085 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2086 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2088 r = MsiEvaluateConditionA(hpkg, "A <= X");
2089 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2091 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2092 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2094 MsiSetPropertyA(hpkg, "X", "50val");
2096 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2097 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2099 r = MsiEvaluateConditionA(hpkg, "A <= X");
2100 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2102 MsiSetPropertyA(hpkg, "A", "7");
2103 MsiSetPropertyA(hpkg, "X", "50");
2105 r = MsiEvaluateConditionA(hpkg, "7 <= X");
2106 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2108 r = MsiEvaluateConditionA(hpkg, "A <= X");
2109 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2111 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2112 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2114 MsiSetPropertyA(hpkg, "X", "50val");
2116 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2117 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2119 r = MsiEvaluateConditionA(hpkg, "A <= X");
2120 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2122 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
2123 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2124 "wrong return val (%d)\n", r);
2126 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
2127 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2128 "wrong return val (%d)\n", r);
2130 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
2131 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2132 "wrong return val (%d)\n", r);
2134 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
2135 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2136 "wrong return val (%d)\n", r);
2138 MsiCloseHandle( hpkg );
2139 DeleteFileA(msifile);
2142 static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case)
2144 char buffer[MAX_PATH] = "x";
2145 DWORD sz = sizeof(buffer);
2146 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz);
2147 ok(!r, "'%s': got %u\n", prop, r);
2148 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %u\n", prop, lstrlenA(buffer), sz);
2149 if (match_case)
2150 ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2151 else
2152 ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2155 static void test_props(void)
2157 MSIHANDLE hpkg, hdb;
2158 UINT r;
2159 DWORD sz;
2160 char buffer[0x100];
2161 WCHAR bufferW[10];
2163 hdb = create_package_db();
2165 create_property_table(hdb);
2166 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'");
2168 r = package_from_db( hdb, &hpkg );
2169 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2171 skip("Not enough rights to perform tests\n");
2172 DeleteFileA(msifile);
2173 return;
2175 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2177 /* test invalid values */
2178 r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2179 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2181 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2182 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2184 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2185 ok(!r, "got %u\n", r);
2187 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2188 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2190 /* test retrieving an empty/nonexistent property */
2191 sz = sizeof buffer;
2192 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2193 ok(!r, "got %u\n", r);
2194 ok(sz == 0, "got size %d\n", sz);
2196 sz = 0;
2197 strcpy(buffer,"x");
2198 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2199 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2200 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer);
2201 ok(sz == 0, "got size %u\n", sz);
2203 sz = 1;
2204 strcpy(buffer,"x");
2205 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2206 ok(!r, "got %u\n", r);
2207 ok(!buffer[0], "got \"%s\"\n", buffer);
2208 ok(sz == 0, "got size %u\n", sz);
2210 /* set the property to something */
2211 r = MsiSetPropertyA( 0, NULL, NULL );
2212 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r);
2214 r = MsiSetPropertyA( hpkg, NULL, NULL );
2215 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2217 r = MsiSetPropertyA( hpkg, "", NULL );
2218 ok(!r, "got %u\n", r);
2220 r = MsiSetPropertyA( hpkg, "", "asdf" );
2221 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
2223 r = MsiSetPropertyA( hpkg, "=", "asdf" );
2224 ok(!r, "got %u\n", r);
2225 check_prop(hpkg, "=", "asdf", 1);
2227 r = MsiSetPropertyA( hpkg, " ", "asdf" );
2228 ok(!r, "got %u\n", r);
2229 check_prop(hpkg, " ", "asdf", 1);
2231 r = MsiSetPropertyA( hpkg, "'", "asdf" );
2232 ok(!r, "got %u\n", r);
2233 check_prop(hpkg, "'", "asdf", 1);
2235 /* set empty values */
2236 r = MsiSetPropertyA( hpkg, "boo", NULL );
2237 ok(!r, "got %u\n", r);
2238 check_prop(hpkg, "boo", "", 1);
2240 r = MsiSetPropertyA( hpkg, "boo", "" );
2241 ok(!r, "got %u\n", r);
2242 check_prop(hpkg, "boo", "", 1);
2244 /* set a non-empty value */
2245 r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2246 ok(!r, "got %u\n", r);
2247 check_prop(hpkg, "boo", "xyz", 1);
2249 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
2250 ok(!r, "got %u\n", r);
2252 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL);
2253 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2255 sz = 0;
2256 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz);
2257 ok(!r, "got %u\n", r);
2258 ok(sz == 3, "got size %u\n", sz);
2260 sz = 0;
2261 strcpy(buffer, "q");
2262 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz);
2263 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2264 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer);
2265 ok(sz == 3, "got size %u\n", sz);
2267 sz = 1;
2268 strcpy(buffer,"x");
2269 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2270 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2271 ok(!buffer[0], "got \"%s\"\n", buffer);
2272 ok(sz == 3, "got size %u\n", sz);
2274 sz = 3;
2275 strcpy(buffer,"x");
2276 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2277 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2278 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer);
2279 ok(sz == 3, "got size %u\n", sz);
2281 sz = 4;
2282 strcpy(buffer,"x");
2283 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2284 ok(!r, "got %u\n", r);
2285 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer);
2286 ok(sz == 3, "got size %u\n", sz);
2288 sz = 0;
2289 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz);
2290 ok(!r, "got %u\n", r);
2291 ok(sz == 3, "got size %u\n", sz);
2293 sz = 0;
2294 lstrcpyW(bufferW, L"boo");
2295 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz);
2296 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2297 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW));
2298 ok(sz == 3, "got size %u\n", sz);
2300 sz = 1;
2301 lstrcpyW(bufferW, L"boo");
2302 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2303 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2304 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
2305 ok(sz == 3, "got size %u\n", sz);
2307 sz = 3;
2308 lstrcpyW(bufferW, L"boo");
2309 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2310 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2311 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW));
2312 ok(sz == 3, "got size %u\n", sz);
2314 sz = 4;
2315 lstrcpyW(bufferW, L"boo");
2316 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2317 ok(!r, "got %u\n", r);
2318 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW));
2319 ok(sz == 3, "got size %u\n", sz);
2321 /* properties are case-sensitive */
2322 check_prop(hpkg, "BOO", "", 1);
2324 /* properties set in Property table should work */
2325 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1);
2327 MsiCloseHandle( hpkg );
2328 DeleteFileA(msifile);
2331 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2333 MSIHANDLE hview, hrec;
2334 BOOL found = FALSE;
2335 CHAR buffer[MAX_PATH];
2336 DWORD sz;
2337 UINT r;
2339 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2340 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2341 r = MsiViewExecute(hview, 0);
2342 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2344 if (len < 0) len = lstrlenA(val);
2346 while (r == ERROR_SUCCESS && !found)
2348 r = MsiViewFetch(hview, &hrec);
2349 if (r != ERROR_SUCCESS) break;
2351 sz = MAX_PATH;
2352 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2353 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2355 sz = MAX_PATH;
2356 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2357 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2359 ok(sz == len, "wrong size %u\n", sz);
2360 found = TRUE;
2364 MsiCloseHandle(hrec);
2366 MsiViewClose(hview);
2367 MsiCloseHandle(hview);
2368 return found;
2371 static void test_property_table(void)
2373 const char *query;
2374 UINT r;
2375 MSIHANDLE hpkg, hdb, hrec;
2376 char buffer[MAX_PATH], package[10];
2377 DWORD sz;
2378 BOOL found;
2380 hdb = create_package_db();
2381 ok( hdb, "failed to create package\n");
2383 r = package_from_db(hdb, &hpkg);
2384 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2386 skip("Not enough rights to perform tests\n");
2387 DeleteFileA(msifile);
2388 return;
2390 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2392 MsiCloseHandle(hdb);
2394 hdb = MsiGetActiveDatabase(hpkg);
2396 query = "CREATE TABLE `_Property` ( "
2397 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2398 r = run_query(hdb, query);
2399 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2401 MsiCloseHandle(hdb);
2402 MsiCloseHandle(hpkg);
2403 DeleteFileA(msifile);
2405 hdb = create_package_db();
2406 ok( hdb, "failed to create package\n");
2408 query = "CREATE TABLE `_Property` ( "
2409 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2410 r = run_query(hdb, query);
2411 ok(r == ERROR_SUCCESS, "failed to create table\n");
2413 query = "ALTER `_Property` ADD `foo` INTEGER";
2414 r = run_query(hdb, query);
2415 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2417 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2418 r = run_query(hdb, query);
2419 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2421 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2422 r = run_query(hdb, query);
2423 ok(r == ERROR_SUCCESS, "failed to add column\n");
2425 sprintf(package, "#%i", hdb);
2426 r = MsiOpenPackageA(package, &hpkg);
2427 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2428 if (r == ERROR_SUCCESS)
2429 MsiCloseHandle(hpkg);
2431 r = MsiCloseHandle(hdb);
2432 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2434 hdb = create_package_db();
2435 ok (hdb, "failed to create package database\n");
2437 create_property_table(hdb);
2438 add_property_entry(hdb, "'prop', 'val'");
2440 create_custom_action_table(hdb);
2441 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2443 r = package_from_db(hdb, &hpkg);
2444 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2446 MsiCloseHandle(hdb);
2448 sz = MAX_PATH;
2449 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2451 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2453 hdb = MsiGetActiveDatabase(hpkg);
2455 found = find_prop_in_property(hdb, "prop", "val", -1);
2456 ok(found, "prop should be in the _Property table\n");
2458 add_property_entry(hdb, "'dantes', 'mercedes'");
2460 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2461 r = do_query(hdb, query, &hrec);
2462 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2464 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2465 ok(found == FALSE, "dantes should not be in the _Property table\n");
2467 sz = MAX_PATH;
2468 lstrcpyA(buffer, "aaa");
2469 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2471 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2473 r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2476 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2477 ok(found == TRUE, "dantes should be in the _Property table\n");
2479 r = MsiDoActionA( hpkg, "EmbedNull" );
2480 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2482 sz = MAX_PATH;
2483 memset( buffer, 'a', sizeof(buffer) );
2484 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2485 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2486 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2487 ok( sz == sizeof("\0np") - 1, "got %u\n", sz );
2489 found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2490 ok(found == TRUE, "prop2 should be in the _Property table\n");
2492 MsiCloseHandle(hdb);
2493 MsiCloseHandle(hpkg);
2494 DeleteFileA(msifile);
2497 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2499 MSIHANDLE htab = 0;
2500 UINT res;
2502 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2503 if( res == ERROR_SUCCESS )
2505 UINT r;
2507 r = MsiViewExecute( htab, hrec );
2508 if( r != ERROR_SUCCESS )
2510 res = r;
2511 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2514 r = MsiViewClose( htab );
2515 if( r != ERROR_SUCCESS )
2516 res = r;
2518 r = MsiCloseHandle( htab );
2519 if( r != ERROR_SUCCESS )
2520 res = r;
2522 return res;
2525 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2527 return try_query_param( hdb, szQuery, 0 );
2530 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2532 MSIHANDLE summary;
2533 UINT r;
2535 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2538 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2541 r = MsiSummaryInfoPersist(summary);
2542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2544 MsiCloseHandle(summary);
2547 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2549 MSIHANDLE summary;
2550 UINT r;
2552 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2555 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2558 r = MsiSummaryInfoPersist(summary);
2559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2561 MsiCloseHandle(summary);
2564 static void test_msipackage(void)
2566 MSIHANDLE hdb = 0, hpack = 100;
2567 UINT r;
2568 const char *query;
2569 char name[10];
2571 /* NULL szPackagePath */
2572 r = MsiOpenPackageA(NULL, &hpack);
2573 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2575 /* empty szPackagePath */
2576 r = MsiOpenPackageA("", &hpack);
2577 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2579 skip("Not enough rights to perform tests\n");
2580 return;
2582 todo_wine
2584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2587 if (r == ERROR_SUCCESS)
2588 MsiCloseHandle(hpack);
2590 /* nonexistent szPackagePath */
2591 r = MsiOpenPackageA("nonexistent", &hpack);
2592 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2594 /* NULL hProduct */
2595 r = MsiOpenPackageA(msifile, NULL);
2596 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2598 name[0]='#';
2599 name[1]=0;
2600 r = MsiOpenPackageA(name, &hpack);
2601 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2603 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2606 /* database exists, but is empty */
2607 sprintf(name, "#%d", hdb);
2608 r = MsiOpenPackageA(name, &hpack);
2609 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2610 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2612 query = "CREATE TABLE `Property` ( "
2613 "`Property` CHAR(72), `Value` CHAR(0) "
2614 "PRIMARY KEY `Property`)";
2615 r = try_query(hdb, query);
2616 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2618 query = "CREATE TABLE `InstallExecuteSequence` ("
2619 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2620 "PRIMARY KEY `Action`)";
2621 r = try_query(hdb, query);
2622 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2624 /* a few key tables exist */
2625 sprintf(name, "#%d", hdb);
2626 r = MsiOpenPackageA(name, &hpack);
2627 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2628 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2630 MsiCloseHandle(hdb);
2631 DeleteFileA(msifile);
2633 /* start with a clean database to show what constitutes a valid package */
2634 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2637 sprintf(name, "#%d", hdb);
2639 /* The following summary information props must exist:
2640 * - PID_REVNUMBER
2641 * - PID_PAGECOUNT
2644 set_summary_dword(hdb, PID_PAGECOUNT, 100);
2645 r = MsiOpenPackageA(name, &hpack);
2646 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2647 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2649 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2650 r = MsiOpenPackageA(name, &hpack);
2651 ok(r == ERROR_SUCCESS,
2652 "Expected ERROR_SUCCESS, got %d\n", r);
2654 MsiCloseHandle(hpack);
2655 MsiCloseHandle(hdb);
2656 DeleteFileA(msifile);
2659 static void test_formatrecord2(void)
2661 MSIHANDLE hpkg, hrec ;
2662 char buffer[0x100];
2663 DWORD sz;
2664 UINT r;
2666 r = package_from_db(create_package_db(), &hpkg);
2667 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2669 skip("Not enough rights to perform tests\n");
2670 DeleteFileA(msifile);
2671 return;
2673 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2675 r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2676 ok( r == ERROR_SUCCESS, "set property failed\n");
2678 hrec = MsiCreateRecord(2);
2679 ok(hrec, "create record failed\n");
2681 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2682 ok( r == ERROR_SUCCESS, "format record failed\n");
2684 buffer[0] = 0;
2685 sz = sizeof buffer;
2686 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2687 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2689 r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2690 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2691 r = MsiRecordSetStringA(hrec, 1, "hoo");
2692 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2693 sz = sizeof buffer;
2694 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2695 ok( sz == 3, "size wrong\n");
2696 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2697 ok( r == ERROR_SUCCESS, "format failed\n");
2699 r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2700 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2701 sz = sizeof buffer;
2702 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2703 ok( sz == 3, "size wrong\n");
2704 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2705 ok( r == ERROR_SUCCESS, "format failed\n");
2707 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2708 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2709 r = MsiRecordSetStringA(hrec, 1, "hoo");
2710 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2711 sz = sizeof buffer;
2712 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2713 ok( sz == 3, "size wrong\n");
2714 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2715 ok( r == ERROR_SUCCESS, "format failed\n");
2717 r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2718 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2719 sz = sizeof buffer;
2720 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2721 ok( sz == 1, "size wrong\n");
2722 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2723 ok( r == ERROR_SUCCESS, "format failed\n");
2725 SetEnvironmentVariableA("FOO", "BAR");
2726 r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2727 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2728 sz = sizeof buffer;
2729 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2730 ok( sz == 3, "size wrong\n");
2731 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2732 ok( r == ERROR_SUCCESS, "format failed\n");
2734 r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2735 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2736 r = MsiRecordSetStringA(hrec, 1, "%FOO");
2737 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2738 sz = sizeof buffer;
2739 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2740 ok( sz == 3, "size wrong\n");
2741 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2742 ok( r == ERROR_SUCCESS, "format failed\n");
2744 MsiCloseHandle( hrec );
2745 MsiCloseHandle( hpkg );
2746 DeleteFileA(msifile);
2749 static void test_formatrecord_tables(void)
2751 MSIHANDLE hdb, hrec, hpkg = 0;
2752 CHAR buf[MAX_PATH + 41];
2753 CHAR curr_dir[MAX_PATH];
2754 CHAR expected[MAX_PATH + 45];
2755 CHAR root[MAX_PATH];
2756 DWORD size;
2757 UINT r;
2759 GetCurrentDirectoryA( MAX_PATH, curr_dir );
2761 hdb = create_package_db();
2762 ok ( hdb, "failed to create package database\n");
2764 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2765 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2766 "'I am a really long directory'" );
2768 create_feature_table( hdb );
2769 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2771 create_component_table( hdb );
2772 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2773 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2774 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2776 create_feature_components_table( hdb );
2777 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2778 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2779 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2781 create_file_table( hdb );
2782 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2783 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2784 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2786 create_custom_action_table( hdb );
2787 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2788 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2789 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2790 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2791 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2793 r = package_from_db( hdb, &hpkg );
2794 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2796 skip("Not enough rights to perform tests\n");
2797 MsiCloseHandle( hdb );
2798 DeleteFileA( msifile );
2799 return;
2801 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2803 MsiCloseHandle( hdb );
2805 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2806 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2808 hrec = MsiCreateRecord( 1 );
2810 /* property doesn't exist */
2811 size = MAX_PATH;
2812 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2813 MsiRecordSetStringA( hrec, 1, "[idontexist]" );
2814 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2815 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2816 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2818 /* property exists */
2819 size = MAX_PATH;
2820 MsiRecordSetStringA( hrec, 1, "[imaprop]" );
2821 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2822 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2823 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2825 size = MAX_PATH;
2826 MsiRecordSetStringA( hrec, 0, "1: [1] " );
2827 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2828 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2829 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2831 /* environment variable doesn't exist */
2832 size = MAX_PATH;
2833 MsiRecordSetStringA( hrec, 1, "[%idontexist]" );
2834 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2835 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2836 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2838 /* environment variable exists */
2839 size = MAX_PATH;
2840 SetEnvironmentVariableA( "crazyvar", "crazyval" );
2841 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" );
2842 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2843 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2844 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2846 /* file key before CostInitialize */
2847 size = MAX_PATH;
2848 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2849 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2850 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2851 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2853 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2855 r = MsiDoActionA(hpkg, "CostInitialize");
2856 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2858 r = MsiDoActionA(hpkg, "FileCost");
2859 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2861 r = MsiDoActionA(hpkg, "CostFinalize");
2862 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2864 size = MAX_PATH;
2865 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size );
2867 sprintf( expected, "1: %sfrontal.txt ", root);
2869 /* frontal full file key */
2870 size = MAX_PATH;
2871 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2872 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2873 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2874 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2876 /* frontal short file key */
2877 size = MAX_PATH;
2878 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" );
2879 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2880 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2881 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2883 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2885 /* temporal full file key */
2886 size = MAX_PATH;
2887 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" );
2888 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2889 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2890 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2892 /* temporal short file key */
2893 size = MAX_PATH;
2894 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" );
2895 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2896 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2897 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2899 /* custom action 51, files don't exist */
2900 r = MsiDoActionA( hpkg, "MyCustom" );
2901 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2903 sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2905 size = MAX_PATH;
2906 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2907 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2908 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2910 sprintf( buf, "%sI am a really long directory", root );
2911 CreateDirectoryA( buf, NULL );
2913 lstrcatA( buf, "\\temporal.txt" );
2914 create_test_file( buf );
2916 /* custom action 51, files exist */
2917 r = MsiDoActionA( hpkg, "MyCustom" );
2918 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2920 size = MAX_PATH;
2921 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2922 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2923 todo_wine
2925 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2928 /* custom action 51, escaped text 1 */
2929 r = MsiDoActionA( hpkg, "EscapeIt1" );
2930 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2932 size = MAX_PATH;
2933 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2934 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2935 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2937 /* custom action 51, escaped text 2 */
2938 r = MsiDoActionA( hpkg, "EscapeIt2" );
2939 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2941 size = MAX_PATH;
2942 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2943 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2944 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf);
2946 /* custom action 51, escaped text 3 */
2947 r = MsiDoActionA( hpkg, "EscapeIt3" );
2948 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2950 size = MAX_PATH;
2951 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2952 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2953 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf);
2955 /* custom action 51, embedded null */
2956 r = MsiDoActionA( hpkg, "EmbedNull" );
2957 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2959 size = MAX_PATH;
2960 memset( buf, 'a', sizeof(buf) );
2961 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2962 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2963 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
2964 ok( size == sizeof("\0np") - 1, "got %u\n", size );
2966 r = MsiSetPropertyA( hpkg, "prop", "[~]np" );
2967 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2969 size = MAX_PATH;
2970 memset( buf, 'a', sizeof(buf) );
2971 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2972 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2973 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2975 sprintf( expected, "1: %sI am a really long directory\\ ", root);
2977 /* component with INSTALLSTATE_LOCAL */
2978 size = MAX_PATH;
2979 MsiRecordSetStringA( hrec, 1, "[$temporal]" );
2980 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2981 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2982 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2984 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE );
2985 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2987 /* component with INSTALLSTATE_SOURCE */
2988 lstrcpyA( expected, "1: " );
2989 lstrcatA( expected, curr_dir );
2990 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" );
2991 lstrcatA( expected, " " );
2992 size = MAX_PATH;
2993 MsiRecordSetStringA( hrec, 1, "[$parietal]" );
2994 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2995 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2996 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2998 sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2999 DeleteFileA( buf );
3001 sprintf( buf, "%sI am a really long directory", root );
3002 RemoveDirectoryA( buf );
3004 MsiCloseHandle( hrec );
3005 MsiCloseHandle( hpkg );
3006 DeleteFileA( msifile );
3009 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
3010 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3012 UINT r;
3013 INSTALLSTATE state = 0xdeadbee;
3014 INSTALLSTATE action = 0xdeadbee;
3016 r = MsiGetFeatureStateA( package, feature, &state, &action );
3017 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3018 if (r == ERROR_SUCCESS)
3020 ok( state == expected_state, "%u: expected state %d got %d\n",
3021 line, expected_state, state );
3022 todo_wine_if (todo)
3023 ok( action == expected_action, "%u: expected action %d got %d\n",
3024 line, expected_action, action );
3026 else
3028 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
3029 todo_wine_if (todo)
3030 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
3035 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
3036 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3038 UINT r;
3039 INSTALLSTATE state = 0xdeadbee;
3040 INSTALLSTATE action = 0xdeadbee;
3042 r = MsiGetComponentStateA( package, component, &state, &action );
3043 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3044 if (r == ERROR_SUCCESS)
3046 ok( state == expected_state, "%u: expected state %d got %d\n",
3047 line, expected_state, state );
3048 todo_wine_if (todo)
3049 ok( action == expected_action, "%u: expected action %d got %d\n",
3050 line, expected_action, action );
3052 else
3054 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
3055 line, state );
3056 todo_wine_if (todo)
3057 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
3058 line, action );
3062 static void test_states(void)
3064 static const char msifile2[] = "winetest2-package.msi";
3065 static const char msifile3[] = "winetest3-package.msi";
3066 static const char msifile4[] = "winetest4-package.msi";
3067 static const WCHAR msifile2W[] = L"winetest2-package.msi";
3068 static const WCHAR msifile3W[] = L"winetest3-package.msi";
3069 static const WCHAR msifile4W[] = L"winetest4-package.msi";
3070 char msi_cache_file[MAX_PATH];
3071 DWORD cache_file_name_len;
3072 INSTALLSTATE state;
3073 MSIHANDLE hpkg, hprod;
3074 UINT r;
3075 MSIHANDLE hdb;
3076 BOOL is_broken;
3077 char value[MAX_PATH];
3078 DWORD size;
3080 if (is_process_limited())
3082 skip("process is limited\n");
3083 return;
3086 hdb = create_package_db();
3087 ok ( hdb, "failed to create package database\n" );
3089 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3091 create_property_table( hdb );
3092 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
3093 add_property_entry( hdb, "'ProductLanguage', '1033'" );
3094 add_property_entry( hdb, "'ProductName', 'MSITEST'" );
3095 add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
3096 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
3097 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
3099 create_install_execute_sequence_table( hdb );
3100 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
3101 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
3102 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
3103 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
3104 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
3105 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
3106 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
3107 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
3108 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
3109 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
3110 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
3112 create_media_table( hdb );
3113 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
3115 create_feature_table( hdb );
3117 create_component_table( hdb );
3119 /* msidbFeatureAttributesFavorLocal */
3120 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3122 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
3123 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
3125 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
3126 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
3128 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
3129 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
3131 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
3132 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
3134 /* msidbFeatureAttributesFavorSource */
3135 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
3137 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
3138 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
3140 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3141 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
3143 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
3144 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
3146 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
3147 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
3149 /* msidbFeatureAttributesFavorSource */
3150 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
3152 /* msidbFeatureAttributesFavorLocal */
3153 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
3155 /* disabled */
3156 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
3158 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3159 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3161 /* no feature parent:msidbComponentAttributesLocalOnly */
3162 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3164 /* msidbFeatureAttributesFavorLocal:removed */
3165 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
3167 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3168 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3170 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3171 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3173 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3174 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3176 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3177 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3179 /* msidbFeatureAttributesFavorSource:removed */
3180 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
3182 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3183 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3185 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3186 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3188 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3189 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3191 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3192 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3194 /* msidbFeatureAttributesFavorLocal */
3195 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
3197 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3199 /* msidbFeatureAttributesFavorSource */
3200 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
3202 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3204 /* msidbFeatureAttributesFavorAdvertise */
3205 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
3207 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3209 /* msidbFeatureAttributesUIDisallowAbsent */
3210 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
3212 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3214 /* high install level */
3215 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
3217 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3219 /* msidbFeatureAttributesFollowParent */
3220 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
3222 create_feature_components_table( hdb );
3223 add_feature_components_entry( hdb, "'one', 'alpha'" );
3224 add_feature_components_entry( hdb, "'one', 'beta'" );
3225 add_feature_components_entry( hdb, "'one', 'gamma'" );
3226 add_feature_components_entry( hdb, "'one', 'theta'" );
3227 add_feature_components_entry( hdb, "'two', 'delta'" );
3228 add_feature_components_entry( hdb, "'two', 'epsilon'" );
3229 add_feature_components_entry( hdb, "'two', 'zeta'" );
3230 add_feature_components_entry( hdb, "'two', 'iota'" );
3231 add_feature_components_entry( hdb, "'three', 'eta'" );
3232 add_feature_components_entry( hdb, "'four', 'eta'" );
3233 add_feature_components_entry( hdb, "'five', 'eta'" );
3234 add_feature_components_entry( hdb, "'six', 'lambda'" );
3235 add_feature_components_entry( hdb, "'six', 'mu'" );
3236 add_feature_components_entry( hdb, "'six', 'nu'" );
3237 add_feature_components_entry( hdb, "'six', 'xi'" );
3238 add_feature_components_entry( hdb, "'seven', 'omicron'" );
3239 add_feature_components_entry( hdb, "'seven', 'pi'" );
3240 add_feature_components_entry( hdb, "'seven', 'rho'" );
3241 add_feature_components_entry( hdb, "'seven', 'sigma'" );
3242 add_feature_components_entry( hdb, "'eight', 'tau'" );
3243 add_feature_components_entry( hdb, "'nine', 'phi'" );
3244 add_feature_components_entry( hdb, "'ten', 'chi'" );
3245 add_feature_components_entry( hdb, "'eleven', 'psi'" );
3246 add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3247 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3249 create_file_table( hdb );
3250 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3251 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3252 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3253 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3254 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3255 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3256 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3257 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3259 /* compressed file */
3260 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3262 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3263 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3264 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3265 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3266 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3267 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3268 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3269 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3270 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3271 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3272 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3273 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3274 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3275 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3277 r = MsiDatabaseCommit(hdb);
3278 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
3280 /* these properties must not be in the saved msi file */
3281 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3282 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3283 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3284 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3285 add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3287 r = package_from_db( hdb, &hpkg );
3288 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3290 skip("Not enough rights to perform tests\n");
3291 DeleteFileA(msifile);
3292 return;
3294 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3296 MsiCloseHandle(hdb);
3298 CopyFileA(msifile, msifile2, FALSE);
3299 CopyFileA(msifile, msifile3, FALSE);
3300 CopyFileA(msifile, msifile4, FALSE);
3302 size = sizeof(value);
3303 memset(value, 0, sizeof(value));
3304 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3305 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3306 ok(!value[0], "ProductToBeRegistered = %s\n", value);
3308 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3309 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3311 r = MsiDoActionA( hpkg, "CostInitialize");
3312 ok( r == ERROR_SUCCESS, "cost init failed\n");
3314 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3315 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3317 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3319 r = MsiDoActionA( hpkg, "FileCost");
3320 ok( r == ERROR_SUCCESS, "file cost failed\n");
3322 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3323 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3325 r = MsiDoActionA( hpkg, "CostFinalize");
3326 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3328 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3329 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3330 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3331 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3332 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3333 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3334 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3335 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3336 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3337 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3338 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3339 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3340 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3342 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3343 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3344 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3345 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3346 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3347 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3348 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3349 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3350 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3351 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3352 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3353 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3354 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3355 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3356 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3357 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3358 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3359 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3360 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3361 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3362 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3363 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3364 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3366 MsiCloseHandle( hpkg );
3368 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3370 /* publish the features and components */
3371 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3374 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
3375 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3377 /* these properties must not be in the saved msi file */
3378 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3379 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3380 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3381 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3383 r = package_from_db( hdb, &hpkg );
3384 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3386 MsiCloseHandle(hdb);
3388 size = sizeof(value);
3389 memset(value, 0, sizeof(value));
3390 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3391 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3392 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value);
3394 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3395 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3397 r = MsiDoActionA( hpkg, "CostInitialize");
3398 ok( r == ERROR_SUCCESS, "cost init failed\n");
3400 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3401 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3403 r = MsiDoActionA( hpkg, "FileCost");
3404 ok( r == ERROR_SUCCESS, "file cost failed\n");
3406 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3407 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3409 r = MsiDoActionA( hpkg, "CostFinalize");
3410 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3412 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3413 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3414 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3415 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3416 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3417 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3418 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3419 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3420 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3421 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3422 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3423 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3424 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3426 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3427 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3428 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3429 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3430 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3431 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3432 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3433 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3434 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3435 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3436 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3437 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3438 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3439 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3440 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3441 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3442 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3443 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3444 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3445 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3446 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3447 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3448 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3450 MsiCloseHandle(hpkg);
3452 /* uninstall the product */
3453 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3456 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3457 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3458 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3459 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3461 /* all features installed locally */
3462 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3466 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3467 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3468 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3470 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb);
3471 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3473 /* these properties must not be in the saved msi file */
3474 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3476 r = package_from_db( hdb, &hpkg );
3477 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3479 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3480 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3482 r = MsiDoActionA( hpkg, "CostInitialize");
3483 ok( r == ERROR_SUCCESS, "cost init failed\n");
3485 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3486 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3488 r = MsiDoActionA( hpkg, "CostFinalize");
3489 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3491 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3492 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3493 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3494 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3495 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3496 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3497 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3498 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3499 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3500 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3501 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3502 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3503 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3505 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3506 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3507 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3508 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3509 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3510 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3511 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3512 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3513 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3514 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3515 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3516 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3517 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3518 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3519 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3520 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3521 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3522 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3523 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3524 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3525 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3526 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3527 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3529 MsiCloseHandle(hpkg);
3531 /* uninstall the product */
3532 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3535 /* all features installed from source */
3536 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3539 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3540 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3541 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3542 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3544 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3545 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3547 /* this property must not be in the saved msi file */
3548 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3550 r = package_from_db( hdb, &hpkg );
3551 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3553 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3554 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3556 r = MsiDoActionA( hpkg, "CostInitialize");
3557 ok( r == ERROR_SUCCESS, "cost init failed\n");
3559 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3560 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3562 r = MsiDoActionA( hpkg, "FileCost");
3563 ok( r == ERROR_SUCCESS, "file cost failed\n");
3565 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3566 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3568 r = MsiDoActionA( hpkg, "CostFinalize");
3569 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3571 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3572 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3573 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3574 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3575 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3576 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3577 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3578 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3579 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3580 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3581 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3582 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3583 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3585 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3586 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3587 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3588 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3589 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3590 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3591 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3592 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3593 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3594 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3595 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3596 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3597 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3598 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3599 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3600 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3601 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3602 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3603 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3604 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3605 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3606 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3607 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3609 MsiCloseHandle(hpkg);
3611 /* reinstall the product */
3612 r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3613 is_broken = (r == ERROR_INSTALL_FAILURE);
3614 ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r);
3616 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3617 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3618 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3619 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3621 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3622 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3624 /* this property must not be in the saved msi file */
3625 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3627 r = package_from_db( hdb, &hpkg );
3628 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3630 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3631 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3633 r = MsiDoActionA( hpkg, "CostInitialize");
3634 ok( r == ERROR_SUCCESS, "cost init failed\n");
3636 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3637 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3639 r = MsiDoActionA( hpkg, "FileCost");
3640 ok( r == ERROR_SUCCESS, "file cost failed\n");
3642 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3643 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3645 r = MsiDoActionA( hpkg, "CostFinalize");
3646 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3648 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3649 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3650 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3651 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3652 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3653 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3654 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3655 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3656 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3657 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3658 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3659 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3660 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3662 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3663 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3664 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3665 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3666 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3667 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3668 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3669 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3670 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3671 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3672 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3673 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3674 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3675 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3676 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3677 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3678 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3679 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3680 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3681 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3682 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3683 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3684 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3686 MsiCloseHandle(hpkg);
3688 /* test source only install */
3689 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3691 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3692 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3693 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3694 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3696 r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3699 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3700 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3701 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3703 /* no arguments test */
3704 cache_file_name_len = sizeof(msi_cache_file);
3705 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3706 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3707 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3708 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3709 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3711 create_custom_action_table( hdb );
3712 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3713 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3714 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3715 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3716 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3717 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3718 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3719 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3720 add_custom_action_entry( hdb,
3721 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3723 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3724 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3725 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3726 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3727 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3728 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3729 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3730 /* Add "one" feature action tests */
3731 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3732 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3733 r = MsiDatabaseCommit(hdb);
3734 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3735 r = package_from_db( hdb, &hpkg );
3736 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3737 MsiCloseHandle(hdb);
3739 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3740 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3741 r = MsiDoActionA( hpkg, "CostInitialize");
3742 ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3743 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3744 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3746 r = MsiDoActionA( hpkg, "FileCost");
3747 ok( r == ERROR_SUCCESS, "FileCost failed\n");
3748 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3749 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3751 r = MsiDoActionA( hpkg, "CostFinalize");
3752 ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3753 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3754 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3755 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3756 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3757 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3758 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3759 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3760 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3761 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3762 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3763 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3764 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3765 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3766 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3767 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3768 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3769 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3770 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3771 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3772 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3773 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3774 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3775 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3776 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3777 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3779 r = MsiDoActionA( hpkg, "InstallValidate");
3780 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3781 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3782 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3783 MsiCloseHandle( hpkg );
3785 r = MsiInstallProductA(msifile, "");
3786 ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */,
3787 "Expected ERROR_SUCCESS, got %d\n", r);
3788 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3789 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3790 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3791 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3792 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3793 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3795 /* minor upgrade test with no REINSTALL argument */
3796 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3798 size = MAX_PATH;
3799 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3801 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
3802 MsiCloseHandle(hprod);
3804 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3805 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3806 update_ProductVersion_property( hdb, "1.1.2" );
3807 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3808 r = MsiDatabaseCommit(hdb);
3809 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3810 MsiCloseHandle(hdb);
3812 r = MsiInstallProductA(msifile2, "");
3813 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
3815 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3818 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3820 size = MAX_PATH;
3821 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3823 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3824 MsiCloseHandle(hprod);
3826 /* major upgrade test */
3827 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3828 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3829 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3830 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3831 create_upgrade_table( hdb );
3832 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3833 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3834 update_ProductVersion_property( hdb, "1.1.3" );
3835 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3836 r = MsiDatabaseCommit(hdb);
3837 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3838 MsiCloseHandle(hdb);
3840 r = MsiInstallProductA(msifile2, "");
3841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3843 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3844 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3845 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
3846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3847 size = MAX_PATH;
3848 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3850 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
3851 MsiCloseHandle(hprod);
3853 /* uninstall the product */
3854 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3857 DeleteFileA(msifile);
3858 DeleteFileA(msifile2);
3859 DeleteFileA(msifile3);
3860 DeleteFileA(msifile4);
3863 static void test_removefiles(void)
3865 MSIHANDLE hpkg;
3866 UINT r;
3867 MSIHANDLE hdb;
3868 INSTALLSTATE installed, action;
3870 hdb = create_package_db();
3871 ok ( hdb, "failed to create package database\n" );
3873 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3875 create_feature_table( hdb );
3876 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3878 create_component_table( hdb );
3879 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3880 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3881 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3882 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3883 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3884 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3885 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3887 create_feature_components_table( hdb );
3888 add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3889 add_feature_components_entry( hdb, "'one', 'helium'" );
3890 add_feature_components_entry( hdb, "'one', 'lithium'" );
3891 add_feature_components_entry( hdb, "'one', 'beryllium'" );
3892 add_feature_components_entry( hdb, "'one', 'boron'" );
3893 add_feature_components_entry( hdb, "'one', 'carbon'" );
3894 add_feature_components_entry( hdb, "'one', 'oxygen'" );
3896 create_file_table( hdb );
3897 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3898 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3899 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3900 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3901 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3902 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3903 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3905 create_remove_file_table( hdb );
3907 r = package_from_db( hdb, &hpkg );
3908 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3910 skip("Not enough rights to perform tests\n");
3911 DeleteFileA(msifile);
3912 return;
3914 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3916 MsiCloseHandle( hdb );
3918 create_test_file( "hydrogen.txt" );
3919 create_test_file( "helium.txt" );
3920 create_test_file( "lithium.txt" );
3921 create_test_file( "beryllium.txt" );
3922 create_test_file( "boron.txt" );
3923 create_test_file( "carbon.txt" );
3924 create_test_file( "oxygen.txt" );
3926 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3927 ok( r == ERROR_SUCCESS, "set property failed\n");
3929 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3931 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3932 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3934 r = MsiDoActionA( hpkg, "CostInitialize");
3935 ok( r == ERROR_SUCCESS, "cost init failed\n");
3937 r = MsiDoActionA( hpkg, "FileCost");
3938 ok( r == ERROR_SUCCESS, "file cost failed\n");
3940 installed = action = 0xdeadbeef;
3941 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3942 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3943 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3944 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3946 r = MsiDoActionA( hpkg, "CostFinalize");
3947 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3949 r = MsiDoActionA( hpkg, "InstallValidate");
3950 ok( r == ERROR_SUCCESS, "install validate failed\n");
3952 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3953 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3955 installed = action = 0xdeadbeef;
3956 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3957 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3958 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3959 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3961 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3962 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3964 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3965 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3967 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3968 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3970 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3971 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3973 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3974 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3976 installed = action = 0xdeadbeef;
3977 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3978 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3979 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3980 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3982 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3983 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3985 installed = action = 0xdeadbeef;
3986 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3987 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3988 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3989 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3991 r = MsiDoActionA( hpkg, "RemoveFiles");
3992 ok( r == ERROR_SUCCESS, "remove files failed\n");
3994 installed = action = 0xdeadbeef;
3995 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3996 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3997 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3998 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
4000 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
4001 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
4002 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
4003 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
4004 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
4005 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
4006 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
4008 MsiCloseHandle( hpkg );
4009 DeleteFileA(msifile);
4012 static void test_appsearch(void)
4014 MSIHANDLE hpkg;
4015 UINT r;
4016 MSIHANDLE hdb;
4017 CHAR prop[MAX_PATH];
4018 DWORD size;
4019 HKEY hkey;
4020 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
4022 hdb = create_package_db();
4023 ok ( hdb, "failed to create package database\n" );
4025 create_appsearch_table( hdb );
4026 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
4027 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
4028 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
4029 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
4030 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
4032 create_reglocator_table( hdb );
4033 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
4035 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
4036 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4037 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
4038 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4039 RegCloseKey(hkey);
4040 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4042 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
4043 NULL, &hkey, NULL);
4044 if (r == ERROR_ACCESS_DENIED)
4046 skip("insufficient rights\n");
4047 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4048 MsiCloseHandle(hdb);
4049 DeleteFileA(msifile);
4050 return;
4052 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4054 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4055 sizeof("c:\\windows\\system32\\notepad.exe"));
4056 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4057 RegCloseKey(hkey);
4058 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4060 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
4061 NULL, &hkey, NULL);
4062 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4063 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4064 sizeof("c:\\windows\\system32\\notepad.exe"));
4065 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4066 RegCloseKey(hkey);
4067 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
4068 msidbLocatorTypeFileName|msidbLocatorType64bit );
4070 create_drlocator_table( hdb );
4071 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
4073 create_signature_table( hdb );
4074 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
4075 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4076 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4077 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4078 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4080 r = package_from_db( hdb, &hpkg );
4081 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4083 skip("Not enough rights to perform tests\n");
4084 DeleteFileA(msifile);
4085 return;
4087 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
4088 MsiCloseHandle( hdb );
4089 if (r != ERROR_SUCCESS)
4090 goto done;
4092 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4094 r = MsiDoActionA( hpkg, "AppSearch" );
4095 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
4097 size = sizeof(prop);
4098 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
4099 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4100 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4102 size = sizeof(prop);
4103 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
4104 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4106 size = sizeof(prop);
4107 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
4108 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4109 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4111 size = sizeof(prop);
4112 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
4113 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4114 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4116 size = sizeof(prop);
4117 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
4118 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4119 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4121 done:
4122 MsiCloseHandle( hpkg );
4123 DeleteFileA(msifile);
4124 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4125 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY);
4126 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY);
4129 static void test_appsearch_complocator(void)
4131 MSIHANDLE hpkg, hdb;
4132 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
4133 LPSTR usersid;
4134 DWORD size;
4135 UINT r;
4137 if (!(usersid = get_user_sid()))
4138 return;
4140 if (is_process_limited())
4142 skip("process is limited\n");
4143 return;
4146 create_test_file("FileName1");
4147 create_test_file("FileName4");
4148 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
4149 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
4151 create_test_file("FileName2");
4152 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
4153 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4155 create_test_file("FileName3");
4156 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
4157 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4159 create_test_file("FileName5");
4160 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
4161 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4163 create_test_file("FileName6");
4164 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
4165 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4167 create_test_file("FileName7");
4168 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
4169 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4171 /* dir is FALSE, but we're pretending it's a directory */
4172 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
4173 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4175 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4176 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
4177 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4179 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4180 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
4181 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4183 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4184 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
4185 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4187 hdb = create_package_db();
4188 ok(hdb, "Expected a valid database handle\n");
4190 create_appsearch_table(hdb);
4191 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4192 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4193 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4194 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4195 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4196 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4197 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4198 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4199 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4200 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4201 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4202 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4204 create_complocator_table(hdb);
4206 /* published component, machine, file, signature, misdbLocatorTypeFile */
4207 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4209 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4210 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4212 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4213 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4215 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4216 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4218 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4219 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4221 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4222 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4224 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4225 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4227 /* unpublished component, no signature, misdbLocatorTypeDir */
4228 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4230 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4231 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4233 /* published component, signature w/ ver, misdbLocatorTypeFile */
4234 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4236 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4237 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4239 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4240 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4242 create_signature_table(hdb);
4243 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4244 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4245 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4246 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4247 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4248 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4249 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4250 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4252 r = package_from_db(hdb, &hpkg);
4253 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4255 skip("Not enough rights to perform tests\n");
4256 goto error;
4258 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4260 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4263 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4265 r = MsiDoActionA(hpkg, "AppSearch");
4266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4268 strcpy(expected, CURR_DIR);
4269 if (is_root(CURR_DIR)) expected[2] = 0;
4271 size = MAX_PATH;
4272 sprintf(path, "%s\\FileName1", expected);
4273 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4275 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4277 size = MAX_PATH;
4278 sprintf(path, "%s\\FileName2", expected);
4279 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4281 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4283 size = MAX_PATH;
4284 sprintf(path, "%s\\FileName3", expected);
4285 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4287 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4289 size = MAX_PATH;
4290 sprintf(path, "%s\\FileName4", expected);
4291 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4293 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4295 size = MAX_PATH;
4296 sprintf(path, "%s\\FileName5", expected);
4297 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4299 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4301 size = MAX_PATH;
4302 sprintf(path, "%s\\", expected);
4303 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4305 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4307 size = MAX_PATH;
4308 sprintf(path, "%s\\", expected);
4309 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4311 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4313 size = MAX_PATH;
4314 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4316 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4318 size = MAX_PATH;
4319 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4321 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4323 size = MAX_PATH;
4324 sprintf(path, "%s\\FileName8.dll", expected);
4325 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4327 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4329 size = MAX_PATH;
4330 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4332 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4334 size = MAX_PATH;
4335 sprintf(path, "%s\\FileName10.dll", expected);
4336 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4338 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4340 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4341 MSIINSTALLCONTEXT_MACHINE, NULL);
4342 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4343 MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
4344 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4345 MSIINSTALLCONTEXT_USERMANAGED, usersid);
4346 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4347 MSIINSTALLCONTEXT_MACHINE, NULL);
4348 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4349 MSIINSTALLCONTEXT_MACHINE, NULL);
4350 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4351 MSIINSTALLCONTEXT_MACHINE, NULL);
4352 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4353 MSIINSTALLCONTEXT_MACHINE, NULL);
4354 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4355 MSIINSTALLCONTEXT_MACHINE, NULL);
4356 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4357 MSIINSTALLCONTEXT_MACHINE, NULL);
4358 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4359 MSIINSTALLCONTEXT_MACHINE, NULL);
4361 MsiCloseHandle(hpkg);
4363 error:
4364 DeleteFileA("FileName1");
4365 DeleteFileA("FileName2");
4366 DeleteFileA("FileName3");
4367 DeleteFileA("FileName4");
4368 DeleteFileA("FileName5");
4369 DeleteFileA("FileName6");
4370 DeleteFileA("FileName7");
4371 DeleteFileA("FileName8.dll");
4372 DeleteFileA("FileName9.dll");
4373 DeleteFileA("FileName10.dll");
4374 DeleteFileA(msifile);
4375 LocalFree(usersid);
4378 static void test_appsearch_reglocator(void)
4380 MSIHANDLE hpkg, hdb;
4381 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4382 DWORD binary[2], size, val;
4383 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4384 HKEY hklm, classes, hkcu, users;
4385 LPSTR pathdata, pathvar, ptr;
4386 LONG res;
4387 UINT r, type = 0;
4388 SYSTEM_INFO si;
4390 version = TRUE;
4391 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4392 version = FALSE;
4394 DeleteFileA("test.dll");
4396 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4397 if (res == ERROR_ACCESS_DENIED)
4399 skip("Not enough rights to perform tests\n");
4400 return;
4402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4404 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4405 (const BYTE *)"regszdata", 10);
4406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4408 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4411 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4412 (const BYTE *)"regszdata", 10);
4413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4415 users = 0;
4416 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4417 ok(res == ERROR_SUCCESS ||
4418 broken(res == ERROR_INVALID_PARAMETER),
4419 "Expected ERROR_SUCCESS, got %d\n", res);
4421 if (res == ERROR_SUCCESS)
4423 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4424 (const BYTE *)"regszdata", 10);
4425 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4428 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4429 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4431 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4432 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4434 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4435 (const BYTE *)"regszdata", 10);
4436 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4438 val = 42;
4439 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4440 (const BYTE *)&val, sizeof(DWORD));
4441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4443 val = -42;
4444 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4445 (const BYTE *)&val, sizeof(DWORD));
4446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4448 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4449 (const BYTE *)"%PATH%", 7);
4450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4452 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4453 (const BYTE *)"my%NOVAR%", 10);
4454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4456 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4457 (const BYTE *)"one\0two\0", 9);
4458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4460 binary[0] = 0x1234abcd;
4461 binary[1] = 0x567890ef;
4462 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4463 (const BYTE *)binary, sizeof(binary));
4464 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4466 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4467 (const BYTE *)"#regszdata", 11);
4468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4470 strcpy(expected, CURR_DIR);
4471 if (is_root(CURR_DIR)) expected[2] = 0;
4473 create_test_file("FileName1");
4474 sprintf(path, "%s\\FileName1", expected);
4475 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4476 (const BYTE *)path, lstrlenA(path) + 1);
4477 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4479 sprintf(path, "%s\\FileName2", expected);
4480 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4481 (const BYTE *)path, lstrlenA(path) + 1);
4482 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4484 lstrcpyA(path, expected);
4485 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4486 (const BYTE *)path, lstrlenA(path) + 1);
4487 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4489 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4490 (const BYTE *)"", 1);
4491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4493 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4494 sprintf(path, "%s\\FileName3.dll", expected);
4495 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4496 (const BYTE *)path, lstrlenA(path) + 1);
4497 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4500 sprintf(path, "%s\\FileName4.dll", expected);
4501 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4502 (const BYTE *)path, lstrlenA(path) + 1);
4503 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4505 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4506 sprintf(path, "%s\\FileName5.dll", expected);
4507 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4508 (const BYTE *)path, lstrlenA(path) + 1);
4509 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4511 sprintf(path, "\"%s\\FileName1\" -option", expected);
4512 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4513 (const BYTE *)path, lstrlenA(path) + 1);
4514 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4516 space = strchr(expected, ' ') != NULL;
4517 sprintf(path, "%s\\FileName1 -option", expected);
4518 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4519 (const BYTE *)path, lstrlenA(path) + 1);
4520 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4522 hdb = create_package_db();
4523 ok(hdb, "Expected a valid database handle\n");
4525 create_appsearch_table(hdb);
4526 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4527 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4528 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4529 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4530 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4531 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4532 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4533 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4534 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4535 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4536 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4537 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4538 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4539 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4540 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4541 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4542 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4543 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4544 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4545 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4546 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4547 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4548 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4549 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4550 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4551 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4552 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4553 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4554 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4555 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4557 create_reglocator_table(hdb);
4559 type = msidbLocatorTypeRawValue;
4560 if (is_64bit)
4561 type |= msidbLocatorType64bit;
4563 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4564 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4566 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4567 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4569 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4570 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4572 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4573 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4575 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4576 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4578 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4579 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4581 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4582 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4584 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4585 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4587 type = msidbLocatorTypeFileName;
4588 if (is_64bit)
4589 type |= msidbLocatorType64bit;
4591 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4592 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4594 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4595 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4597 /* HKLM, msidbLocatorTypeFileName, no signature */
4598 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4600 type = msidbLocatorTypeDirectory;
4601 if (is_64bit)
4602 type |= msidbLocatorType64bit;
4604 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4605 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4607 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4608 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4610 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4611 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4613 type = msidbLocatorTypeRawValue;
4614 if (is_64bit)
4615 type |= msidbLocatorType64bit;
4617 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4618 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4620 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4621 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4623 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4624 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4626 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4627 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4629 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4630 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4632 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4633 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4635 type = msidbLocatorTypeFileName;
4636 if (is_64bit)
4637 type |= msidbLocatorType64bit;
4639 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4640 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4642 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4643 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4645 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4646 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4648 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4649 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4651 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4652 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4654 type = msidbLocatorTypeDirectory;
4655 if (is_64bit)
4656 type |= msidbLocatorType64bit;
4658 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4659 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4661 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4662 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4664 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4665 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4667 type = msidbLocatorTypeFileName;
4668 if (is_64bit)
4669 type |= msidbLocatorType64bit;
4671 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4672 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4674 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4675 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4677 create_signature_table(hdb);
4678 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4679 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4680 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4681 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4682 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4683 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4685 if (!is_root(CURR_DIR))
4687 ptr = strrchr(expected, '\\') + 1;
4688 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4689 add_signature_entry(hdb, path);
4691 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4692 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4693 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4695 r = package_from_db(hdb, &hpkg);
4696 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4698 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4700 r = MsiDoActionA(hpkg, "AppSearch");
4701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4703 size = MAX_PATH;
4704 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4706 ok(!lstrcmpA(prop, "regszdata"),
4707 "Expected \"regszdata\", got \"%s\"\n", prop);
4709 size = MAX_PATH;
4710 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4712 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4714 size = MAX_PATH;
4715 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4716 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4717 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4719 memset(&si, 0, sizeof(si));
4720 GetNativeSystemInfo(&si);
4722 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4724 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4725 pathvar = HeapAlloc(GetProcessHeap(), 0, size);
4726 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4728 size = 0;
4729 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4732 pathdata = HeapAlloc(GetProcessHeap(), 0, ++size);
4733 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4735 ok(!lstrcmpA(pathdata, pathvar),
4736 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4738 HeapFree(GetProcessHeap(), 0, pathvar);
4739 HeapFree(GetProcessHeap(), 0, pathdata);
4742 size = MAX_PATH;
4743 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4745 ok(!lstrcmpA(prop,
4746 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4748 size = MAX_PATH;
4749 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4751 todo_wine
4753 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4754 "Expected \"\\0one\\0two\\0\\0\"\n");
4757 size = MAX_PATH;
4758 lstrcpyA(path, "#xCDAB3412EF907856");
4759 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4761 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4763 size = MAX_PATH;
4764 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4766 ok(!lstrcmpA(prop, "##regszdata"),
4767 "Expected \"##regszdata\", got \"%s\"\n", prop);
4769 size = MAX_PATH;
4770 sprintf(path, "%s\\FileName1", expected);
4771 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4772 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4773 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4775 size = MAX_PATH;
4776 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4777 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4778 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4780 size = MAX_PATH;
4781 sprintf(path, "%s\\", expected);
4782 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4784 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4786 size = MAX_PATH;
4787 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4789 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4791 size = MAX_PATH;
4792 sprintf(path, "%s\\", expected);
4793 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4795 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4797 size = MAX_PATH;
4798 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4802 size = MAX_PATH;
4803 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805 ok(!lstrcmpA(prop, "regszdata"),
4806 "Expected \"regszdata\", got \"%s\"\n", prop);
4808 size = MAX_PATH;
4809 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4811 ok(!lstrcmpA(prop, "regszdata"),
4812 "Expected \"regszdata\", got \"%s\"\n", prop);
4814 if (users)
4816 size = MAX_PATH;
4817 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4818 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4819 ok(!lstrcmpA(prop, "regszdata"),
4820 "Expected \"regszdata\", got \"%s\"\n", prop);
4823 size = MAX_PATH;
4824 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4825 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4826 ok(!lstrcmpA(prop, "defvalue"),
4827 "Expected \"defvalue\", got \"%s\"\n", prop);
4829 size = MAX_PATH;
4830 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4832 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4834 size = MAX_PATH;
4835 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4836 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4837 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4839 if (version)
4841 size = MAX_PATH;
4842 sprintf(path, "%s\\FileName3.dll", expected);
4843 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4845 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4847 size = MAX_PATH;
4848 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4850 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4852 size = MAX_PATH;
4853 sprintf(path, "%s\\FileName5.dll", expected);
4854 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4856 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4859 if (!is_root(CURR_DIR))
4861 size = MAX_PATH;
4862 lstrcpyA(path, expected);
4863 ptr = strrchr(path, '\\') + 1;
4864 *ptr = '\0';
4865 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4867 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4869 size = MAX_PATH;
4870 sprintf(path, "%s\\", expected);
4871 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4873 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4875 size = MAX_PATH;
4876 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4877 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4878 if (is_root(CURR_DIR))
4879 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4880 else
4881 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4883 size = MAX_PATH;
4884 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4886 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4888 size = MAX_PATH;
4889 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4891 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4893 size = MAX_PATH;
4894 sprintf(path, "%s\\FileName1", expected);
4895 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4897 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4899 size = MAX_PATH;
4900 sprintf(path, "%s\\FileName1", expected);
4901 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4903 if (space)
4904 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4905 else
4906 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4908 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4909 RegDeleteValueA(hklm, "Value1");
4910 RegDeleteValueA(hklm, "Value2");
4911 RegDeleteValueA(hklm, "Value3");
4912 RegDeleteValueA(hklm, "Value4");
4913 RegDeleteValueA(hklm, "Value5");
4914 RegDeleteValueA(hklm, "Value6");
4915 RegDeleteValueA(hklm, "Value7");
4916 RegDeleteValueA(hklm, "Value8");
4917 RegDeleteValueA(hklm, "Value9");
4918 RegDeleteValueA(hklm, "Value10");
4919 RegDeleteValueA(hklm, "Value11");
4920 RegDeleteValueA(hklm, "Value12");
4921 RegDeleteValueA(hklm, "Value13");
4922 RegDeleteValueA(hklm, "Value14");
4923 RegDeleteValueA(hklm, "Value15");
4924 RegDeleteValueA(hklm, "Value16");
4925 RegDeleteValueA(hklm, "Value17");
4926 RegDeleteKeyA(hklm, "");
4927 RegCloseKey(hklm);
4929 RegDeleteValueA(classes, "Value1");
4930 RegDeleteKeyA(classes, "");
4931 RegCloseKey(classes);
4933 RegDeleteValueA(hkcu, "Value1");
4934 RegDeleteKeyA(hkcu, "");
4935 RegCloseKey(hkcu);
4937 RegDeleteValueA(users, "Value1");
4938 RegDeleteKeyA(users, "");
4939 RegCloseKey(users);
4941 DeleteFileA("FileName1");
4942 DeleteFileA("FileName3.dll");
4943 DeleteFileA("FileName4.dll");
4944 DeleteFileA("FileName5.dll");
4945 MsiCloseHandle(hpkg);
4946 DeleteFileA(msifile);
4949 static void delete_win_ini(LPCSTR file)
4951 CHAR path[MAX_PATH];
4953 GetWindowsDirectoryA(path, MAX_PATH);
4954 lstrcatA(path, "\\");
4955 lstrcatA(path, file);
4957 DeleteFileA(path);
4960 static void test_appsearch_inilocator(void)
4962 MSIHANDLE hpkg, hdb;
4963 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4964 BOOL version;
4965 LPSTR ptr;
4966 DWORD size;
4967 UINT r;
4969 version = TRUE;
4970 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4971 version = FALSE;
4973 DeleteFileA("test.dll");
4975 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4977 strcpy(expected, CURR_DIR);
4978 if (is_root(CURR_DIR)) expected[2] = 0;
4980 create_test_file("FileName1");
4981 sprintf(path, "%s\\FileName1", expected);
4982 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4984 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4986 sprintf(path, "%s\\IDontExist", expected);
4987 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4989 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4990 sprintf(path, "%s\\FileName2.dll", expected);
4991 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4993 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4994 sprintf(path, "%s\\FileName3.dll", expected);
4995 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4997 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4998 sprintf(path, "%s\\FileName4.dll", expected);
4999 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
5001 hdb = create_package_db();
5002 ok(hdb, "Expected a valid database handle\n");
5004 create_appsearch_table(hdb);
5005 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5006 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5007 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5008 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5009 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5010 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5011 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5012 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5013 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5014 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5015 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5016 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
5018 create_inilocator_table(hdb);
5020 /* msidbLocatorTypeRawValue, field 1 */
5021 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
5023 /* msidbLocatorTypeRawValue, field 2 */
5024 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
5026 /* msidbLocatorTypeRawValue, entire field */
5027 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
5029 /* msidbLocatorTypeFile */
5030 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5032 /* msidbLocatorTypeDirectory, file */
5033 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
5035 /* msidbLocatorTypeDirectory, directory */
5036 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
5038 /* msidbLocatorTypeFile, file, no signature */
5039 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5041 /* msidbLocatorTypeFile, dir, no signature */
5042 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
5044 /* msidbLocatorTypeFile, file does not exist */
5045 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
5047 /* msidbLocatorTypeFile, signature with version */
5048 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
5050 /* msidbLocatorTypeFile, signature with version, ver > max */
5051 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
5053 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
5054 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
5056 create_signature_table(hdb);
5057 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
5058 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
5059 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5060 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5061 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5063 r = package_from_db(hdb, &hpkg);
5064 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5066 skip("Not enough rights to perform tests\n");
5067 goto error;
5069 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5071 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5073 r = MsiDoActionA(hpkg, "AppSearch");
5074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5076 size = MAX_PATH;
5077 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5079 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
5081 size = MAX_PATH;
5082 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5084 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
5086 size = MAX_PATH;
5087 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5089 ok(!lstrcmpA(prop, "keydata,field2"),
5090 "Expected \"keydata,field2\", got \"%s\"\n", prop);
5092 size = MAX_PATH;
5093 sprintf(path, "%s\\FileName1", expected);
5094 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5096 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5098 size = MAX_PATH;
5099 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5101 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5103 size = MAX_PATH;
5104 sprintf(path, "%s\\", expected);
5105 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5107 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5109 size = MAX_PATH;
5110 sprintf(path, "%s\\", expected);
5111 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5113 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5115 if (!is_root(CURR_DIR))
5117 size = MAX_PATH;
5118 lstrcpyA(path, expected);
5119 ptr = strrchr(path, '\\');
5120 *(ptr + 1) = 0;
5121 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5123 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5125 size = MAX_PATH;
5126 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5128 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5130 if (version)
5132 size = MAX_PATH;
5133 sprintf(path, "%s\\FileName2.dll", expected);
5134 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5136 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5138 size = MAX_PATH;
5139 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5141 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5143 size = MAX_PATH;
5144 sprintf(path, "%s\\FileName4.dll", expected);
5145 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
5146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5147 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5150 MsiCloseHandle(hpkg);
5152 error:
5153 delete_win_ini("IniFile.ini");
5154 DeleteFileA("FileName1");
5155 DeleteFileA("FileName2.dll");
5156 DeleteFileA("FileName3.dll");
5157 DeleteFileA("FileName4.dll");
5158 DeleteFileA(msifile);
5162 * MSI AppSearch action on DrLocator table always returns absolute paths.
5163 * If a relative path was set, it returns the first absolute path that
5164 * matches or an empty string if it didn't find anything.
5165 * This helper function replicates this behaviour.
5167 static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5169 int i, size;
5170 DWORD attr, drives;
5172 size = lstrlenA(relative);
5173 drives = GetLogicalDrives();
5174 lstrcpyA(absolute, "A:\\");
5175 for (i = 0; i < 26; absolute[0] = '\0', i++)
5177 if (!(drives & (1 << i)))
5178 continue;
5180 absolute[0] = 'A' + i;
5181 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5182 continue;
5184 lstrcpynA(absolute + 3, relative, size + 1);
5185 attr = GetFileAttributesA(absolute);
5186 if (attr != INVALID_FILE_ATTRIBUTES &&
5187 (attr & FILE_ATTRIBUTE_DIRECTORY))
5189 if (absolute[3 + size - 1] != '\\')
5190 lstrcatA(absolute, "\\");
5191 break;
5193 absolute[3] = '\0';
5197 static void test_appsearch_drlocator(void)
5199 MSIHANDLE hpkg, hdb;
5200 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5201 BOOL version;
5202 DWORD size;
5203 UINT r;
5205 version = TRUE;
5206 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5207 version = FALSE;
5209 DeleteFileA("test.dll");
5211 create_test_file("FileName1");
5212 CreateDirectoryA("one", NULL);
5213 CreateDirectoryA("one\\two", NULL);
5214 CreateDirectoryA("one\\two\\three", NULL);
5215 create_test_file("one\\two\\three\\FileName2");
5216 CreateDirectoryA("another", NULL);
5217 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5218 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5219 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5221 hdb = create_package_db();
5222 ok(hdb, "Expected a valid database handle\n");
5224 create_appsearch_table(hdb);
5225 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5226 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5227 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5228 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5229 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5230 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5231 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5232 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5233 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5234 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5235 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5236 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5238 create_drlocator_table(hdb);
5240 strcpy(expected, CURR_DIR);
5241 if (is_root(CURR_DIR)) expected[2] = 0;
5243 /* no parent, full path, depth 0, signature */
5244 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5245 add_drlocator_entry(hdb, path);
5247 /* no parent, full path, depth 0, no signature */
5248 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5249 add_drlocator_entry(hdb, path);
5251 /* no parent, relative path, depth 0, no signature */
5252 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5253 add_drlocator_entry(hdb, path);
5255 /* no parent, full path, depth 2, signature */
5256 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5257 add_drlocator_entry(hdb, path);
5259 /* no parent, full path, depth 3, signature */
5260 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5261 add_drlocator_entry(hdb, path);
5263 /* no parent, full path, depth 1, signature is dir */
5264 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5265 add_drlocator_entry(hdb, path);
5267 /* parent is in DrLocator, relative path, depth 0, signature */
5268 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5269 add_drlocator_entry(hdb, path);
5271 /* no parent, full path, depth 0, signature w/ version */
5272 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5273 add_drlocator_entry(hdb, path);
5275 /* no parent, full path, depth 0, signature w/ version, ver > max */
5276 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5277 add_drlocator_entry(hdb, path);
5279 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5280 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5281 add_drlocator_entry(hdb, path);
5283 /* no parent, relative empty path, depth 0, no signature */
5284 sprintf(path, "'NewSignature11', '', '', 0");
5285 add_drlocator_entry(hdb, path);
5287 create_reglocator_table(hdb);
5289 /* parent */
5290 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5292 /* parent is in RegLocator, no path, depth 0, no signature */
5293 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5294 add_drlocator_entry(hdb, path);
5296 create_signature_table(hdb);
5297 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5298 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5299 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5300 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5301 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5302 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5303 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5304 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5306 r = package_from_db(hdb, &hpkg);
5307 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5309 skip("Not enough rights to perform tests\n");
5310 goto error;
5312 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5314 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5316 r = MsiDoActionA(hpkg, "AppSearch");
5317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5319 size = MAX_PATH;
5320 sprintf(path, "%s\\FileName1", expected);
5321 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5323 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5325 size = MAX_PATH;
5326 sprintf(path, "%s\\", expected);
5327 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5329 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5331 size = MAX_PATH;
5332 search_absolute_directory(path, expected + 3);
5333 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5335 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5337 size = MAX_PATH;
5338 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5340 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5342 size = MAX_PATH;
5343 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5344 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5346 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5348 size = MAX_PATH;
5349 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5351 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5353 size = MAX_PATH;
5354 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5355 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5357 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5359 if (version)
5361 size = MAX_PATH;
5362 sprintf(path, "%s\\FileName3.dll", expected);
5363 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5365 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5367 size = MAX_PATH;
5368 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5370 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5372 size = MAX_PATH;
5373 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5375 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5378 size = MAX_PATH;
5379 search_absolute_directory(path, "");
5380 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5382 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5384 size = MAX_PATH;
5385 strcpy(path, "c:\\");
5386 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5388 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5390 MsiCloseHandle(hpkg);
5392 error:
5393 DeleteFileA("FileName1");
5394 DeleteFileA("FileName3.dll");
5395 DeleteFileA("FileName4.dll");
5396 DeleteFileA("FileName5.dll");
5397 DeleteFileA("one\\two\\three\\FileName2");
5398 RemoveDirectoryA("one\\two\\three");
5399 RemoveDirectoryA("one\\two");
5400 RemoveDirectoryA("one");
5401 RemoveDirectoryA("another");
5402 DeleteFileA(msifile);
5405 static void test_featureparents(void)
5407 MSIHANDLE hpkg;
5408 UINT r;
5409 MSIHANDLE hdb;
5411 hdb = create_package_db();
5412 ok ( hdb, "failed to create package database\n" );
5414 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5416 create_feature_table( hdb );
5417 create_component_table( hdb );
5418 create_feature_components_table( hdb );
5419 create_file_table( hdb );
5421 /* msidbFeatureAttributesFavorLocal */
5422 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5424 /* msidbFeatureAttributesFavorSource */
5425 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5427 /* msidbFeatureAttributesFavorLocal */
5428 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5430 /* msidbFeatureAttributesUIDisallowAbsent */
5431 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5433 /* disabled because of install level */
5434 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5436 /* child feature of disabled feature */
5437 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5439 /* component of disabled feature (install level) */
5440 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5442 /* component of disabled child feature (install level) */
5443 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5445 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5446 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5448 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5449 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5451 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5452 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5454 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5455 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5457 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5458 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5460 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5461 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5463 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5464 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5466 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5467 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5469 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5470 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5472 add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5473 add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5474 add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5475 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5476 add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5477 add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5478 add_feature_components_entry( hdb, "'orion', 'leo'" );
5479 add_feature_components_entry( hdb, "'orion', 'virgo'" );
5480 add_feature_components_entry( hdb, "'orion', 'libra'" );
5481 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5482 add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5483 add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5484 add_feature_components_entry( hdb, "'orion', 'canis'" );
5485 add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5486 add_feature_components_entry( hdb, "'orion', 'lepus'" );
5487 add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5488 add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5490 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5491 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5492 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5493 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5494 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5495 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5496 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5497 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5498 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5499 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5500 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5502 r = package_from_db( hdb, &hpkg );
5503 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5505 skip("Not enough rights to perform tests\n");
5506 DeleteFileA(msifile);
5507 return;
5509 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5511 MsiCloseHandle( hdb );
5513 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5515 r = MsiDoActionA( hpkg, "CostInitialize");
5516 ok( r == ERROR_SUCCESS, "cost init failed\n");
5518 r = MsiDoActionA( hpkg, "FileCost");
5519 ok( r == ERROR_SUCCESS, "file cost failed\n");
5521 r = MsiDoActionA( hpkg, "CostFinalize");
5522 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5524 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5525 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5526 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5527 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5528 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5529 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5531 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5532 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5533 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5534 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5535 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5536 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5537 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5538 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5539 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5540 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5541 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5543 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5544 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5546 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5547 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5549 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5550 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5552 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5553 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5554 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5555 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5556 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5557 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5559 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5560 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5561 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5562 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5563 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5564 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5565 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5566 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5567 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5568 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5569 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5571 MsiCloseHandle(hpkg);
5572 DeleteFileA(msifile);
5575 static void test_installprops(void)
5577 MSIHANDLE hpkg, hdb;
5578 CHAR path[MAX_PATH], buf[MAX_PATH];
5579 DWORD size, type;
5580 LANGID langid;
5581 HKEY hkey1, hkey2, pathkey;
5582 int res;
5583 UINT r;
5584 REGSAM access = KEY_ALL_ACCESS;
5585 SYSTEM_INFO si;
5586 INSTALLUILEVEL uilevel;
5588 if (is_wow64)
5589 access |= KEY_WOW64_64KEY;
5591 lstrcpyA(path, CURR_DIR);
5592 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5593 lstrcatA(path, msifile);
5595 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5597 hdb = create_package_db();
5598 ok( hdb, "failed to create database\n");
5600 r = package_from_db(hdb, &hpkg);
5601 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5603 skip("Not enough rights to perform tests\n");
5604 MsiSetInternalUI(uilevel, NULL);
5605 DeleteFileA(msifile);
5606 return;
5608 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5610 MsiCloseHandle(hdb);
5612 buf[0] = 0;
5613 size = MAX_PATH;
5614 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5615 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5616 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5618 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5620 buf[0] = 0;
5621 size = MAX_PATH;
5622 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5623 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5624 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5626 buf[0] = 0;
5627 size = MAX_PATH;
5628 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5629 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5630 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5632 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5633 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5634 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5635 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5637 size = MAX_PATH;
5638 type = REG_SZ;
5639 *path = '\0';
5640 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5642 size = MAX_PATH;
5643 type = REG_SZ;
5644 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5647 buf[0] = 0;
5648 size = MAX_PATH;
5649 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5650 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5651 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5653 size = MAX_PATH;
5654 type = REG_SZ;
5655 *path = '\0';
5656 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5658 size = MAX_PATH;
5659 type = REG_SZ;
5660 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5663 if (*path)
5665 buf[0] = 0;
5666 size = MAX_PATH;
5667 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5668 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5669 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5672 buf[0] = 0;
5673 size = MAX_PATH;
5674 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5675 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5676 trace("VersionDatabase = %s\n", buf);
5678 buf[0] = 0;
5679 size = MAX_PATH;
5680 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5681 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5682 trace("VersionMsi = %s\n", buf);
5684 buf[0] = 0;
5685 size = MAX_PATH;
5686 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5687 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5688 trace("Date = %s\n", buf);
5690 buf[0] = 0;
5691 size = MAX_PATH;
5692 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5693 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5694 trace("Time = %s\n", buf);
5696 buf[0] = 0;
5697 size = MAX_PATH;
5698 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5699 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5700 trace("PackageCode = %s\n", buf);
5702 buf[0] = 0;
5703 size = MAX_PATH;
5704 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5705 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5706 trace("ComputerName = %s\n", buf);
5708 langid = GetUserDefaultLangID();
5709 sprintf(path, "%d", langid);
5711 buf[0] = 0;
5712 size = MAX_PATH;
5713 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5714 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5715 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5717 res = GetSystemMetrics(SM_CXSCREEN);
5718 buf[0] = 0;
5719 size = MAX_PATH;
5720 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5721 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5722 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5724 res = GetSystemMetrics(SM_CYSCREEN);
5725 buf[0] = 0;
5726 size = MAX_PATH;
5727 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5728 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5729 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5731 buf[0] = 0;
5732 size = MAX_PATH;
5733 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
5734 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
5736 GetNativeSystemInfo(&si);
5738 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5739 check_prop(hpkg, "VersionNT", buf, 1);
5741 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5743 sprintf(buf, "%d", si.wProcessorLevel);
5744 check_prop(hpkg, "Intel", buf, 1);
5745 check_prop(hpkg, "MsiAMD64", buf, 1);
5746 check_prop(hpkg, "Msix64", buf, 1);
5747 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5748 check_prop(hpkg, "VersionNT64", buf, 1);
5750 GetSystemDirectoryA(path, MAX_PATH);
5751 strcat(path, "\\");
5752 check_prop(hpkg, "System64Folder", path, 0);
5754 GetSystemWow64DirectoryA(path, MAX_PATH);
5755 strcat(path, "\\");
5756 check_prop(hpkg, "SystemFolder", path, 0);
5758 size = MAX_PATH;
5759 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5760 strcat(path, "\\");
5761 check_prop(hpkg, "ProgramFilesFolder", path, 0);
5763 size = MAX_PATH;
5764 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5765 strcat(path, "\\");
5766 check_prop(hpkg, "ProgramFiles64Folder", path, 0);
5768 size = MAX_PATH;
5769 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5770 strcat(path, "\\");
5771 check_prop(hpkg, "CommonFilesFolder", path, 0);
5773 size = MAX_PATH;
5774 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5775 strcat(path, "\\");
5776 check_prop(hpkg, "CommonFiles64Folder", path, 0);
5778 else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5780 sprintf(buf, "%d", si.wProcessorLevel);
5781 check_prop(hpkg, "Intel", buf, 1);
5783 GetSystemDirectoryA(path, MAX_PATH);
5784 strcat(path, "\\");
5785 check_prop(hpkg, "SystemFolder", path, 0);
5787 size = MAX_PATH;
5788 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5789 strcat(path, "\\");
5790 check_prop(hpkg, "ProgramFilesFolder", path, 0);
5792 size = MAX_PATH;
5793 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5794 strcat(path, "\\");
5795 check_prop(hpkg, "CommonFilesFolder", path, 0);
5797 check_prop(hpkg, "MsiAMD64", "", 1);
5798 check_prop(hpkg, "Msix64", "", 1);
5799 check_prop(hpkg, "VersionNT64", "", 1);
5800 check_prop(hpkg, "System64Folder", "", 0);
5801 check_prop(hpkg, "ProgramFiles64Dir", "", 0);
5802 check_prop(hpkg, "CommonFiles64Dir", "", 0);
5805 CloseHandle(hkey1);
5806 CloseHandle(hkey2);
5807 RegCloseKey(pathkey);
5808 MsiCloseHandle(hpkg);
5809 DeleteFileA(msifile);
5810 MsiSetInternalUI(uilevel, NULL);
5813 static void test_launchconditions(void)
5815 MSIHANDLE hpkg;
5816 MSIHANDLE hdb;
5817 UINT r;
5819 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5821 hdb = create_package_db();
5822 ok( hdb, "failed to create package database\n" );
5824 create_launchcondition_table( hdb );
5826 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5828 /* invalid condition */
5829 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5831 r = package_from_db( hdb, &hpkg );
5832 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5834 skip("Not enough rights to perform tests\n");
5835 DeleteFileA(msifile);
5836 return;
5838 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5840 MsiCloseHandle( hdb );
5842 r = MsiSetPropertyA( hpkg, "X", "1" );
5843 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5845 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5847 /* invalid conditions are ignored */
5848 r = MsiDoActionA( hpkg, "LaunchConditions" );
5849 ok( r == ERROR_SUCCESS, "cost init failed\n" );
5851 /* verify LaunchConditions still does some verification */
5852 r = MsiSetPropertyA( hpkg, "X", "2" );
5853 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5855 r = MsiDoActionA( hpkg, "LaunchConditions" );
5856 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5858 MsiCloseHandle( hpkg );
5859 DeleteFileA( msifile );
5862 static void test_ccpsearch(void)
5864 MSIHANDLE hdb, hpkg;
5865 CHAR prop[MAX_PATH];
5866 DWORD size = MAX_PATH;
5867 UINT r;
5869 hdb = create_package_db();
5870 ok(hdb, "failed to create package database\n");
5872 create_ccpsearch_table(hdb);
5873 add_ccpsearch_entry(hdb, "'CCP_random'");
5874 add_ccpsearch_entry(hdb, "'RMCCP_random'");
5876 create_reglocator_table(hdb);
5877 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5879 create_drlocator_table(hdb);
5880 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5882 create_signature_table(hdb);
5884 r = package_from_db(hdb, &hpkg);
5885 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5887 skip("Not enough rights to perform tests\n");
5888 DeleteFileA(msifile);
5889 return;
5891 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5893 MsiCloseHandle(hdb);
5895 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5897 r = MsiDoActionA(hpkg, "CCPSearch");
5898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5900 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5902 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5904 MsiCloseHandle(hpkg);
5905 DeleteFileA(msifile);
5908 static void test_complocator(void)
5910 MSIHANDLE hdb, hpkg;
5911 UINT r;
5912 CHAR prop[MAX_PATH];
5913 CHAR expected[MAX_PATH];
5914 DWORD size = MAX_PATH;
5916 hdb = create_package_db();
5917 ok(hdb, "failed to create package database\n");
5919 create_appsearch_table(hdb);
5920 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5921 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5922 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5923 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5924 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5925 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5926 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5927 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5928 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5929 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5930 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5931 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5932 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5933 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5934 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5935 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5937 create_complocator_table(hdb);
5938 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5939 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5940 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5941 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5942 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5943 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5944 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5945 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5946 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5947 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5948 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5949 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5950 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5951 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5952 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5953 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5955 create_signature_table(hdb);
5956 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5957 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5958 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5959 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5960 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5961 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5962 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5963 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5965 r = package_from_db(hdb, &hpkg);
5966 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5968 skip("Not enough rights to perform tests\n");
5969 DeleteFileA(msifile);
5970 return;
5972 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5974 MsiCloseHandle(hdb);
5976 create_test_file("abelisaurus");
5977 create_test_file("bactrosaurus");
5978 create_test_file("camelotia");
5979 create_test_file("diclonius");
5980 create_test_file("echinodon");
5981 create_test_file("falcarius");
5982 create_test_file("gallimimus");
5983 create_test_file("hagryphus");
5984 CreateDirectoryA("iguanodon", NULL);
5985 CreateDirectoryA("jobaria", NULL);
5986 CreateDirectoryA("kakuru", NULL);
5987 CreateDirectoryA("labocania", NULL);
5988 CreateDirectoryA("megaraptor", NULL);
5989 CreateDirectoryA("neosodon", NULL);
5990 CreateDirectoryA("olorotitan", NULL);
5991 CreateDirectoryA("pantydraco", NULL);
5993 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
5994 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5995 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
5996 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5997 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
5998 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5999 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
6000 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
6001 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
6002 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
6003 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
6004 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
6005 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
6006 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
6007 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
6008 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
6010 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6012 r = MsiDoActionA(hpkg, "AppSearch");
6013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6015 size = MAX_PATH;
6016 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
6017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6019 lstrcpyA(expected, CURR_DIR);
6020 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6021 lstrcatA(expected, "abelisaurus");
6022 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6023 "Expected %s or empty string, got %s\n", expected, prop);
6025 size = MAX_PATH;
6026 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
6027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6028 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6030 size = MAX_PATH;
6031 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
6032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6033 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6035 size = MAX_PATH;
6036 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
6037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6038 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6040 size = MAX_PATH;
6041 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
6042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6044 lstrcpyA(expected, CURR_DIR);
6045 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6046 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6047 "Expected %s or empty string, got %s\n", expected, prop);
6049 size = MAX_PATH;
6050 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
6051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6052 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6054 size = MAX_PATH;
6055 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
6056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6057 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6059 size = MAX_PATH;
6060 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
6061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6062 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6064 size = MAX_PATH;
6065 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
6066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6067 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6069 size = MAX_PATH;
6070 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
6071 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6072 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6074 size = MAX_PATH;
6075 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
6076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6077 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6079 size = MAX_PATH;
6080 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
6081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6082 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6084 size = MAX_PATH;
6085 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
6086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6088 lstrcpyA(expected, CURR_DIR);
6089 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6090 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6091 "Expected %s or empty string, got %s\n", expected, prop);
6093 size = MAX_PATH;
6094 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
6095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6097 lstrcpyA(expected, CURR_DIR);
6098 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6099 lstrcatA(expected, "neosodon\\");
6100 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6101 "Expected %s or empty string, got %s\n", expected, prop);
6103 size = MAX_PATH;
6104 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6106 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6108 size = MAX_PATH;
6109 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6111 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6113 MsiCloseHandle(hpkg);
6114 DeleteFileA("abelisaurus");
6115 DeleteFileA("bactrosaurus");
6116 DeleteFileA("camelotia");
6117 DeleteFileA("diclonius");
6118 DeleteFileA("echinodon");
6119 DeleteFileA("falcarius");
6120 DeleteFileA("gallimimus");
6121 DeleteFileA("hagryphus");
6122 RemoveDirectoryA("iguanodon");
6123 RemoveDirectoryA("jobaria");
6124 RemoveDirectoryA("kakuru");
6125 RemoveDirectoryA("labocania");
6126 RemoveDirectoryA("megaraptor");
6127 RemoveDirectoryA("neosodon");
6128 RemoveDirectoryA("olorotitan");
6129 RemoveDirectoryA("pantydraco");
6130 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6131 MSIINSTALLCONTEXT_MACHINE, NULL);
6132 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6133 MSIINSTALLCONTEXT_MACHINE, NULL);
6134 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6135 MSIINSTALLCONTEXT_MACHINE, NULL);
6136 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6137 MSIINSTALLCONTEXT_MACHINE, NULL);
6138 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6139 MSIINSTALLCONTEXT_MACHINE, NULL);
6140 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6141 MSIINSTALLCONTEXT_MACHINE, NULL);
6142 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6143 MSIINSTALLCONTEXT_MACHINE, NULL);
6144 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6145 MSIINSTALLCONTEXT_MACHINE, NULL);
6146 DeleteFileA(msifile);
6149 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6151 MSIHANDLE summary;
6152 UINT r;
6154 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6157 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6160 r = MsiSummaryInfoPersist(summary);
6161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6163 MsiCloseHandle(summary);
6166 static void test_MsiGetSourcePath(void)
6168 MSIHANDLE hdb, hpkg;
6169 CHAR path[MAX_PATH];
6170 CHAR cwd[MAX_PATH];
6171 CHAR subsrc[MAX_PATH];
6172 CHAR sub2[MAX_PATH];
6173 DWORD size;
6174 UINT r;
6176 lstrcpyA(cwd, CURR_DIR);
6177 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6179 lstrcpyA(subsrc, cwd);
6180 lstrcatA(subsrc, "subsource");
6181 lstrcatA(subsrc, "\\");
6183 lstrcpyA(sub2, subsrc);
6184 lstrcatA(sub2, "sub2");
6185 lstrcatA(sub2, "\\");
6187 /* uncompressed source */
6189 hdb = create_package_db();
6190 ok( hdb, "failed to create database\n");
6192 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6194 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6195 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6196 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6198 r = MsiDatabaseCommit(hdb);
6199 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6201 r = package_from_db(hdb, &hpkg);
6202 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6204 skip("Not enough rights to perform tests\n");
6205 DeleteFileA(msifile);
6206 return;
6208 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6210 MsiCloseHandle(hdb);
6212 /* invalid database handle */
6213 size = MAX_PATH;
6214 lstrcpyA(path, "kiwi");
6215 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6216 ok(r == ERROR_INVALID_HANDLE,
6217 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6218 ok(!lstrcmpA(path, "kiwi"),
6219 "Expected path to be unchanged, got \"%s\"\n", path);
6220 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6222 /* NULL szFolder */
6223 size = MAX_PATH;
6224 lstrcpyA(path, "kiwi");
6225 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6226 ok(r == ERROR_INVALID_PARAMETER,
6227 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6228 ok(!lstrcmpA(path, "kiwi"),
6229 "Expected path to be unchanged, got \"%s\"\n", path);
6230 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6232 /* empty szFolder */
6233 size = MAX_PATH;
6234 lstrcpyA(path, "kiwi");
6235 r = MsiGetSourcePathA(hpkg, "", path, &size);
6236 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6237 ok(!lstrcmpA(path, "kiwi"),
6238 "Expected path to be unchanged, got \"%s\"\n", path);
6239 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6241 /* try TARGETDIR */
6242 size = MAX_PATH;
6243 lstrcpyA(path, "kiwi");
6244 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6245 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6246 ok(!lstrcmpA(path, "kiwi"),
6247 "Expected path to be unchanged, got \"%s\"\n", path);
6248 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6250 size = MAX_PATH;
6251 lstrcpyA(path, "kiwi");
6252 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6254 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6255 ok(size == 0, "Expected 0, got %d\n", size);
6257 size = MAX_PATH;
6258 lstrcpyA(path, "kiwi");
6259 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6261 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6262 ok(size == 0, "Expected 0, got %d\n", size);
6264 /* try SourceDir */
6265 size = MAX_PATH;
6266 lstrcpyA(path, "kiwi");
6267 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6268 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6269 ok(!lstrcmpA(path, "kiwi"),
6270 "Expected path to be unchanged, got \"%s\"\n", path);
6271 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6273 /* try SOURCEDIR */
6274 size = MAX_PATH;
6275 lstrcpyA(path, "kiwi");
6276 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6277 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6278 ok(!lstrcmpA(path, "kiwi"),
6279 "Expected path to be unchanged, got \"%s\"\n", path);
6280 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6282 /* source path does not exist, but the property exists */
6283 size = MAX_PATH;
6284 lstrcpyA(path, "kiwi");
6285 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6287 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6288 ok(size == 0, "Expected 0, got %d\n", size);
6290 size = MAX_PATH;
6291 lstrcpyA(path, "kiwi");
6292 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6294 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6295 ok(size == 0, "Expected 0, got %d\n", size);
6297 /* try SubDir */
6298 size = MAX_PATH;
6299 lstrcpyA(path, "kiwi");
6300 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6301 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6302 ok(!lstrcmpA(path, "kiwi"),
6303 "Expected path to be unchanged, got \"%s\"\n", path);
6304 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6306 /* try SubDir2 */
6307 size = MAX_PATH;
6308 lstrcpyA(path, "kiwi");
6309 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6310 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6311 ok(!lstrcmpA(path, "kiwi"),
6312 "Expected path to be unchanged, got \"%s\"\n", path);
6313 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6315 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6317 r = MsiDoActionA(hpkg, "CostInitialize");
6318 ok(r == ERROR_SUCCESS, "cost init failed\n");
6320 /* try TARGETDIR after CostInitialize */
6321 size = MAX_PATH;
6322 lstrcpyA(path, "kiwi");
6323 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6325 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6326 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6328 /* try SourceDir after CostInitialize */
6329 size = MAX_PATH;
6330 lstrcpyA(path, "kiwi");
6331 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6333 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6334 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6336 /* try SOURCEDIR after CostInitialize */
6337 size = MAX_PATH;
6338 lstrcpyA(path, "kiwi");
6339 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6340 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6341 ok(!lstrcmpA(path, "kiwi"),
6342 "Expected path to be unchanged, got \"%s\"\n", path);
6343 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6345 /* source path does not exist, but the property exists */
6346 size = MAX_PATH;
6347 lstrcpyA(path, "kiwi");
6348 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6350 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6351 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6353 size = MAX_PATH;
6354 lstrcpyA(path, "kiwi");
6355 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6357 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6358 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6360 /* try SubDir after CostInitialize */
6361 size = MAX_PATH;
6362 lstrcpyA(path, "kiwi");
6363 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6365 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6366 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6368 /* try SubDir2 after CostInitialize */
6369 size = MAX_PATH;
6370 lstrcpyA(path, "kiwi");
6371 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6373 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6374 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6376 r = MsiDoActionA(hpkg, "ResolveSource");
6377 ok(r == ERROR_SUCCESS, "file cost failed\n");
6379 /* try TARGETDIR after ResolveSource */
6380 size = MAX_PATH;
6381 lstrcpyA(path, "kiwi");
6382 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6384 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6385 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6387 /* try SourceDir after ResolveSource */
6388 size = MAX_PATH;
6389 lstrcpyA(path, "kiwi");
6390 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6392 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6393 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6395 /* try SOURCEDIR after ResolveSource */
6396 size = MAX_PATH;
6397 lstrcpyA(path, "kiwi");
6398 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6399 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6400 ok(!lstrcmpA(path, "kiwi"),
6401 "Expected path to be unchanged, got \"%s\"\n", path);
6402 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6404 /* source path does not exist, but the property exists */
6405 size = MAX_PATH;
6406 lstrcpyA(path, "kiwi");
6407 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6409 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6410 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6412 size = MAX_PATH;
6413 lstrcpyA(path, "kiwi");
6414 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6416 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6417 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6419 /* try SubDir after ResolveSource */
6420 size = MAX_PATH;
6421 lstrcpyA(path, "kiwi");
6422 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6424 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6425 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6427 /* try SubDir2 after ResolveSource */
6428 size = MAX_PATH;
6429 lstrcpyA(path, "kiwi");
6430 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6432 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6433 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6435 r = MsiDoActionA(hpkg, "FileCost");
6436 ok(r == ERROR_SUCCESS, "file cost failed\n");
6438 /* try TARGETDIR after FileCost */
6439 size = MAX_PATH;
6440 lstrcpyA(path, "kiwi");
6441 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6443 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6444 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6446 /* try SourceDir after FileCost */
6447 size = MAX_PATH;
6448 lstrcpyA(path, "kiwi");
6449 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6452 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6454 /* try SOURCEDIR after FileCost */
6455 size = MAX_PATH;
6456 lstrcpyA(path, "kiwi");
6457 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6458 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6459 ok(!lstrcmpA(path, "kiwi"),
6460 "Expected path to be unchanged, got \"%s\"\n", path);
6461 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6463 /* source path does not exist, but the property exists */
6464 size = MAX_PATH;
6465 lstrcpyA(path, "kiwi");
6466 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6467 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6468 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6469 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6471 size = MAX_PATH;
6472 lstrcpyA(path, "kiwi");
6473 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6476 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6478 /* try SubDir after FileCost */
6479 size = MAX_PATH;
6480 lstrcpyA(path, "kiwi");
6481 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6483 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6484 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6486 /* try SubDir2 after FileCost */
6487 size = MAX_PATH;
6488 lstrcpyA(path, "kiwi");
6489 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6491 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6492 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6494 r = MsiDoActionA(hpkg, "CostFinalize");
6495 ok(r == ERROR_SUCCESS, "file cost failed\n");
6497 /* try TARGETDIR after CostFinalize */
6498 size = MAX_PATH;
6499 lstrcpyA(path, "kiwi");
6500 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6502 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6503 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6505 /* try SourceDir after CostFinalize */
6506 size = MAX_PATH;
6507 lstrcpyA(path, "kiwi");
6508 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6510 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6511 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6513 /* try SOURCEDIR after CostFinalize */
6514 size = MAX_PATH;
6515 lstrcpyA(path, "kiwi");
6516 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6517 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6518 ok(!lstrcmpA(path, "kiwi"),
6519 "Expected path to be unchanged, got \"%s\"\n", path);
6520 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6522 /* source path does not exist, but the property exists */
6523 size = MAX_PATH;
6524 lstrcpyA(path, "kiwi");
6525 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6526 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6527 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6528 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6530 size = MAX_PATH;
6531 lstrcpyA(path, "kiwi");
6532 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6534 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6535 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6537 /* try SubDir after CostFinalize */
6538 size = MAX_PATH;
6539 lstrcpyA(path, "kiwi");
6540 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6541 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6542 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6543 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6545 /* try SubDir2 after CostFinalize */
6546 size = MAX_PATH;
6547 lstrcpyA(path, "kiwi");
6548 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6550 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6551 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6553 /* nonexistent directory */
6554 size = MAX_PATH;
6555 lstrcpyA(path, "kiwi");
6556 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6557 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6558 ok(!lstrcmpA(path, "kiwi"),
6559 "Expected path to be unchanged, got \"%s\"\n", path);
6560 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6562 /* NULL szPathBuf */
6563 size = MAX_PATH;
6564 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6566 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6568 /* NULL pcchPathBuf */
6569 lstrcpyA(path, "kiwi");
6570 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6571 ok(r == ERROR_INVALID_PARAMETER,
6572 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6573 ok(!lstrcmpA(path, "kiwi"),
6574 "Expected path to be unchanged, got \"%s\"\n", path);
6576 /* pcchPathBuf is 0 */
6577 size = 0;
6578 lstrcpyA(path, "kiwi");
6579 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6580 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6581 ok(!lstrcmpA(path, "kiwi"),
6582 "Expected path to be unchanged, got \"%s\"\n", path);
6583 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6585 /* pcchPathBuf does not have room for NULL terminator */
6586 size = lstrlenA(cwd);
6587 lstrcpyA(path, "kiwi");
6588 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6589 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6590 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6591 "Expected path with no backslash, got \"%s\"\n", path);
6592 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6594 /* pcchPathBuf has room for NULL terminator */
6595 size = lstrlenA(cwd) + 1;
6596 lstrcpyA(path, "kiwi");
6597 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6599 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6600 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6602 /* remove property */
6603 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6606 /* try SourceDir again */
6607 size = MAX_PATH;
6608 lstrcpyA(path, "kiwi");
6609 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6611 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6612 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6614 /* set property to a valid directory */
6615 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6618 /* try SOURCEDIR again */
6619 size = MAX_PATH;
6620 lstrcpyA(path, "kiwi");
6621 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6622 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6623 ok(!lstrcmpA(path, "kiwi"),
6624 "Expected path to be unchanged, got \"%s\"\n", path);
6625 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6627 MsiCloseHandle(hpkg);
6629 /* compressed source */
6631 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6634 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
6636 r = package_from_db(hdb, &hpkg);
6637 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6639 /* try TARGETDIR */
6640 size = MAX_PATH;
6641 lstrcpyA(path, "kiwi");
6642 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6643 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6644 ok(!lstrcmpA(path, "kiwi"),
6645 "Expected path to be unchanged, got \"%s\"\n", path);
6646 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6648 /* try SourceDir */
6649 size = MAX_PATH;
6650 lstrcpyA(path, "kiwi");
6651 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6652 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6653 ok(!lstrcmpA(path, "kiwi"),
6654 "Expected path to be unchanged, got \"%s\"\n", path);
6655 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6657 /* try SOURCEDIR */
6658 size = MAX_PATH;
6659 lstrcpyA(path, "kiwi");
6660 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6661 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6662 ok(!lstrcmpA(path, "kiwi"),
6663 "Expected path to be unchanged, got \"%s\"\n", path);
6664 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6666 /* source path nor the property exist */
6667 size = MAX_PATH;
6668 lstrcpyA(path, "kiwi");
6669 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6671 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6672 ok(size == 0, "Expected 0, got %d\n", size);
6674 size = MAX_PATH;
6675 lstrcpyA(path, "kiwi");
6676 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6678 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6679 ok(size == 0, "Expected 0, got %d\n", size);
6681 /* try SubDir */
6682 size = MAX_PATH;
6683 lstrcpyA(path, "kiwi");
6684 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6685 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6686 ok(!lstrcmpA(path, "kiwi"),
6687 "Expected path to be unchanged, got \"%s\"\n", path);
6688 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6690 /* try SubDir2 */
6691 size = MAX_PATH;
6692 lstrcpyA(path, "kiwi");
6693 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6694 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6695 ok(!lstrcmpA(path, "kiwi"),
6696 "Expected path to be unchanged, got \"%s\"\n", path);
6697 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6699 r = MsiDoActionA(hpkg, "CostInitialize");
6700 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6702 /* try TARGETDIR after CostInitialize */
6703 size = MAX_PATH;
6704 lstrcpyA(path, "kiwi");
6705 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6707 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6708 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6710 /* try SourceDir after CostInitialize */
6711 size = MAX_PATH;
6712 lstrcpyA(path, "kiwi");
6713 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6715 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6716 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6718 /* try SOURCEDIR after CostInitialize */
6719 size = MAX_PATH;
6720 lstrcpyA(path, "kiwi");
6721 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6722 todo_wine
6724 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6725 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6726 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6729 /* source path does not exist, but the property exists */
6730 size = MAX_PATH;
6731 lstrcpyA(path, "kiwi");
6732 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6734 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6735 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6737 size = MAX_PATH;
6738 lstrcpyA(path, "kiwi");
6739 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6741 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6742 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6744 /* try SubDir after CostInitialize */
6745 size = MAX_PATH;
6746 lstrcpyA(path, "kiwi");
6747 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6749 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6750 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6752 /* try SubDir2 after CostInitialize */
6753 size = MAX_PATH;
6754 lstrcpyA(path, "kiwi");
6755 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6757 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6758 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6760 r = MsiDoActionA(hpkg, "ResolveSource");
6761 ok(r == ERROR_SUCCESS, "file cost failed\n");
6763 /* try TARGETDIR after ResolveSource */
6764 size = MAX_PATH;
6765 lstrcpyA(path, "kiwi");
6766 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6768 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6769 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6771 /* try SourceDir after ResolveSource */
6772 size = MAX_PATH;
6773 lstrcpyA(path, "kiwi");
6774 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6776 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6777 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6779 /* try SOURCEDIR after ResolveSource */
6780 size = MAX_PATH;
6781 lstrcpyA(path, "kiwi");
6782 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6783 todo_wine
6785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6786 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6787 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6790 /* source path and the property exist */
6791 size = MAX_PATH;
6792 lstrcpyA(path, "kiwi");
6793 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6795 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6796 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6798 size = MAX_PATH;
6799 lstrcpyA(path, "kiwi");
6800 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6802 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6803 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6805 /* try SubDir after ResolveSource */
6806 size = MAX_PATH;
6807 lstrcpyA(path, "kiwi");
6808 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6810 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6811 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6813 /* try SubDir2 after ResolveSource */
6814 size = MAX_PATH;
6815 lstrcpyA(path, "kiwi");
6816 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6818 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6819 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6821 r = MsiDoActionA(hpkg, "FileCost");
6822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6824 /* try TARGETDIR after CostFinalize */
6825 size = MAX_PATH;
6826 lstrcpyA(path, "kiwi");
6827 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6829 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6830 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6832 /* try SourceDir after CostFinalize */
6833 size = MAX_PATH;
6834 lstrcpyA(path, "kiwi");
6835 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6836 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6837 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6838 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6840 /* try SOURCEDIR after CostFinalize */
6841 size = MAX_PATH;
6842 lstrcpyA(path, "kiwi");
6843 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6844 todo_wine
6846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6847 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6848 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6851 /* source path and the property exist */
6852 size = MAX_PATH;
6853 lstrcpyA(path, "kiwi");
6854 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6856 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6857 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6859 size = MAX_PATH;
6860 lstrcpyA(path, "kiwi");
6861 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6862 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6863 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6864 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6866 /* try SubDir after CostFinalize */
6867 size = MAX_PATH;
6868 lstrcpyA(path, "kiwi");
6869 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6870 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6871 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6872 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6874 /* try SubDir2 after CostFinalize */
6875 size = MAX_PATH;
6876 lstrcpyA(path, "kiwi");
6877 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6879 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6880 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6882 r = MsiDoActionA(hpkg, "CostFinalize");
6883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6885 /* try TARGETDIR after CostFinalize */
6886 size = MAX_PATH;
6887 lstrcpyA(path, "kiwi");
6888 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6890 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6891 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6893 /* try SourceDir after CostFinalize */
6894 size = MAX_PATH;
6895 lstrcpyA(path, "kiwi");
6896 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6898 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6899 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6901 /* try SOURCEDIR after CostFinalize */
6902 size = MAX_PATH;
6903 lstrcpyA(path, "kiwi");
6904 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6905 todo_wine
6907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6908 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6909 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6912 /* source path and the property exist */
6913 size = MAX_PATH;
6914 lstrcpyA(path, "kiwi");
6915 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6917 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6918 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6920 size = MAX_PATH;
6921 lstrcpyA(path, "kiwi");
6922 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6924 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6925 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6927 /* try SubDir after CostFinalize */
6928 size = MAX_PATH;
6929 lstrcpyA(path, "kiwi");
6930 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6932 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6933 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6935 /* try SubDir2 after CostFinalize */
6936 size = MAX_PATH;
6937 lstrcpyA(path, "kiwi");
6938 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6940 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6941 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6943 MsiCloseHandle(hpkg);
6944 DeleteFileA(msifile);
6947 static void test_shortlongsource(void)
6949 MSIHANDLE hdb, hpkg;
6950 CHAR path[MAX_PATH];
6951 CHAR cwd[MAX_PATH];
6952 CHAR subsrc[MAX_PATH];
6953 DWORD size;
6954 UINT r;
6956 lstrcpyA(cwd, CURR_DIR);
6957 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6959 lstrcpyA(subsrc, cwd);
6960 lstrcatA(subsrc, "long");
6961 lstrcatA(subsrc, "\\");
6963 /* long file names */
6965 hdb = create_package_db();
6966 ok( hdb, "failed to create database\n");
6968 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6970 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6971 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6973 /* CostInitialize:short */
6974 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6976 /* CostInitialize:long */
6977 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6979 /* FileCost:short */
6980 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6982 /* FileCost:long */
6983 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6985 /* CostFinalize:short */
6986 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6988 /* CostFinalize:long */
6989 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6991 r = MsiDatabaseCommit(hdb);
6992 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6994 r = package_from_db(hdb, &hpkg);
6995 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6997 skip("Not enough rights to perform tests\n");
6998 DeleteFileA(msifile);
6999 return;
7001 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7003 MsiCloseHandle(hdb);
7005 CreateDirectoryA("one", NULL);
7006 CreateDirectoryA("four", NULL);
7008 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7010 r = MsiDoActionA(hpkg, "CostInitialize");
7011 ok(r == ERROR_SUCCESS, "file cost failed\n");
7013 CreateDirectoryA("five", NULL);
7014 CreateDirectoryA("eight", NULL);
7016 r = MsiDoActionA(hpkg, "FileCost");
7017 ok(r == ERROR_SUCCESS, "file cost failed\n");
7019 CreateDirectoryA("nine", NULL);
7020 CreateDirectoryA("twelve", NULL);
7022 r = MsiDoActionA(hpkg, "CostFinalize");
7023 ok(r == ERROR_SUCCESS, "file cost failed\n");
7025 /* neither short nor long source directories exist */
7026 size = MAX_PATH;
7027 lstrcpyA(path, "kiwi");
7028 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7030 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7031 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7033 CreateDirectoryA("short", NULL);
7035 /* short source directory exists */
7036 size = MAX_PATH;
7037 lstrcpyA(path, "kiwi");
7038 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7040 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7041 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7043 CreateDirectoryA("long", NULL);
7045 /* both short and long source directories exist */
7046 size = MAX_PATH;
7047 lstrcpyA(path, "kiwi");
7048 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7050 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7051 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7053 lstrcpyA(subsrc, cwd);
7054 lstrcatA(subsrc, "two");
7055 lstrcatA(subsrc, "\\");
7057 /* short dir exists before CostInitialize */
7058 size = MAX_PATH;
7059 lstrcpyA(path, "kiwi");
7060 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7062 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7063 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7065 lstrcpyA(subsrc, cwd);
7066 lstrcatA(subsrc, "four");
7067 lstrcatA(subsrc, "\\");
7069 /* long dir exists before CostInitialize */
7070 size = MAX_PATH;
7071 lstrcpyA(path, "kiwi");
7072 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7074 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7075 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7077 lstrcpyA(subsrc, cwd);
7078 lstrcatA(subsrc, "six");
7079 lstrcatA(subsrc, "\\");
7081 /* short dir exists before FileCost */
7082 size = MAX_PATH;
7083 lstrcpyA(path, "kiwi");
7084 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7086 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7087 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7089 lstrcpyA(subsrc, cwd);
7090 lstrcatA(subsrc, "eight");
7091 lstrcatA(subsrc, "\\");
7093 /* long dir exists before FileCost */
7094 size = MAX_PATH;
7095 lstrcpyA(path, "kiwi");
7096 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7098 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7099 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7101 lstrcpyA(subsrc, cwd);
7102 lstrcatA(subsrc, "ten");
7103 lstrcatA(subsrc, "\\");
7105 /* short dir exists before CostFinalize */
7106 size = MAX_PATH;
7107 lstrcpyA(path, "kiwi");
7108 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7110 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7111 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7113 lstrcpyA(subsrc, cwd);
7114 lstrcatA(subsrc, "twelve");
7115 lstrcatA(subsrc, "\\");
7117 /* long dir exists before CostFinalize */
7118 size = MAX_PATH;
7119 lstrcpyA(path, "kiwi");
7120 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7122 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7123 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7125 MsiCloseHandle(hpkg);
7126 RemoveDirectoryA("short");
7127 RemoveDirectoryA("long");
7128 RemoveDirectoryA("one");
7129 RemoveDirectoryA("four");
7130 RemoveDirectoryA("five");
7131 RemoveDirectoryA("eight");
7132 RemoveDirectoryA("nine");
7133 RemoveDirectoryA("twelve");
7135 /* short file names */
7137 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
7138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7140 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7142 r = package_from_db(hdb, &hpkg);
7143 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7145 MsiCloseHandle(hdb);
7147 CreateDirectoryA("one", NULL);
7148 CreateDirectoryA("four", NULL);
7150 r = MsiDoActionA(hpkg, "CostInitialize");
7151 ok(r == ERROR_SUCCESS, "file cost failed\n");
7153 CreateDirectoryA("five", NULL);
7154 CreateDirectoryA("eight", NULL);
7156 r = MsiDoActionA(hpkg, "FileCost");
7157 ok(r == ERROR_SUCCESS, "file cost failed\n");
7159 CreateDirectoryA("nine", NULL);
7160 CreateDirectoryA("twelve", NULL);
7162 r = MsiDoActionA(hpkg, "CostFinalize");
7163 ok(r == ERROR_SUCCESS, "file cost failed\n");
7165 lstrcpyA(subsrc, cwd);
7166 lstrcatA(subsrc, "short");
7167 lstrcatA(subsrc, "\\");
7169 /* neither short nor long source directories exist */
7170 size = MAX_PATH;
7171 lstrcpyA(path, "kiwi");
7172 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7174 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7175 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7177 CreateDirectoryA("short", NULL);
7179 /* short source directory exists */
7180 size = MAX_PATH;
7181 lstrcpyA(path, "kiwi");
7182 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7184 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7185 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7187 CreateDirectoryA("long", NULL);
7189 /* both short and long source directories exist */
7190 size = MAX_PATH;
7191 lstrcpyA(path, "kiwi");
7192 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7194 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7195 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7197 lstrcpyA(subsrc, cwd);
7198 lstrcatA(subsrc, "one");
7199 lstrcatA(subsrc, "\\");
7201 /* short dir exists before CostInitialize */
7202 size = MAX_PATH;
7203 lstrcpyA(path, "kiwi");
7204 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7205 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7206 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7207 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7209 lstrcpyA(subsrc, cwd);
7210 lstrcatA(subsrc, "three");
7211 lstrcatA(subsrc, "\\");
7213 /* long dir exists before CostInitialize */
7214 size = MAX_PATH;
7215 lstrcpyA(path, "kiwi");
7216 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7218 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7219 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7221 lstrcpyA(subsrc, cwd);
7222 lstrcatA(subsrc, "five");
7223 lstrcatA(subsrc, "\\");
7225 /* short dir exists before FileCost */
7226 size = MAX_PATH;
7227 lstrcpyA(path, "kiwi");
7228 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7230 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7231 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7233 lstrcpyA(subsrc, cwd);
7234 lstrcatA(subsrc, "seven");
7235 lstrcatA(subsrc, "\\");
7237 /* long dir exists before FileCost */
7238 size = MAX_PATH;
7239 lstrcpyA(path, "kiwi");
7240 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7242 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7243 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7245 lstrcpyA(subsrc, cwd);
7246 lstrcatA(subsrc, "nine");
7247 lstrcatA(subsrc, "\\");
7249 /* short dir exists before CostFinalize */
7250 size = MAX_PATH;
7251 lstrcpyA(path, "kiwi");
7252 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7254 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7255 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7257 lstrcpyA(subsrc, cwd);
7258 lstrcatA(subsrc, "eleven");
7259 lstrcatA(subsrc, "\\");
7261 /* long dir exists before CostFinalize */
7262 size = MAX_PATH;
7263 lstrcpyA(path, "kiwi");
7264 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7266 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7267 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7269 MsiCloseHandle(hpkg);
7270 RemoveDirectoryA("short");
7271 RemoveDirectoryA("long");
7272 RemoveDirectoryA("one");
7273 RemoveDirectoryA("four");
7274 RemoveDirectoryA("five");
7275 RemoveDirectoryA("eight");
7276 RemoveDirectoryA("nine");
7277 RemoveDirectoryA("twelve");
7278 DeleteFileA(msifile);
7281 static void test_sourcedir(void)
7283 MSIHANDLE hdb, hpkg;
7284 CHAR package[12];
7285 CHAR path[MAX_PATH];
7286 CHAR cwd[MAX_PATH];
7287 CHAR subsrc[MAX_PATH];
7288 DWORD size;
7289 UINT r;
7291 lstrcpyA(cwd, CURR_DIR);
7292 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7294 lstrcpyA(subsrc, cwd);
7295 lstrcatA(subsrc, "long");
7296 lstrcatA(subsrc, "\\");
7298 hdb = create_package_db();
7299 ok( hdb, "failed to create database\n");
7301 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7303 sprintf(package, "#%u", hdb);
7304 r = MsiOpenPackageA(package, &hpkg);
7305 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7307 skip("Not enough rights to perform tests\n");
7308 goto error;
7310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7312 /* properties only */
7314 /* SourceDir prop */
7315 size = MAX_PATH;
7316 lstrcpyA(path, "kiwi");
7317 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7319 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7320 ok(size == 0, "Expected 0, got %d\n", size);
7322 /* SOURCEDIR prop */
7323 size = MAX_PATH;
7324 lstrcpyA(path, "kiwi");
7325 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7327 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7328 ok(size == 0, "Expected 0, got %d\n", size);
7330 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7332 r = MsiDoActionA(hpkg, "CostInitialize");
7333 ok(r == ERROR_SUCCESS, "file cost failed\n");
7335 /* SourceDir after CostInitialize */
7336 size = MAX_PATH;
7337 lstrcpyA(path, "kiwi");
7338 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7340 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7341 ok(size == 0, "Expected 0, got %d\n", size);
7343 /* SOURCEDIR after CostInitialize */
7344 size = MAX_PATH;
7345 lstrcpyA(path, "kiwi");
7346 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7348 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7349 ok(size == 0, "Expected 0, got %d\n", size);
7351 r = MsiDoActionA(hpkg, "FileCost");
7352 ok(r == ERROR_SUCCESS, "file cost failed\n");
7354 /* SourceDir after FileCost */
7355 size = MAX_PATH;
7356 lstrcpyA(path, "kiwi");
7357 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7359 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7360 ok(size == 0, "Expected 0, got %d\n", size);
7362 /* SOURCEDIR after FileCost */
7363 size = MAX_PATH;
7364 lstrcpyA(path, "kiwi");
7365 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7367 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7368 ok(size == 0, "Expected 0, got %d\n", size);
7370 r = MsiDoActionA(hpkg, "CostFinalize");
7371 ok(r == ERROR_SUCCESS, "file cost failed\n");
7373 /* SourceDir after CostFinalize */
7374 size = MAX_PATH;
7375 lstrcpyA(path, "kiwi");
7376 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7378 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7379 ok(size == 0, "Expected 0, got %d\n", size);
7381 /* SOURCEDIR after CostFinalize */
7382 size = MAX_PATH;
7383 lstrcpyA(path, "kiwi");
7384 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7386 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7387 ok(size == 0, "Expected 0, got %d\n", size);
7389 size = MAX_PATH;
7390 lstrcpyA(path, "kiwi");
7391 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7392 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7393 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7394 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
7396 /* SOURCEDIR after calling MsiGetSourcePath */
7397 size = MAX_PATH;
7398 lstrcpyA(path, "kiwi");
7399 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7401 todo_wine {
7402 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7403 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7406 r = MsiDoActionA(hpkg, "ResolveSource");
7407 ok(r == ERROR_SUCCESS, "file cost failed\n");
7409 /* SourceDir after ResolveSource */
7410 size = MAX_PATH;
7411 lstrcpyA(path, "kiwi");
7412 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7414 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7415 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7417 /* SOURCEDIR after ResolveSource */
7418 size = MAX_PATH;
7419 lstrcpyA(path, "kiwi");
7420 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7422 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7423 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7425 /* random casing */
7426 size = MAX_PATH;
7427 lstrcpyA(path, "kiwi");
7428 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7430 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7431 ok(size == 0, "Expected 0, got %d\n", size);
7433 MsiCloseHandle(hpkg);
7435 /* reset the package state */
7436 sprintf(package, "#%i", hdb);
7437 r = MsiOpenPackageA(package, &hpkg);
7438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7440 /* test how MsiGetSourcePath affects the properties */
7442 /* SourceDir prop */
7443 size = MAX_PATH;
7444 lstrcpyA(path, "kiwi");
7445 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7447 todo_wine
7449 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7450 ok(size == 0, "Expected 0, got %d\n", size);
7453 size = MAX_PATH;
7454 lstrcpyA(path, "kiwi");
7455 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7456 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7457 ok(!lstrcmpA(path, "kiwi"),
7458 "Expected path to be unchanged, got \"%s\"\n", path);
7459 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7461 /* SourceDir after MsiGetSourcePath */
7462 size = MAX_PATH;
7463 lstrcpyA(path, "kiwi");
7464 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7466 todo_wine
7468 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7469 ok(size == 0, "Expected 0, got %d\n", size);
7472 /* SOURCEDIR prop */
7473 size = MAX_PATH;
7474 lstrcpyA(path, "kiwi");
7475 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7477 todo_wine
7479 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7480 ok(size == 0, "Expected 0, got %d\n", size);
7483 size = MAX_PATH;
7484 lstrcpyA(path, "kiwi");
7485 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7486 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7487 ok(!lstrcmpA(path, "kiwi"),
7488 "Expected path to be unchanged, got \"%s\"\n", path);
7489 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7491 /* SOURCEDIR prop after MsiGetSourcePath */
7492 size = MAX_PATH;
7493 lstrcpyA(path, "kiwi");
7494 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7496 todo_wine
7498 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7499 ok(size == 0, "Expected 0, got %d\n", size);
7502 r = MsiDoActionA(hpkg, "CostInitialize");
7503 ok(r == ERROR_SUCCESS, "file cost failed\n");
7505 /* SourceDir after CostInitialize */
7506 size = MAX_PATH;
7507 lstrcpyA(path, "kiwi");
7508 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7510 todo_wine
7512 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7513 ok(size == 0, "Expected 0, got %d\n", size);
7516 size = MAX_PATH;
7517 lstrcpyA(path, "kiwi");
7518 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7520 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7521 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7523 /* SourceDir after MsiGetSourcePath */
7524 size = MAX_PATH;
7525 lstrcpyA(path, "kiwi");
7526 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7528 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7529 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7531 /* SOURCEDIR after CostInitialize */
7532 size = MAX_PATH;
7533 lstrcpyA(path, "kiwi");
7534 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7536 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7537 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7539 /* SOURCEDIR source path still does not exist */
7540 size = MAX_PATH;
7541 lstrcpyA(path, "kiwi");
7542 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7543 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7544 ok(!lstrcmpA(path, "kiwi"),
7545 "Expected path to be unchanged, got \"%s\"\n", path);
7546 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7548 r = MsiDoActionA(hpkg, "FileCost");
7549 ok(r == ERROR_SUCCESS, "file cost failed\n");
7551 /* SourceDir after FileCost */
7552 size = MAX_PATH;
7553 lstrcpyA(path, "kiwi");
7554 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7555 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7556 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7557 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7559 /* SOURCEDIR after FileCost */
7560 size = MAX_PATH;
7561 lstrcpyA(path, "kiwi");
7562 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7564 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7565 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7567 /* SOURCEDIR source path still does not exist */
7568 size = MAX_PATH;
7569 lstrcpyA(path, "kiwi");
7570 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7571 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7572 ok(!lstrcmpA(path, "kiwi"),
7573 "Expected path to be unchanged, got \"%s\"\n", path);
7574 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7576 r = MsiDoActionA(hpkg, "CostFinalize");
7577 ok(r == ERROR_SUCCESS, "file cost failed\n");
7579 /* SourceDir after CostFinalize */
7580 size = MAX_PATH;
7581 lstrcpyA(path, "kiwi");
7582 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7584 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7585 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7587 /* SOURCEDIR after CostFinalize */
7588 size = MAX_PATH;
7589 lstrcpyA(path, "kiwi");
7590 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7592 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7593 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7595 /* SOURCEDIR source path still does not exist */
7596 size = MAX_PATH;
7597 lstrcpyA(path, "kiwi");
7598 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7599 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7600 ok(!lstrcmpA(path, "kiwi"),
7601 "Expected path to be unchanged, got \"%s\"\n", path);
7602 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7604 r = MsiDoActionA(hpkg, "ResolveSource");
7605 ok(r == ERROR_SUCCESS, "file cost failed\n");
7607 /* SourceDir after ResolveSource */
7608 size = MAX_PATH;
7609 lstrcpyA(path, "kiwi");
7610 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7612 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7613 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7615 /* SOURCEDIR after ResolveSource */
7616 size = MAX_PATH;
7617 lstrcpyA(path, "kiwi");
7618 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7620 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7621 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7623 /* SOURCEDIR source path still does not exist */
7624 size = MAX_PATH;
7625 lstrcpyA(path, "kiwi");
7626 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7627 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7628 ok(!lstrcmpA(path, "kiwi"),
7629 "Expected path to be unchanged, got \"%s\"\n", path);
7630 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7632 MsiCloseHandle(hpkg);
7634 error:
7635 MsiCloseHandle(hdb);
7636 DeleteFileA(msifile);
7639 struct access_res
7641 BOOL gothandle;
7642 DWORD lasterr;
7643 BOOL ignore;
7646 static const struct access_res create[16] =
7648 { TRUE, ERROR_SUCCESS, TRUE },
7649 { TRUE, ERROR_SUCCESS, TRUE },
7650 { TRUE, ERROR_SUCCESS, FALSE },
7651 { TRUE, ERROR_SUCCESS, FALSE },
7652 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7653 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7654 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7655 { TRUE, ERROR_SUCCESS, FALSE },
7656 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7657 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7658 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7659 { TRUE, ERROR_SUCCESS, TRUE },
7660 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7661 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7662 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7663 { TRUE, ERROR_SUCCESS, TRUE }
7666 static const struct access_res create_commit[16] =
7668 { TRUE, ERROR_SUCCESS, TRUE },
7669 { TRUE, ERROR_SUCCESS, TRUE },
7670 { TRUE, ERROR_SUCCESS, FALSE },
7671 { TRUE, ERROR_SUCCESS, FALSE },
7672 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7673 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7674 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7675 { TRUE, ERROR_SUCCESS, FALSE },
7676 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7677 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7678 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7679 { TRUE, ERROR_SUCCESS, TRUE },
7680 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7681 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7682 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7683 { TRUE, ERROR_SUCCESS, TRUE }
7686 static const struct access_res create_close[16] =
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, FALSE },
7702 { TRUE, ERROR_SUCCESS, FALSE },
7703 { TRUE, ERROR_SUCCESS }
7706 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7708 DWORD access = 0, share = 0;
7709 DWORD lasterr;
7710 HANDLE hfile;
7711 int i, j, idx = 0;
7713 for (i = 0; i < 4; i++)
7715 if (i == 0) access = 0;
7716 if (i == 1) access = GENERIC_READ;
7717 if (i == 2) access = GENERIC_WRITE;
7718 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7720 for (j = 0; j < 4; j++)
7722 if (ares[idx].ignore)
7723 continue;
7725 if (j == 0) share = 0;
7726 if (j == 1) share = FILE_SHARE_READ;
7727 if (j == 2) share = FILE_SHARE_WRITE;
7728 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7730 SetLastError(0xdeadbeef);
7731 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7732 FILE_ATTRIBUTE_NORMAL, 0);
7733 lasterr = GetLastError();
7735 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7736 "(%d, handle, %d): Expected %d, got %d\n",
7737 line, idx, ares[idx].gothandle,
7738 (hfile != INVALID_HANDLE_VALUE));
7740 ok(lasterr == ares[idx].lasterr, "(%d, lasterr, %d): Expected %d, got %d\n",
7741 line, idx, ares[idx].lasterr, lasterr);
7743 CloseHandle(hfile);
7744 idx++;
7749 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7751 static void test_access(void)
7753 MSIHANDLE hdb;
7754 UINT r;
7756 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7759 test_file_access(msifile, create);
7761 r = MsiDatabaseCommit(hdb);
7762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7764 test_file_access(msifile, create_commit);
7765 MsiCloseHandle(hdb);
7767 test_file_access(msifile, create_close);
7768 DeleteFileA(msifile);
7770 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
7771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7773 test_file_access(msifile, create);
7775 r = MsiDatabaseCommit(hdb);
7776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7778 test_file_access(msifile, create_commit);
7779 MsiCloseHandle(hdb);
7781 test_file_access(msifile, create_close);
7782 DeleteFileA(msifile);
7785 static void test_emptypackage(void)
7787 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7788 MSIHANDLE hview = 0, hrec = 0;
7789 MSICONDITION condition;
7790 CHAR buffer[MAX_PATH];
7791 DWORD size;
7792 UINT r;
7794 r = MsiOpenPackageA("", &hpkg);
7795 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7797 skip("Not enough rights to perform tests\n");
7798 return;
7800 todo_wine
7802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7805 hdb = MsiGetActiveDatabase(hpkg);
7806 todo_wine
7808 ok(hdb != 0, "Expected a valid database handle\n");
7811 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7812 todo_wine
7814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7816 r = MsiViewExecute(hview, 0);
7817 todo_wine
7819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7822 r = MsiViewFetch(hview, &hrec);
7823 todo_wine
7825 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7828 buffer[0] = 0;
7829 size = MAX_PATH;
7830 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7831 todo_wine
7833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7834 ok(!lstrcmpA(buffer, "_Property"),
7835 "Expected \"_Property\", got \"%s\"\n", buffer);
7838 MsiCloseHandle(hrec);
7840 r = MsiViewFetch(hview, &hrec);
7841 todo_wine
7843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7846 size = MAX_PATH;
7847 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7848 todo_wine
7850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7851 ok(!lstrcmpA(buffer, "#_FolderCache"),
7852 "Expected \"_Property\", got \"%s\"\n", buffer);
7855 MsiCloseHandle(hrec);
7856 MsiViewClose(hview);
7857 MsiCloseHandle(hview);
7859 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7860 todo_wine
7862 ok(condition == MSICONDITION_FALSE,
7863 "Expected MSICONDITION_FALSE, got %d\n", condition);
7866 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7867 todo_wine
7869 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7871 r = MsiViewExecute(hview, 0);
7872 todo_wine
7874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7877 /* _Property table is not empty */
7878 r = MsiViewFetch(hview, &hrec);
7879 todo_wine
7881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7884 MsiCloseHandle(hrec);
7885 MsiViewClose(hview);
7886 MsiCloseHandle(hview);
7888 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7889 todo_wine
7891 ok(condition == MSICONDITION_FALSE,
7892 "Expected MSICONDITION_FALSE, got %d\n", condition);
7895 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7896 todo_wine
7898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7900 r = MsiViewExecute(hview, 0);
7901 todo_wine
7903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7906 /* #_FolderCache is not empty */
7907 r = MsiViewFetch(hview, &hrec);
7908 todo_wine
7910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7913 MsiCloseHandle(hrec);
7914 MsiViewClose(hview);
7915 MsiCloseHandle(hview);
7917 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7918 todo_wine
7920 ok(r == ERROR_BAD_QUERY_SYNTAX,
7921 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7924 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7925 todo_wine
7927 ok(r == ERROR_BAD_QUERY_SYNTAX,
7928 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7931 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7932 todo_wine
7934 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
7935 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7938 MsiCloseHandle(hsuminfo);
7940 r = MsiDatabaseCommit(hdb);
7941 todo_wine
7943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7946 MsiCloseHandle(hdb);
7947 MsiCloseHandle(hpkg);
7950 static void test_MsiGetProductProperty(void)
7952 WCHAR valW[MAX_PATH];
7953 MSIHANDLE hprod, hdb;
7954 CHAR val[MAX_PATH];
7955 CHAR path[MAX_PATH];
7956 CHAR query[MAX_PATH + 17];
7957 CHAR keypath[MAX_PATH*2];
7958 CHAR prodcode[MAX_PATH];
7959 WCHAR prodcodeW[MAX_PATH];
7960 CHAR prod_squashed[MAX_PATH];
7961 WCHAR prod_squashedW[MAX_PATH];
7962 HKEY prodkey, userkey, props;
7963 DWORD size;
7964 LONG res;
7965 UINT r;
7966 REGSAM access = KEY_ALL_ACCESS;
7968 GetCurrentDirectoryA(MAX_PATH, path);
7969 lstrcatA(path, "\\");
7971 create_test_guid(prodcode, prod_squashed);
7972 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7973 squash_guid(prodcodeW, prod_squashedW);
7975 if (is_wow64)
7976 access |= KEY_WOW64_64KEY;
7978 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7979 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7981 r = MsiDatabaseCommit(hdb);
7982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7984 r = set_summary_info(hdb);
7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7987 r = run_query(hdb,
7988 "CREATE TABLE `Directory` ( "
7989 "`Directory` CHAR(255) NOT NULL, "
7990 "`Directory_Parent` CHAR(255), "
7991 "`DefaultDir` CHAR(255) NOT NULL "
7992 "PRIMARY KEY `Directory`)");
7993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7995 create_property_table(hdb);
7997 sprintf(query, "'ProductCode', '%s'", prodcode);
7998 r = add_property_entry(hdb, query);
8000 r = MsiDatabaseCommit(hdb);
8001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8003 MsiCloseHandle(hdb);
8005 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8006 lstrcatA(keypath, prod_squashed);
8008 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8009 if (res == ERROR_ACCESS_DENIED)
8011 skip("Not enough rights to perform tests\n");
8012 DeleteFileA(msifile);
8013 return;
8015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8017 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8018 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8019 lstrcatA(keypath, prod_squashed);
8021 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8022 if (res == ERROR_ACCESS_DENIED)
8024 skip("Not enough rights to perform tests\n");
8025 RegDeleteKeyA(prodkey, "");
8026 RegCloseKey(prodkey);
8027 return;
8029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8031 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8032 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8034 lstrcpyA(val, path);
8035 lstrcatA(val, "\\");
8036 lstrcatA(val, msifile);
8037 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8038 (const BYTE *)val, lstrlenA(val) + 1);
8039 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8041 hprod = 0xdeadbeef;
8042 r = MsiOpenProductA(prodcode, &hprod);
8043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8044 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8046 /* hProduct is invalid */
8047 size = MAX_PATH;
8048 lstrcpyA(val, "apple");
8049 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
8050 ok(r == ERROR_INVALID_HANDLE,
8051 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8052 ok(!lstrcmpA(val, "apple"),
8053 "Expected val to be unchanged, got \"%s\"\n", val);
8054 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8056 size = MAX_PATH;
8057 lstrcpyW(valW, L"apple");
8058 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
8059 ok(r == ERROR_INVALID_HANDLE,
8060 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8061 ok(!lstrcmpW(valW, L"apple"),
8062 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8063 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8065 /* szProperty is NULL */
8066 size = MAX_PATH;
8067 lstrcpyA(val, "apple");
8068 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
8069 ok(r == ERROR_INVALID_PARAMETER,
8070 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8071 ok(!lstrcmpA(val, "apple"),
8072 "Expected val to be unchanged, got \"%s\"\n", val);
8073 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8075 size = MAX_PATH;
8076 lstrcpyW(valW, L"apple");
8077 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
8078 ok(r == ERROR_INVALID_PARAMETER,
8079 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8080 ok(!lstrcmpW(valW, L"apple"),
8081 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8082 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8084 /* szProperty is empty */
8085 size = MAX_PATH;
8086 lstrcpyA(val, "apple");
8087 r = MsiGetProductPropertyA(hprod, "", val, &size);
8088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8089 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8090 ok(size == 0, "Expected 0, got %d\n", size);
8092 size = MAX_PATH;
8093 lstrcpyW(valW, L"apple");
8094 r = MsiGetProductPropertyW(hprod, L"", valW, &size);
8095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8096 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8097 ok(size == 0, "Expected 0, got %d\n", size);
8099 /* get the property */
8100 size = MAX_PATH;
8101 lstrcpyA(val, "apple");
8102 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8104 ok(!lstrcmpA(val, prodcode),
8105 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8106 ok(size == lstrlenA(prodcode),
8107 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8109 size = MAX_PATH;
8110 lstrcpyW(valW, L"apple");
8111 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8113 ok(!lstrcmpW(valW, prodcodeW),
8114 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8115 ok(size == lstrlenW(prodcodeW),
8116 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8118 /* lpValueBuf is NULL */
8119 size = MAX_PATH;
8120 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8122 ok(size == lstrlenA(prodcode),
8123 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8125 size = MAX_PATH;
8126 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
8127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8128 ok(size == lstrlenW(prodcodeW),
8129 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8131 /* pcchValueBuf is NULL */
8132 lstrcpyA(val, "apple");
8133 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8134 ok(r == ERROR_INVALID_PARAMETER,
8135 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8136 ok(!lstrcmpA(val, "apple"),
8137 "Expected val to be unchanged, got \"%s\"\n", val);
8138 ok(size == lstrlenA(prodcode),
8139 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8141 lstrcpyW(valW, L"apple");
8142 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8143 ok(r == ERROR_INVALID_PARAMETER,
8144 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8145 ok(!lstrcmpW(valW, L"apple"),
8146 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8147 ok(size == lstrlenW(prodcodeW),
8148 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8150 /* pcchValueBuf is too small */
8151 size = 4;
8152 lstrcpyA(val, "apple");
8153 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8154 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8155 ok(!strncmp(val, prodcode, 3),
8156 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8157 ok(size == lstrlenA(prodcode),
8158 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8160 size = 4;
8161 lstrcpyW(valW, L"apple");
8162 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8163 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8164 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8165 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8166 ok(size == lstrlenW(prodcodeW),
8167 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8169 /* pcchValueBuf does not leave room for NULL terminator */
8170 size = lstrlenA(prodcode);
8171 lstrcpyA(val, "apple");
8172 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8173 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8174 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8175 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8176 ok(size == lstrlenA(prodcode),
8177 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8179 size = lstrlenW(prodcodeW);
8180 lstrcpyW(valW, L"apple");
8181 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8182 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8183 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8184 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8185 ok(size == lstrlenW(prodcodeW),
8186 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8188 /* pcchValueBuf has enough room for NULL terminator */
8189 size = lstrlenA(prodcode) + 1;
8190 lstrcpyA(val, "apple");
8191 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8193 ok(!lstrcmpA(val, prodcode),
8194 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8195 ok(size == lstrlenA(prodcode),
8196 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8198 size = lstrlenW(prodcodeW) + 1;
8199 lstrcpyW(valW, L"apple");
8200 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8202 ok(!lstrcmpW(valW, prodcodeW),
8203 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8204 ok(size == lstrlenW(prodcodeW),
8205 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8207 /* nonexistent property */
8208 size = MAX_PATH;
8209 lstrcpyA(val, "apple");
8210 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8212 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8213 ok(size == 0, "Expected 0, got %d\n", size);
8215 size = MAX_PATH;
8216 lstrcpyW(valW, L"apple");
8217 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8219 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8220 ok(size == 0, "Expected 0, got %d\n", size);
8222 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8225 /* non-product property set */
8226 size = MAX_PATH;
8227 lstrcpyA(val, "apple");
8228 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8230 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8231 ok(size == 0, "Expected 0, got %d\n", size);
8233 size = MAX_PATH;
8234 lstrcpyW(valW, L"apple");
8235 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8237 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8238 ok(size == 0, "Expected 0, got %d\n", size);
8240 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8243 /* non-product property that is also a product property set */
8244 size = MAX_PATH;
8245 lstrcpyA(val, "apple");
8246 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8248 ok(!lstrcmpA(val, prodcode),
8249 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8250 ok(size == lstrlenA(prodcode),
8251 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8253 size = MAX_PATH;
8254 lstrcpyW(valW, L"apple");
8255 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8257 ok(!lstrcmpW(valW, prodcodeW),
8258 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8259 ok(size == lstrlenW(prodcodeW),
8260 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8262 MsiCloseHandle(hprod);
8264 RegDeleteValueA(props, "LocalPackage");
8265 delete_key(props, "", access);
8266 RegCloseKey(props);
8267 delete_key(userkey, "", access);
8268 RegCloseKey(userkey);
8269 delete_key(prodkey, "", access);
8270 RegCloseKey(prodkey);
8271 DeleteFileA(msifile);
8274 static void test_MsiSetProperty(void)
8276 MSIHANDLE hpkg, hdb, hrec;
8277 CHAR buf[MAX_PATH];
8278 LPCSTR query;
8279 DWORD size;
8280 UINT r;
8282 r = package_from_db(create_package_db(), &hpkg);
8283 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8285 skip("Not enough rights to perform tests\n");
8286 DeleteFileA(msifile);
8287 return;
8289 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8291 /* invalid hInstall */
8292 r = MsiSetPropertyA(0, "Prop", "Val");
8293 ok(r == ERROR_INVALID_HANDLE,
8294 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8296 /* invalid hInstall */
8297 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8298 ok(r == ERROR_INVALID_HANDLE,
8299 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8301 /* szName is NULL */
8302 r = MsiSetPropertyA(hpkg, NULL, "Val");
8303 ok(r == ERROR_INVALID_PARAMETER,
8304 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8306 /* both szName and szValue are NULL */
8307 r = MsiSetPropertyA(hpkg, NULL, NULL);
8308 ok(r == ERROR_INVALID_PARAMETER,
8309 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8311 /* szName is empty */
8312 r = MsiSetPropertyA(hpkg, "", "Val");
8313 ok(r == ERROR_FUNCTION_FAILED,
8314 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8316 /* szName is empty and szValue is NULL */
8317 r = MsiSetPropertyA(hpkg, "", NULL);
8318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8320 /* set a property */
8321 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8324 /* get the property */
8325 size = MAX_PATH;
8326 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8328 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8329 ok(size == 3, "Expected 3, got %d\n", size);
8331 /* update the property */
8332 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8335 /* get the property */
8336 size = MAX_PATH;
8337 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8338 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8339 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8340 ok(size == 4, "Expected 4, got %d\n", size);
8342 hdb = MsiGetActiveDatabase(hpkg);
8343 ok(hdb != 0, "Expected a valid database handle\n");
8345 /* set prop is not in the _Property table */
8346 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8347 r = do_query(hdb, query, &hrec);
8348 ok(r == ERROR_BAD_QUERY_SYNTAX,
8349 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8351 /* set prop is not in the Property table */
8352 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8353 r = do_query(hdb, query, &hrec);
8354 ok(r == ERROR_BAD_QUERY_SYNTAX,
8355 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8357 MsiCloseHandle(hdb);
8359 /* szValue is an empty string */
8360 r = MsiSetPropertyA(hpkg, "Prop", "");
8361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8363 /* try to get the property */
8364 size = MAX_PATH;
8365 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8367 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8368 ok(size == 0, "Expected 0, got %d\n", size);
8370 /* reset the property */
8371 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8374 /* delete the property */
8375 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8378 /* try to get the property */
8379 size = MAX_PATH;
8380 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8382 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8383 ok(size == 0, "Expected 0, got %d\n", size);
8385 MsiCloseHandle(hpkg);
8386 DeleteFileA(msifile);
8389 static void test_MsiApplyMultiplePatches(void)
8391 UINT r, type = GetDriveTypeW(NULL);
8393 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
8394 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8396 r = MsiApplyMultiplePatchesA("", NULL, NULL);
8397 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8399 r = MsiApplyMultiplePatchesA(";", NULL, NULL);
8400 if (type == DRIVE_FIXED)
8401 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8402 else
8403 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8405 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL);
8406 if (type == DRIVE_FIXED)
8407 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8408 else
8409 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8411 r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
8412 if (type == DRIVE_FIXED)
8413 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8414 else
8415 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8417 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8418 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8420 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8421 if (type == DRIVE_FIXED)
8422 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8423 else
8424 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8426 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8427 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8429 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8430 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8433 static void test_MsiApplyPatch(void)
8435 UINT r;
8437 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8438 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8440 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL);
8441 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8444 static void test_costs(void)
8446 MSIHANDLE hdb, hpkg;
8447 char package[12], drive[3];
8448 DWORD len;
8449 UINT r;
8450 int cost, temp;
8452 hdb = create_package_db();
8453 ok( hdb, "failed to create database\n" );
8455 create_property_table( hdb );
8456 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8457 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8458 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8460 create_media_table( hdb );
8461 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8463 create_file_table( hdb );
8464 add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8466 create_component_table( hdb );
8467 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8468 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8470 create_feature_table( hdb );
8471 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8472 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8474 create_feature_components_table( hdb );
8475 add_feature_components_entry( hdb, "'one', 'one'" );
8476 add_feature_components_entry( hdb, "'two', 'two'" );
8478 create_install_execute_sequence_table( hdb );
8479 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8480 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8481 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8482 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8484 r = MsiDatabaseCommit( hdb );
8485 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8487 sprintf( package, "#%u", hdb );
8488 r = MsiOpenPackageA( package, &hpkg );
8489 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8491 skip("Not enough rights to perform tests\n");
8492 goto error;
8494 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8496 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8497 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8499 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8500 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8502 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8503 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8505 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8506 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8508 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8509 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8511 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8512 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8514 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8515 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8517 len = sizeof(drive);
8518 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8519 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8521 len = sizeof(drive);
8522 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8523 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8525 len = sizeof(drive);
8526 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8527 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8529 len = sizeof(drive);
8530 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8531 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8533 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
8535 r = MsiDoActionA( hpkg, "CostInitialize" );
8536 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8538 r = MsiDoActionA( hpkg, "FileCost" );
8539 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8541 len = sizeof(drive);
8542 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8543 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8545 r = MsiDoActionA( hpkg, "CostFinalize" );
8546 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8548 /* contrary to what msdn says InstallValidate must be called too */
8549 len = sizeof(drive);
8550 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8551 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8553 r = MsiDoActionA( hpkg, "InstallValidate" );
8554 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8556 len = 0;
8557 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8558 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8560 len = 0;
8561 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8562 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8563 ok( len == 2, "expected len == 2, got %u\n", len );
8565 len = 2;
8566 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8567 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8568 ok( len == 2, "expected len == 2, got %u\n", len );
8570 len = 2;
8571 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8572 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8573 ok( len == 2, "expected len == 2, got %u\n", len );
8575 /* install state doesn't seem to matter */
8576 len = sizeof(drive);
8577 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8578 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8580 len = sizeof(drive);
8581 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8582 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8584 len = sizeof(drive);
8585 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8586 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8588 len = sizeof(drive);
8589 drive[0] = 0;
8590 cost = temp = 0xdead;
8591 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8592 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8593 ok( len == 2, "expected len == 2, got %u\n", len );
8594 ok( drive[0], "expected a drive\n" );
8595 ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
8596 ok( !temp, "expected temp == 0, got %d\n", temp );
8598 len = sizeof(drive);
8599 drive[0] = 0;
8600 cost = temp = 0xdead;
8601 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8602 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8603 ok( len == 2, "expected len == 2, got %u\n", len );
8604 ok( drive[0], "expected a drive\n" );
8605 ok( !cost, "expected cost == 0, got %d\n", cost );
8606 ok( !temp, "expected temp == 0, got %d\n", temp );
8608 len = sizeof(drive);
8609 drive[0] = 0;
8610 cost = temp = 0xdead;
8611 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8612 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8613 ok( len == 2, "expected len == 2, got %u\n", len );
8614 ok( drive[0], "expected a drive\n" );
8615 ok( !cost, "expected cost == 0, got %d\n", cost );
8616 ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8618 /* increased index */
8619 len = sizeof(drive);
8620 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8621 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8623 len = sizeof(drive);
8624 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8625 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8627 /* test MsiGetFeatureCost */
8628 cost = 0xdead;
8629 r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8630 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8631 ok( cost == 0xdead, "got %d\n", cost );
8633 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL );
8634 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8636 cost = 0xdead;
8637 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8638 ok( !r, "got %u\n", r);
8639 ok( cost == 8, "got %d\n", cost );
8641 MsiCloseHandle( hpkg );
8642 error:
8643 MsiCloseHandle( hdb );
8644 DeleteFileA( msifile );
8647 static void test_MsiDatabaseCommit(void)
8649 UINT r;
8650 MSIHANDLE hdb, hpkg = 0;
8651 char buf[32], package[12];
8652 DWORD sz;
8654 hdb = create_package_db();
8655 ok( hdb, "failed to create database\n" );
8657 create_property_table( hdb );
8659 sprintf( package, "#%u", hdb );
8660 r = MsiOpenPackageA( package, &hpkg );
8661 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8663 skip("Not enough rights to perform tests\n");
8664 goto error;
8666 ok( r == ERROR_SUCCESS, "got %u\n", r );
8668 r = MsiSetPropertyA( hpkg, "PROP", "value" );
8669 ok( r == ERROR_SUCCESS, "got %u\n", r );
8671 buf[0] = 0;
8672 sz = sizeof(buf);
8673 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8674 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8675 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8677 r = MsiDatabaseCommit( hdb );
8678 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8680 buf[0] = 0;
8681 sz = sizeof(buf);
8682 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8683 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8684 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8686 MsiCloseHandle( hpkg );
8687 error:
8688 MsiCloseHandle( hdb );
8689 DeleteFileA( msifile );
8692 static int externalui_ran;
8694 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
8696 externalui_ran = 1;
8697 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8698 return 0;
8701 static int externalui_record_ran;
8703 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
8705 INT retval = context ? *((INT *)context) : 0;
8706 UINT r;
8707 externalui_record_ran = 1;
8708 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8709 r = MsiRecordGetFieldCount(hrecord);
8710 ok(r == 1, "expected 1, got %u\n", r);
8711 r = MsiRecordGetInteger(hrecord, 1);
8712 ok(r == 12345, "expected 12345, got %u\n", r);
8713 return retval;
8716 static void test_externalui(void)
8718 /* test that external UI handlers work correctly */
8720 INSTALLUI_HANDLERA prev;
8721 INSTALLUI_HANDLER_RECORD prev_record;
8722 MSIHANDLE hpkg, hrecord;
8723 UINT r;
8724 INT retval = 0;
8726 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8728 r = package_from_db(create_package_db(), &hpkg);
8729 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8731 skip("Not enough rights to perform tests\n");
8732 DeleteFileA(msifile);
8733 return;
8735 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8737 hrecord = MsiCreateRecord(1);
8738 ok(hrecord, "Expected a valid record\n");
8739 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
8740 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
8741 r = MsiRecordSetInteger(hrecord, 1, 12345);
8742 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
8744 externalui_ran = 0;
8745 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8746 ok(r == 0, "expected 0, got %u\n", r);
8747 ok(externalui_ran == 1, "external UI callback did not run\n");
8749 prev = MsiSetExternalUIA(prev, 0, NULL);
8750 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
8751 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record);
8752 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8754 externalui_ran = externalui_record_ran = 0;
8755 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8756 ok(r == 0, "expected 0, got %u\n", r);
8757 ok(externalui_ran == 0, "external UI callback should not have run\n");
8758 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8760 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8762 externalui_ran = externalui_record_ran = 0;
8763 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8764 ok(r == 0, "expected 0, got %u\n", r);
8765 ok(externalui_ran == 1, "external UI callback did not run\n");
8766 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8768 retval = 1;
8769 externalui_ran = externalui_record_ran = 0;
8770 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8771 ok(r == 1, "expected 1, got %u\n", r);
8772 ok(externalui_ran == 0, "external UI callback should not have run\n");
8773 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8775 /* filter and context should be kept separately */
8776 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record);
8777 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8779 externalui_ran = externalui_record_ran = 0;
8780 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8781 ok(r == 0, "expected 0, got %u\n", r);
8782 ok(externalui_ran == 1, "external UI callback did not run\n");
8783 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
8785 MsiCloseHandle(hpkg);
8786 DeleteFileA(msifile);
8789 struct externalui_message {
8790 UINT message;
8791 int field_count;
8792 char field[4][100];
8793 int match[4]; /* should we test for a match */
8794 int optional;
8797 static struct externalui_message *sequence;
8798 static int sequence_count, sequence_size;
8800 static void add_message(const struct externalui_message *msg)
8802 if (!sequence)
8804 sequence_size = 10;
8805 sequence = HeapAlloc(GetProcessHeap(), 0, sequence_size * sizeof(*sequence));
8807 if (sequence_count == sequence_size)
8809 sequence_size *= 2;
8810 sequence = HeapReAlloc(GetProcessHeap(), 0, sequence, sequence_size * sizeof(*sequence));
8813 assert(sequence);
8815 sequence[sequence_count++] = *msg;
8818 static void flush_sequence(void)
8820 HeapFree(GetProcessHeap(), 0, sequence);
8821 sequence = NULL;
8822 sequence_count = sequence_size = 0;
8825 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
8826 const char *file, int line)
8828 static const struct externalui_message end_of_sequence = {0};
8829 const struct externalui_message *actual;
8830 int failcount = 0;
8831 int i;
8833 add_message(&end_of_sequence);
8835 actual = sequence;
8837 while (expected->message && actual->message)
8839 if (expected->message == actual->message)
8841 if (expected->field_count < actual->field_count)
8843 todo_wine_if (todo)
8844 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
8845 context, expected->message, expected->field_count, actual->field_count);
8846 failcount++;
8849 for (i = 0; i <= actual->field_count; i++)
8851 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
8853 todo_wine_if (todo)
8854 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8855 context, expected->message, i, expected->field[i], actual->field[i]);
8856 failcount++;
8860 expected++;
8861 actual++;
8863 else if (expected->optional)
8865 expected++;
8867 else
8869 todo_wine_if (todo)
8870 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8871 context, expected->message, actual->message);
8872 failcount++;
8873 if (todo)
8874 goto done;
8875 expected++;
8876 actual++;
8880 if (expected->message || actual->message)
8882 todo_wine_if (todo)
8883 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8884 context, expected->message, actual->message);
8885 failcount++;
8888 if(todo && !failcount) /* succeeded yet marked todo */
8890 todo_wine
8891 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
8894 done:
8895 flush_sequence();
8898 #define ok_sequence(exp, contx, todo) \
8899 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8901 /* don't use PROGRESS, which is timing-dependent,
8902 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8903 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE =
8904 INSTALLLOGMODE_FATALEXIT |
8905 INSTALLLOGMODE_ERROR |
8906 INSTALLLOGMODE_WARNING |
8907 INSTALLLOGMODE_USER |
8908 INSTALLLOGMODE_INFO |
8909 INSTALLLOGMODE_FILESINUSE |
8910 INSTALLLOGMODE_RESOLVESOURCE |
8911 INSTALLLOGMODE_OUTOFDISKSPACE |
8912 INSTALLLOGMODE_ACTIONSTART |
8913 INSTALLLOGMODE_ACTIONDATA |
8914 INSTALLLOGMODE_COMMONDATA |
8915 INSTALLLOGMODE_INITIALIZE |
8916 INSTALLLOGMODE_TERMINATE |
8917 INSTALLLOGMODE_RMFILESINUSE |
8918 INSTALLLOGMODE_INSTALLSTART |
8919 INSTALLLOGMODE_INSTALLEND;
8921 static const struct externalui_message empty_sequence[] = {
8925 static const struct externalui_message openpackage_nonexistent_sequence[] = {
8926 {INSTALLMESSAGE_INITIALIZE, -1},
8927 {INSTALLMESSAGE_TERMINATE, -1},
8931 static const struct externalui_message openpackage_sequence[] = {
8932 {INSTALLMESSAGE_INITIALIZE, -1},
8933 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8934 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
8935 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8936 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8940 static const struct externalui_message processmessage_info_sequence[] = {
8941 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8945 static const struct externalui_message processmessage_actionstart_sequence[] = {
8946 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8950 static const struct externalui_message processmessage_actiondata_sequence[] = {
8951 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8955 static const struct externalui_message processmessage_error_sequence[] = {
8956 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8960 static const struct externalui_message processmessage_internal_error_sequence[] = {
8961 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8962 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8966 static const struct externalui_message processmessage_error_format_sequence[] = {
8967 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8971 static const struct externalui_message doaction_costinitialize_sequence[] = {
8972 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8973 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8974 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8978 static const struct externalui_message doaction_custom_sequence[] = {
8979 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8980 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8981 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8985 static const struct externalui_message doaction_custom_fullui_sequence[] = {
8986 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8987 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
8988 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8989 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8993 static const struct externalui_message doaction_custom_cancel_sequence[] = {
8994 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8998 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
8999 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9000 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9001 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
9002 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
9003 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
9004 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
9008 static const struct externalui_message doaction_dialog_sequence[] = {
9009 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9010 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9011 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9012 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
9013 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
9017 static const struct externalui_message doaction_dialog_error_sequence[] = {
9018 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
9019 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
9020 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
9024 static const struct externalui_message doaction_dialog_3_sequence[] = {
9025 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9026 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9027 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9028 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9032 static const struct externalui_message doaction_dialog_12345_sequence[] = {
9033 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9034 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9035 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9036 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
9040 static const struct externalui_message closehandle_sequence[] = {
9041 {INSTALLMESSAGE_TERMINATE, -1},
9045 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
9047 INT retval = context ? *((INT *)context) : 0;
9048 struct externalui_message msg;
9050 msg.message = message;
9051 msg.field_count = 0;
9052 strcpy(msg.field[0], string);
9053 add_message(&msg);
9055 return retval;
9058 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
9060 INT retval = context ? *((INT *)context) : 0;
9061 struct externalui_message msg;
9062 char buffer[256];
9063 DWORD length;
9064 UINT r;
9065 int i;
9067 msg.message = message;
9068 if (message == INSTALLMESSAGE_TERMINATE)
9070 /* trying to access the record seems to hang on some versions of Windows */
9071 msg.field_count = -1;
9072 add_message(&msg);
9073 return 1;
9075 msg.field_count = MsiRecordGetFieldCount(hrecord);
9076 for (i = 0; i <= msg.field_count; i++)
9078 length = sizeof(buffer);
9079 r = MsiRecordGetStringA(hrecord, i, buffer, &length);
9080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9081 memcpy(msg.field[i], buffer, min(100, length+1));
9084 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
9085 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
9086 return retval;
9088 add_message(&msg);
9090 return retval;
9093 static void test_externalui_message(void)
9095 /* test that events trigger the correct sequence of messages */
9097 INSTALLUI_HANDLER_RECORD prev;
9098 MSIHANDLE hdb, hpkg, hrecord;
9099 INT retval = 1;
9100 UINT r;
9102 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9104 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval);
9105 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev);
9107 flush_sequence();
9109 CoInitialize(NULL);
9111 hdb = create_package_db();
9112 ok(hdb, "failed to create database\n");
9114 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9115 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9118 r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9119 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
9120 r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9121 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
9123 create_actiontext_table(hdb);
9124 add_actiontext_entry(hdb, "'custom', 'description', 'template'");
9125 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
9127 r = MsiOpenPackageA(NULL, &hpkg);
9128 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9129 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
9131 r = MsiOpenPackageA("nonexistent", &hpkg);
9132 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9133 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9135 r = package_from_db(hdb, &hpkg);
9136 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9138 skip("Not enough rights to perform tests\n");
9139 DeleteFileA(msifile);
9140 return;
9142 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9143 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9145 /* Test MsiProcessMessage */
9146 hrecord = MsiCreateRecord(3);
9147 ok(hrecord, "failed to create record\n");
9149 MsiRecordSetStringA(hrecord, 0, "zero");
9150 MsiRecordSetStringA(hrecord, 1, "one");
9151 MsiRecordSetStringA(hrecord, 2, "two");
9152 MsiRecordSetStringA(hrecord, 3, "three");
9153 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9154 ok(r == 1, "Expected 1, got %d\n", r);
9155 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9157 MsiRecordSetStringA(hrecord, 1, "name");
9158 MsiRecordSetStringA(hrecord, 2, "description");
9159 MsiRecordSetStringA(hrecord, 3, "template");
9160 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord);
9161 ok(r == 1, "Expected 1, got %d\n", r);
9162 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9164 MsiRecordSetStringA(hrecord, 0, "apple");
9165 MsiRecordSetStringA(hrecord, 1, "cherry");
9166 MsiRecordSetStringA(hrecord, 2, "banana");
9167 MsiRecordSetStringA(hrecord, 3, "guava");
9168 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord);
9169 ok(r == 1, "Expected 1, got %d\n", r);
9170 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9172 /* non-internal error */
9173 MsiRecordSetStringA(hrecord, 0, NULL);
9174 MsiRecordSetInteger(hrecord, 1, 1311);
9175 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9176 ok(r == 1, "Expected 1, got %d\n", r);
9177 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9179 /* internal error */
9180 MsiRecordSetStringA(hrecord, 0, NULL);
9181 MsiRecordSetInteger(hrecord, 1, 2726);
9182 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9183 ok(r == 0, "Expected 0, got %d\n", r);
9184 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9186 /* with format field */
9187 MsiRecordSetStringA(hrecord, 0, "starfruit");
9188 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9189 ok(r == 1, "Expected 1, got %d\n", r);
9190 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9192 /* Test a standard action */
9193 r = MsiDoActionA(hpkg, "CostInitialize");
9194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9195 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9197 /* Test a custom action */
9198 r = MsiDoActionA(hpkg, "custom");
9199 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9200 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9202 /* close the package */
9203 MsiCloseHandle(hpkg);
9204 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9206 /* Test dialogs */
9207 hdb = create_package_db();
9208 ok(hdb, "failed to create database\n");
9210 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9213 create_dialog_table(hdb);
9214 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9216 create_control_table(hdb);
9217 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9219 r = package_from_db(hdb, &hpkg);
9220 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9221 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9223 /* Test a custom action */
9224 r = MsiDoActionA(hpkg, "custom");
9225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9226 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9228 retval = 2;
9229 r = MsiDoActionA(hpkg, "custom");
9230 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9231 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9233 retval = 0;
9234 r = MsiDoActionA(hpkg, "custom");
9235 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9236 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9238 r = MsiDoActionA(hpkg, "dialog");
9239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9240 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9242 retval = -1;
9243 r = MsiDoActionA(hpkg, "error");
9244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9245 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9247 r = MsiDoActionA(hpkg, "error");
9248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9249 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9251 retval = -2;
9252 r = MsiDoActionA(hpkg, "custom");
9253 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9254 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9256 retval = 3;
9257 r = MsiDoActionA(hpkg, "dialog");
9258 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9259 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9261 retval = 12345;
9262 r = MsiDoActionA(hpkg, "dialog");
9263 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9264 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9266 MsiCloseHandle(hpkg);
9267 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9269 MsiCloseHandle(hrecord);
9270 CoUninitialize();
9271 DeleteFileA(msifile);
9272 DeleteFileA("forcecodepage.idt");
9275 static const struct externalui_message controlevent_spawn_sequence[] = {
9276 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9277 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9278 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9279 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9281 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9282 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9283 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9285 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9287 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9291 static const struct externalui_message controlevent_spawn2_sequence[] = {
9292 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9293 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9294 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9295 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9297 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9298 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9299 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9301 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9303 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9307 static void test_controlevent(void)
9309 INSTALLUI_HANDLER_RECORD prev;
9310 MSIHANDLE hdb, hpkg;
9311 UINT r;
9313 if (!winetest_interactive)
9315 skip("interactive ControlEvent tests\n");
9316 return;
9319 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9321 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9322 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9324 flush_sequence();
9326 CoInitialize(NULL);
9328 hdb = create_package_db();
9329 ok(hdb, "failed to create database\n");
9331 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9332 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9335 create_dialog_table(hdb);
9336 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9337 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9338 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9339 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9341 create_control_table(hdb);
9342 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9343 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9344 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9345 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9347 create_controlevent_table(hdb);
9348 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9349 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9351 create_custom_action_table(hdb);
9352 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9354 /* SpawnDialog and EndDialog should trigger after all other events */
9355 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9356 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9358 /* Multiple dialog events cause only the last one to be triggered */
9359 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9360 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9361 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9363 r = package_from_db(hdb, &hpkg);
9364 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9365 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9367 r = MsiDoActionA(hpkg, "spawn");
9368 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9369 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9371 r = MsiDoActionA(hpkg, "spawn2");
9372 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9373 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9375 MsiCloseHandle(hpkg);
9376 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9378 CoUninitialize();
9379 DeleteFileA(msifile);
9380 DeleteFileA("forcecodepage.idt");
9383 static const struct externalui_message toplevel_install_sequence[] = {
9384 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9385 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9387 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9388 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9389 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9390 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9391 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9393 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9394 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9395 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9397 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9398 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9399 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9401 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9402 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9403 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9405 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9406 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9407 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9409 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9410 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9412 /* property dump */
9414 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9415 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9416 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9420 static const struct externalui_message toplevel_install_ui_sequence[] = {
9421 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9422 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9424 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9425 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9426 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9428 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9432 static const struct externalui_message toplevel_executeaction_install_sequence[] = {
9433 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9434 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9436 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9437 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9438 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9439 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9441 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9442 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9443 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9445 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9446 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9447 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9449 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9450 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9451 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9453 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9454 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9455 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9457 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9458 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9460 /* property dump */
9462 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9463 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9464 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9468 static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = {
9469 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9470 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9472 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9473 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9474 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9475 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9477 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9478 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9479 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9481 /* property dump */
9483 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9484 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9485 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9489 static const struct externalui_message toplevel_msiinstallproduct_sequence[] = {
9490 {INSTALLMESSAGE_INITIALIZE, -1},
9492 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9493 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9494 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9495 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9496 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9498 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9499 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9501 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9502 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9503 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9505 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9507 /* property dump */
9509 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9510 {INSTALLMESSAGE_TERMINATE, -1},
9514 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = {
9515 {INSTALLMESSAGE_INITIALIZE, -1},
9517 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9518 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9519 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9520 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9521 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9523 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9524 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9525 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9527 /* property dump */
9529 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9530 {INSTALLMESSAGE_TERMINATE, -1},
9534 /* tests involving top-level actions: INSTALL, ExecuteAction */
9535 static void test_top_level_action(void)
9537 INSTALLUI_HANDLER_RECORD prev;
9538 MSIHANDLE hdb, hpkg;
9539 UINT r;
9540 char msifile_absolute[MAX_PATH];
9542 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9544 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9545 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9547 flush_sequence();
9549 CoInitialize(NULL);
9551 hdb = create_package_db();
9552 ok(hdb, "failed to create database\n");
9554 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9555 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9558 create_property_table(hdb);
9559 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9561 create_install_execute_sequence_table(hdb);
9562 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9563 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9564 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9566 create_install_ui_sequence_table(hdb);
9567 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9569 MsiDatabaseCommit(hdb);
9571 /* for some reason we have to open the package from file using an absolute path */
9572 MsiCloseHandle(hdb);
9573 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9574 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9575 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9576 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9578 /* test INSTALL */
9579 r = MsiDoActionA(hpkg, "INSTALL");
9580 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9581 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9583 /* test INSTALL with reduced+ UI */
9584 /* for some reason we need to re-open the package to change the internal UI */
9585 MsiCloseHandle(hpkg);
9586 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9587 MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL);
9588 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9589 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9590 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9592 r = MsiDoActionA(hpkg, "INSTALL");
9593 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9594 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9596 /* test ExecuteAction with EXECUTEACTION property unset */
9597 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9598 r = MsiDoActionA(hpkg, "ExecuteAction");
9599 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9600 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9602 /* test ExecuteAction with EXECUTEACTION property set */
9603 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9604 r = MsiDoActionA(hpkg, "ExecuteAction");
9605 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9606 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9608 MsiCloseHandle(hpkg);
9609 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9611 /* test MsiInstallProduct() */
9612 r = MsiInstallProductA(msifile_absolute, NULL);
9613 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9614 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9616 r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9617 todo_wine
9618 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9619 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9621 CoUninitialize();
9622 DeleteFileA(msifile);
9623 DeleteFileA("forcecodepage.idt");
9626 START_TEST(package)
9628 char temp_path[MAX_PATH], prev_path[MAX_PATH];
9629 STATEMGRSTATUS status;
9630 BOOL ret = FALSE;
9631 DWORD len;
9633 init_functionpointers();
9635 if (pIsWow64Process)
9636 pIsWow64Process(GetCurrentProcess(), &is_wow64);
9638 GetCurrentDirectoryA(MAX_PATH, prev_path);
9639 GetTempPathA(MAX_PATH, temp_path);
9640 SetCurrentDirectoryA(temp_path);
9642 lstrcpyA(CURR_DIR, temp_path);
9643 len = lstrlenA(CURR_DIR);
9645 if (len && (CURR_DIR[len - 1] == '\\'))
9646 CURR_DIR[len - 1] = 0;
9648 /* Create a restore point ourselves so we circumvent the multitude of restore points
9649 * that would have been created by all the installation and removal tests.
9651 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
9652 * creation of restore points.
9654 if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
9656 memset(&status, 0, sizeof(status));
9657 ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9660 test_createpackage();
9661 test_doaction();
9662 test_gettargetpath_bad();
9663 test_settargetpath();
9664 test_props();
9665 test_property_table();
9666 test_condition();
9667 test_msipackage();
9668 test_formatrecord2();
9669 test_formatrecord_tables();
9670 test_states();
9671 test_removefiles();
9672 test_appsearch();
9673 test_appsearch_complocator();
9674 test_appsearch_reglocator();
9675 test_appsearch_inilocator();
9676 test_appsearch_drlocator();
9677 test_featureparents();
9678 test_installprops();
9679 test_launchconditions();
9680 test_ccpsearch();
9681 test_complocator();
9682 test_MsiGetSourcePath();
9683 test_shortlongsource();
9684 test_sourcedir();
9685 test_access();
9686 test_emptypackage();
9687 test_MsiGetProductProperty();
9688 test_MsiSetProperty();
9689 test_MsiApplyMultiplePatches();
9690 test_MsiApplyPatch();
9691 test_costs();
9692 test_MsiDatabaseCommit();
9693 test_externalui();
9694 test_externalui_message();
9695 test_controlevent();
9696 test_top_level_action();
9698 if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
9700 ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9701 if (ret)
9702 remove_restore_point(status.llSequenceNumber);
9705 SetCurrentDirectoryA(prev_path);