Release 9.12.
[wine.git] / dlls / msi / tests / package.c
blob5977a525fb6d75c5bd22a79b0cc2996a1a9903d6
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"
35 #include "utils.h"
37 static BOOL is_wow64;
38 static const char msifile[] = "winetest-package.msi";
39 static const WCHAR msifileW[] = L"winetest-package.msi";
41 static char *get_user_sid(void)
43 HANDLE token;
44 DWORD size = 0;
45 TOKEN_USER *user;
46 char *usersid = NULL;
48 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
49 GetTokenInformation(token, TokenUser, NULL, size, &size);
51 user = malloc(size);
52 GetTokenInformation(token, TokenUser, user, size, &size);
53 ConvertSidToStringSidA(user->User.Sid, &usersid);
54 free(user);
56 CloseHandle(token);
57 return usersid;
60 /* RegDeleteTreeW from dlls/advapi32/registry.c */
61 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
63 LONG ret;
64 DWORD dwMaxSubkeyLen, dwMaxValueLen;
65 DWORD dwMaxLen, dwSize;
66 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
67 HKEY hSubKey = hKey;
69 if(lpszSubKey)
71 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
72 if (ret) return ret;
75 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
76 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
77 if (ret) goto cleanup;
79 dwMaxSubkeyLen++;
80 dwMaxValueLen++;
81 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
82 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
84 /* Name too big: alloc a buffer for it */
85 if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR))))
87 ret = ERROR_NOT_ENOUGH_MEMORY;
88 goto cleanup;
92 /* Recursively delete all the subkeys */
93 while (TRUE)
95 dwSize = dwMaxLen;
96 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
97 NULL, NULL, NULL)) break;
99 ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
100 if (ret) goto cleanup;
103 if (lpszSubKey)
104 ret = RegDeleteKeyExW(hKey, lpszSubKey, access, 0);
105 else
106 while (TRUE)
108 dwSize = dwMaxLen;
109 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
110 NULL, NULL, NULL, NULL)) break;
112 ret = RegDeleteValueW(hKey, lpszName);
113 if (ret) goto cleanup;
116 cleanup:
117 if (lpszName != szNameBuf) free(lpszName);
118 if (lpszSubKey) RegCloseKey(hSubKey);
119 return ret;
122 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
124 DWORD i,n=1;
125 GUID guid;
127 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
128 return FALSE;
130 for(i=0; i<8; i++)
131 out[7-i] = in[n++];
132 n++;
133 for(i=0; i<4; i++)
134 out[11-i] = in[n++];
135 n++;
136 for(i=0; i<4; i++)
137 out[15-i] = in[n++];
138 n++;
139 for(i=0; i<2; i++)
141 out[17+i*2] = in[n++];
142 out[16+i*2] = in[n++];
144 n++;
145 for( ; i<8; i++)
147 out[17+i*2] = in[n++];
148 out[16+i*2] = in[n++];
150 out[32]=0;
151 return TRUE;
154 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
156 WCHAR guidW[MAX_PATH];
157 WCHAR squashedW[MAX_PATH];
158 GUID guid;
159 HRESULT hr;
160 int size;
162 hr = CoCreateGuid(&guid);
163 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
165 size = StringFromGUID2(&guid, guidW, MAX_PATH);
166 ok(size == 39, "Expected 39, got %#lx\n", hr);
168 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
169 squash_guid(guidW, squashedW);
170 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
173 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
174 LPCSTR guid, LPSTR usersid, BOOL dir)
176 WCHAR guidW[MAX_PATH];
177 WCHAR squashedW[MAX_PATH];
178 CHAR squashed[MAX_PATH];
179 CHAR comppath[MAX_PATH + 81];
180 CHAR prodpath[MAX_PATH];
181 CHAR path[MAX_PATH];
182 LPCSTR prod = NULL;
183 HKEY hkey;
184 REGSAM access = KEY_ALL_ACCESS;
186 if (is_wow64)
187 access |= KEY_WOW64_64KEY;
189 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
190 squash_guid(guidW, squashedW);
191 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
193 if (context == MSIINSTALLCONTEXT_MACHINE)
195 prod = "3D0DAE300FACA1300AD792060BCDAA92";
196 sprintf(comppath,
197 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
198 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
199 lstrcpyA(prodpath,
200 "SOFTWARE\\Classes\\Installer\\"
201 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
203 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
205 prod = "7D2F387510109040002000060BECB6AB";
206 sprintf(comppath,
207 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
208 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
209 sprintf(prodpath,
210 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
211 "Installer\\%s\\Installer\\Products\\"
212 "7D2F387510109040002000060BECB6AB", usersid);
214 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
216 prod = "7D2F387510109040002000060BECB6AB";
217 sprintf(comppath,
218 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
219 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
220 sprintf(prodpath,
221 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
222 "Installer\\Managed\\%s\\Installer\\Products\\"
223 "7D2F387510109040002000060BECB6AB", usersid);
226 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
228 lstrcpyA(path, CURR_DIR);
229 lstrcatA(path, "\\");
230 if (!dir) lstrcatA(path, filename);
232 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
233 RegCloseKey(hkey);
235 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
236 RegCloseKey(hkey);
239 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
241 WCHAR guidW[MAX_PATH];
242 WCHAR squashedW[MAX_PATH];
243 WCHAR substrW[MAX_PATH];
244 CHAR squashed[MAX_PATH];
245 CHAR comppath[MAX_PATH + 81];
246 CHAR prodpath[MAX_PATH];
247 REGSAM access = KEY_ALL_ACCESS;
249 if (is_wow64)
250 access |= KEY_WOW64_64KEY;
252 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
253 squash_guid(guidW, squashedW);
254 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
256 if (context == MSIINSTALLCONTEXT_MACHINE)
258 sprintf(comppath,
259 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
260 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
261 lstrcpyA(prodpath,
262 "SOFTWARE\\Classes\\Installer\\"
263 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
265 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
267 sprintf(comppath,
268 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
269 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
270 sprintf(prodpath,
271 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
272 "Installer\\%s\\Installer\\Products\\"
273 "7D2F387510109040002000060BECB6AB", usersid);
275 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
277 sprintf(comppath,
278 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
279 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
280 sprintf(prodpath,
281 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
282 "Installer\\Managed\\%s\\Installer\\Products\\"
283 "7D2F387510109040002000060BECB6AB", usersid);
286 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
287 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
289 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
290 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
293 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
295 MSIHANDLE hview = 0;
296 UINT r, ret;
298 /* open a select query */
299 r = MsiDatabaseOpenViewA(hdb, query, &hview);
300 if (r != ERROR_SUCCESS)
301 return r;
302 r = MsiViewExecute(hview, 0);
303 if (r != ERROR_SUCCESS)
304 return r;
305 ret = MsiViewFetch(hview, phrec);
306 r = MsiViewClose(hview);
307 if (r != ERROR_SUCCESS)
308 return r;
309 r = MsiCloseHandle(hview);
310 if (r != ERROR_SUCCESS)
311 return r;
312 return ret;
315 static UINT create_component_table( MSIHANDLE hdb )
317 UINT r = run_query( hdb, 0,
318 "CREATE TABLE `Component` ( "
319 "`Component` CHAR(72) NOT NULL, "
320 "`ComponentId` CHAR(38), "
321 "`Directory_` CHAR(72) NOT NULL, "
322 "`Attributes` SHORT NOT NULL, "
323 "`Condition` CHAR(255), "
324 "`KeyPath` CHAR(72) "
325 "PRIMARY KEY `Component`)" );
326 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
327 return r;
330 static UINT create_feature_table( MSIHANDLE hdb )
332 UINT r = run_query( hdb, 0,
333 "CREATE TABLE `Feature` ( "
334 "`Feature` CHAR(38) NOT NULL, "
335 "`Feature_Parent` CHAR(38), "
336 "`Title` CHAR(64), "
337 "`Description` CHAR(255), "
338 "`Display` SHORT NOT NULL, "
339 "`Level` SHORT NOT NULL, "
340 "`Directory_` CHAR(72), "
341 "`Attributes` SHORT NOT NULL "
342 "PRIMARY KEY `Feature`)" );
343 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r);
344 return r;
347 static UINT create_feature_components_table( MSIHANDLE hdb )
349 UINT r = run_query( hdb, 0,
350 "CREATE TABLE `FeatureComponents` ( "
351 "`Feature_` CHAR(38) NOT NULL, "
352 "`Component_` CHAR(72) NOT NULL "
353 "PRIMARY KEY `Feature_`, `Component_` )" );
354 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
355 return r;
358 static UINT create_file_table( MSIHANDLE hdb )
360 UINT r = run_query( hdb, 0,
361 "CREATE TABLE `File` ("
362 "`File` CHAR(72) NOT NULL, "
363 "`Component_` CHAR(72) NOT NULL, "
364 "`FileName` CHAR(255) NOT NULL, "
365 "`FileSize` LONG NOT NULL, "
366 "`Version` CHAR(72), "
367 "`Language` CHAR(20), "
368 "`Attributes` SHORT, "
369 "`Sequence` SHORT NOT NULL "
370 "PRIMARY KEY `File`)" );
371 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r);
372 return r;
375 static UINT create_remove_file_table( MSIHANDLE hdb )
377 UINT r = run_query( hdb, 0,
378 "CREATE TABLE `RemoveFile` ("
379 "`FileKey` CHAR(72) NOT NULL, "
380 "`Component_` CHAR(72) NOT NULL, "
381 "`FileName` CHAR(255) LOCALIZABLE, "
382 "`DirProperty` CHAR(72) NOT NULL, "
383 "`InstallMode` SHORT NOT NULL "
384 "PRIMARY KEY `FileKey`)" );
385 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r);
386 return r;
389 static UINT create_appsearch_table( MSIHANDLE hdb )
391 UINT r = run_query( hdb, 0,
392 "CREATE TABLE `AppSearch` ("
393 "`Property` CHAR(72) NOT NULL, "
394 "`Signature_` CHAR(72) NOT NULL "
395 "PRIMARY KEY `Property`, `Signature_`)" );
396 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r);
397 return r;
400 static UINT create_reglocator_table( MSIHANDLE hdb )
402 UINT r = run_query( hdb, 0,
403 "CREATE TABLE `RegLocator` ("
404 "`Signature_` CHAR(72) NOT NULL, "
405 "`Root` SHORT NOT NULL, "
406 "`Key` CHAR(255) NOT NULL, "
407 "`Name` CHAR(255), "
408 "`Type` SHORT "
409 "PRIMARY KEY `Signature_`)" );
410 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r);
411 return r;
414 static UINT create_signature_table( MSIHANDLE hdb )
416 UINT r = run_query( hdb, 0,
417 "CREATE TABLE `Signature` ("
418 "`Signature` CHAR(72) NOT NULL, "
419 "`FileName` CHAR(255) NOT NULL, "
420 "`MinVersion` CHAR(20), "
421 "`MaxVersion` CHAR(20), "
422 "`MinSize` LONG, "
423 "`MaxSize` LONG, "
424 "`MinDate` LONG, "
425 "`MaxDate` LONG, "
426 "`Languages` CHAR(255) "
427 "PRIMARY KEY `Signature`)" );
428 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r);
429 return r;
432 static UINT create_launchcondition_table( MSIHANDLE hdb )
434 UINT r = run_query( hdb, 0,
435 "CREATE TABLE `LaunchCondition` ("
436 "`Condition` CHAR(255) NOT NULL, "
437 "`Description` CHAR(255) NOT NULL "
438 "PRIMARY KEY `Condition`)" );
439 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r);
440 return r;
443 static UINT create_property_table( MSIHANDLE hdb )
445 UINT r = run_query( hdb, 0,
446 "CREATE TABLE `Property` ("
447 "`Property` CHAR(72) NOT NULL, "
448 "`Value` CHAR(0) "
449 "PRIMARY KEY `Property`)" );
450 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r);
451 return r;
454 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
456 UINT r = run_query( hdb, 0,
457 "CREATE TABLE `InstallExecuteSequence` ("
458 "`Action` CHAR(72) NOT NULL, "
459 "`Condition` CHAR(255), "
460 "`Sequence` SHORT "
461 "PRIMARY KEY `Action`)" );
462 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r);
463 return r;
466 static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
468 UINT r = run_query( hdb, 0,
469 "CREATE TABLE `InstallUISequence` ("
470 "`Action` CHAR(72) NOT NULL, "
471 "`Condition` CHAR(255), "
472 "`Sequence` SHORT "
473 "PRIMARY KEY `Action`)" );
474 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r);
475 return r;
478 static UINT create_media_table( MSIHANDLE hdb )
480 UINT r = run_query( hdb, 0,
481 "CREATE TABLE `Media` ("
482 "`DiskId` SHORT NOT NULL, "
483 "`LastSequence` SHORT NOT NULL, "
484 "`DiskPrompt` CHAR(64), "
485 "`Cabinet` CHAR(255), "
486 "`VolumeLabel` CHAR(32), "
487 "`Source` CHAR(72) "
488 "PRIMARY KEY `DiskId`)" );
489 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r);
490 return r;
493 static UINT create_ccpsearch_table( MSIHANDLE hdb )
495 UINT r = run_query( hdb, 0,
496 "CREATE TABLE `CCPSearch` ("
497 "`Signature_` CHAR(72) NOT NULL "
498 "PRIMARY KEY `Signature_`)" );
499 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r);
500 return r;
503 static UINT create_drlocator_table( MSIHANDLE hdb )
505 UINT r = run_query( hdb, 0,
506 "CREATE TABLE `DrLocator` ("
507 "`Signature_` CHAR(72) NOT NULL, "
508 "`Parent` CHAR(72), "
509 "`Path` CHAR(255), "
510 "`Depth` SHORT "
511 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
512 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r);
513 return r;
516 static UINT create_complocator_table( MSIHANDLE hdb )
518 UINT r = run_query( hdb, 0,
519 "CREATE TABLE `CompLocator` ("
520 "`Signature_` CHAR(72) NOT NULL, "
521 "`ComponentId` CHAR(38) NOT NULL, "
522 "`Type` SHORT "
523 "PRIMARY KEY `Signature_`)" );
524 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r);
525 return r;
528 static UINT create_inilocator_table( MSIHANDLE hdb )
530 UINT r = run_query( hdb, 0,
531 "CREATE TABLE `IniLocator` ("
532 "`Signature_` CHAR(72) NOT NULL, "
533 "`FileName` CHAR(255) NOT NULL, "
534 "`Section` CHAR(96)NOT NULL, "
535 "`Key` CHAR(128)NOT NULL, "
536 "`Field` SHORT, "
537 "`Type` SHORT "
538 "PRIMARY KEY `Signature_`)" );
539 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r);
540 return r;
543 static UINT create_custom_action_table( MSIHANDLE hdb )
545 UINT r = run_query( hdb, 0,
546 "CREATE TABLE `CustomAction` ("
547 "`Action` CHAR(72) NOT NULL, "
548 "`Type` SHORT NOT NULL, "
549 "`Source` CHAR(75), "
550 "`Target` CHAR(255) "
551 "PRIMARY KEY `Action`)" );
552 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
553 return r;
556 static UINT create_dialog_table( MSIHANDLE hdb )
558 UINT r = run_query(hdb, 0,
559 "CREATE TABLE `Dialog` ("
560 "`Dialog` CHAR(72) NOT NULL, "
561 "`HCentering` SHORT NOT NULL, "
562 "`VCentering` SHORT NOT NULL, "
563 "`Width` SHORT NOT NULL, "
564 "`Height` SHORT NOT NULL, "
565 "`Attributes` LONG, "
566 "`Title` CHAR(128) LOCALIZABLE, "
567 "`Control_First` CHAR(50) NOT NULL, "
568 "`Control_Default` CHAR(50), "
569 "`Control_Cancel` CHAR(50) "
570 "PRIMARY KEY `Dialog`)");
571 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r);
572 return r;
575 static UINT create_control_table( MSIHANDLE hdb )
577 UINT r = run_query(hdb, 0,
578 "CREATE TABLE `Control` ("
579 "`Dialog_` CHAR(72) NOT NULL, "
580 "`Control` CHAR(50) NOT NULL, "
581 "`Type` CHAR(20) NOT NULL, "
582 "`X` SHORT NOT NULL, "
583 "`Y` SHORT NOT NULL, "
584 "`Width` SHORT NOT NULL, "
585 "`Height` SHORT NOT NULL, "
586 "`Attributes` LONG, "
587 "`Property` CHAR(50), "
588 "`Text` CHAR(0) LOCALIZABLE, "
589 "`Control_Next` CHAR(50), "
590 "`Help` CHAR(255) LOCALIZABLE "
591 "PRIMARY KEY `Dialog_`, `Control`)");
592 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r);
593 return r;
596 static UINT create_controlevent_table( MSIHANDLE hdb )
598 UINT r = run_query(hdb, 0,
599 "CREATE TABLE `ControlEvent` ("
600 "`Dialog_` CHAR(72) NOT NULL, "
601 "`Control_` CHAR(50) NOT NULL, "
602 "`Event` CHAR(50) NOT NULL, "
603 "`Argument` CHAR(255) NOT NULL, "
604 "`Condition` CHAR(255), "
605 "`Ordering` SHORT "
606 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
607 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r);
608 return r;
611 static UINT create_actiontext_table( MSIHANDLE hdb )
613 UINT r = run_query(hdb, 0,
614 "CREATE TABLE `ActionText` ("
615 "`Action` CHAR(72) NOT NULL, "
616 "`Description` CHAR(64) LOCALIZABLE, "
617 "`Template` CHAR(128) LOCALIZABLE "
618 "PRIMARY KEY `Action`)");
619 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
620 return r;
623 static UINT create_upgrade_table( MSIHANDLE hdb )
625 UINT r = run_query( hdb, 0,
626 "CREATE TABLE `Upgrade` ("
627 "`UpgradeCode` CHAR(38) NOT NULL, "
628 "`VersionMin` CHAR(20), "
629 "`VersionMax` CHAR(20), "
630 "`Language` CHAR(255), "
631 "`Attributes` SHORT, "
632 "`Remove` CHAR(255), "
633 "`ActionProperty` CHAR(72) NOT NULL "
634 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
635 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r);
636 return r;
639 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
641 char *query;
642 UINT sz, r;
644 sz = strlen(values) + strlen(insert) + 1;
645 query = malloc(sz);
646 sprintf(query, insert, values);
647 r = run_query(hdb, 0, query);
648 free(query);
649 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
650 return r;
653 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
654 "INSERT INTO `Component` " \
655 "(`Component`, `ComponentId`, `Directory_`, " \
656 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
658 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
659 "INSERT INTO `Directory` " \
660 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
662 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
663 "INSERT INTO `Feature` " \
664 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
665 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
667 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
668 "INSERT INTO `FeatureComponents` " \
669 "(`Feature_`, `Component_`) VALUES( %s )")
671 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
672 "INSERT INTO `File` " \
673 "(`File`, `Component_`, `FileName`, `FileSize`, " \
674 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
676 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
677 "INSERT INTO `AppSearch` " \
678 "(`Property`, `Signature_`) VALUES( %s )")
680 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
681 "INSERT INTO `Signature` " \
682 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
683 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
684 "VALUES( %s )")
686 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
687 "INSERT INTO `LaunchCondition` " \
688 "(`Condition`, `Description`) VALUES( %s )")
690 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
691 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
693 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
694 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
696 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
697 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
699 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
700 "INSERT INTO `InstallExecuteSequence` " \
701 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
703 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
704 "INSERT INTO `InstallUISequence` " \
705 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
707 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
708 "INSERT INTO `Media` " \
709 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
710 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
712 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
713 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
715 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
716 "INSERT INTO `DrLocator` " \
717 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
719 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
720 "INSERT INTO `CompLocator` " \
721 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
723 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
724 "INSERT INTO `IniLocator` " \
725 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
726 "VALUES( %s )")
728 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
729 "INSERT INTO `CustomAction` " \
730 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
732 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
733 "INSERT INTO `Dialog` " \
734 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
736 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
737 "INSERT INTO `Control` " \
738 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
740 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
741 "INSERT INTO `ControlEvent` " \
742 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
744 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
745 "INSERT INTO `ActionText` " \
746 "(`Action`, `Description`, `Template`) VALUES( %s )");
748 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
749 "INSERT INTO `Upgrade` " \
750 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
752 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
753 const char *name, UINT type )
755 const char insert[] =
756 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
757 "VALUES( '%s', %u, '%s', '%s', %u )";
758 char *query;
759 UINT sz, r;
761 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
762 query = malloc( sz );
763 sprintf( query, insert, sig, root, path, name, type );
764 r = run_query( hdb, 0, query );
765 free( query );
766 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
767 return r;
770 static UINT set_summary_info(MSIHANDLE hdb)
772 UINT res;
773 MSIHANDLE suminfo;
775 /* build summary info */
776 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
777 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
779 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL,
780 "Installation Database");
781 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
783 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL,
784 "Installation Database");
785 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
787 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL,
788 "Wine Hackers");
789 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
791 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL,
792 ";1033");
793 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
795 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL,
796 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
797 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
799 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
800 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
802 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
803 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
805 res = MsiSummaryInfoPersist(suminfo);
806 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
808 res = MsiCloseHandle( suminfo);
809 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
811 return res;
815 static MSIHANDLE create_package_db(void)
817 MSIHANDLE hdb = 0;
818 UINT res;
820 DeleteFileA(msifile);
822 /* create an empty database */
823 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb );
824 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
825 if( res != ERROR_SUCCESS )
826 return hdb;
828 res = MsiDatabaseCommit( hdb );
829 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
831 res = set_summary_info(hdb);
832 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
834 res = run_query( hdb, 0,
835 "CREATE TABLE `Directory` ( "
836 "`Directory` CHAR(255) NOT NULL, "
837 "`Directory_Parent` CHAR(255), "
838 "`DefaultDir` CHAR(255) NOT NULL "
839 "PRIMARY KEY `Directory`)" );
840 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
842 return hdb;
845 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
847 UINT res;
848 CHAR szPackage[12];
849 MSIHANDLE hPackage;
851 sprintf(szPackage, "#%lu", hdb);
852 res = MsiOpenPackageA(szPackage, &hPackage);
853 if (res != ERROR_SUCCESS)
855 MsiCloseHandle(hdb);
856 return res;
859 res = MsiCloseHandle(hdb);
860 if (res != ERROR_SUCCESS)
862 MsiCloseHandle(hPackage);
863 return res;
866 *handle = hPackage;
867 return ERROR_SUCCESS;
870 static void create_test_file(const CHAR *name)
872 create_file_data(name, name, strlen(name));
875 typedef struct _tagVS_VERSIONINFO
877 WORD wLength;
878 WORD wValueLength;
879 WORD wType;
880 WCHAR szKey[1];
881 WORD wPadding1[1];
882 VS_FIXEDFILEINFO Value;
883 WORD wPadding2[1];
884 WORD wChildren[1];
885 } VS_VERSIONINFO;
887 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
888 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
890 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
892 VS_VERSIONINFO *pVerInfo;
893 VS_FIXEDFILEINFO *pFixedInfo;
894 LPBYTE buffer, ofs;
895 CHAR path[MAX_PATH];
896 DWORD handle, size;
897 HANDLE resource;
898 BOOL ret = FALSE;
900 GetSystemDirectoryA(path, MAX_PATH);
901 /* Some dlls can't be updated on Vista/W2K8 */
902 lstrcatA(path, "\\version.dll");
904 CopyFileA(path, name, FALSE);
906 size = GetFileVersionInfoSizeA(path, &handle);
907 buffer = malloc(size);
909 GetFileVersionInfoA(path, 0, size, buffer);
911 pVerInfo = (VS_VERSIONINFO *)buffer;
912 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
913 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
915 pFixedInfo->dwFileVersionMS = ms;
916 pFixedInfo->dwFileVersionLS = ls;
917 pFixedInfo->dwProductVersionMS = ms;
918 pFixedInfo->dwProductVersionLS = ls;
920 resource = BeginUpdateResourceA(name, FALSE);
921 if (!resource)
922 goto done;
924 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO),
925 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
926 goto done;
928 if (!EndUpdateResourceA(resource, FALSE))
929 goto done;
931 ret = TRUE;
933 done:
934 free(buffer);
935 return ret;
938 static BOOL is_root(const char *path)
940 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
943 static void test_createpackage(void)
945 MSIHANDLE hPackage = 0;
946 UINT res;
948 res = package_from_db(create_package_db(), &hPackage);
949 if (res == ERROR_INSTALL_PACKAGE_REJECTED)
951 skip("Not enough rights to perform tests\n");
952 DeleteFileA(msifile);
953 return;
955 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
957 res = MsiCloseHandle( hPackage);
958 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
959 DeleteFileA(msifile);
962 static void test_doaction( void )
964 MSIHANDLE hpkg;
965 UINT r;
967 r = MsiDoActionA( -1, NULL );
968 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
970 r = package_from_db(create_package_db(), &hpkg);
971 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
973 skip("Not enough rights to perform tests\n");
974 DeleteFileA(msifile);
975 return;
977 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
979 r = MsiDoActionA(hpkg, NULL);
980 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
982 r = MsiDoActionA(0, "boo");
983 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
985 r = MsiDoActionA(hpkg, "boo");
986 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
988 MsiCloseHandle( hpkg );
989 DeleteFileA(msifile);
992 static void test_gettargetpath_bad(void)
994 char buffer[0x80];
995 WCHAR bufferW[0x80];
996 MSIHANDLE hpkg;
997 DWORD sz;
998 UINT r;
1000 r = package_from_db(create_package_db(), &hpkg);
1001 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1003 skip("Not enough rights to perform tests\n");
1004 DeleteFileA(msifile);
1005 return;
1007 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1009 r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1010 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1012 r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1013 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1015 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1016 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1018 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1019 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1021 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1022 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1024 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1025 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1027 sz = 0;
1028 r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1029 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1031 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1032 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1034 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1035 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1037 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1038 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1040 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1041 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1043 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL );
1044 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1046 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL );
1047 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1049 sz = 0;
1050 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz );
1051 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1053 MsiCloseHandle( hpkg );
1054 DeleteFileA(msifile);
1057 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1059 UINT r;
1060 DWORD size;
1061 MSIHANDLE rec;
1063 rec = MsiCreateRecord( 1 );
1064 ok(rec, "MsiCreate record failed\n");
1066 r = MsiRecordSetStringA( rec, 0, file );
1067 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1069 size = MAX_PATH;
1070 r = MsiFormatRecordA( hpkg, rec, buff, &size );
1071 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1073 MsiCloseHandle( rec );
1076 static void test_settargetpath(void)
1078 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20];
1079 DWORD sz;
1080 MSIHANDLE hpkg;
1081 UINT r;
1082 MSIHANDLE hdb;
1084 hdb = create_package_db();
1085 ok ( hdb, "failed to create package database\n" );
1087 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1089 create_component_table( hdb );
1090 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1091 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1093 create_feature_table( hdb );
1094 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1096 create_feature_components_table( hdb );
1097 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1098 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1100 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1101 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1103 create_file_table( hdb );
1104 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1105 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1107 r = package_from_db( hdb, &hpkg );
1108 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1110 skip("Not enough rights to perform tests\n");
1111 DeleteFileA(msifile);
1112 return;
1114 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1116 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1118 r = MsiDoActionA( hpkg, "CostInitialize");
1119 ok( r == ERROR_SUCCESS, "cost init failed\n");
1121 r = MsiDoActionA( hpkg, "FileCost");
1122 ok( r == ERROR_SUCCESS, "file cost failed\n");
1124 r = MsiDoActionA( hpkg, "CostFinalize");
1125 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1127 buffer[0] = 0;
1128 sz = sizeof(buffer);
1129 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1130 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1131 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1133 r = MsiSetTargetPathA( 0, NULL, NULL );
1134 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1136 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1137 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1139 r = MsiSetTargetPathA( hpkg, "boo", NULL );
1140 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1142 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1143 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1145 sz = sizeof tempdir - 1;
1146 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1147 sprintf( file, "%srootfile.txt", tempdir );
1148 buffer[0] = 0;
1149 query_file_path( hpkg, "[#RootFile]", buffer );
1150 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1151 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1153 GetTempFileNameA( tempdir, "_wt", 0, buffer );
1154 sprintf( tempdir, "%s\\subdir", buffer );
1156 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1157 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1158 "MsiSetTargetPath on file returned %d\n", r );
1160 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1161 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1162 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1164 DeleteFileA( buffer );
1166 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1167 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1169 r = GetFileAttributesA( buffer );
1170 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1172 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1173 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1175 buffer[0] = 0;
1176 sz = sizeof buffer - 1;
1177 lstrcatA( tempdir, "\\" );
1178 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1179 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1180 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1182 sprintf( file, "%srootfile.txt", tempdir );
1183 query_file_path( hpkg, "[#RootFile]", buffer );
1184 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1186 buffer[0] = 0;
1187 sz = sizeof(buffer);
1188 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1189 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1190 lstrcatA( tempdir, "TestParent\\" );
1191 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1193 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1194 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1196 buffer[0] = 0;
1197 sz = sizeof(buffer);
1198 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1199 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1200 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1201 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1203 buffer[0] = 0;
1204 query_file_path( hpkg, "[#TestFile]", buffer );
1205 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1206 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1208 buffer[0] = 0;
1209 sz = sizeof buffer - 1;
1210 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1211 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1212 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1214 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1215 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1217 buffer[0] = 0;
1218 sz = sizeof buffer - 1;
1219 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1220 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1221 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1223 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " );
1224 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1226 buffer[0] = 0;
1227 sz = sizeof buffer - 1;
1228 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1229 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1230 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1232 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1233 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1235 buffer[0] = 0;
1236 sz = sizeof buffer - 1;
1237 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1238 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1239 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1241 MsiCloseHandle( hpkg );
1244 static void test_condition(void)
1246 MSICONDITION r;
1247 MSIHANDLE hpkg;
1249 r = package_from_db(create_package_db(), &hpkg);
1250 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1252 skip("Not enough rights to perform tests\n");
1253 DeleteFileA(msifile);
1254 return;
1256 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1258 r = MsiEvaluateConditionA(0, NULL);
1259 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1261 r = MsiEvaluateConditionA(hpkg, NULL);
1262 ok( r == MSICONDITION_NONE, "wrong return val\n");
1264 r = MsiEvaluateConditionA(hpkg, "");
1265 ok( r == MSICONDITION_NONE, "wrong return val\n");
1267 r = MsiEvaluateConditionA(hpkg, "1");
1268 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1270 r = MsiEvaluateConditionA(hpkg, "0");
1271 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1273 r = MsiEvaluateConditionA(hpkg, "-1");
1274 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1276 r = MsiEvaluateConditionA(hpkg, "0 = 0");
1277 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1279 r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1280 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1282 r = MsiEvaluateConditionA(hpkg, "0 = 1");
1283 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1285 r = MsiEvaluateConditionA(hpkg, "0 > 1");
1286 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1288 r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1289 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1291 r = MsiEvaluateConditionA(hpkg, "1 > 1");
1292 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1294 r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1295 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1297 r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1298 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1300 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1301 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1303 r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1304 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1306 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1307 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1309 r = MsiEvaluateConditionA(hpkg, "0 < 1");
1310 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1312 r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1313 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1315 r = MsiEvaluateConditionA(hpkg, "1 < 1");
1316 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1318 r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1319 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1321 r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1322 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1324 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1325 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1327 r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1328 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1330 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1331 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1333 r = MsiEvaluateConditionA(hpkg, "0 >=");
1334 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1336 r = MsiEvaluateConditionA(hpkg, " ");
1337 ok( r == MSICONDITION_NONE, "wrong return val\n");
1339 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1340 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1342 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1343 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1345 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1346 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1348 r = MsiEvaluateConditionA(hpkg, "not 0");
1349 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1351 r = MsiEvaluateConditionA(hpkg, "not LicView");
1352 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1354 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1355 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1357 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1358 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1360 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1361 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1363 r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1364 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1366 r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1367 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1369 r = MsiEvaluateConditionA(hpkg, "\"0\"");
1370 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1372 r = MsiEvaluateConditionA(hpkg, "1 and 2");
1373 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1375 r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1376 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1378 r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1379 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1381 r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1382 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1384 r = MsiEvaluateConditionA(hpkg, "(0)");
1385 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1387 r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1388 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1390 r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1391 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1393 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1394 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1396 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1397 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1399 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1400 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1402 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1403 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1405 r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1406 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1408 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1409 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1411 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1412 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1414 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1415 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1417 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1418 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1420 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1421 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1423 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1424 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1426 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1427 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1429 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1430 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1432 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1433 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1435 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1436 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1438 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1439 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1441 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1442 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1444 r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1445 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1447 r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1448 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1450 r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1451 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1453 r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1454 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1456 r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1457 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1459 r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1460 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1462 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1463 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1465 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1466 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1468 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1469 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1471 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1472 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1474 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1475 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1477 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1478 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1480 MsiSetPropertyA(hpkg, "mm", "5" );
1482 r = MsiEvaluateConditionA(hpkg, "mm = 5");
1483 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1485 r = MsiEvaluateConditionA(hpkg, "mm < 6");
1486 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1488 r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1489 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1491 r = MsiEvaluateConditionA(hpkg, "mm > 4");
1492 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1494 r = MsiEvaluateConditionA(hpkg, "mm < 12");
1495 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1497 r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1498 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1500 r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1501 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1503 r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1504 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1506 r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1507 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1509 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1510 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1512 r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1513 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1515 r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1516 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1518 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1519 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1521 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1522 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1524 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1525 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1527 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1528 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1530 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1531 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1533 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1534 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1536 r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1537 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1539 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1540 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1542 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1543 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1545 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1546 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1548 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1549 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1551 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1552 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1554 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1555 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1557 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1558 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1560 r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1561 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1563 r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1564 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1566 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1567 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1569 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1570 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1572 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1573 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1575 MsiSetPropertyA(hpkg, "bandalmael", "0" );
1576 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1577 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1579 MsiSetPropertyA(hpkg, "bandalmael", "" );
1580 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1581 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1583 MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1584 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1585 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1587 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1588 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1589 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1591 MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1592 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1593 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1595 MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1596 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1599 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1600 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1601 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1603 MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1604 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1605 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1607 MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1608 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1609 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1611 MsiSetPropertyA(hpkg, "bandalmael", "-" );
1612 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1613 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1615 MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1616 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1617 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1619 MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1620 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1621 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1622 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1623 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1625 MsiSetPropertyA(hpkg, "one", "hi");
1626 MsiSetPropertyA(hpkg, "two", "hithere");
1627 r = MsiEvaluateConditionA(hpkg, "one >< two");
1628 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1630 MsiSetPropertyA(hpkg, "one", "hithere");
1631 MsiSetPropertyA(hpkg, "two", "hi");
1632 r = MsiEvaluateConditionA(hpkg, "one >< two");
1633 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1635 MsiSetPropertyA(hpkg, "one", "hello");
1636 MsiSetPropertyA(hpkg, "two", "hi");
1637 r = MsiEvaluateConditionA(hpkg, "one >< two");
1638 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1640 MsiSetPropertyA(hpkg, "one", "hellohithere");
1641 MsiSetPropertyA(hpkg, "two", "hi");
1642 r = MsiEvaluateConditionA(hpkg, "one >< two");
1643 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1645 MsiSetPropertyA(hpkg, "one", "");
1646 MsiSetPropertyA(hpkg, "two", "hi");
1647 r = MsiEvaluateConditionA(hpkg, "one >< two");
1648 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1650 MsiSetPropertyA(hpkg, "one", "hi");
1651 MsiSetPropertyA(hpkg, "two", "");
1652 r = MsiEvaluateConditionA(hpkg, "one >< two");
1653 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1655 MsiSetPropertyA(hpkg, "one", "");
1656 MsiSetPropertyA(hpkg, "two", "");
1657 r = MsiEvaluateConditionA(hpkg, "one >< two");
1658 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1660 MsiSetPropertyA(hpkg, "one", "1234");
1661 MsiSetPropertyA(hpkg, "two", "1");
1662 r = MsiEvaluateConditionA(hpkg, "one >< two");
1663 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1665 MsiSetPropertyA(hpkg, "one", "one 1234");
1666 MsiSetPropertyA(hpkg, "two", "1");
1667 r = MsiEvaluateConditionA(hpkg, "one >< two");
1668 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1670 MsiSetPropertyA(hpkg, "one", "hithere");
1671 MsiSetPropertyA(hpkg, "two", "hi");
1672 r = MsiEvaluateConditionA(hpkg, "one << two");
1673 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1675 MsiSetPropertyA(hpkg, "one", "hi");
1676 MsiSetPropertyA(hpkg, "two", "hithere");
1677 r = MsiEvaluateConditionA(hpkg, "one << two");
1678 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1680 MsiSetPropertyA(hpkg, "one", "hi");
1681 MsiSetPropertyA(hpkg, "two", "hi");
1682 r = MsiEvaluateConditionA(hpkg, "one << two");
1683 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1685 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1686 MsiSetPropertyA(hpkg, "two", "hi");
1687 r = MsiEvaluateConditionA(hpkg, "one << two");
1688 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1690 MsiSetPropertyA(hpkg, "one", "");
1691 MsiSetPropertyA(hpkg, "two", "hi");
1692 r = MsiEvaluateConditionA(hpkg, "one << two");
1693 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1695 MsiSetPropertyA(hpkg, "one", "hithere");
1696 MsiSetPropertyA(hpkg, "two", "");
1697 r = MsiEvaluateConditionA(hpkg, "one << two");
1698 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1700 MsiSetPropertyA(hpkg, "one", "");
1701 MsiSetPropertyA(hpkg, "two", "");
1702 r = MsiEvaluateConditionA(hpkg, "one << two");
1703 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1705 MsiSetPropertyA(hpkg, "one", "1234");
1706 MsiSetPropertyA(hpkg, "two", "1");
1707 r = MsiEvaluateConditionA(hpkg, "one << two");
1708 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1710 MsiSetPropertyA(hpkg, "one", "1234 one");
1711 MsiSetPropertyA(hpkg, "two", "1");
1712 r = MsiEvaluateConditionA(hpkg, "one << two");
1713 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1715 MsiSetPropertyA(hpkg, "one", "hithere");
1716 MsiSetPropertyA(hpkg, "two", "there");
1717 r = MsiEvaluateConditionA(hpkg, "one >> two");
1718 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1720 MsiSetPropertyA(hpkg, "one", "hithere");
1721 MsiSetPropertyA(hpkg, "two", "hi");
1722 r = MsiEvaluateConditionA(hpkg, "one >> two");
1723 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1725 MsiSetPropertyA(hpkg, "one", "there");
1726 MsiSetPropertyA(hpkg, "two", "hithere");
1727 r = MsiEvaluateConditionA(hpkg, "one >> two");
1728 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1730 MsiSetPropertyA(hpkg, "one", "there");
1731 MsiSetPropertyA(hpkg, "two", "there");
1732 r = MsiEvaluateConditionA(hpkg, "one >> two");
1733 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1735 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1736 MsiSetPropertyA(hpkg, "two", "hi");
1737 r = MsiEvaluateConditionA(hpkg, "one >> two");
1738 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1740 MsiSetPropertyA(hpkg, "one", "");
1741 MsiSetPropertyA(hpkg, "two", "there");
1742 r = MsiEvaluateConditionA(hpkg, "one >> two");
1743 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1745 MsiSetPropertyA(hpkg, "one", "there");
1746 MsiSetPropertyA(hpkg, "two", "");
1747 r = MsiEvaluateConditionA(hpkg, "one >> two");
1748 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1750 MsiSetPropertyA(hpkg, "one", "");
1751 MsiSetPropertyA(hpkg, "two", "");
1752 r = MsiEvaluateConditionA(hpkg, "one >> two");
1753 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1755 MsiSetPropertyA(hpkg, "one", "1234");
1756 MsiSetPropertyA(hpkg, "two", "4");
1757 r = MsiEvaluateConditionA(hpkg, "one >> two");
1758 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1760 MsiSetPropertyA(hpkg, "one", "one 1234");
1761 MsiSetPropertyA(hpkg, "two", "4");
1762 r = MsiEvaluateConditionA(hpkg, "one >> two");
1763 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1765 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1767 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1768 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1770 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1771 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1773 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1774 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1776 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1777 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1779 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1780 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1782 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1783 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1785 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1786 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1788 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1789 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1791 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1792 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1794 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1795 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1797 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1798 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1800 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1801 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1803 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1804 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1806 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1807 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1809 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1810 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1812 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1813 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1815 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1816 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1818 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1819 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1821 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1822 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1824 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1825 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1827 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1828 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1830 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1831 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1833 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1834 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1836 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1837 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1839 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1840 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1842 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1843 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1845 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1846 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1848 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1849 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1851 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1852 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1854 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1855 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1857 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
1858 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1860 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
1861 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1863 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
1864 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1866 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
1867 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1869 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
1870 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1872 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
1873 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1875 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
1876 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1878 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
1879 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1880 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1882 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
1883 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1885 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
1886 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1888 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1889 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1891 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1892 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1894 MsiSetPropertyA(hpkg, "one", "1");
1895 r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
1896 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1898 MsiSetPropertyA(hpkg, "X", "5.0");
1900 r = MsiEvaluateConditionA(hpkg, "X != \"\"");
1901 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1903 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
1904 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1906 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
1907 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1909 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
1910 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1912 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
1913 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1915 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1916 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1918 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1919 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1921 /* feature doesn't exist */
1922 r = MsiEvaluateConditionA(hpkg, "&nofeature");
1923 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1924 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\"");
1925 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1926 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3");
1927 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1928 r = MsiEvaluateConditionA(hpkg, "\"\"<>3");
1929 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1930 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\"");
1931 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1932 r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\"");
1933 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1934 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\"");
1935 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1937 MsiSetPropertyA(hpkg, "A", "2");
1938 MsiSetPropertyA(hpkg, "X", "50");
1940 r = MsiEvaluateConditionA(hpkg, "2 <= X");
1941 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1943 r = MsiEvaluateConditionA(hpkg, "A <= X");
1944 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1946 r = MsiEvaluateConditionA(hpkg, "A <= 50");
1947 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1949 MsiSetPropertyA(hpkg, "X", "50val");
1951 r = MsiEvaluateConditionA(hpkg, "2 <= X");
1952 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1954 r = MsiEvaluateConditionA(hpkg, "A <= X");
1955 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1957 MsiSetPropertyA(hpkg, "A", "7");
1958 MsiSetPropertyA(hpkg, "X", "50");
1960 r = MsiEvaluateConditionA(hpkg, "7 <= X");
1961 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1963 r = MsiEvaluateConditionA(hpkg, "A <= X");
1964 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1966 r = MsiEvaluateConditionA(hpkg, "A <= 50");
1967 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1969 MsiSetPropertyA(hpkg, "X", "50val");
1971 r = MsiEvaluateConditionA(hpkg, "2 <= X");
1972 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1974 r = MsiEvaluateConditionA(hpkg, "A <= X");
1975 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1977 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
1978 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1980 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
1981 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1983 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
1984 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1986 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
1987 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1989 MsiCloseHandle( hpkg );
1990 DeleteFileA(msifile);
1993 static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value)
1995 char buffer[MAX_PATH] = "x";
1996 DWORD sz = sizeof(buffer);
1997 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz);
1998 ok(!r, "'%s': got %u\n", prop, r);
1999 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz);
2000 if (match_case)
2001 todo_wine_if (todo_value) ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2002 else
2003 todo_wine_if (todo_value) ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2006 static void test_props(void)
2008 MSIHANDLE hpkg, hdb;
2009 UINT r;
2010 DWORD sz;
2011 char buffer[0x100];
2012 WCHAR bufferW[10];
2014 hdb = create_package_db();
2016 create_property_table(hdb);
2017 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'");
2019 r = package_from_db( hdb, &hpkg );
2020 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2022 skip("Not enough rights to perform tests\n");
2023 DeleteFileA(msifile);
2024 return;
2026 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2028 /* test invalid values */
2029 r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2030 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2032 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2033 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2035 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2036 ok(!r, "got %u\n", r);
2038 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2039 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2041 /* test retrieving an empty/nonexistent property */
2042 sz = sizeof buffer;
2043 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2044 ok(!r, "got %u\n", r);
2045 ok(sz == 0, "got size %lu\n", sz);
2047 sz = 0;
2048 strcpy(buffer,"x");
2049 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2050 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2051 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer);
2052 ok(sz == 0, "got size %lu\n", sz);
2054 sz = 1;
2055 strcpy(buffer,"x");
2056 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2057 ok(!r, "got %u\n", r);
2058 ok(!buffer[0], "got \"%s\"\n", buffer);
2059 ok(sz == 0, "got size %lu\n", sz);
2061 /* set the property to something */
2062 r = MsiSetPropertyA( 0, NULL, NULL );
2063 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r);
2065 r = MsiSetPropertyA( hpkg, NULL, NULL );
2066 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2068 r = MsiSetPropertyA( hpkg, "", NULL );
2069 ok(!r, "got %u\n", r);
2071 r = MsiSetPropertyA( hpkg, "", "asdf" );
2072 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
2074 r = MsiSetPropertyA( hpkg, "=", "asdf" );
2075 ok(!r, "got %u\n", r);
2076 check_prop(hpkg, "=", "asdf", 1, 0);
2078 r = MsiSetPropertyA( hpkg, " ", "asdf" );
2079 ok(!r, "got %u\n", r);
2080 check_prop(hpkg, " ", "asdf", 1, 0);
2082 r = MsiSetPropertyA( hpkg, "'", "asdf" );
2083 ok(!r, "got %u\n", r);
2084 check_prop(hpkg, "'", "asdf", 1, 0);
2086 /* set empty values */
2087 r = MsiSetPropertyA( hpkg, "boo", NULL );
2088 ok(!r, "got %u\n", r);
2089 check_prop(hpkg, "boo", "", 1, 0);
2091 r = MsiSetPropertyA( hpkg, "boo", "" );
2092 ok(!r, "got %u\n", r);
2093 check_prop(hpkg, "boo", "", 1, 0);
2095 /* set a non-empty value */
2096 r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2097 ok(!r, "got %u\n", r);
2098 check_prop(hpkg, "boo", "xyz", 1, 0);
2100 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
2101 ok(!r, "got %u\n", r);
2103 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL);
2104 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2106 sz = 0;
2107 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz);
2108 ok(!r, "got %u\n", r);
2109 ok(sz == 3, "got size %lu\n", sz);
2111 sz = 0;
2112 strcpy(buffer, "q");
2113 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz);
2114 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2115 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer);
2116 ok(sz == 3, "got size %lu\n", sz);
2118 sz = 1;
2119 strcpy(buffer,"x");
2120 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2121 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2122 ok(!buffer[0], "got \"%s\"\n", buffer);
2123 ok(sz == 3, "got size %lu\n", sz);
2125 sz = 3;
2126 strcpy(buffer,"x");
2127 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2128 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2129 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer);
2130 ok(sz == 3, "got size %lu\n", sz);
2132 sz = 4;
2133 strcpy(buffer,"x");
2134 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2135 ok(!r, "got %u\n", r);
2136 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer);
2137 ok(sz == 3, "got size %lu\n", sz);
2139 sz = 0;
2140 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz);
2141 ok(!r, "got %u\n", r);
2142 ok(sz == 3, "got size %lu\n", sz);
2144 sz = 0;
2145 lstrcpyW(bufferW, L"boo");
2146 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz);
2147 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2148 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW));
2149 ok(sz == 3, "got size %lu\n", sz);
2151 sz = 1;
2152 lstrcpyW(bufferW, L"boo");
2153 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2154 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2155 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
2156 ok(sz == 3, "got size %lu\n", sz);
2158 sz = 3;
2159 lstrcpyW(bufferW, L"boo");
2160 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2161 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2162 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW));
2163 ok(sz == 3, "got size %lu\n", sz);
2165 sz = 4;
2166 lstrcpyW(bufferW, L"boo");
2167 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2168 ok(!r, "got %u\n", r);
2169 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW));
2170 ok(sz == 3, "got size %lu\n", sz);
2172 /* properties are case-sensitive */
2173 check_prop(hpkg, "BOO", "", 1, 0);
2175 /* properties set in Property table should work */
2176 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1, 0);
2178 MsiCloseHandle( hpkg );
2179 DeleteFileA(msifile);
2182 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2184 MSIHANDLE hview, hrec;
2185 BOOL found = FALSE;
2186 CHAR buffer[MAX_PATH];
2187 DWORD sz;
2188 UINT r;
2190 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2191 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2192 r = MsiViewExecute(hview, 0);
2193 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2195 if (len < 0) len = lstrlenA(val);
2197 while (r == ERROR_SUCCESS && !found)
2199 r = MsiViewFetch(hview, &hrec);
2200 if (r != ERROR_SUCCESS) break;
2202 sz = MAX_PATH;
2203 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2204 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2206 sz = MAX_PATH;
2207 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2208 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2210 ok(sz == len, "wrong size %lu\n", sz);
2211 found = TRUE;
2215 MsiCloseHandle(hrec);
2217 MsiViewClose(hview);
2218 MsiCloseHandle(hview);
2219 return found;
2222 static void test_property_table(void)
2224 const char *query;
2225 UINT r;
2226 MSIHANDLE hpkg, hdb, hrec;
2227 char buffer[MAX_PATH], package[10];
2228 DWORD sz;
2229 BOOL found;
2231 hdb = create_package_db();
2232 ok( hdb, "failed to create package\n");
2234 r = package_from_db(hdb, &hpkg);
2235 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2237 skip("Not enough rights to perform tests\n");
2238 DeleteFileA(msifile);
2239 return;
2241 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2243 MsiCloseHandle(hdb);
2245 hdb = MsiGetActiveDatabase(hpkg);
2247 query = "CREATE TABLE `_Property` ( "
2248 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2249 r = run_query(hdb, 0, query);
2250 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2252 MsiCloseHandle(hdb);
2253 MsiCloseHandle(hpkg);
2254 DeleteFileA(msifile);
2256 hdb = create_package_db();
2257 ok( hdb, "failed to create package\n");
2259 query = "CREATE TABLE `_Property` ( "
2260 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2261 r = run_query(hdb, 0, query);
2262 ok(r == ERROR_SUCCESS, "failed to create table\n");
2264 query = "ALTER `_Property` ADD `foo` INTEGER";
2265 r = run_query(hdb, 0, query);
2266 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2268 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2269 r = run_query(hdb, 0, query);
2270 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2272 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2273 r = run_query(hdb, 0, query);
2274 ok(r == ERROR_SUCCESS, "failed to add column\n");
2276 sprintf(package, "#%lu", hdb);
2277 r = MsiOpenPackageA(package, &hpkg);
2278 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2279 if (r == ERROR_SUCCESS)
2280 MsiCloseHandle(hpkg);
2282 r = MsiCloseHandle(hdb);
2283 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2285 hdb = create_package_db();
2286 ok (hdb, "failed to create package database\n");
2288 create_property_table(hdb);
2289 add_property_entry(hdb, "'prop', 'val'");
2291 create_custom_action_table(hdb);
2292 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2294 r = package_from_db(hdb, &hpkg);
2295 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2297 MsiCloseHandle(hdb);
2299 sz = MAX_PATH;
2300 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2302 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2304 hdb = MsiGetActiveDatabase(hpkg);
2306 found = find_prop_in_property(hdb, "prop", "val", -1);
2307 ok(found, "prop should be in the _Property table\n");
2309 add_property_entry(hdb, "'dantes', 'mercedes'");
2311 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2312 r = do_query(hdb, query, &hrec);
2313 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2315 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2316 ok(found == FALSE, "dantes should not be in the _Property table\n");
2318 sz = MAX_PATH;
2319 lstrcpyA(buffer, "aaa");
2320 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2322 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2324 r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2327 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2328 ok(found == TRUE, "dantes should be in the _Property table\n");
2330 r = MsiDoActionA( hpkg, "EmbedNull" );
2331 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2333 sz = MAX_PATH;
2334 memset( buffer, 'a', sizeof(buffer) );
2335 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2336 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2337 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2338 ok( sz == sizeof("\0np") - 1, "got %lu\n", sz );
2340 found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2341 ok(found == TRUE, "prop2 should be in the _Property table\n");
2343 MsiCloseHandle(hdb);
2344 MsiCloseHandle(hpkg);
2345 DeleteFileA(msifile);
2348 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2350 MSIHANDLE htab = 0;
2351 UINT res;
2353 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2354 if( res == ERROR_SUCCESS )
2356 UINT r;
2358 r = MsiViewExecute( htab, hrec );
2359 if( r != ERROR_SUCCESS )
2361 res = r;
2362 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2365 r = MsiViewClose( htab );
2366 if( r != ERROR_SUCCESS )
2367 res = r;
2369 r = MsiCloseHandle( htab );
2370 if( r != ERROR_SUCCESS )
2371 res = r;
2373 return res;
2376 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2378 return try_query_param( hdb, szQuery, 0 );
2381 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2383 MSIHANDLE summary;
2384 UINT r;
2386 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2389 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2392 r = MsiSummaryInfoPersist(summary);
2393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2395 MsiCloseHandle(summary);
2398 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2400 MSIHANDLE summary;
2401 UINT r;
2403 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2406 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2409 r = MsiSummaryInfoPersist(summary);
2410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2412 MsiCloseHandle(summary);
2415 static void test_msipackage(void)
2417 MSIHANDLE hdb = 0, hpack = 100;
2418 UINT r;
2419 const char *query;
2420 char name[10];
2422 /* NULL szPackagePath */
2423 r = MsiOpenPackageA(NULL, &hpack);
2424 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2426 /* empty szPackagePath */
2427 r = MsiOpenPackageA("", &hpack);
2428 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2430 skip("Not enough rights to perform tests\n");
2431 return;
2433 todo_wine
2435 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2438 if (r == ERROR_SUCCESS)
2439 MsiCloseHandle(hpack);
2441 /* nonexistent szPackagePath */
2442 r = MsiOpenPackageA("nonexistent", &hpack);
2443 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2445 /* NULL hProduct */
2446 r = MsiOpenPackageA(msifile, NULL);
2447 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2449 name[0]='#';
2450 name[1]=0;
2451 r = MsiOpenPackageA(name, &hpack);
2452 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2454 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2457 /* database exists, but is empty */
2458 sprintf(name, "#%lu", hdb);
2459 r = MsiOpenPackageA(name, &hpack);
2460 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2461 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2463 query = "CREATE TABLE `Property` ( "
2464 "`Property` CHAR(72), `Value` CHAR(0) "
2465 "PRIMARY KEY `Property`)";
2466 r = try_query(hdb, query);
2467 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2469 query = "CREATE TABLE `InstallExecuteSequence` ("
2470 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2471 "PRIMARY KEY `Action`)";
2472 r = try_query(hdb, query);
2473 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2475 /* a few key tables exist */
2476 sprintf(name, "#%lu", hdb);
2477 r = MsiOpenPackageA(name, &hpack);
2478 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2479 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2481 MsiCloseHandle(hdb);
2482 DeleteFileA(msifile);
2484 /* start with a clean database to show what constitutes a valid package */
2485 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2488 sprintf(name, "#%lu", hdb);
2490 /* The following summary information props must exist:
2491 * - PID_REVNUMBER
2492 * - PID_PAGECOUNT
2495 set_summary_dword(hdb, PID_PAGECOUNT, 100);
2496 r = MsiOpenPackageA(name, &hpack);
2497 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2498 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2500 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2501 r = MsiOpenPackageA(name, &hpack);
2502 ok(r == ERROR_SUCCESS,
2503 "Expected ERROR_SUCCESS, got %d\n", r);
2505 MsiCloseHandle(hpack);
2506 MsiCloseHandle(hdb);
2507 DeleteFileA(msifile);
2510 static void test_formatrecord2(void)
2512 MSIHANDLE hpkg, hrec ;
2513 char buffer[0x100];
2514 DWORD sz;
2515 UINT r;
2517 r = package_from_db(create_package_db(), &hpkg);
2518 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2520 skip("Not enough rights to perform tests\n");
2521 DeleteFileA(msifile);
2522 return;
2524 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2526 r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2527 ok( r == ERROR_SUCCESS, "set property failed\n");
2529 hrec = MsiCreateRecord(2);
2530 ok(hrec, "create record failed\n");
2532 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2533 ok( r == ERROR_SUCCESS, "format record failed\n");
2535 buffer[0] = 0;
2536 sz = sizeof buffer;
2537 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2538 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2540 r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2541 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2542 r = MsiRecordSetStringA(hrec, 1, "hoo");
2543 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2544 sz = sizeof buffer;
2545 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2546 ok( sz == 3, "size wrong\n");
2547 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2548 ok( r == ERROR_SUCCESS, "format failed\n");
2550 r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2551 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2552 sz = sizeof buffer;
2553 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2554 ok( sz == 3, "size wrong\n");
2555 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2556 ok( r == ERROR_SUCCESS, "format failed\n");
2558 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2559 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2560 r = MsiRecordSetStringA(hrec, 1, "hoo");
2561 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2562 sz = sizeof buffer;
2563 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2564 ok( sz == 3, "size wrong\n");
2565 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2566 ok( r == ERROR_SUCCESS, "format failed\n");
2568 r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2569 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2570 sz = sizeof buffer;
2571 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2572 ok( sz == 1, "size wrong\n");
2573 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2574 ok( r == ERROR_SUCCESS, "format failed\n");
2576 SetEnvironmentVariableA("FOO", "BAR");
2577 r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2578 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2579 sz = sizeof buffer;
2580 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2581 ok( sz == 3, "size wrong\n");
2582 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2583 ok( r == ERROR_SUCCESS, "format failed\n");
2585 r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2586 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2587 r = MsiRecordSetStringA(hrec, 1, "%FOO");
2588 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2589 sz = sizeof buffer;
2590 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2591 ok( sz == 3, "size wrong\n");
2592 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2593 ok( r == ERROR_SUCCESS, "format failed\n");
2595 MsiCloseHandle( hrec );
2596 MsiCloseHandle( hpkg );
2597 DeleteFileA(msifile);
2600 static void test_formatrecord_tables(void)
2602 MSIHANDLE hdb, hrec, hpkg = 0;
2603 CHAR buf[MAX_PATH + 41];
2604 CHAR curr_dir[MAX_PATH];
2605 CHAR expected[MAX_PATH + 45];
2606 CHAR root[MAX_PATH];
2607 DWORD size;
2608 UINT r;
2610 GetCurrentDirectoryA( MAX_PATH, curr_dir );
2612 hdb = create_package_db();
2613 ok ( hdb, "failed to create package database\n");
2615 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2616 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2617 "'I am a really long directory'" );
2619 create_feature_table( hdb );
2620 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2622 create_component_table( hdb );
2623 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2624 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2625 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2627 create_feature_components_table( hdb );
2628 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2629 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2630 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2632 create_file_table( hdb );
2633 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2634 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2635 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2637 create_custom_action_table( hdb );
2638 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2639 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2640 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2641 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2642 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2644 r = package_from_db( hdb, &hpkg );
2645 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2647 skip("Not enough rights to perform tests\n");
2648 MsiCloseHandle( hdb );
2649 DeleteFileA( msifile );
2650 return;
2652 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2654 MsiCloseHandle( hdb );
2656 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2657 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2659 hrec = MsiCreateRecord( 1 );
2661 /* property doesn't exist */
2662 size = MAX_PATH;
2663 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2664 MsiRecordSetStringA( hrec, 1, "[idontexist]" );
2665 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2666 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2667 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2669 /* property exists */
2670 size = MAX_PATH;
2671 MsiRecordSetStringA( hrec, 1, "[imaprop]" );
2672 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2673 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2674 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2676 size = MAX_PATH;
2677 MsiRecordSetStringA( hrec, 0, "1: [1] " );
2678 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2679 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2680 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2682 /* environment variable doesn't exist */
2683 size = MAX_PATH;
2684 MsiRecordSetStringA( hrec, 1, "[%idontexist]" );
2685 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2686 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2687 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2689 /* environment variable exists */
2690 size = MAX_PATH;
2691 SetEnvironmentVariableA( "crazyvar", "crazyval" );
2692 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" );
2693 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2694 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2695 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2697 /* file key before CostInitialize */
2698 size = MAX_PATH;
2699 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2700 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2701 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2702 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2704 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2706 r = MsiDoActionA(hpkg, "CostInitialize");
2707 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2709 r = MsiDoActionA(hpkg, "FileCost");
2710 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2712 r = MsiDoActionA(hpkg, "CostFinalize");
2713 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2715 size = MAX_PATH;
2716 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size );
2718 sprintf( expected, "1: %sfrontal.txt ", root);
2720 /* frontal full file key */
2721 size = MAX_PATH;
2722 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2723 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2724 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2725 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2727 /* frontal short file key */
2728 size = MAX_PATH;
2729 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" );
2730 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2731 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2732 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2734 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2736 /* temporal full file key */
2737 size = MAX_PATH;
2738 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" );
2739 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2740 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2741 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2743 /* temporal short file key */
2744 size = MAX_PATH;
2745 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" );
2746 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2747 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2748 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2750 /* custom action 51, files don't exist */
2751 r = MsiDoActionA( hpkg, "MyCustom" );
2752 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2754 sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2756 size = MAX_PATH;
2757 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2758 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2759 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2761 sprintf( buf, "%sI am a really long directory", root );
2762 CreateDirectoryA( buf, NULL );
2764 lstrcatA( buf, "\\temporal.txt" );
2765 create_test_file( buf );
2767 /* custom action 51, files exist */
2768 r = MsiDoActionA( hpkg, "MyCustom" );
2769 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2771 size = MAX_PATH;
2772 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2773 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2774 todo_wine
2776 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2779 /* custom action 51, escaped text 1 */
2780 r = MsiDoActionA( hpkg, "EscapeIt1" );
2781 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2783 size = MAX_PATH;
2784 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2785 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2786 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2788 /* custom action 51, escaped text 2 */
2789 r = MsiDoActionA( hpkg, "EscapeIt2" );
2790 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2792 size = MAX_PATH;
2793 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2794 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2795 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf);
2797 /* custom action 51, escaped text 3 */
2798 r = MsiDoActionA( hpkg, "EscapeIt3" );
2799 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2801 size = MAX_PATH;
2802 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2803 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2804 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf);
2806 /* custom action 51, embedded null */
2807 r = MsiDoActionA( hpkg, "EmbedNull" );
2808 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2810 size = MAX_PATH;
2811 memset( buf, 'a', sizeof(buf) );
2812 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2813 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2814 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
2815 ok( size == sizeof("\0np") - 1, "got %lu\n", size );
2817 r = MsiSetPropertyA( hpkg, "prop", "[~]np" );
2818 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2820 size = MAX_PATH;
2821 memset( buf, 'a', sizeof(buf) );
2822 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2823 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2824 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2826 sprintf( expected, "1: %sI am a really long directory\\ ", root);
2828 /* component with INSTALLSTATE_LOCAL */
2829 size = MAX_PATH;
2830 MsiRecordSetStringA( hrec, 1, "[$temporal]" );
2831 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2832 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2833 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2835 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE );
2836 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2838 /* component with INSTALLSTATE_SOURCE */
2839 lstrcpyA( expected, "1: " );
2840 lstrcatA( expected, curr_dir );
2841 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" );
2842 lstrcatA( expected, " " );
2843 size = MAX_PATH;
2844 MsiRecordSetStringA( hrec, 1, "[$parietal]" );
2845 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2846 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2847 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2849 sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2850 DeleteFileA( buf );
2852 sprintf( buf, "%sI am a really long directory", root );
2853 RemoveDirectoryA( buf );
2855 MsiCloseHandle( hrec );
2856 MsiCloseHandle( hpkg );
2857 DeleteFileA( msifile );
2860 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
2861 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2863 UINT r;
2864 INSTALLSTATE state = 0xdeadbee;
2865 INSTALLSTATE action = 0xdeadbee;
2867 r = MsiGetFeatureStateA( package, feature, &state, &action );
2868 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2869 if (r == ERROR_SUCCESS)
2871 ok( state == expected_state, "%u: expected state %d got %d\n",
2872 line, expected_state, state );
2873 todo_wine_if (todo)
2874 ok( action == expected_action, "%u: expected action %d got %d\n",
2875 line, expected_action, action );
2877 else
2879 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
2880 todo_wine_if (todo)
2881 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2886 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
2887 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2889 UINT r;
2890 INSTALLSTATE state = 0xdeadbee;
2891 INSTALLSTATE action = 0xdeadbee;
2893 r = MsiGetComponentStateA( package, component, &state, &action );
2894 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2895 if (r == ERROR_SUCCESS)
2897 ok( state == expected_state, "%u: expected state %d got %d\n",
2898 line, expected_state, state );
2899 todo_wine_if (todo)
2900 ok( action == expected_action, "%u: expected action %d got %d\n",
2901 line, expected_action, action );
2903 else
2905 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2906 line, state );
2907 todo_wine_if (todo)
2908 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2909 line, action );
2913 static void test_states(void)
2915 static const char msifile2[] = "winetest2-package.msi";
2916 static const char msifile3[] = "winetest3-package.msi";
2917 static const char msifile4[] = "winetest4-package.msi";
2918 static const WCHAR msifile2W[] = L"winetest2-package.msi";
2919 static const WCHAR msifile3W[] = L"winetest3-package.msi";
2920 static const WCHAR msifile4W[] = L"winetest4-package.msi";
2921 char msi_cache_file[MAX_PATH];
2922 DWORD cache_file_name_len;
2923 INSTALLSTATE state;
2924 MSIHANDLE hpkg, hprod;
2925 UINT r;
2926 MSIHANDLE hdb;
2927 char value[MAX_PATH];
2928 DWORD size;
2930 if (!is_process_elevated())
2932 skip("process is limited\n");
2933 return;
2936 hdb = create_package_db();
2937 ok ( hdb, "failed to create package database\n" );
2939 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2941 create_property_table( hdb );
2942 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2943 add_property_entry( hdb, "'ProductLanguage', '1033'" );
2944 add_property_entry( hdb, "'ProductName', 'MSITEST'" );
2945 add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
2946 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
2947 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
2949 create_install_execute_sequence_table( hdb );
2950 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
2951 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
2952 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
2953 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
2954 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
2955 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
2956 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
2957 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
2958 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
2959 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
2960 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
2962 create_media_table( hdb );
2963 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
2965 create_feature_table( hdb );
2967 create_component_table( hdb );
2969 /* msidbFeatureAttributesFavorLocal */
2970 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2972 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2973 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
2975 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2976 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
2978 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2979 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
2981 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
2982 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
2984 /* msidbFeatureAttributesFavorSource */
2985 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
2987 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2988 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
2990 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2991 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
2993 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2994 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
2996 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
2997 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
2999 /* msidbFeatureAttributesFavorSource */
3000 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
3002 /* msidbFeatureAttributesFavorLocal */
3003 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
3005 /* disabled */
3006 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
3008 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3009 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3011 /* no feature parent:msidbComponentAttributesLocalOnly */
3012 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3014 /* msidbFeatureAttributesFavorLocal:removed */
3015 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
3017 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3018 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3020 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3021 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3023 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3024 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3026 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3027 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3029 /* msidbFeatureAttributesFavorSource:removed */
3030 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
3032 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3033 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3035 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3036 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3038 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3039 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3041 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3042 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3044 /* msidbFeatureAttributesFavorLocal */
3045 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
3047 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3049 /* msidbFeatureAttributesFavorSource */
3050 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
3052 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3054 /* msidbFeatureAttributesFavorAdvertise */
3055 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
3057 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3059 /* msidbFeatureAttributesUIDisallowAbsent */
3060 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
3062 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3064 /* high install level */
3065 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
3067 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3069 /* msidbFeatureAttributesFollowParent */
3070 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
3072 create_feature_components_table( hdb );
3073 add_feature_components_entry( hdb, "'one', 'alpha'" );
3074 add_feature_components_entry( hdb, "'one', 'beta'" );
3075 add_feature_components_entry( hdb, "'one', 'gamma'" );
3076 add_feature_components_entry( hdb, "'one', 'theta'" );
3077 add_feature_components_entry( hdb, "'two', 'delta'" );
3078 add_feature_components_entry( hdb, "'two', 'epsilon'" );
3079 add_feature_components_entry( hdb, "'two', 'zeta'" );
3080 add_feature_components_entry( hdb, "'two', 'iota'" );
3081 add_feature_components_entry( hdb, "'three', 'eta'" );
3082 add_feature_components_entry( hdb, "'four', 'eta'" );
3083 add_feature_components_entry( hdb, "'five', 'eta'" );
3084 add_feature_components_entry( hdb, "'six', 'lambda'" );
3085 add_feature_components_entry( hdb, "'six', 'mu'" );
3086 add_feature_components_entry( hdb, "'six', 'nu'" );
3087 add_feature_components_entry( hdb, "'six', 'xi'" );
3088 add_feature_components_entry( hdb, "'seven', 'omicron'" );
3089 add_feature_components_entry( hdb, "'seven', 'pi'" );
3090 add_feature_components_entry( hdb, "'seven', 'rho'" );
3091 add_feature_components_entry( hdb, "'seven', 'sigma'" );
3092 add_feature_components_entry( hdb, "'eight', 'tau'" );
3093 add_feature_components_entry( hdb, "'nine', 'phi'" );
3094 add_feature_components_entry( hdb, "'ten', 'chi'" );
3095 add_feature_components_entry( hdb, "'eleven', 'psi'" );
3096 add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3097 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3099 create_file_table( hdb );
3100 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3101 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3102 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3103 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3104 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3105 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3106 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3107 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3109 /* compressed file */
3110 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3112 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3113 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3114 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3115 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3116 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3117 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3118 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3119 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3120 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3121 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3122 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3123 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3124 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3125 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3127 r = MsiDatabaseCommit(hdb);
3128 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
3130 /* these properties must not be in the saved msi file */
3131 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3132 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3133 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3134 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3135 add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3137 r = package_from_db( hdb, &hpkg );
3138 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3140 skip("Not enough rights to perform tests\n");
3141 DeleteFileA(msifile);
3142 return;
3144 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3146 MsiCloseHandle(hdb);
3148 CopyFileA(msifile, msifile2, FALSE);
3149 CopyFileA(msifile, msifile3, FALSE);
3150 CopyFileA(msifile, msifile4, FALSE);
3152 size = sizeof(value);
3153 memset(value, 0, sizeof(value));
3154 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3155 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3156 ok(!value[0], "ProductToBeRegistered = %s\n", value);
3158 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3159 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3161 r = MsiDoActionA( hpkg, "CostInitialize");
3162 ok( r == ERROR_SUCCESS, "cost init failed\n");
3164 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3165 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3167 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3169 r = MsiDoActionA( hpkg, "FileCost");
3170 ok( r == ERROR_SUCCESS, "file cost failed\n");
3172 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3173 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3175 r = MsiDoActionA( hpkg, "CostFinalize");
3176 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3178 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3179 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3180 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3181 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3182 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3183 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3184 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3185 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3186 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3187 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3188 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3189 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3190 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3192 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3193 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3194 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3195 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3196 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3197 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3198 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3199 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3200 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3201 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3202 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3203 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3204 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3205 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3206 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3207 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3208 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3209 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3210 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3211 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3212 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3213 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3214 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3216 MsiCloseHandle( hpkg );
3218 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3220 /* publish the features and components */
3221 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3224 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
3225 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3227 /* these properties must not be in the saved msi file */
3228 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3229 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3230 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3231 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3233 r = package_from_db( hdb, &hpkg );
3234 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3236 MsiCloseHandle(hdb);
3238 size = sizeof(value);
3239 memset(value, 0, sizeof(value));
3240 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3241 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3242 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value);
3244 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3245 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3247 r = MsiDoActionA( hpkg, "CostInitialize");
3248 ok( r == ERROR_SUCCESS, "cost init failed\n");
3250 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3251 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3253 r = MsiDoActionA( hpkg, "FileCost");
3254 ok( r == ERROR_SUCCESS, "file cost failed\n");
3256 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3257 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3259 r = MsiDoActionA( hpkg, "CostFinalize");
3260 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3262 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3263 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3264 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3265 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3266 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3267 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3268 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3269 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3270 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3271 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3272 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3273 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3274 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3276 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3277 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3278 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3279 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3280 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3281 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3282 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3283 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3284 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3285 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3286 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3287 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3288 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3289 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3290 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3291 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3292 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3293 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3294 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3295 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3296 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3297 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3298 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3300 MsiCloseHandle(hpkg);
3302 /* uninstall the product */
3303 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3306 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3307 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3308 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3309 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3311 /* all features installed locally */
3312 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3316 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3317 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3318 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3320 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb);
3321 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3323 /* these properties must not be in the saved msi file */
3324 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3326 r = package_from_db( hdb, &hpkg );
3327 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3329 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3330 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3332 r = MsiDoActionA( hpkg, "CostInitialize");
3333 ok( r == ERROR_SUCCESS, "cost init failed\n");
3335 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3336 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3338 r = MsiDoActionA( hpkg, "CostFinalize");
3339 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3341 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3342 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3343 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3344 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3345 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3346 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3347 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3348 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3349 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3350 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3351 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3352 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3353 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3355 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3356 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3357 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3358 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3359 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3360 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3361 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3362 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3363 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3364 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3365 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3366 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3367 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3368 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3369 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3370 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3371 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3372 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3373 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3374 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3375 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3376 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3377 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3379 MsiCloseHandle(hpkg);
3381 /* uninstall the product */
3382 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3385 /* all features installed from source */
3386 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3389 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3390 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3391 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3392 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3394 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3395 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3397 /* this property must not be in the saved msi file */
3398 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3400 r = package_from_db( hdb, &hpkg );
3401 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3403 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3404 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3406 r = MsiDoActionA( hpkg, "CostInitialize");
3407 ok( r == ERROR_SUCCESS, "cost init failed\n");
3409 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3410 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3412 r = MsiDoActionA( hpkg, "FileCost");
3413 ok( r == ERROR_SUCCESS, "file cost failed\n");
3415 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3416 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3418 r = MsiDoActionA( hpkg, "CostFinalize");
3419 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3421 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3422 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3423 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3424 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3425 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3426 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3427 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3428 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3429 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3430 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3431 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3432 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3433 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3435 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3436 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3437 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3438 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3439 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3440 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3441 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3442 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3443 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3444 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3445 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3446 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3447 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3448 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3449 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3450 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3451 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3452 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3453 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3454 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3455 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3456 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3457 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3459 MsiCloseHandle(hpkg);
3461 /* reinstall the product */
3462 r = MsiInstallProductA(msifile3, "REINSTALL=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(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3471 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3473 /* this property must not be in the saved msi file */
3474 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
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, "FileCost");
3489 ok( r == ERROR_SUCCESS, "file cost failed\n");
3491 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3492 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3494 r = MsiDoActionA( hpkg, "CostFinalize");
3495 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3497 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3498 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3499 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3500 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3501 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3502 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3503 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3504 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3505 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3506 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3507 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3508 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3509 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3511 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3512 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3513 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3514 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3515 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3516 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3517 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3518 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3519 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3520 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3521 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3522 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3523 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3524 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3525 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3526 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3527 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3528 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3529 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3530 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3531 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3532 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3533 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3535 MsiCloseHandle(hpkg);
3537 /* test source only install */
3538 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3540 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3541 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3542 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3543 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3545 r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3547 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3548 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3549 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3550 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3552 /* no arguments test */
3553 cache_file_name_len = sizeof(msi_cache_file);
3554 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3555 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3558 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3560 create_custom_action_table( hdb );
3561 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3562 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3563 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3564 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3565 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3566 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3567 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3568 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3569 add_custom_action_entry( hdb,
3570 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3572 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3573 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3574 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3575 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3576 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3577 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3578 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3579 /* Add "one" feature action tests */
3580 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3581 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3582 r = MsiDatabaseCommit(hdb);
3583 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3584 r = package_from_db( hdb, &hpkg );
3585 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3586 MsiCloseHandle(hdb);
3588 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3589 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3590 r = MsiDoActionA( hpkg, "CostInitialize");
3591 ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3592 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3593 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3595 r = MsiDoActionA( hpkg, "FileCost");
3596 ok( r == ERROR_SUCCESS, "FileCost failed\n");
3597 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3598 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3600 r = MsiDoActionA( hpkg, "CostFinalize");
3601 ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3602 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3603 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3604 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3605 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3606 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3607 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3608 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3609 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3610 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3611 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3612 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3613 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3614 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3615 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3616 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3617 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3618 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3619 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3620 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3621 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3622 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3623 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3624 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3625 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3626 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3628 r = MsiDoActionA( hpkg, "InstallValidate");
3629 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3630 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3631 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3632 MsiCloseHandle( hpkg );
3634 r = MsiInstallProductA(msifile, "");
3635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3637 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3638 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3639 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3640 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3641 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3643 /* minor upgrade test with no REINSTALL argument */
3644 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3646 size = MAX_PATH;
3647 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3649 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
3650 MsiCloseHandle(hprod);
3652 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3653 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3654 update_ProductVersion_property( hdb, "1.1.2" );
3655 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3656 r = MsiDatabaseCommit(hdb);
3657 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3658 MsiCloseHandle(hdb);
3660 r = MsiInstallProductA(msifile2, "");
3661 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
3663 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3666 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668 size = MAX_PATH;
3669 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3672 MsiCloseHandle(hprod);
3674 /* major upgrade test */
3675 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3676 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3677 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3678 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3679 create_upgrade_table( hdb );
3680 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3681 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3682 update_ProductVersion_property( hdb, "1.1.3" );
3683 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3684 r = MsiDatabaseCommit(hdb);
3685 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3686 MsiCloseHandle(hdb);
3688 r = MsiInstallProductA(msifile2, "");
3689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3691 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3692 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3693 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
3694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3695 size = MAX_PATH;
3696 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
3699 MsiCloseHandle(hprod);
3701 /* uninstall the product */
3702 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3705 DeleteFileA(msifile);
3706 DeleteFileA(msifile2);
3707 DeleteFileA(msifile3);
3708 DeleteFileA(msifile4);
3711 static void test_removefiles(void)
3713 MSIHANDLE hpkg;
3714 UINT r;
3715 MSIHANDLE hdb;
3716 INSTALLSTATE installed, action;
3718 hdb = create_package_db();
3719 ok ( hdb, "failed to create package database\n" );
3721 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3723 create_feature_table( hdb );
3724 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3726 create_component_table( hdb );
3727 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3728 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3729 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3730 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3731 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3732 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3733 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3735 create_feature_components_table( hdb );
3736 add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3737 add_feature_components_entry( hdb, "'one', 'helium'" );
3738 add_feature_components_entry( hdb, "'one', 'lithium'" );
3739 add_feature_components_entry( hdb, "'one', 'beryllium'" );
3740 add_feature_components_entry( hdb, "'one', 'boron'" );
3741 add_feature_components_entry( hdb, "'one', 'carbon'" );
3742 add_feature_components_entry( hdb, "'one', 'oxygen'" );
3744 create_file_table( hdb );
3745 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3746 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3747 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3748 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3749 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3750 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3751 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3753 create_remove_file_table( hdb );
3755 r = package_from_db( hdb, &hpkg );
3756 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3758 skip("Not enough rights to perform tests\n");
3759 DeleteFileA(msifile);
3760 return;
3762 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3764 MsiCloseHandle( hdb );
3766 create_test_file( "hydrogen.txt" );
3767 create_test_file( "helium.txt" );
3768 create_test_file( "lithium.txt" );
3769 create_test_file( "beryllium.txt" );
3770 create_test_file( "boron.txt" );
3771 create_test_file( "carbon.txt" );
3772 create_test_file( "oxygen.txt" );
3774 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3775 ok( r == ERROR_SUCCESS, "set property failed\n");
3777 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3779 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3780 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3782 r = MsiDoActionA( hpkg, "CostInitialize");
3783 ok( r == ERROR_SUCCESS, "cost init failed\n");
3785 r = MsiDoActionA( hpkg, "FileCost");
3786 ok( r == ERROR_SUCCESS, "file cost failed\n");
3788 installed = action = 0xdeadbeef;
3789 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3790 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3791 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3792 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3794 r = MsiDoActionA( hpkg, "CostFinalize");
3795 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3797 r = MsiDoActionA( hpkg, "InstallValidate");
3798 ok( r == ERROR_SUCCESS, "install validate failed\n");
3800 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3801 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3803 installed = action = 0xdeadbeef;
3804 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3805 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3806 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3807 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3809 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3810 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3812 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3813 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3815 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3816 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3818 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3819 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3821 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3822 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3824 installed = action = 0xdeadbeef;
3825 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3826 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3827 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3828 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3830 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3831 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3833 installed = action = 0xdeadbeef;
3834 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3835 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3836 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3837 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3839 r = MsiDoActionA( hpkg, "RemoveFiles");
3840 ok( r == ERROR_SUCCESS, "remove files failed\n");
3842 installed = action = 0xdeadbeef;
3843 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3844 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3845 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3846 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3848 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3849 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
3850 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
3851 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
3852 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
3853 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
3854 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
3856 MsiCloseHandle( hpkg );
3857 DeleteFileA(msifile);
3860 static void test_appsearch(void)
3862 MSIHANDLE hpkg;
3863 UINT r;
3864 MSIHANDLE hdb;
3865 CHAR prop[MAX_PATH];
3866 DWORD size;
3867 HKEY hkey;
3868 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
3870 hdb = create_package_db();
3871 ok ( hdb, "failed to create package database\n" );
3873 create_appsearch_table( hdb );
3874 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
3875 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
3876 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
3877 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
3878 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
3880 create_reglocator_table( hdb );
3881 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
3883 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
3884 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3885 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
3886 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3887 RegCloseKey(hkey);
3888 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3890 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
3891 NULL, &hkey, NULL);
3892 if (r == ERROR_ACCESS_DENIED)
3894 skip("insufficient rights\n");
3895 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3896 MsiCloseHandle(hdb);
3897 DeleteFileA(msifile);
3898 return;
3900 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3902 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3903 sizeof("c:\\windows\\system32\\notepad.exe"));
3904 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3905 RegCloseKey(hkey);
3906 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3908 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
3909 NULL, &hkey, NULL);
3910 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3911 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3912 sizeof("c:\\windows\\system32\\notepad.exe"));
3913 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3914 RegCloseKey(hkey);
3915 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
3916 msidbLocatorTypeFileName|msidbLocatorType64bit );
3918 create_drlocator_table( hdb );
3919 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
3921 create_signature_table( hdb );
3922 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
3923 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3924 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3925 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3926 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3928 r = package_from_db( hdb, &hpkg );
3929 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3931 skip("Not enough rights to perform tests\n");
3932 DeleteFileA(msifile);
3933 return;
3935 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3936 MsiCloseHandle( hdb );
3937 if (r != ERROR_SUCCESS)
3938 goto done;
3940 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3942 r = MsiDoActionA( hpkg, "AppSearch" );
3943 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
3945 size = sizeof(prop);
3946 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
3947 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3948 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3950 size = sizeof(prop);
3951 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
3952 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3954 size = sizeof(prop);
3955 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
3956 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3957 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3959 size = sizeof(prop);
3960 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
3961 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3962 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3964 size = sizeof(prop);
3965 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
3966 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3967 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3969 done:
3970 MsiCloseHandle( hpkg );
3971 DeleteFileA(msifile);
3972 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3973 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY, 0);
3974 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY, 0);
3977 static void test_appsearch_complocator(void)
3979 MSIHANDLE hpkg, hdb;
3980 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
3981 LPSTR usersid;
3982 DWORD size;
3983 UINT r;
3985 if (!(usersid = get_user_sid()))
3986 return;
3988 if (!is_process_elevated())
3990 skip("process is limited\n");
3991 return;
3994 create_test_file("FileName1");
3995 create_test_file("FileName4");
3996 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
3997 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
3999 create_test_file("FileName2");
4000 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
4001 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4003 create_test_file("FileName3");
4004 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
4005 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4007 create_test_file("FileName5");
4008 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
4009 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4011 create_test_file("FileName6");
4012 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
4013 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4015 create_test_file("FileName7");
4016 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
4017 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4019 /* dir is FALSE, but we're pretending it's a directory */
4020 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
4021 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4023 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4024 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
4025 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4027 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4028 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
4029 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4031 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4032 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
4033 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4035 hdb = create_package_db();
4036 ok(hdb, "Expected a valid database handle\n");
4038 create_appsearch_table(hdb);
4039 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4040 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4041 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4042 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4043 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4044 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4045 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4046 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4047 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4048 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4049 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4050 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4052 create_complocator_table(hdb);
4054 /* published component, machine, file, signature, misdbLocatorTypeFile */
4055 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4057 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4058 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4060 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4061 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4063 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4064 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4066 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4067 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4069 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4070 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4072 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4073 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4075 /* unpublished component, no signature, misdbLocatorTypeDir */
4076 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4078 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4079 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4081 /* published component, signature w/ ver, misdbLocatorTypeFile */
4082 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4084 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4085 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4087 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4088 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4090 create_signature_table(hdb);
4091 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4092 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4093 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4094 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4095 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4096 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4097 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4098 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4100 r = package_from_db(hdb, &hpkg);
4101 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4103 skip("Not enough rights to perform tests\n");
4104 goto error;
4106 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4108 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4111 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4113 r = MsiDoActionA(hpkg, "AppSearch");
4114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4116 strcpy(expected, CURR_DIR);
4117 if (is_root(CURR_DIR)) expected[2] = 0;
4119 size = MAX_PATH;
4120 sprintf(path, "%s\\FileName1", expected);
4121 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4125 size = MAX_PATH;
4126 sprintf(path, "%s\\FileName2", expected);
4127 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4129 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4131 size = MAX_PATH;
4132 sprintf(path, "%s\\FileName3", expected);
4133 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4135 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4137 size = MAX_PATH;
4138 sprintf(path, "%s\\FileName4", expected);
4139 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4141 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4143 size = MAX_PATH;
4144 sprintf(path, "%s\\FileName5", expected);
4145 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4147 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4149 size = MAX_PATH;
4150 sprintf(path, "%s\\", expected);
4151 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4153 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4155 size = MAX_PATH;
4156 sprintf(path, "%s\\", expected);
4157 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4159 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4161 size = MAX_PATH;
4162 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4164 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4166 size = MAX_PATH;
4167 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4169 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4171 size = MAX_PATH;
4172 sprintf(path, "%s\\FileName8.dll", expected);
4173 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4175 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4177 size = MAX_PATH;
4178 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4182 size = MAX_PATH;
4183 sprintf(path, "%s\\FileName10.dll", expected);
4184 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4186 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4188 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4189 MSIINSTALLCONTEXT_MACHINE, NULL);
4190 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4191 MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
4192 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4193 MSIINSTALLCONTEXT_USERMANAGED, usersid);
4194 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4195 MSIINSTALLCONTEXT_MACHINE, NULL);
4196 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4197 MSIINSTALLCONTEXT_MACHINE, NULL);
4198 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4199 MSIINSTALLCONTEXT_MACHINE, NULL);
4200 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4201 MSIINSTALLCONTEXT_MACHINE, NULL);
4202 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4203 MSIINSTALLCONTEXT_MACHINE, NULL);
4204 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4205 MSIINSTALLCONTEXT_MACHINE, NULL);
4206 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4207 MSIINSTALLCONTEXT_MACHINE, NULL);
4209 MsiCloseHandle(hpkg);
4211 error:
4212 DeleteFileA("FileName1");
4213 DeleteFileA("FileName2");
4214 DeleteFileA("FileName3");
4215 DeleteFileA("FileName4");
4216 DeleteFileA("FileName5");
4217 DeleteFileA("FileName6");
4218 DeleteFileA("FileName7");
4219 DeleteFileA("FileName8.dll");
4220 DeleteFileA("FileName9.dll");
4221 DeleteFileA("FileName10.dll");
4222 DeleteFileA(msifile);
4223 LocalFree(usersid);
4226 static void test_appsearch_reglocator(void)
4228 MSIHANDLE hpkg, hdb;
4229 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4230 DWORD binary[2], size, val;
4231 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4232 HKEY hklm, classes, hkcu, users;
4233 LPSTR pathdata, pathvar, ptr;
4234 LONG res;
4235 UINT r, type = 0;
4236 SYSTEM_INFO si;
4238 version = TRUE;
4239 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4240 version = FALSE;
4242 DeleteFileA("test.dll");
4244 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4245 if (res == ERROR_ACCESS_DENIED)
4247 skip("Not enough rights to perform tests\n");
4248 return;
4250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4252 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4253 (const BYTE *)"regszdata", 10);
4254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4256 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4259 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4260 (const BYTE *)"regszdata", 10);
4261 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4263 users = 0;
4264 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4267 if (res == ERROR_SUCCESS)
4269 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4270 (const BYTE *)"regszdata", 10);
4271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4274 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4277 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4280 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4281 (const BYTE *)"regszdata", 10);
4282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4284 val = 42;
4285 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4286 (const BYTE *)&val, sizeof(DWORD));
4287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4289 val = -42;
4290 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4291 (const BYTE *)&val, sizeof(DWORD));
4292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4294 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4295 (const BYTE *)"%PATH%", 7);
4296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4298 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4299 (const BYTE *)"my%NOVAR%", 10);
4300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4302 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4303 (const BYTE *)"one\0two\0", 9);
4304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4306 binary[0] = 0x1234abcd;
4307 binary[1] = 0x567890ef;
4308 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4309 (const BYTE *)binary, sizeof(binary));
4310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4312 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4313 (const BYTE *)"#regszdata", 11);
4314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4316 strcpy(expected, CURR_DIR);
4317 if (is_root(CURR_DIR)) expected[2] = 0;
4319 create_test_file("FileName1");
4320 sprintf(path, "%s\\FileName1", expected);
4321 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4322 (const BYTE *)path, lstrlenA(path) + 1);
4323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4325 sprintf(path, "%s\\FileName2", expected);
4326 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4327 (const BYTE *)path, lstrlenA(path) + 1);
4328 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4330 lstrcpyA(path, expected);
4331 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4332 (const BYTE *)path, lstrlenA(path) + 1);
4333 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4335 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4336 (const BYTE *)"", 1);
4337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4339 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4340 sprintf(path, "%s\\FileName3.dll", expected);
4341 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4342 (const BYTE *)path, lstrlenA(path) + 1);
4343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4345 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4346 sprintf(path, "%s\\FileName4.dll", expected);
4347 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4348 (const BYTE *)path, lstrlenA(path) + 1);
4349 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4351 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4352 sprintf(path, "%s\\FileName5.dll", expected);
4353 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4354 (const BYTE *)path, lstrlenA(path) + 1);
4355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4357 sprintf(path, "\"%s\\FileName1\" -option", expected);
4358 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4359 (const BYTE *)path, lstrlenA(path) + 1);
4360 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4362 space = strchr(expected, ' ') != NULL;
4363 sprintf(path, "%s\\FileName1 -option", expected);
4364 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4365 (const BYTE *)path, lstrlenA(path) + 1);
4366 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4368 hdb = create_package_db();
4369 ok(hdb, "Expected a valid database handle\n");
4371 create_appsearch_table(hdb);
4372 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4373 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4374 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4375 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4376 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4377 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4378 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4379 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4380 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4381 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4382 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4383 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4384 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4385 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4386 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4387 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4388 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4389 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4390 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4391 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4392 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4393 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4394 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4395 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4396 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4397 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4398 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4399 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4400 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4401 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4403 create_reglocator_table(hdb);
4405 type = msidbLocatorTypeRawValue;
4406 if (is_64bit)
4407 type |= msidbLocatorType64bit;
4409 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4410 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4412 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4413 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4415 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4416 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4418 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4419 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4421 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4422 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4424 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4425 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4427 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4428 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4430 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4431 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4433 type = msidbLocatorTypeFileName;
4434 if (is_64bit)
4435 type |= msidbLocatorType64bit;
4437 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4438 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4440 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4441 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4443 /* HKLM, msidbLocatorTypeFileName, no signature */
4444 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4446 type = msidbLocatorTypeDirectory;
4447 if (is_64bit)
4448 type |= msidbLocatorType64bit;
4450 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4451 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4453 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4454 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4456 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4457 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4459 type = msidbLocatorTypeRawValue;
4460 if (is_64bit)
4461 type |= msidbLocatorType64bit;
4463 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4464 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4466 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4467 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4469 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4470 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4472 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4473 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4475 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4476 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4478 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4479 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4481 type = msidbLocatorTypeFileName;
4482 if (is_64bit)
4483 type |= msidbLocatorType64bit;
4485 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4486 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4488 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4489 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4491 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4492 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4494 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4495 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4497 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4498 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4500 type = msidbLocatorTypeDirectory;
4501 if (is_64bit)
4502 type |= msidbLocatorType64bit;
4504 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4505 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4507 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4508 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4510 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4511 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4513 type = msidbLocatorTypeFileName;
4514 if (is_64bit)
4515 type |= msidbLocatorType64bit;
4517 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4518 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4520 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4521 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4523 create_signature_table(hdb);
4524 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4525 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4526 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4527 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4528 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4529 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4531 if (!is_root(CURR_DIR))
4533 ptr = strrchr(expected, '\\') + 1;
4534 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4535 add_signature_entry(hdb, path);
4537 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4538 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4539 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4541 r = package_from_db(hdb, &hpkg);
4542 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4544 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4546 r = MsiDoActionA(hpkg, "AppSearch");
4547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4549 size = MAX_PATH;
4550 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4552 ok(!lstrcmpA(prop, "regszdata"),
4553 "Expected \"regszdata\", got \"%s\"\n", prop);
4555 size = MAX_PATH;
4556 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4558 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4560 size = MAX_PATH;
4561 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4563 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4565 memset(&si, 0, sizeof(si));
4566 GetNativeSystemInfo(&si);
4568 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4570 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4571 pathvar = malloc(size);
4572 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4574 size = 0;
4575 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4578 pathdata = malloc(++size);
4579 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4581 ok(!lstrcmpA(pathdata, pathvar),
4582 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4584 free(pathvar);
4585 free(pathdata);
4588 size = MAX_PATH;
4589 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4591 ok(!lstrcmpA(prop,
4592 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4594 size = MAX_PATH;
4595 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4597 todo_wine
4599 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4600 "Expected \"\\0one\\0two\\0\\0\"\n");
4603 size = MAX_PATH;
4604 lstrcpyA(path, "#xCDAB3412EF907856");
4605 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4607 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4609 size = MAX_PATH;
4610 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4612 ok(!lstrcmpA(prop, "##regszdata"),
4613 "Expected \"##regszdata\", got \"%s\"\n", prop);
4615 size = MAX_PATH;
4616 sprintf(path, "%s\\FileName1", expected);
4617 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4619 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4621 size = MAX_PATH;
4622 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4624 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4626 size = MAX_PATH;
4627 sprintf(path, "%s\\", expected);
4628 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4630 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4632 size = MAX_PATH;
4633 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4635 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4637 size = MAX_PATH;
4638 sprintf(path, "%s\\", expected);
4639 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4641 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4643 size = MAX_PATH;
4644 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4646 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4648 size = MAX_PATH;
4649 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4651 ok(!lstrcmpA(prop, "regszdata"),
4652 "Expected \"regszdata\", got \"%s\"\n", prop);
4654 size = MAX_PATH;
4655 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4657 ok(!lstrcmpA(prop, "regszdata"),
4658 "Expected \"regszdata\", got \"%s\"\n", prop);
4660 if (users)
4662 size = MAX_PATH;
4663 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4665 ok(!lstrcmpA(prop, "regszdata"),
4666 "Expected \"regszdata\", got \"%s\"\n", prop);
4669 size = MAX_PATH;
4670 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4672 ok(!lstrcmpA(prop, "defvalue"),
4673 "Expected \"defvalue\", got \"%s\"\n", prop);
4675 size = MAX_PATH;
4676 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4680 size = MAX_PATH;
4681 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4682 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4683 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4685 if (version)
4687 size = MAX_PATH;
4688 sprintf(path, "%s\\FileName3.dll", expected);
4689 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4693 size = MAX_PATH;
4694 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4698 size = MAX_PATH;
4699 sprintf(path, "%s\\FileName5.dll", expected);
4700 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4705 if (!is_root(CURR_DIR))
4707 size = MAX_PATH;
4708 lstrcpyA(path, expected);
4709 ptr = strrchr(path, '\\') + 1;
4710 *ptr = '\0';
4711 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4713 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4715 size = MAX_PATH;
4716 sprintf(path, "%s\\", expected);
4717 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4719 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4721 size = MAX_PATH;
4722 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4724 if (is_root(CURR_DIR))
4725 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4726 else
4727 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4729 size = MAX_PATH;
4730 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4732 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4734 size = MAX_PATH;
4735 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4737 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4739 size = MAX_PATH;
4740 sprintf(path, "%s\\FileName1", expected);
4741 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4745 size = MAX_PATH;
4746 sprintf(path, "%s\\FileName1", expected);
4747 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749 if (space)
4750 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4751 else
4752 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4754 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4755 RegDeleteValueA(hklm, "Value1");
4756 RegDeleteValueA(hklm, "Value2");
4757 RegDeleteValueA(hklm, "Value3");
4758 RegDeleteValueA(hklm, "Value4");
4759 RegDeleteValueA(hklm, "Value5");
4760 RegDeleteValueA(hklm, "Value6");
4761 RegDeleteValueA(hklm, "Value7");
4762 RegDeleteValueA(hklm, "Value8");
4763 RegDeleteValueA(hklm, "Value9");
4764 RegDeleteValueA(hklm, "Value10");
4765 RegDeleteValueA(hklm, "Value11");
4766 RegDeleteValueA(hklm, "Value12");
4767 RegDeleteValueA(hklm, "Value13");
4768 RegDeleteValueA(hklm, "Value14");
4769 RegDeleteValueA(hklm, "Value15");
4770 RegDeleteValueA(hklm, "Value16");
4771 RegDeleteValueA(hklm, "Value17");
4772 RegDeleteKeyA(hklm, "");
4773 RegCloseKey(hklm);
4775 RegDeleteValueA(classes, "Value1");
4776 RegDeleteKeyA(classes, "");
4777 RegCloseKey(classes);
4779 RegDeleteValueA(hkcu, "Value1");
4780 RegDeleteKeyA(hkcu, "");
4781 RegCloseKey(hkcu);
4783 RegDeleteValueA(users, "Value1");
4784 RegDeleteKeyA(users, "");
4785 RegCloseKey(users);
4787 DeleteFileA("FileName1");
4788 DeleteFileA("FileName3.dll");
4789 DeleteFileA("FileName4.dll");
4790 DeleteFileA("FileName5.dll");
4791 MsiCloseHandle(hpkg);
4792 DeleteFileA(msifile);
4795 static void delete_win_ini(LPCSTR file)
4797 CHAR path[MAX_PATH];
4799 GetWindowsDirectoryA(path, MAX_PATH);
4800 lstrcatA(path, "\\");
4801 lstrcatA(path, file);
4803 DeleteFileA(path);
4806 static void test_appsearch_inilocator(void)
4808 MSIHANDLE hpkg, hdb;
4809 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4810 BOOL version;
4811 LPSTR ptr;
4812 DWORD size;
4813 UINT r;
4815 version = TRUE;
4816 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4817 version = FALSE;
4819 DeleteFileA("test.dll");
4821 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4823 strcpy(expected, CURR_DIR);
4824 if (is_root(CURR_DIR)) expected[2] = 0;
4826 create_test_file("FileName1");
4827 sprintf(path, "%s\\FileName1", expected);
4828 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4830 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4832 sprintf(path, "%s\\IDontExist", expected);
4833 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4835 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4836 sprintf(path, "%s\\FileName2.dll", expected);
4837 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4839 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4840 sprintf(path, "%s\\FileName3.dll", expected);
4841 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4843 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4844 sprintf(path, "%s\\FileName4.dll", expected);
4845 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4847 hdb = create_package_db();
4848 ok(hdb, "Expected a valid database handle\n");
4850 create_appsearch_table(hdb);
4851 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4852 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4853 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4854 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4855 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4856 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4857 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4858 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4859 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4860 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4861 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4862 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4864 create_inilocator_table(hdb);
4866 /* msidbLocatorTypeRawValue, field 1 */
4867 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
4869 /* msidbLocatorTypeRawValue, field 2 */
4870 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
4872 /* msidbLocatorTypeRawValue, entire field */
4873 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
4875 /* msidbLocatorTypeFile */
4876 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4878 /* msidbLocatorTypeDirectory, file */
4879 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
4881 /* msidbLocatorTypeDirectory, directory */
4882 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
4884 /* msidbLocatorTypeFile, file, no signature */
4885 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4887 /* msidbLocatorTypeFile, dir, no signature */
4888 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
4890 /* msidbLocatorTypeFile, file does not exist */
4891 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
4893 /* msidbLocatorTypeFile, signature with version */
4894 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
4896 /* msidbLocatorTypeFile, signature with version, ver > max */
4897 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
4899 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
4900 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
4902 create_signature_table(hdb);
4903 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
4904 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
4905 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4906 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4907 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4909 r = package_from_db(hdb, &hpkg);
4910 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4912 skip("Not enough rights to perform tests\n");
4913 goto error;
4915 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4917 MsiCloseHandle( hdb );
4918 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4920 r = MsiDoActionA(hpkg, "AppSearch");
4921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4923 size = MAX_PATH;
4924 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4926 if (!prop[0])
4928 win_skip("broken result\n");
4929 MsiCloseHandle(hpkg);
4930 goto error;
4932 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
4934 size = MAX_PATH;
4935 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4937 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
4939 size = MAX_PATH;
4940 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942 ok(!lstrcmpA(prop, "keydata,field2"),
4943 "Expected \"keydata,field2\", got \"%s\"\n", prop);
4945 size = MAX_PATH;
4946 sprintf(path, "%s\\FileName1", expected);
4947 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4951 size = MAX_PATH;
4952 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4956 size = MAX_PATH;
4957 sprintf(path, "%s\\", expected);
4958 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4962 size = MAX_PATH;
4963 sprintf(path, "%s\\", expected);
4964 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4966 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4968 if (!is_root(CURR_DIR))
4970 size = MAX_PATH;
4971 lstrcpyA(path, expected);
4972 ptr = strrchr(path, '\\');
4973 *(ptr + 1) = 0;
4974 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4976 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4978 size = MAX_PATH;
4979 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4981 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4983 if (version)
4985 size = MAX_PATH;
4986 sprintf(path, "%s\\FileName2.dll", expected);
4987 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4989 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4991 size = MAX_PATH;
4992 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4994 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4996 size = MAX_PATH;
4997 sprintf(path, "%s\\FileName4.dll", expected);
4998 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5000 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5003 MsiCloseHandle(hpkg);
5005 error:
5006 delete_win_ini("IniFile.ini");
5007 DeleteFileA("FileName1");
5008 DeleteFileA("FileName2.dll");
5009 DeleteFileA("FileName3.dll");
5010 DeleteFileA("FileName4.dll");
5011 DeleteFileA(msifile);
5015 * MSI AppSearch action on DrLocator table always returns absolute paths.
5016 * If a relative path was set, it returns the first absolute path that
5017 * matches or an empty string if it didn't find anything.
5018 * This helper function replicates this behaviour.
5020 static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5022 int i, size;
5023 DWORD attr, drives;
5025 size = lstrlenA(relative);
5026 drives = GetLogicalDrives();
5027 lstrcpyA(absolute, "A:\\");
5028 for (i = 0; i < 26; absolute[0] = '\0', i++)
5030 if (!(drives & (1 << i)))
5031 continue;
5033 absolute[0] = 'A' + i;
5034 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5035 continue;
5037 lstrcpynA(absolute + 3, relative, size + 1);
5038 attr = GetFileAttributesA(absolute);
5039 if (attr != INVALID_FILE_ATTRIBUTES &&
5040 (attr & FILE_ATTRIBUTE_DIRECTORY))
5042 if (absolute[3 + size - 1] != '\\')
5043 lstrcatA(absolute, "\\");
5044 break;
5046 absolute[3] = '\0';
5050 static void test_appsearch_drlocator(void)
5052 MSIHANDLE hpkg, hdb;
5053 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5054 BOOL version;
5055 DWORD size;
5056 UINT r;
5058 version = TRUE;
5059 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5060 version = FALSE;
5062 DeleteFileA("test.dll");
5064 create_test_file("FileName1");
5065 CreateDirectoryA("one", NULL);
5066 CreateDirectoryA("one\\two", NULL);
5067 CreateDirectoryA("one\\two\\three", NULL);
5068 create_test_file("one\\two\\three\\FileName2");
5069 CreateDirectoryA("another", NULL);
5070 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5071 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5072 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5074 hdb = create_package_db();
5075 ok(hdb, "Expected a valid database handle\n");
5077 create_appsearch_table(hdb);
5078 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5079 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5080 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5081 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5082 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5083 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5084 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5085 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5086 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5087 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5088 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5089 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5091 create_drlocator_table(hdb);
5093 strcpy(expected, CURR_DIR);
5094 if (is_root(CURR_DIR)) expected[2] = 0;
5096 /* no parent, full path, depth 0, signature */
5097 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5098 add_drlocator_entry(hdb, path);
5100 /* no parent, full path, depth 0, no signature */
5101 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5102 add_drlocator_entry(hdb, path);
5104 /* no parent, relative path, depth 0, no signature */
5105 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5106 add_drlocator_entry(hdb, path);
5108 /* no parent, full path, depth 2, signature */
5109 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5110 add_drlocator_entry(hdb, path);
5112 /* no parent, full path, depth 3, signature */
5113 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5114 add_drlocator_entry(hdb, path);
5116 /* no parent, full path, depth 1, signature is dir */
5117 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5118 add_drlocator_entry(hdb, path);
5120 /* parent is in DrLocator, relative path, depth 0, signature */
5121 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5122 add_drlocator_entry(hdb, path);
5124 /* no parent, full path, depth 0, signature w/ version */
5125 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5126 add_drlocator_entry(hdb, path);
5128 /* no parent, full path, depth 0, signature w/ version, ver > max */
5129 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5130 add_drlocator_entry(hdb, path);
5132 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5133 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5134 add_drlocator_entry(hdb, path);
5136 /* no parent, relative empty path, depth 0, no signature */
5137 sprintf(path, "'NewSignature11', '', '', 0");
5138 add_drlocator_entry(hdb, path);
5140 create_reglocator_table(hdb);
5142 /* parent */
5143 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5145 /* parent is in RegLocator, no path, depth 0, no signature */
5146 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5147 add_drlocator_entry(hdb, path);
5149 create_signature_table(hdb);
5150 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5151 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5152 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5153 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5154 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5155 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5156 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5157 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5159 r = package_from_db(hdb, &hpkg);
5160 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5162 skip("Not enough rights to perform tests\n");
5163 goto error;
5165 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5167 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5169 r = MsiDoActionA(hpkg, "AppSearch");
5170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5172 size = MAX_PATH;
5173 sprintf(path, "%s\\FileName1", expected);
5174 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5176 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5178 size = MAX_PATH;
5179 sprintf(path, "%s\\", expected);
5180 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5182 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5184 size = MAX_PATH;
5185 search_absolute_directory(path, expected + 3);
5186 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5188 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5190 size = MAX_PATH;
5191 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5193 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5195 size = MAX_PATH;
5196 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5197 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5199 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5201 size = MAX_PATH;
5202 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5204 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5206 size = MAX_PATH;
5207 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5208 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5210 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5212 if (version)
5214 size = MAX_PATH;
5215 sprintf(path, "%s\\FileName3.dll", expected);
5216 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5218 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5220 size = MAX_PATH;
5221 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5223 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5225 size = MAX_PATH;
5226 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5228 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5231 size = MAX_PATH;
5232 search_absolute_directory(path, "");
5233 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5237 size = MAX_PATH;
5238 strcpy(path, "c:\\");
5239 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5243 MsiCloseHandle(hpkg);
5245 error:
5246 DeleteFileA("FileName1");
5247 DeleteFileA("FileName3.dll");
5248 DeleteFileA("FileName4.dll");
5249 DeleteFileA("FileName5.dll");
5250 DeleteFileA("one\\two\\three\\FileName2");
5251 RemoveDirectoryA("one\\two\\three");
5252 RemoveDirectoryA("one\\two");
5253 RemoveDirectoryA("one");
5254 RemoveDirectoryA("another");
5255 DeleteFileA(msifile);
5258 static void test_featureparents(void)
5260 MSIHANDLE hpkg;
5261 UINT r;
5262 MSIHANDLE hdb;
5264 hdb = create_package_db();
5265 ok ( hdb, "failed to create package database\n" );
5267 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5269 create_feature_table( hdb );
5270 create_component_table( hdb );
5271 create_feature_components_table( hdb );
5272 create_file_table( hdb );
5274 /* msidbFeatureAttributesFavorLocal */
5275 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5277 /* msidbFeatureAttributesFavorSource */
5278 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5280 /* msidbFeatureAttributesFavorLocal */
5281 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5283 /* msidbFeatureAttributesUIDisallowAbsent */
5284 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5286 /* disabled because of install level */
5287 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5289 /* child feature of disabled feature */
5290 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5292 /* component of disabled feature (install level) */
5293 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5295 /* component of disabled child feature (install level) */
5296 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5298 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5299 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5301 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5302 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5304 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5305 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5307 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5308 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5310 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5311 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5313 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5314 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5316 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5317 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5319 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5320 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5322 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5323 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5325 add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5326 add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5327 add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5328 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5329 add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5330 add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5331 add_feature_components_entry( hdb, "'orion', 'leo'" );
5332 add_feature_components_entry( hdb, "'orion', 'virgo'" );
5333 add_feature_components_entry( hdb, "'orion', 'libra'" );
5334 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5335 add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5336 add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5337 add_feature_components_entry( hdb, "'orion', 'canis'" );
5338 add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5339 add_feature_components_entry( hdb, "'orion', 'lepus'" );
5340 add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5341 add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5343 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5344 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5345 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5346 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5347 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5348 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5349 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5350 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5351 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5352 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5353 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5355 r = package_from_db( hdb, &hpkg );
5356 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5358 skip("Not enough rights to perform tests\n");
5359 DeleteFileA(msifile);
5360 return;
5362 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5364 MsiCloseHandle( hdb );
5366 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5368 r = MsiDoActionA( hpkg, "CostInitialize");
5369 ok( r == ERROR_SUCCESS, "cost init failed\n");
5371 r = MsiDoActionA( hpkg, "FileCost");
5372 ok( r == ERROR_SUCCESS, "file cost failed\n");
5374 r = MsiDoActionA( hpkg, "CostFinalize");
5375 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5377 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5378 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5379 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5380 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5381 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5382 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5384 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5385 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5386 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5387 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5388 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5389 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5390 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5391 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5392 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5393 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5394 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5396 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5397 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5399 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5400 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5402 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5403 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5405 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5406 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5407 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5408 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5409 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5410 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5412 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5413 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5414 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5415 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5416 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5417 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5418 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5419 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5420 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5421 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5422 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5424 MsiCloseHandle(hpkg);
5425 DeleteFileA(msifile);
5428 static void test_installprops(void)
5430 MSIHANDLE hpkg, hdb;
5431 CHAR path[MAX_PATH], buf[MAX_PATH];
5432 DWORD size, type;
5433 LANGID langid;
5434 HKEY hkey1, hkey2, pathkey = NULL;
5435 int res;
5436 UINT r;
5437 REGSAM access = KEY_ALL_ACCESS;
5438 SYSTEM_INFO si;
5439 INSTALLUILEVEL uilevel;
5441 if (is_wow64)
5442 access |= KEY_WOW64_64KEY;
5444 lstrcpyA(path, CURR_DIR);
5445 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5446 lstrcatA(path, msifile);
5448 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5450 hdb = create_package_db();
5451 ok( hdb, "failed to create database\n");
5453 r = package_from_db(hdb, &hpkg);
5454 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5456 skip("Not enough rights to perform tests\n");
5457 MsiSetInternalUI(uilevel, NULL);
5458 DeleteFileA(msifile);
5459 return;
5461 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5463 MsiCloseHandle(hdb);
5465 buf[0] = 0;
5466 size = MAX_PATH;
5467 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5468 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5469 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5471 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5473 buf[0] = 0;
5474 size = MAX_PATH;
5475 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5476 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5477 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5479 buf[0] = 0;
5480 size = MAX_PATH;
5481 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5482 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5483 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5485 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5486 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5487 if (res == ERROR_ACCESS_DENIED)
5489 win_skip("no access\n");
5490 goto done;
5492 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5493 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5495 size = MAX_PATH;
5496 type = REG_SZ;
5497 *path = '\0';
5498 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5500 size = MAX_PATH;
5501 type = REG_SZ;
5502 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5505 buf[0] = 0;
5506 size = MAX_PATH;
5507 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5508 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5509 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5511 size = MAX_PATH;
5512 type = REG_SZ;
5513 *path = '\0';
5514 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5516 size = MAX_PATH;
5517 type = REG_SZ;
5518 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5521 if (*path)
5523 buf[0] = 0;
5524 size = MAX_PATH;
5525 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5526 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5527 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5530 buf[0] = 0;
5531 size = MAX_PATH;
5532 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5533 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5534 trace("VersionDatabase = %s\n", buf);
5536 buf[0] = 0;
5537 size = MAX_PATH;
5538 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5539 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5540 trace("VersionMsi = %s\n", buf);
5542 buf[0] = 0;
5543 size = MAX_PATH;
5544 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5545 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5546 trace("Date = %s\n", buf);
5548 buf[0] = 0;
5549 size = MAX_PATH;
5550 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5551 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5552 trace("Time = %s\n", buf);
5554 buf[0] = 0;
5555 size = MAX_PATH;
5556 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5557 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5558 trace("PackageCode = %s\n", buf);
5560 buf[0] = 0;
5561 size = MAX_PATH;
5562 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5563 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5564 trace("ComputerName = %s\n", buf);
5566 langid = GetUserDefaultLangID();
5567 sprintf(path, "%d", langid);
5569 buf[0] = 0;
5570 size = MAX_PATH;
5571 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5572 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5573 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5575 res = GetSystemMetrics(SM_CXSCREEN);
5576 buf[0] = 0;
5577 size = MAX_PATH;
5578 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5579 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5580 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5582 res = GetSystemMetrics(SM_CYSCREEN);
5583 buf[0] = 0;
5584 size = MAX_PATH;
5585 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5586 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5587 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5589 buf[0] = 0;
5590 size = MAX_PATH;
5591 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
5592 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
5594 GetNativeSystemInfo(&si);
5596 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5597 check_prop(hpkg, "VersionNT", buf, 1, 1);
5599 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5601 sprintf(buf, "%d", si.wProcessorLevel);
5602 check_prop(hpkg, "Intel", buf, 1, 0);
5603 check_prop(hpkg, "MsiAMD64", buf, 1, 0);
5604 check_prop(hpkg, "Msix64", buf, 1, 0);
5605 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5606 check_prop(hpkg, "VersionNT64", buf, 1, 1);
5608 GetSystemDirectoryA(path, MAX_PATH);
5609 strcat(path, "\\");
5610 check_prop(hpkg, "System64Folder", path, 0, 0);
5612 GetSystemWow64DirectoryA(path, MAX_PATH);
5613 strcat(path, "\\");
5614 check_prop(hpkg, "SystemFolder", path, 0, 0);
5616 size = MAX_PATH;
5617 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5618 strcat(path, "\\");
5619 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5621 size = MAX_PATH;
5622 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5623 strcat(path, "\\");
5624 check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0);
5626 size = MAX_PATH;
5627 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5628 strcat(path, "\\");
5629 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5631 size = MAX_PATH;
5632 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5633 strcat(path, "\\");
5634 check_prop(hpkg, "CommonFiles64Folder", path, 0, 0);
5636 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5638 sprintf(buf, "%d", si.wProcessorLevel);
5639 check_prop(hpkg, "Intel", buf, 1, 0);
5641 GetSystemDirectoryA(path, MAX_PATH);
5642 strcat(path, "\\");
5643 check_prop(hpkg, "SystemFolder", path, 0, 0);
5645 size = MAX_PATH;
5646 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5647 strcat(path, "\\");
5648 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5650 size = MAX_PATH;
5651 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5652 strcat(path, "\\");
5653 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5655 check_prop(hpkg, "MsiAMD64", "", 1, 0);
5656 check_prop(hpkg, "Msix64", "", 1, 0);
5657 check_prop(hpkg, "VersionNT64", "", 1, 0);
5658 check_prop(hpkg, "System64Folder", "", 0, 0);
5659 check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0);
5660 check_prop(hpkg, "CommonFiles64Dir", "", 0, 0);
5663 done:
5664 CloseHandle(hkey1);
5665 CloseHandle(hkey2);
5666 RegCloseKey(pathkey);
5667 MsiCloseHandle(hpkg);
5668 DeleteFileA(msifile);
5669 MsiSetInternalUI(uilevel, NULL);
5672 static void test_launchconditions(void)
5674 MSIHANDLE hpkg;
5675 MSIHANDLE hdb;
5676 UINT r;
5678 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5680 hdb = create_package_db();
5681 ok( hdb, "failed to create package database\n" );
5683 create_launchcondition_table( hdb );
5685 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5687 /* invalid condition */
5688 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5690 r = package_from_db( hdb, &hpkg );
5691 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5693 skip("Not enough rights to perform tests\n");
5694 DeleteFileA(msifile);
5695 return;
5697 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5699 MsiCloseHandle( hdb );
5701 r = MsiSetPropertyA( hpkg, "X", "1" );
5702 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5704 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5706 /* invalid conditions are ignored */
5707 r = MsiDoActionA( hpkg, "LaunchConditions" );
5708 ok( r == ERROR_SUCCESS, "cost init failed\n" );
5710 /* verify LaunchConditions still does some verification */
5711 r = MsiSetPropertyA( hpkg, "X", "2" );
5712 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5714 r = MsiDoActionA( hpkg, "LaunchConditions" );
5715 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5717 MsiCloseHandle( hpkg );
5718 DeleteFileA( msifile );
5721 static void test_ccpsearch(void)
5723 MSIHANDLE hdb, hpkg;
5724 CHAR prop[MAX_PATH];
5725 DWORD size = MAX_PATH;
5726 UINT r;
5728 hdb = create_package_db();
5729 ok(hdb, "failed to create package database\n");
5731 create_ccpsearch_table(hdb);
5732 add_ccpsearch_entry(hdb, "'CCP_random'");
5733 add_ccpsearch_entry(hdb, "'RMCCP_random'");
5735 create_reglocator_table(hdb);
5736 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5738 create_drlocator_table(hdb);
5739 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5741 create_signature_table(hdb);
5743 r = package_from_db(hdb, &hpkg);
5744 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5746 skip("Not enough rights to perform tests\n");
5747 DeleteFileA(msifile);
5748 return;
5750 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5752 MsiCloseHandle(hdb);
5754 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5756 r = MsiDoActionA(hpkg, "CCPSearch");
5757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5759 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5761 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5763 MsiCloseHandle(hpkg);
5764 DeleteFileA(msifile);
5767 static void test_complocator(void)
5769 MSIHANDLE hdb, hpkg;
5770 UINT r;
5771 CHAR prop[MAX_PATH];
5772 CHAR expected[MAX_PATH];
5773 DWORD size = MAX_PATH;
5775 hdb = create_package_db();
5776 ok(hdb, "failed to create package database\n");
5778 create_appsearch_table(hdb);
5779 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5780 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5781 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5782 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5783 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5784 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5785 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5786 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5787 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5788 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5789 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5790 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5791 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5792 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5793 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5794 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5796 create_complocator_table(hdb);
5797 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5798 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5799 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5800 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5801 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5802 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5803 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5804 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5805 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5806 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5807 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5808 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5809 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5810 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5811 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5812 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5814 create_signature_table(hdb);
5815 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5816 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5817 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5818 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5819 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5820 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5821 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5822 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5824 r = package_from_db(hdb, &hpkg);
5825 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5827 skip("Not enough rights to perform tests\n");
5828 DeleteFileA(msifile);
5829 return;
5831 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5833 MsiCloseHandle(hdb);
5835 create_test_file("abelisaurus");
5836 create_test_file("bactrosaurus");
5837 create_test_file("camelotia");
5838 create_test_file("diclonius");
5839 create_test_file("echinodon");
5840 create_test_file("falcarius");
5841 create_test_file("gallimimus");
5842 create_test_file("hagryphus");
5843 CreateDirectoryA("iguanodon", NULL);
5844 CreateDirectoryA("jobaria", NULL);
5845 CreateDirectoryA("kakuru", NULL);
5846 CreateDirectoryA("labocania", NULL);
5847 CreateDirectoryA("megaraptor", NULL);
5848 CreateDirectoryA("neosodon", NULL);
5849 CreateDirectoryA("olorotitan", NULL);
5850 CreateDirectoryA("pantydraco", NULL);
5852 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
5853 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5854 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
5855 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5856 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
5857 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5858 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
5859 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
5860 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
5861 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
5862 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
5863 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
5864 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
5865 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
5866 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
5867 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
5869 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5871 r = MsiDoActionA(hpkg, "AppSearch");
5872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5874 size = MAX_PATH;
5875 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
5876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5878 lstrcpyA(expected, CURR_DIR);
5879 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5880 lstrcatA(expected, "abelisaurus");
5881 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5882 "Expected %s or empty string, got %s\n", expected, prop);
5884 size = MAX_PATH;
5885 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
5886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5887 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5889 size = MAX_PATH;
5890 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
5891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5892 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5894 size = MAX_PATH;
5895 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
5896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5897 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5899 size = MAX_PATH;
5900 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
5901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5903 lstrcpyA(expected, CURR_DIR);
5904 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5905 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5906 "Expected %s or empty string, got %s\n", expected, prop);
5908 size = MAX_PATH;
5909 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
5910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5911 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5913 size = MAX_PATH;
5914 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
5915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5916 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5918 size = MAX_PATH;
5919 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
5920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5921 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5923 size = MAX_PATH;
5924 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
5925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5926 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5928 size = MAX_PATH;
5929 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
5930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5931 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5933 size = MAX_PATH;
5934 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
5935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5936 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5938 size = MAX_PATH;
5939 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
5940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5941 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5943 size = MAX_PATH;
5944 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
5945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5947 lstrcpyA(expected, CURR_DIR);
5948 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5949 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5950 "Expected %s or empty string, got %s\n", expected, prop);
5952 size = MAX_PATH;
5953 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
5954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5956 lstrcpyA(expected, CURR_DIR);
5957 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5958 lstrcatA(expected, "neosodon\\");
5959 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5960 "Expected %s or empty string, got %s\n", expected, prop);
5962 size = MAX_PATH;
5963 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
5964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5965 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5967 size = MAX_PATH;
5968 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
5969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5970 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5972 MsiCloseHandle(hpkg);
5973 DeleteFileA("abelisaurus");
5974 DeleteFileA("bactrosaurus");
5975 DeleteFileA("camelotia");
5976 DeleteFileA("diclonius");
5977 DeleteFileA("echinodon");
5978 DeleteFileA("falcarius");
5979 DeleteFileA("gallimimus");
5980 DeleteFileA("hagryphus");
5981 RemoveDirectoryA("iguanodon");
5982 RemoveDirectoryA("jobaria");
5983 RemoveDirectoryA("kakuru");
5984 RemoveDirectoryA("labocania");
5985 RemoveDirectoryA("megaraptor");
5986 RemoveDirectoryA("neosodon");
5987 RemoveDirectoryA("olorotitan");
5988 RemoveDirectoryA("pantydraco");
5989 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
5990 MSIINSTALLCONTEXT_MACHINE, NULL);
5991 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
5992 MSIINSTALLCONTEXT_MACHINE, NULL);
5993 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
5994 MSIINSTALLCONTEXT_MACHINE, NULL);
5995 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
5996 MSIINSTALLCONTEXT_MACHINE, NULL);
5997 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
5998 MSIINSTALLCONTEXT_MACHINE, NULL);
5999 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6000 MSIINSTALLCONTEXT_MACHINE, NULL);
6001 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6002 MSIINSTALLCONTEXT_MACHINE, NULL);
6003 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6004 MSIINSTALLCONTEXT_MACHINE, NULL);
6005 DeleteFileA(msifile);
6008 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6010 MSIHANDLE summary;
6011 UINT r;
6013 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6016 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6019 r = MsiSummaryInfoPersist(summary);
6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6022 MsiCloseHandle(summary);
6025 static void test_MsiGetSourcePath(void)
6027 MSIHANDLE hdb, hpkg;
6028 CHAR path[MAX_PATH];
6029 CHAR cwd[MAX_PATH];
6030 CHAR subsrc[MAX_PATH];
6031 CHAR sub2[MAX_PATH];
6032 DWORD size;
6033 UINT r;
6035 lstrcpyA(cwd, CURR_DIR);
6036 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6038 lstrcpyA(subsrc, cwd);
6039 lstrcatA(subsrc, "subsource");
6040 lstrcatA(subsrc, "\\");
6042 lstrcpyA(sub2, subsrc);
6043 lstrcatA(sub2, "sub2");
6044 lstrcatA(sub2, "\\");
6046 /* uncompressed source */
6048 hdb = create_package_db();
6049 ok( hdb, "failed to create database\n");
6051 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6053 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6054 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6055 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6057 r = MsiDatabaseCommit(hdb);
6058 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6060 r = package_from_db(hdb, &hpkg);
6061 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6063 skip("Not enough rights to perform tests\n");
6064 DeleteFileA(msifile);
6065 return;
6067 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6069 MsiCloseHandle(hdb);
6071 /* invalid database handle */
6072 size = MAX_PATH;
6073 lstrcpyA(path, "kiwi");
6074 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6075 ok(r == ERROR_INVALID_HANDLE,
6076 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6077 ok(!lstrcmpA(path, "kiwi"),
6078 "Expected path to be unchanged, got \"%s\"\n", path);
6079 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6081 /* NULL szFolder */
6082 size = MAX_PATH;
6083 lstrcpyA(path, "kiwi");
6084 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6085 ok(r == ERROR_INVALID_PARAMETER,
6086 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6087 ok(!lstrcmpA(path, "kiwi"),
6088 "Expected path to be unchanged, got \"%s\"\n", path);
6089 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6091 /* empty szFolder */
6092 size = MAX_PATH;
6093 lstrcpyA(path, "kiwi");
6094 r = MsiGetSourcePathA(hpkg, "", path, &size);
6095 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6096 ok(!lstrcmpA(path, "kiwi"),
6097 "Expected path to be unchanged, got \"%s\"\n", path);
6098 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6100 /* try TARGETDIR */
6101 size = MAX_PATH;
6102 lstrcpyA(path, "kiwi");
6103 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6104 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6105 ok(!lstrcmpA(path, "kiwi"),
6106 "Expected path to be unchanged, got \"%s\"\n", path);
6107 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6109 size = MAX_PATH;
6110 lstrcpyA(path, "kiwi");
6111 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6113 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6114 ok(size == 0, "Expected 0, got %lu\n", size);
6116 size = MAX_PATH;
6117 lstrcpyA(path, "kiwi");
6118 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6120 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6121 ok(size == 0, "Expected 0, got %lu\n", size);
6123 /* try SourceDir */
6124 size = MAX_PATH;
6125 lstrcpyA(path, "kiwi");
6126 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6127 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6128 ok(!lstrcmpA(path, "kiwi"),
6129 "Expected path to be unchanged, got \"%s\"\n", path);
6130 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6132 /* try SOURCEDIR */
6133 size = MAX_PATH;
6134 lstrcpyA(path, "kiwi");
6135 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6136 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6137 ok(!lstrcmpA(path, "kiwi"),
6138 "Expected path to be unchanged, got \"%s\"\n", path);
6139 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6141 /* source path does not exist, but the property exists */
6142 size = MAX_PATH;
6143 lstrcpyA(path, "kiwi");
6144 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6146 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6147 ok(size == 0, "Expected 0, got %lu\n", size);
6149 size = MAX_PATH;
6150 lstrcpyA(path, "kiwi");
6151 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6153 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6154 ok(size == 0, "Expected 0, got %lu\n", size);
6156 /* try SubDir */
6157 size = MAX_PATH;
6158 lstrcpyA(path, "kiwi");
6159 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6160 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6161 ok(!lstrcmpA(path, "kiwi"),
6162 "Expected path to be unchanged, got \"%s\"\n", path);
6163 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6165 /* try SubDir2 */
6166 size = MAX_PATH;
6167 lstrcpyA(path, "kiwi");
6168 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6169 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6170 ok(!lstrcmpA(path, "kiwi"),
6171 "Expected path to be unchanged, got \"%s\"\n", path);
6172 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6174 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6176 r = MsiDoActionA(hpkg, "CostInitialize");
6177 ok(r == ERROR_SUCCESS, "cost init failed\n");
6179 /* try TARGETDIR after CostInitialize */
6180 size = MAX_PATH;
6181 lstrcpyA(path, "kiwi");
6182 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6184 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6185 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6187 /* try SourceDir after CostInitialize */
6188 size = MAX_PATH;
6189 lstrcpyA(path, "kiwi");
6190 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6193 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6195 /* try SOURCEDIR after CostInitialize */
6196 size = MAX_PATH;
6197 lstrcpyA(path, "kiwi");
6198 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6199 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6200 ok(!lstrcmpA(path, "kiwi"),
6201 "Expected path to be unchanged, got \"%s\"\n", path);
6202 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6204 /* source path does not exist, but the property exists */
6205 size = MAX_PATH;
6206 lstrcpyA(path, "kiwi");
6207 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6209 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6210 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6212 size = MAX_PATH;
6213 lstrcpyA(path, "kiwi");
6214 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6216 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6217 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6219 /* try SubDir after CostInitialize */
6220 size = MAX_PATH;
6221 lstrcpyA(path, "kiwi");
6222 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6224 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6225 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6227 /* try SubDir2 after CostInitialize */
6228 size = MAX_PATH;
6229 lstrcpyA(path, "kiwi");
6230 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6232 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6233 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6235 r = MsiDoActionA(hpkg, "ResolveSource");
6236 ok(r == ERROR_SUCCESS, "file cost failed\n");
6238 /* try TARGETDIR after ResolveSource */
6239 size = MAX_PATH;
6240 lstrcpyA(path, "kiwi");
6241 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6243 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6244 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6246 /* try SourceDir after ResolveSource */
6247 size = MAX_PATH;
6248 lstrcpyA(path, "kiwi");
6249 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6251 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6252 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6254 /* try SOURCEDIR after ResolveSource */
6255 size = MAX_PATH;
6256 lstrcpyA(path, "kiwi");
6257 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6258 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6259 ok(!lstrcmpA(path, "kiwi"),
6260 "Expected path to be unchanged, got \"%s\"\n", path);
6261 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6263 /* source path does not exist, but the property exists */
6264 size = MAX_PATH;
6265 lstrcpyA(path, "kiwi");
6266 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6268 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6269 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6271 size = MAX_PATH;
6272 lstrcpyA(path, "kiwi");
6273 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6275 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6276 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6278 /* try SubDir after ResolveSource */
6279 size = MAX_PATH;
6280 lstrcpyA(path, "kiwi");
6281 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6283 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6284 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6286 /* try SubDir2 after ResolveSource */
6287 size = MAX_PATH;
6288 lstrcpyA(path, "kiwi");
6289 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6291 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6292 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6294 r = MsiDoActionA(hpkg, "FileCost");
6295 ok(r == ERROR_SUCCESS, "file cost failed\n");
6297 /* try TARGETDIR after FileCost */
6298 size = MAX_PATH;
6299 lstrcpyA(path, "kiwi");
6300 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6302 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6303 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6305 /* try SourceDir after FileCost */
6306 size = MAX_PATH;
6307 lstrcpyA(path, "kiwi");
6308 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6310 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6311 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6313 /* try SOURCEDIR after FileCost */
6314 size = MAX_PATH;
6315 lstrcpyA(path, "kiwi");
6316 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6317 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6318 ok(!lstrcmpA(path, "kiwi"),
6319 "Expected path to be unchanged, got \"%s\"\n", path);
6320 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6322 /* source path does not exist, but the property exists */
6323 size = MAX_PATH;
6324 lstrcpyA(path, "kiwi");
6325 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6327 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6328 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6330 size = MAX_PATH;
6331 lstrcpyA(path, "kiwi");
6332 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6334 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6335 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6337 /* try SubDir after FileCost */
6338 size = MAX_PATH;
6339 lstrcpyA(path, "kiwi");
6340 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6342 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6343 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6345 /* try SubDir2 after FileCost */
6346 size = MAX_PATH;
6347 lstrcpyA(path, "kiwi");
6348 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6350 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6351 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6353 r = MsiDoActionA(hpkg, "CostFinalize");
6354 ok(r == ERROR_SUCCESS, "file cost failed\n");
6356 /* try TARGETDIR after CostFinalize */
6357 size = MAX_PATH;
6358 lstrcpyA(path, "kiwi");
6359 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6361 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6362 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6364 /* try SourceDir after CostFinalize */
6365 size = MAX_PATH;
6366 lstrcpyA(path, "kiwi");
6367 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6370 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6372 /* try SOURCEDIR after CostFinalize */
6373 size = MAX_PATH;
6374 lstrcpyA(path, "kiwi");
6375 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6376 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6377 ok(!lstrcmpA(path, "kiwi"),
6378 "Expected path to be unchanged, got \"%s\"\n", path);
6379 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6381 /* source path does not exist, but the property exists */
6382 size = MAX_PATH;
6383 lstrcpyA(path, "kiwi");
6384 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6386 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6387 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6389 size = MAX_PATH;
6390 lstrcpyA(path, "kiwi");
6391 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6393 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6394 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6396 /* try SubDir after CostFinalize */
6397 size = MAX_PATH;
6398 lstrcpyA(path, "kiwi");
6399 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6401 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6402 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6404 /* try SubDir2 after CostFinalize */
6405 size = MAX_PATH;
6406 lstrcpyA(path, "kiwi");
6407 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6409 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6410 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6412 /* nonexistent directory */
6413 size = MAX_PATH;
6414 lstrcpyA(path, "kiwi");
6415 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6416 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6417 ok(!lstrcmpA(path, "kiwi"),
6418 "Expected path to be unchanged, got \"%s\"\n", path);
6419 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6421 /* NULL szPathBuf */
6422 size = MAX_PATH;
6423 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6425 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6427 /* NULL pcchPathBuf */
6428 lstrcpyA(path, "kiwi");
6429 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6430 ok(r == ERROR_INVALID_PARAMETER,
6431 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6432 ok(!lstrcmpA(path, "kiwi"),
6433 "Expected path to be unchanged, got \"%s\"\n", path);
6435 /* pcchPathBuf is 0 */
6436 size = 0;
6437 lstrcpyA(path, "kiwi");
6438 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6439 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6440 ok(!lstrcmpA(path, "kiwi"),
6441 "Expected path to be unchanged, got \"%s\"\n", path);
6442 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6444 /* pcchPathBuf does not have room for NULL terminator */
6445 size = lstrlenA(cwd);
6446 lstrcpyA(path, "kiwi");
6447 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6448 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6449 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6450 "Expected path with no backslash, got \"%s\"\n", path);
6451 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6453 /* pcchPathBuf has room for NULL terminator */
6454 size = lstrlenA(cwd) + 1;
6455 lstrcpyA(path, "kiwi");
6456 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6458 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6459 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6461 /* remove property */
6462 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6465 /* try SourceDir again */
6466 size = MAX_PATH;
6467 lstrcpyA(path, "kiwi");
6468 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6470 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6471 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6473 /* set property to a valid directory */
6474 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6475 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6477 /* try SOURCEDIR again */
6478 size = MAX_PATH;
6479 lstrcpyA(path, "kiwi");
6480 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6481 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6482 ok(!lstrcmpA(path, "kiwi"),
6483 "Expected path to be unchanged, got \"%s\"\n", path);
6484 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6486 MsiCloseHandle(hpkg);
6488 /* compressed source */
6490 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6491 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6493 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
6495 r = package_from_db(hdb, &hpkg);
6496 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6498 /* try TARGETDIR */
6499 size = MAX_PATH;
6500 lstrcpyA(path, "kiwi");
6501 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6502 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6503 ok(!lstrcmpA(path, "kiwi"),
6504 "Expected path to be unchanged, got \"%s\"\n", path);
6505 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6507 /* try SourceDir */
6508 size = MAX_PATH;
6509 lstrcpyA(path, "kiwi");
6510 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6511 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6512 ok(!lstrcmpA(path, "kiwi"),
6513 "Expected path to be unchanged, got \"%s\"\n", path);
6514 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6516 /* try SOURCEDIR */
6517 size = MAX_PATH;
6518 lstrcpyA(path, "kiwi");
6519 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6520 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6521 ok(!lstrcmpA(path, "kiwi"),
6522 "Expected path to be unchanged, got \"%s\"\n", path);
6523 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6525 /* source path nor the property exist */
6526 size = MAX_PATH;
6527 lstrcpyA(path, "kiwi");
6528 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6530 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6531 ok(size == 0, "Expected 0, got %lu\n", size);
6533 size = MAX_PATH;
6534 lstrcpyA(path, "kiwi");
6535 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6537 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6538 ok(size == 0, "Expected 0, got %lu\n", size);
6540 /* try SubDir */
6541 size = MAX_PATH;
6542 lstrcpyA(path, "kiwi");
6543 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6544 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6545 ok(!lstrcmpA(path, "kiwi"),
6546 "Expected path to be unchanged, got \"%s\"\n", path);
6547 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6549 /* try SubDir2 */
6550 size = MAX_PATH;
6551 lstrcpyA(path, "kiwi");
6552 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6553 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6554 ok(!lstrcmpA(path, "kiwi"),
6555 "Expected path to be unchanged, got \"%s\"\n", path);
6556 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6558 r = MsiDoActionA(hpkg, "CostInitialize");
6559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6561 /* try TARGETDIR after CostInitialize */
6562 size = MAX_PATH;
6563 lstrcpyA(path, "kiwi");
6564 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6566 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6567 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6569 /* try SourceDir after CostInitialize */
6570 size = MAX_PATH;
6571 lstrcpyA(path, "kiwi");
6572 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6574 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6575 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6577 /* try SOURCEDIR after CostInitialize */
6578 size = MAX_PATH;
6579 lstrcpyA(path, "kiwi");
6580 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6581 todo_wine
6583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6584 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6585 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6588 /* source path does not exist, but the property exists */
6589 size = MAX_PATH;
6590 lstrcpyA(path, "kiwi");
6591 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6593 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6594 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6596 size = MAX_PATH;
6597 lstrcpyA(path, "kiwi");
6598 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6600 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6601 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6603 /* try SubDir after CostInitialize */
6604 size = MAX_PATH;
6605 lstrcpyA(path, "kiwi");
6606 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6608 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6609 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6611 /* try SubDir2 after CostInitialize */
6612 size = MAX_PATH;
6613 lstrcpyA(path, "kiwi");
6614 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6616 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6617 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6619 r = MsiDoActionA(hpkg, "ResolveSource");
6620 ok(r == ERROR_SUCCESS, "file cost failed\n");
6622 /* try TARGETDIR after ResolveSource */
6623 size = MAX_PATH;
6624 lstrcpyA(path, "kiwi");
6625 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6627 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6628 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6630 /* try SourceDir after ResolveSource */
6631 size = MAX_PATH;
6632 lstrcpyA(path, "kiwi");
6633 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6635 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6636 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6638 /* try SOURCEDIR after ResolveSource */
6639 size = MAX_PATH;
6640 lstrcpyA(path, "kiwi");
6641 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6642 todo_wine
6644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6645 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6646 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6649 /* source path and the property exist */
6650 size = MAX_PATH;
6651 lstrcpyA(path, "kiwi");
6652 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6654 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6655 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6657 size = MAX_PATH;
6658 lstrcpyA(path, "kiwi");
6659 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6661 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6662 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6664 /* try SubDir after ResolveSource */
6665 size = MAX_PATH;
6666 lstrcpyA(path, "kiwi");
6667 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6670 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6672 /* try SubDir2 after ResolveSource */
6673 size = MAX_PATH;
6674 lstrcpyA(path, "kiwi");
6675 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6677 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6678 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6680 r = MsiDoActionA(hpkg, "FileCost");
6681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6683 /* try TARGETDIR after CostFinalize */
6684 size = MAX_PATH;
6685 lstrcpyA(path, "kiwi");
6686 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6688 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6689 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6691 /* try SourceDir after CostFinalize */
6692 size = MAX_PATH;
6693 lstrcpyA(path, "kiwi");
6694 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6696 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6697 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6699 /* try SOURCEDIR after CostFinalize */
6700 size = MAX_PATH;
6701 lstrcpyA(path, "kiwi");
6702 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6703 todo_wine
6705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6706 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6707 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6710 /* source path and the property exist */
6711 size = MAX_PATH;
6712 lstrcpyA(path, "kiwi");
6713 r = MsiGetPropertyA(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 %lu\n", lstrlenA(cwd), size);
6718 size = MAX_PATH;
6719 lstrcpyA(path, "kiwi");
6720 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6722 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6723 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6725 /* try SubDir after CostFinalize */
6726 size = MAX_PATH;
6727 lstrcpyA(path, "kiwi");
6728 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6730 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6731 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6733 /* try SubDir2 after CostFinalize */
6734 size = MAX_PATH;
6735 lstrcpyA(path, "kiwi");
6736 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6738 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6739 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6741 r = MsiDoActionA(hpkg, "CostFinalize");
6742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6744 /* try TARGETDIR after CostFinalize */
6745 size = MAX_PATH;
6746 lstrcpyA(path, "kiwi");
6747 r = MsiGetSourcePathA(hpkg, "TARGETDIR", 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 %lu\n", lstrlenA(cwd), size);
6752 /* try SourceDir after CostFinalize */
6753 size = MAX_PATH;
6754 lstrcpyA(path, "kiwi");
6755 r = MsiGetSourcePathA(hpkg, "SourceDir", 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 %lu\n", lstrlenA(cwd), size);
6760 /* try SOURCEDIR after CostFinalize */
6761 size = MAX_PATH;
6762 lstrcpyA(path, "kiwi");
6763 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6764 todo_wine
6766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6767 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6768 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6771 /* source path and the property exist */
6772 size = MAX_PATH;
6773 lstrcpyA(path, "kiwi");
6774 r = MsiGetPropertyA(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 %lu\n", lstrlenA(cwd), size);
6779 size = MAX_PATH;
6780 lstrcpyA(path, "kiwi");
6781 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6783 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6784 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6786 /* try SubDir after CostFinalize */
6787 size = MAX_PATH;
6788 lstrcpyA(path, "kiwi");
6789 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6791 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6792 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6794 /* try SubDir2 after CostFinalize */
6795 size = MAX_PATH;
6796 lstrcpyA(path, "kiwi");
6797 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6799 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6800 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6802 MsiCloseHandle(hpkg);
6803 DeleteFileA(msifile);
6806 static void test_shortlongsource(void)
6808 MSIHANDLE hdb, hpkg;
6809 CHAR path[MAX_PATH];
6810 CHAR cwd[MAX_PATH];
6811 CHAR subsrc[MAX_PATH];
6812 DWORD size;
6813 UINT r;
6815 lstrcpyA(cwd, CURR_DIR);
6816 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6818 lstrcpyA(subsrc, cwd);
6819 lstrcatA(subsrc, "long");
6820 lstrcatA(subsrc, "\\");
6822 /* long file names */
6824 hdb = create_package_db();
6825 ok( hdb, "failed to create database\n");
6827 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6829 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6830 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6832 /* CostInitialize:short */
6833 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6835 /* CostInitialize:long */
6836 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6838 /* FileCost:short */
6839 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6841 /* FileCost:long */
6842 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6844 /* CostFinalize:short */
6845 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6847 /* CostFinalize:long */
6848 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6850 r = MsiDatabaseCommit(hdb);
6851 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6853 r = package_from_db(hdb, &hpkg);
6854 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6856 skip("Not enough rights to perform tests\n");
6857 DeleteFileA(msifile);
6858 return;
6860 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6862 MsiCloseHandle(hdb);
6864 CreateDirectoryA("one", NULL);
6865 CreateDirectoryA("four", NULL);
6867 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6869 r = MsiDoActionA(hpkg, "CostInitialize");
6870 ok(r == ERROR_SUCCESS, "file cost failed\n");
6872 CreateDirectoryA("five", NULL);
6873 CreateDirectoryA("eight", NULL);
6875 r = MsiDoActionA(hpkg, "FileCost");
6876 ok(r == ERROR_SUCCESS, "file cost failed\n");
6878 CreateDirectoryA("nine", NULL);
6879 CreateDirectoryA("twelve", NULL);
6881 r = MsiDoActionA(hpkg, "CostFinalize");
6882 ok(r == ERROR_SUCCESS, "file cost failed\n");
6884 /* neither short nor long source directories exist */
6885 size = MAX_PATH;
6886 lstrcpyA(path, "kiwi");
6887 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6889 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6890 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6892 CreateDirectoryA("short", NULL);
6894 /* short source directory exists */
6895 size = MAX_PATH;
6896 lstrcpyA(path, "kiwi");
6897 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6899 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6900 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6902 CreateDirectoryA("long", NULL);
6904 /* both short and long source directories exist */
6905 size = MAX_PATH;
6906 lstrcpyA(path, "kiwi");
6907 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6909 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6910 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6912 lstrcpyA(subsrc, cwd);
6913 lstrcatA(subsrc, "two");
6914 lstrcatA(subsrc, "\\");
6916 /* short dir exists before CostInitialize */
6917 size = MAX_PATH;
6918 lstrcpyA(path, "kiwi");
6919 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6921 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6922 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6924 lstrcpyA(subsrc, cwd);
6925 lstrcatA(subsrc, "four");
6926 lstrcatA(subsrc, "\\");
6928 /* long dir exists before CostInitialize */
6929 size = MAX_PATH;
6930 lstrcpyA(path, "kiwi");
6931 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
6932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6933 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6934 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6936 lstrcpyA(subsrc, cwd);
6937 lstrcatA(subsrc, "six");
6938 lstrcatA(subsrc, "\\");
6940 /* short dir exists before FileCost */
6941 size = MAX_PATH;
6942 lstrcpyA(path, "kiwi");
6943 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
6944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6946 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6948 lstrcpyA(subsrc, cwd);
6949 lstrcatA(subsrc, "eight");
6950 lstrcatA(subsrc, "\\");
6952 /* long dir exists before FileCost */
6953 size = MAX_PATH;
6954 lstrcpyA(path, "kiwi");
6955 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
6956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6957 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6958 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6960 lstrcpyA(subsrc, cwd);
6961 lstrcatA(subsrc, "ten");
6962 lstrcatA(subsrc, "\\");
6964 /* short dir exists before CostFinalize */
6965 size = MAX_PATH;
6966 lstrcpyA(path, "kiwi");
6967 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
6968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6969 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6970 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6972 lstrcpyA(subsrc, cwd);
6973 lstrcatA(subsrc, "twelve");
6974 lstrcatA(subsrc, "\\");
6976 /* long dir exists before CostFinalize */
6977 size = MAX_PATH;
6978 lstrcpyA(path, "kiwi");
6979 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
6980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6981 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6982 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6984 MsiCloseHandle(hpkg);
6985 RemoveDirectoryA("short");
6986 RemoveDirectoryA("long");
6987 RemoveDirectoryA("one");
6988 RemoveDirectoryA("four");
6989 RemoveDirectoryA("five");
6990 RemoveDirectoryA("eight");
6991 RemoveDirectoryA("nine");
6992 RemoveDirectoryA("twelve");
6994 /* short file names */
6996 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6999 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7001 r = package_from_db(hdb, &hpkg);
7002 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7004 MsiCloseHandle(hdb);
7006 CreateDirectoryA("one", NULL);
7007 CreateDirectoryA("four", NULL);
7009 r = MsiDoActionA(hpkg, "CostInitialize");
7010 ok(r == ERROR_SUCCESS, "file cost failed\n");
7012 CreateDirectoryA("five", NULL);
7013 CreateDirectoryA("eight", NULL);
7015 r = MsiDoActionA(hpkg, "FileCost");
7016 ok(r == ERROR_SUCCESS, "file cost failed\n");
7018 CreateDirectoryA("nine", NULL);
7019 CreateDirectoryA("twelve", NULL);
7021 r = MsiDoActionA(hpkg, "CostFinalize");
7022 ok(r == ERROR_SUCCESS, "file cost failed\n");
7024 lstrcpyA(subsrc, cwd);
7025 lstrcatA(subsrc, "short");
7026 lstrcatA(subsrc, "\\");
7028 /* neither short nor long source directories exist */
7029 size = MAX_PATH;
7030 lstrcpyA(path, "kiwi");
7031 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7033 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7034 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7036 CreateDirectoryA("short", NULL);
7038 /* short source directory exists */
7039 size = MAX_PATH;
7040 lstrcpyA(path, "kiwi");
7041 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7043 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7044 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7046 CreateDirectoryA("long", NULL);
7048 /* both short and long source directories exist */
7049 size = MAX_PATH;
7050 lstrcpyA(path, "kiwi");
7051 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7053 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7054 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7056 lstrcpyA(subsrc, cwd);
7057 lstrcatA(subsrc, "one");
7058 lstrcatA(subsrc, "\\");
7060 /* short dir exists before CostInitialize */
7061 size = MAX_PATH;
7062 lstrcpyA(path, "kiwi");
7063 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7065 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7066 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7068 lstrcpyA(subsrc, cwd);
7069 lstrcatA(subsrc, "three");
7070 lstrcatA(subsrc, "\\");
7072 /* long dir exists before CostInitialize */
7073 size = MAX_PATH;
7074 lstrcpyA(path, "kiwi");
7075 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7077 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7078 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7080 lstrcpyA(subsrc, cwd);
7081 lstrcatA(subsrc, "five");
7082 lstrcatA(subsrc, "\\");
7084 /* short dir exists before FileCost */
7085 size = MAX_PATH;
7086 lstrcpyA(path, "kiwi");
7087 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7089 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7090 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7092 lstrcpyA(subsrc, cwd);
7093 lstrcatA(subsrc, "seven");
7094 lstrcatA(subsrc, "\\");
7096 /* long dir exists before FileCost */
7097 size = MAX_PATH;
7098 lstrcpyA(path, "kiwi");
7099 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7101 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7102 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7104 lstrcpyA(subsrc, cwd);
7105 lstrcatA(subsrc, "nine");
7106 lstrcatA(subsrc, "\\");
7108 /* short dir exists before CostFinalize */
7109 size = MAX_PATH;
7110 lstrcpyA(path, "kiwi");
7111 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7113 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7114 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7116 lstrcpyA(subsrc, cwd);
7117 lstrcatA(subsrc, "eleven");
7118 lstrcatA(subsrc, "\\");
7120 /* long dir exists before CostFinalize */
7121 size = MAX_PATH;
7122 lstrcpyA(path, "kiwi");
7123 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7125 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7126 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7128 MsiCloseHandle(hpkg);
7129 RemoveDirectoryA("short");
7130 RemoveDirectoryA("long");
7131 RemoveDirectoryA("one");
7132 RemoveDirectoryA("four");
7133 RemoveDirectoryA("five");
7134 RemoveDirectoryA("eight");
7135 RemoveDirectoryA("nine");
7136 RemoveDirectoryA("twelve");
7137 DeleteFileA(msifile);
7140 static void test_sourcedir(void)
7142 MSIHANDLE hdb, hpkg;
7143 CHAR package[12];
7144 CHAR path[MAX_PATH];
7145 CHAR cwd[MAX_PATH];
7146 CHAR subsrc[MAX_PATH];
7147 DWORD size;
7148 UINT r;
7150 lstrcpyA(cwd, CURR_DIR);
7151 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7153 lstrcpyA(subsrc, cwd);
7154 lstrcatA(subsrc, "long");
7155 lstrcatA(subsrc, "\\");
7157 hdb = create_package_db();
7158 ok( hdb, "failed to create database\n");
7160 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7162 sprintf(package, "#%lu", hdb);
7163 r = MsiOpenPackageA(package, &hpkg);
7164 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7166 skip("Not enough rights to perform tests\n");
7167 goto error;
7169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7171 /* properties only */
7173 /* SourceDir prop */
7174 size = MAX_PATH;
7175 lstrcpyA(path, "kiwi");
7176 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7177 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7178 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7179 ok(size == 0, "Expected 0, got %lu\n", size);
7181 /* SOURCEDIR prop */
7182 size = MAX_PATH;
7183 lstrcpyA(path, "kiwi");
7184 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7186 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7187 ok(size == 0, "Expected 0, got %lu\n", size);
7189 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7191 r = MsiDoActionA(hpkg, "CostInitialize");
7192 ok(r == ERROR_SUCCESS, "file cost failed\n");
7194 /* SourceDir after CostInitialize */
7195 size = MAX_PATH;
7196 lstrcpyA(path, "kiwi");
7197 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7199 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7200 ok(size == 0, "Expected 0, got %lu\n", size);
7202 /* SOURCEDIR after CostInitialize */
7203 size = MAX_PATH;
7204 lstrcpyA(path, "kiwi");
7205 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7207 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7208 ok(size == 0, "Expected 0, got %lu\n", size);
7210 r = MsiDoActionA(hpkg, "FileCost");
7211 ok(r == ERROR_SUCCESS, "file cost failed\n");
7213 /* SourceDir after FileCost */
7214 size = MAX_PATH;
7215 lstrcpyA(path, "kiwi");
7216 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7218 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7219 ok(size == 0, "Expected 0, got %lu\n", size);
7221 /* SOURCEDIR after FileCost */
7222 size = MAX_PATH;
7223 lstrcpyA(path, "kiwi");
7224 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7226 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7227 ok(size == 0, "Expected 0, got %lu\n", size);
7229 r = MsiDoActionA(hpkg, "CostFinalize");
7230 ok(r == ERROR_SUCCESS, "file cost failed\n");
7232 /* SourceDir after CostFinalize */
7233 size = MAX_PATH;
7234 lstrcpyA(path, "kiwi");
7235 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7237 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7238 ok(size == 0, "Expected 0, got %lu\n", size);
7240 /* SOURCEDIR after CostFinalize */
7241 size = MAX_PATH;
7242 lstrcpyA(path, "kiwi");
7243 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7245 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7246 ok(size == 0, "Expected 0, got %lu\n", size);
7248 size = MAX_PATH;
7249 lstrcpyA(path, "kiwi");
7250 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7251 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7252 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7253 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
7255 /* SOURCEDIR after calling MsiGetSourcePath */
7256 size = MAX_PATH;
7257 lstrcpyA(path, "kiwi");
7258 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7260 todo_wine {
7261 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7262 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7265 r = MsiDoActionA(hpkg, "ResolveSource");
7266 ok(r == ERROR_SUCCESS, "file cost failed\n");
7268 /* SourceDir after ResolveSource */
7269 size = MAX_PATH;
7270 lstrcpyA(path, "kiwi");
7271 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7273 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7274 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7276 /* SOURCEDIR after ResolveSource */
7277 size = MAX_PATH;
7278 lstrcpyA(path, "kiwi");
7279 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7281 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7282 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7284 /* random casing */
7285 size = MAX_PATH;
7286 lstrcpyA(path, "kiwi");
7287 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7289 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7290 ok(size == 0, "Expected 0, got %lu\n", size);
7292 MsiCloseHandle(hpkg);
7294 /* reset the package state */
7295 sprintf(package, "#%lu", hdb);
7296 r = MsiOpenPackageA(package, &hpkg);
7297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7299 /* test how MsiGetSourcePath affects the properties */
7301 /* SourceDir prop */
7302 size = MAX_PATH;
7303 lstrcpyA(path, "kiwi");
7304 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7306 todo_wine
7308 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7309 ok(size == 0, "Expected 0, got %lu\n", size);
7312 size = MAX_PATH;
7313 lstrcpyA(path, "kiwi");
7314 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7315 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7316 ok(!lstrcmpA(path, "kiwi"),
7317 "Expected path to be unchanged, got \"%s\"\n", path);
7318 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7320 /* SourceDir after MsiGetSourcePath */
7321 size = MAX_PATH;
7322 lstrcpyA(path, "kiwi");
7323 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7325 todo_wine
7327 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7328 ok(size == 0, "Expected 0, got %lu\n", size);
7331 /* SOURCEDIR prop */
7332 size = MAX_PATH;
7333 lstrcpyA(path, "kiwi");
7334 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7336 todo_wine
7338 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7339 ok(size == 0, "Expected 0, got %lu\n", size);
7342 size = MAX_PATH;
7343 lstrcpyA(path, "kiwi");
7344 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7345 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7346 ok(!lstrcmpA(path, "kiwi"),
7347 "Expected path to be unchanged, got \"%s\"\n", path);
7348 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7350 /* SOURCEDIR prop after MsiGetSourcePath */
7351 size = MAX_PATH;
7352 lstrcpyA(path, "kiwi");
7353 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7355 todo_wine
7357 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7358 ok(size == 0, "Expected 0, got %lu\n", size);
7361 r = MsiDoActionA(hpkg, "CostInitialize");
7362 ok(r == ERROR_SUCCESS, "file cost failed\n");
7364 /* SourceDir after CostInitialize */
7365 size = MAX_PATH;
7366 lstrcpyA(path, "kiwi");
7367 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7369 todo_wine
7371 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7372 ok(size == 0, "Expected 0, got %lu\n", size);
7375 size = MAX_PATH;
7376 lstrcpyA(path, "kiwi");
7377 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7379 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7380 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7382 /* SourceDir after MsiGetSourcePath */
7383 size = MAX_PATH;
7384 lstrcpyA(path, "kiwi");
7385 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7387 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7388 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7390 /* SOURCEDIR after CostInitialize */
7391 size = MAX_PATH;
7392 lstrcpyA(path, "kiwi");
7393 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7395 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7396 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7398 /* SOURCEDIR source path still does not exist */
7399 size = MAX_PATH;
7400 lstrcpyA(path, "kiwi");
7401 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7402 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7403 ok(!lstrcmpA(path, "kiwi"),
7404 "Expected path to be unchanged, got \"%s\"\n", path);
7405 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7407 r = MsiDoActionA(hpkg, "FileCost");
7408 ok(r == ERROR_SUCCESS, "file cost failed\n");
7410 /* SourceDir after FileCost */
7411 size = MAX_PATH;
7412 lstrcpyA(path, "kiwi");
7413 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7415 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7416 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7418 /* SOURCEDIR after FileCost */
7419 size = MAX_PATH;
7420 lstrcpyA(path, "kiwi");
7421 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7423 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7424 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7426 /* SOURCEDIR source path still does not exist */
7427 size = MAX_PATH;
7428 lstrcpyA(path, "kiwi");
7429 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7430 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7431 ok(!lstrcmpA(path, "kiwi"),
7432 "Expected path to be unchanged, got \"%s\"\n", path);
7433 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7435 r = MsiDoActionA(hpkg, "CostFinalize");
7436 ok(r == ERROR_SUCCESS, "file cost failed\n");
7438 /* SourceDir after CostFinalize */
7439 size = MAX_PATH;
7440 lstrcpyA(path, "kiwi");
7441 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7443 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7444 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7446 /* SOURCEDIR after CostFinalize */
7447 size = MAX_PATH;
7448 lstrcpyA(path, "kiwi");
7449 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7451 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7452 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7454 /* SOURCEDIR source path still does not exist */
7455 size = MAX_PATH;
7456 lstrcpyA(path, "kiwi");
7457 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7458 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7459 ok(!lstrcmpA(path, "kiwi"),
7460 "Expected path to be unchanged, got \"%s\"\n", path);
7461 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7463 r = MsiDoActionA(hpkg, "ResolveSource");
7464 ok(r == ERROR_SUCCESS, "file cost failed\n");
7466 /* SourceDir after ResolveSource */
7467 size = MAX_PATH;
7468 lstrcpyA(path, "kiwi");
7469 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7471 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7472 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7474 /* SOURCEDIR after ResolveSource */
7475 size = MAX_PATH;
7476 lstrcpyA(path, "kiwi");
7477 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7479 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7480 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7482 /* SOURCEDIR source path still does not exist */
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 %lu\n", size);
7491 MsiCloseHandle(hpkg);
7493 error:
7494 MsiCloseHandle(hdb);
7495 DeleteFileA(msifile);
7498 struct access_res
7500 BOOL gothandle;
7501 DWORD lasterr;
7502 BOOL ignore;
7505 static const struct access_res create[16] =
7507 { TRUE, ERROR_SUCCESS, TRUE },
7508 { TRUE, ERROR_SUCCESS, TRUE },
7509 { TRUE, ERROR_SUCCESS, FALSE },
7510 { TRUE, ERROR_SUCCESS, FALSE },
7511 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7512 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7513 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7514 { TRUE, ERROR_SUCCESS, FALSE },
7515 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7516 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7517 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7518 { TRUE, ERROR_SUCCESS, TRUE },
7519 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7520 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7521 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7522 { TRUE, ERROR_SUCCESS, TRUE }
7525 static const struct access_res create_commit[16] =
7527 { TRUE, ERROR_SUCCESS, TRUE },
7528 { TRUE, ERROR_SUCCESS, TRUE },
7529 { TRUE, ERROR_SUCCESS, FALSE },
7530 { TRUE, ERROR_SUCCESS, FALSE },
7531 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7532 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7533 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7534 { TRUE, ERROR_SUCCESS, FALSE },
7535 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7536 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7537 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7538 { TRUE, ERROR_SUCCESS, TRUE },
7539 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7540 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7541 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7542 { TRUE, ERROR_SUCCESS, TRUE }
7545 static const struct access_res create_close[16] =
7547 { TRUE, ERROR_SUCCESS, FALSE },
7548 { TRUE, ERROR_SUCCESS, FALSE },
7549 { TRUE, ERROR_SUCCESS, FALSE },
7550 { TRUE, ERROR_SUCCESS, FALSE },
7551 { TRUE, ERROR_SUCCESS, FALSE },
7552 { TRUE, ERROR_SUCCESS, FALSE },
7553 { TRUE, ERROR_SUCCESS, FALSE },
7554 { TRUE, ERROR_SUCCESS, FALSE },
7555 { TRUE, ERROR_SUCCESS, FALSE },
7556 { TRUE, ERROR_SUCCESS, FALSE },
7557 { TRUE, ERROR_SUCCESS, FALSE },
7558 { TRUE, ERROR_SUCCESS, FALSE },
7559 { TRUE, ERROR_SUCCESS, FALSE },
7560 { TRUE, ERROR_SUCCESS, FALSE },
7561 { TRUE, ERROR_SUCCESS, FALSE },
7562 { TRUE, ERROR_SUCCESS }
7565 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7567 DWORD access = 0, share = 0;
7568 DWORD lasterr;
7569 HANDLE hfile;
7570 int i, j, idx = 0;
7572 for (i = 0; i < 4; i++)
7574 if (i == 0) access = 0;
7575 if (i == 1) access = GENERIC_READ;
7576 if (i == 2) access = GENERIC_WRITE;
7577 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7579 for (j = 0; j < 4; j++)
7581 if (ares[idx].ignore)
7582 continue;
7584 if (j == 0) share = 0;
7585 if (j == 1) share = FILE_SHARE_READ;
7586 if (j == 2) share = FILE_SHARE_WRITE;
7587 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7589 SetLastError(0xdeadbeef);
7590 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7591 FILE_ATTRIBUTE_NORMAL, 0);
7592 lasterr = GetLastError();
7594 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7595 "(%lu, handle, %d): Expected %d, got %d\n",
7596 line, idx, ares[idx].gothandle,
7597 (hfile != INVALID_HANDLE_VALUE));
7599 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n",
7600 line, idx, ares[idx].lasterr, lasterr);
7602 CloseHandle(hfile);
7603 idx++;
7608 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7610 static void test_access(void)
7612 MSIHANDLE hdb;
7613 UINT r;
7615 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7618 test_file_access(msifile, create);
7620 r = MsiDatabaseCommit(hdb);
7621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7623 test_file_access(msifile, create_commit);
7624 MsiCloseHandle(hdb);
7626 test_file_access(msifile, create_close);
7627 DeleteFileA(msifile);
7629 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
7630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7632 test_file_access(msifile, create);
7634 r = MsiDatabaseCommit(hdb);
7635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7637 test_file_access(msifile, create_commit);
7638 MsiCloseHandle(hdb);
7640 test_file_access(msifile, create_close);
7641 DeleteFileA(msifile);
7644 static void test_emptypackage(void)
7646 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7647 MSIHANDLE hview = 0, hrec = 0;
7648 MSICONDITION condition;
7649 CHAR buffer[MAX_PATH];
7650 DWORD size;
7651 UINT r;
7653 r = MsiOpenPackageA("", &hpkg);
7654 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7656 skip("Not enough rights to perform tests\n");
7657 return;
7659 todo_wine
7661 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7664 hdb = MsiGetActiveDatabase(hpkg);
7665 todo_wine
7667 ok(hdb != 0, "Expected a valid database handle\n");
7670 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7671 todo_wine
7673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7675 r = MsiViewExecute(hview, 0);
7676 todo_wine
7678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7681 r = MsiViewFetch(hview, &hrec);
7682 todo_wine
7684 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7687 buffer[0] = 0;
7688 size = MAX_PATH;
7689 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7690 todo_wine
7692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7693 ok(!lstrcmpA(buffer, "_Property"),
7694 "Expected \"_Property\", got \"%s\"\n", buffer);
7697 MsiCloseHandle(hrec);
7699 r = MsiViewFetch(hview, &hrec);
7700 todo_wine
7702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7705 size = MAX_PATH;
7706 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7707 todo_wine
7709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7710 ok(!lstrcmpA(buffer, "#_FolderCache"),
7711 "Expected \"_Property\", got \"%s\"\n", buffer);
7714 MsiCloseHandle(hrec);
7715 MsiViewClose(hview);
7716 MsiCloseHandle(hview);
7718 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7719 todo_wine
7721 ok(condition == MSICONDITION_FALSE,
7722 "Expected MSICONDITION_FALSE, got %d\n", condition);
7725 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7726 todo_wine
7728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7730 r = MsiViewExecute(hview, 0);
7731 todo_wine
7733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7736 /* _Property table is not empty */
7737 r = MsiViewFetch(hview, &hrec);
7738 todo_wine
7740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7743 MsiCloseHandle(hrec);
7744 MsiViewClose(hview);
7745 MsiCloseHandle(hview);
7747 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7748 todo_wine
7750 ok(condition == MSICONDITION_FALSE,
7751 "Expected MSICONDITION_FALSE, got %d\n", condition);
7754 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7755 todo_wine
7757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7759 r = MsiViewExecute(hview, 0);
7760 todo_wine
7762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7765 /* #_FolderCache is not empty */
7766 r = MsiViewFetch(hview, &hrec);
7767 todo_wine
7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7772 MsiCloseHandle(hrec);
7773 MsiViewClose(hview);
7774 MsiCloseHandle(hview);
7776 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7777 todo_wine
7779 ok(r == ERROR_BAD_QUERY_SYNTAX,
7780 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7783 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7784 todo_wine
7786 ok(r == ERROR_BAD_QUERY_SYNTAX,
7787 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7790 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7791 todo_wine
7793 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
7794 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7797 MsiCloseHandle(hsuminfo);
7799 r = MsiDatabaseCommit(hdb);
7800 todo_wine
7802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7805 MsiCloseHandle(hdb);
7806 MsiCloseHandle(hpkg);
7809 static void test_MsiGetProductProperty(void)
7811 WCHAR valW[MAX_PATH];
7812 MSIHANDLE hprod, hdb;
7813 CHAR val[MAX_PATH];
7814 CHAR path[MAX_PATH];
7815 CHAR query[MAX_PATH + 17];
7816 CHAR keypath[MAX_PATH*2];
7817 CHAR prodcode[MAX_PATH];
7818 WCHAR prodcodeW[MAX_PATH];
7819 CHAR prod_squashed[MAX_PATH];
7820 WCHAR prod_squashedW[MAX_PATH];
7821 HKEY prodkey, userkey, props;
7822 DWORD size;
7823 LONG res;
7824 UINT r;
7825 REGSAM access = KEY_ALL_ACCESS;
7827 GetCurrentDirectoryA(MAX_PATH, path);
7828 lstrcatA(path, "\\");
7830 create_test_guid(prodcode, prod_squashed);
7831 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7832 squash_guid(prodcodeW, prod_squashedW);
7834 if (is_wow64)
7835 access |= KEY_WOW64_64KEY;
7837 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7840 r = MsiDatabaseCommit(hdb);
7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7843 r = set_summary_info(hdb);
7844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7846 r = run_query(hdb, 0,
7847 "CREATE TABLE `Directory` ( "
7848 "`Directory` CHAR(255) NOT NULL, "
7849 "`Directory_Parent` CHAR(255), "
7850 "`DefaultDir` CHAR(255) NOT NULL "
7851 "PRIMARY KEY `Directory`)");
7852 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7854 create_property_table(hdb);
7856 sprintf(query, "'ProductCode', '%s'", prodcode);
7857 r = add_property_entry(hdb, query);
7859 r = MsiDatabaseCommit(hdb);
7860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7862 MsiCloseHandle(hdb);
7864 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7865 lstrcatA(keypath, prod_squashed);
7867 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7868 if (res == ERROR_ACCESS_DENIED)
7870 skip("Not enough rights to perform tests\n");
7871 DeleteFileA(msifile);
7872 return;
7874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7876 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7877 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7878 lstrcatA(keypath, prod_squashed);
7880 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7881 if (res == ERROR_ACCESS_DENIED)
7883 skip("Not enough rights to perform tests\n");
7884 RegDeleteKeyA(prodkey, "");
7885 RegCloseKey(prodkey);
7886 DeleteFileA(msifile);
7887 return;
7889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7891 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7894 lstrcpyA(val, path);
7895 lstrcatA(val, "\\");
7896 lstrcatA(val, msifile);
7897 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1);
7898 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7900 hprod = 0xdeadbeef;
7901 r = MsiOpenProductA(prodcode, &hprod);
7902 if (r == ERROR_UNKNOWN_PRODUCT)
7904 win_skip("broken result, skipping tests\n");
7905 goto done;
7907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7908 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7910 /* hProduct is invalid */
7911 size = MAX_PATH;
7912 lstrcpyA(val, "apple");
7913 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
7914 ok(r == ERROR_INVALID_HANDLE,
7915 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7916 ok(!lstrcmpA(val, "apple"),
7917 "Expected val to be unchanged, got \"%s\"\n", val);
7918 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7920 size = MAX_PATH;
7921 lstrcpyW(valW, L"apple");
7922 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
7923 ok(r == ERROR_INVALID_HANDLE,
7924 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7925 ok(!lstrcmpW(valW, L"apple"),
7926 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
7927 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7929 /* szProperty is NULL */
7930 size = MAX_PATH;
7931 lstrcpyA(val, "apple");
7932 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
7933 ok(r == ERROR_INVALID_PARAMETER,
7934 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7935 ok(!lstrcmpA(val, "apple"),
7936 "Expected val to be unchanged, got \"%s\"\n", val);
7937 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7939 size = MAX_PATH;
7940 lstrcpyW(valW, L"apple");
7941 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
7942 ok(r == ERROR_INVALID_PARAMETER,
7943 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7944 ok(!lstrcmpW(valW, L"apple"),
7945 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
7946 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7948 /* szProperty is empty */
7949 size = MAX_PATH;
7950 lstrcpyA(val, "apple");
7951 r = MsiGetProductPropertyA(hprod, "", val, &size);
7952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7953 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
7954 ok(size == 0, "Expected 0, got %lu\n", size);
7956 size = MAX_PATH;
7957 lstrcpyW(valW, L"apple");
7958 r = MsiGetProductPropertyW(hprod, L"", valW, &size);
7959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7960 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
7961 ok(size == 0, "Expected 0, got %lu\n", size);
7963 /* get the property */
7964 size = MAX_PATH;
7965 lstrcpyA(val, "apple");
7966 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
7967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7968 ok(!lstrcmpA(val, prodcode),
7969 "Expected \"%s\", got \"%s\"\n", prodcode, val);
7970 ok(size == lstrlenA(prodcode),
7971 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
7973 size = MAX_PATH;
7974 lstrcpyW(valW, L"apple");
7975 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
7976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7977 ok(!lstrcmpW(valW, prodcodeW),
7978 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
7979 ok(size == lstrlenW(prodcodeW),
7980 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
7982 /* lpValueBuf is NULL */
7983 size = MAX_PATH;
7984 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7986 ok(size == lstrlenA(prodcode),
7987 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
7989 size = MAX_PATH;
7990 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7992 ok(size == lstrlenW(prodcodeW),
7993 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
7995 /* pcchValueBuf is NULL */
7996 lstrcpyA(val, "apple");
7997 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
7998 ok(r == ERROR_INVALID_PARAMETER,
7999 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8000 ok(!lstrcmpA(val, "apple"),
8001 "Expected val to be unchanged, got \"%s\"\n", val);
8002 ok(size == lstrlenA(prodcode),
8003 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8005 lstrcpyW(valW, L"apple");
8006 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8007 ok(r == ERROR_INVALID_PARAMETER,
8008 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8009 ok(!lstrcmpW(valW, L"apple"),
8010 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8011 ok(size == lstrlenW(prodcodeW),
8012 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8014 /* pcchValueBuf is too small */
8015 size = 4;
8016 lstrcpyA(val, "apple");
8017 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8018 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8019 ok(!strncmp(val, prodcode, 3),
8020 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8021 ok(size == lstrlenA(prodcode),
8022 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8024 size = 4;
8025 lstrcpyW(valW, L"apple");
8026 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8027 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8028 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8029 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8030 ok(size == lstrlenW(prodcodeW),
8031 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8033 /* pcchValueBuf does not leave room for NULL terminator */
8034 size = lstrlenA(prodcode);
8035 lstrcpyA(val, "apple");
8036 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8037 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8038 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8039 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8040 ok(size == lstrlenA(prodcode),
8041 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8043 size = lstrlenW(prodcodeW);
8044 lstrcpyW(valW, L"apple");
8045 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8046 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8047 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8048 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8049 ok(size == lstrlenW(prodcodeW),
8050 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8052 /* pcchValueBuf has enough room for NULL terminator */
8053 size = lstrlenA(prodcode) + 1;
8054 lstrcpyA(val, "apple");
8055 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8057 ok(!lstrcmpA(val, prodcode),
8058 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8059 ok(size == lstrlenA(prodcode),
8060 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8062 size = lstrlenW(prodcodeW) + 1;
8063 lstrcpyW(valW, L"apple");
8064 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8066 ok(!lstrcmpW(valW, prodcodeW),
8067 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8068 ok(size == lstrlenW(prodcodeW),
8069 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8071 /* nonexistent property */
8072 size = MAX_PATH;
8073 lstrcpyA(val, "apple");
8074 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8076 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8077 ok(size == 0, "Expected 0, got %lu\n", size);
8079 size = MAX_PATH;
8080 lstrcpyW(valW, L"apple");
8081 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8083 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8084 ok(size == 0, "Expected 0, got %lu\n", size);
8086 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8089 /* non-product property set */
8090 size = MAX_PATH;
8091 lstrcpyA(val, "apple");
8092 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8095 ok(size == 0, "Expected 0, got %lu\n", size);
8097 size = MAX_PATH;
8098 lstrcpyW(valW, L"apple");
8099 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8101 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8102 ok(size == 0, "Expected 0, got %lu\n", size);
8104 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8107 /* non-product property that is also a product property set */
8108 size = MAX_PATH;
8109 lstrcpyA(val, "apple");
8110 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8112 ok(!lstrcmpA(val, prodcode),
8113 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8114 ok(size == lstrlenA(prodcode),
8115 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8117 size = MAX_PATH;
8118 lstrcpyW(valW, L"apple");
8119 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8121 ok(!lstrcmpW(valW, prodcodeW),
8122 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8123 ok(size == lstrlenW(prodcodeW),
8124 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8126 MsiCloseHandle(hprod);
8127 done:
8128 RegDeleteValueA(props, "LocalPackage");
8129 RegDeleteKeyExA(props, "", access, 0);
8130 RegCloseKey(props);
8131 RegDeleteKeyExA(userkey, "", access, 0);
8132 RegCloseKey(userkey);
8133 RegDeleteKeyExA(prodkey, "", access, 0);
8134 RegCloseKey(prodkey);
8135 DeleteFileA(msifile);
8138 static void test_MsiSetProperty(void)
8140 MSIHANDLE hpkg, hdb, hrec;
8141 CHAR buf[MAX_PATH];
8142 LPCSTR query;
8143 DWORD size;
8144 UINT r;
8146 r = package_from_db(create_package_db(), &hpkg);
8147 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8149 skip("Not enough rights to perform tests\n");
8150 DeleteFileA(msifile);
8151 return;
8153 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8155 /* invalid hInstall */
8156 r = MsiSetPropertyA(0, "Prop", "Val");
8157 ok(r == ERROR_INVALID_HANDLE,
8158 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8160 /* invalid hInstall */
8161 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8162 ok(r == ERROR_INVALID_HANDLE,
8163 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8165 /* szName is NULL */
8166 r = MsiSetPropertyA(hpkg, NULL, "Val");
8167 ok(r == ERROR_INVALID_PARAMETER,
8168 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8170 /* both szName and szValue are NULL */
8171 r = MsiSetPropertyA(hpkg, NULL, NULL);
8172 ok(r == ERROR_INVALID_PARAMETER,
8173 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8175 /* szName is empty */
8176 r = MsiSetPropertyA(hpkg, "", "Val");
8177 ok(r == ERROR_FUNCTION_FAILED,
8178 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8180 /* szName is empty and szValue is NULL */
8181 r = MsiSetPropertyA(hpkg, "", NULL);
8182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8184 /* set a property */
8185 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8188 /* get the property */
8189 size = MAX_PATH;
8190 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8192 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8193 ok(size == 3, "Expected 3, got %lu\n", size);
8195 /* update the property */
8196 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8199 /* get the property */
8200 size = MAX_PATH;
8201 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8203 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8204 ok(size == 4, "Expected 4, got %lu\n", size);
8206 hdb = MsiGetActiveDatabase(hpkg);
8207 ok(hdb != 0, "Expected a valid database handle\n");
8209 /* set prop is not in the _Property table */
8210 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8211 r = do_query(hdb, query, &hrec);
8212 ok(r == ERROR_BAD_QUERY_SYNTAX,
8213 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8215 /* set prop is not in the Property table */
8216 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8217 r = do_query(hdb, query, &hrec);
8218 ok(r == ERROR_BAD_QUERY_SYNTAX,
8219 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8221 MsiCloseHandle(hdb);
8223 /* szValue is an empty string */
8224 r = MsiSetPropertyA(hpkg, "Prop", "");
8225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8227 /* try to get the property */
8228 size = MAX_PATH;
8229 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8231 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8232 ok(size == 0, "Expected 0, got %lu\n", size);
8234 /* reset the property */
8235 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8238 /* delete the property */
8239 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8242 /* try to get the property */
8243 size = MAX_PATH;
8244 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8246 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8247 ok(size == 0, "Expected 0, got %lu\n", size);
8249 MsiCloseHandle(hpkg);
8250 DeleteFileA(msifile);
8253 static void test_MsiApplyMultiplePatches(void)
8255 UINT r, type = GetDriveTypeW(NULL);
8257 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
8258 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8260 r = MsiApplyMultiplePatchesA("", NULL, NULL);
8261 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8263 r = MsiApplyMultiplePatchesA(";", NULL, NULL);
8264 if (type == DRIVE_FIXED)
8265 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8266 else
8267 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8269 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL);
8270 if (type == DRIVE_FIXED)
8271 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8272 else
8273 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8275 r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
8276 if (type == DRIVE_FIXED)
8277 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8278 else
8279 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8281 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8282 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8284 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8285 if (type == DRIVE_FIXED)
8286 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8287 else
8288 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8290 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8291 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8293 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8294 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8297 static void test_MsiApplyPatch(void)
8299 UINT r;
8301 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8302 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8304 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL);
8305 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8308 static void test_costs(void)
8310 MSIHANDLE hdb, hpkg;
8311 char package[12], drive[3];
8312 DWORD len;
8313 UINT r;
8314 int cost, temp;
8316 hdb = create_package_db();
8317 ok( hdb, "failed to create database\n" );
8319 create_property_table( hdb );
8320 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8321 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8322 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8324 create_media_table( hdb );
8325 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8327 create_file_table( hdb );
8328 add_file_entry( hdb, "'a.txt', 'one', 'a.txt', 2048000000, '', '', 8192, 1" );
8329 add_file_entry( hdb, "'b.txt', 'one', 'b.txt', 2048000000, '', '', 8192, 1" );
8330 add_file_entry( hdb, "'c.txt', 'one', 'c.txt', 2048000000, '', '', 8192, 1" );
8331 add_file_entry( hdb, "'d.txt', 'one', 'd.txt', 4097, '', '', 8192, 1" );
8332 add_file_entry( hdb, "'e.txt', 'one', 'e.txt', 1, '', '', 8192, 1" );
8334 create_component_table( hdb );
8335 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'a.txt'" );
8336 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8338 create_feature_table( hdb );
8339 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8340 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8342 create_feature_components_table( hdb );
8343 add_feature_components_entry( hdb, "'one', 'one'" );
8344 add_feature_components_entry( hdb, "'two', 'two'" );
8346 create_install_execute_sequence_table( hdb );
8347 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8348 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8349 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8350 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8352 r = MsiDatabaseCommit( hdb );
8353 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8355 sprintf( package, "#%lu", hdb );
8356 r = MsiOpenPackageA( package, &hpkg );
8357 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8359 skip("Not enough rights to perform tests\n");
8360 goto error;
8362 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8364 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8365 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8367 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8368 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8370 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8371 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8373 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8374 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8376 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8377 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8379 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8380 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8382 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8383 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8385 len = sizeof(drive);
8386 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8387 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8389 len = sizeof(drive);
8390 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8391 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8393 len = sizeof(drive);
8394 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8395 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8397 len = sizeof(drive);
8398 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8399 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8401 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
8403 r = MsiDoActionA( hpkg, "CostInitialize" );
8404 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8406 r = MsiDoActionA( hpkg, "FileCost" );
8407 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8409 len = sizeof(drive);
8410 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8411 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8413 r = MsiDoActionA( hpkg, "CostFinalize" );
8414 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8416 /* contrary to what msdn says InstallValidate must be called too */
8417 len = sizeof(drive);
8418 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8419 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8421 r = MsiDoActionA( hpkg, "InstallValidate" );
8422 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8424 len = 0;
8425 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8426 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8428 len = 0;
8429 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8430 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8431 ok( len == 2, "expected len == 2, got %lu\n", len );
8433 len = 2;
8434 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8435 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8436 ok( len == 2, "expected len == 2, got %lu\n", len );
8438 len = 2;
8439 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8440 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8441 ok( len == 2, "expected len == 2, got %lu\n", len );
8443 /* install state doesn't seem to matter */
8444 len = sizeof(drive);
8445 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8446 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8448 len = sizeof(drive);
8449 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8450 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8452 len = sizeof(drive);
8453 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8454 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8456 len = sizeof(drive);
8457 drive[0] = 0;
8458 cost = temp = 0xdead;
8459 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8460 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8461 ok( len == 2, "expected len == 2, got %lu\n", len );
8462 ok( drive[0], "expected a drive\n" );
8463 ok( cost == 12000024, "got %d\n", cost );
8464 ok( !temp, "expected temp == 0, got %d\n", temp );
8466 len = sizeof(drive);
8467 drive[0] = 0;
8468 cost = temp = 0xdead;
8469 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8470 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8471 ok( len == 2, "expected len == 2, got %lu\n", len );
8472 ok( drive[0], "expected a drive\n" );
8473 ok( !cost, "expected cost == 0, got %d\n", cost );
8474 ok( !temp, "expected temp == 0, got %d\n", temp );
8476 len = sizeof(drive);
8477 drive[0] = 0;
8478 cost = temp = 0xdead;
8479 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8480 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8481 ok( len == 2, "expected len == 2, got %lu\n", len );
8482 ok( drive[0], "expected a drive\n" );
8483 ok( !cost, "expected cost == 0, got %d\n", cost );
8484 todo_wine ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8486 /* increased index */
8487 len = sizeof(drive);
8488 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8489 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8491 len = sizeof(drive);
8492 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8493 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8495 /* test MsiGetFeatureCost */
8496 cost = 0xdead;
8497 r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8498 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8499 ok( cost == 0xdead, "got %d\n", cost );
8501 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL );
8502 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8504 cost = 0xdead;
8505 r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8506 ok( !r, "got %u\n", r);
8507 ok( cost == 12000024, "got %d\n", cost );
8509 MsiCloseHandle( hpkg );
8510 error:
8511 MsiCloseHandle( hdb );
8512 DeleteFileA( msifile );
8515 static void test_MsiDatabaseCommit(void)
8517 UINT r;
8518 MSIHANDLE hdb, hpkg = 0;
8519 char buf[32], package[12];
8520 DWORD sz;
8522 hdb = create_package_db();
8523 ok( hdb, "failed to create database\n" );
8525 create_property_table( hdb );
8527 sprintf( package, "#%lu", hdb );
8528 r = MsiOpenPackageA( package, &hpkg );
8529 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8531 skip("Not enough rights to perform tests\n");
8532 goto error;
8534 ok( r == ERROR_SUCCESS, "got %u\n", r );
8536 r = MsiSetPropertyA( hpkg, "PROP", "value" );
8537 ok( r == ERROR_SUCCESS, "got %u\n", r );
8539 buf[0] = 0;
8540 sz = sizeof(buf);
8541 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8542 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8543 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8545 r = MsiDatabaseCommit( hdb );
8546 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8548 buf[0] = 0;
8549 sz = sizeof(buf);
8550 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8551 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8552 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8554 MsiCloseHandle( hpkg );
8555 error:
8556 MsiCloseHandle( hdb );
8557 DeleteFileA( msifile );
8560 static int externalui_ran;
8562 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
8564 externalui_ran = 1;
8565 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8566 return 0;
8569 static int externalui_record_ran;
8571 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
8573 INT retval = context ? *((INT *)context) : 0;
8574 UINT r;
8575 externalui_record_ran = 1;
8576 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8577 r = MsiRecordGetFieldCount(hrecord);
8578 ok(r == 1, "expected 1, got %u\n", r);
8579 r = MsiRecordGetInteger(hrecord, 1);
8580 ok(r == 12345, "expected 12345, got %u\n", r);
8581 return retval;
8584 static void test_externalui(void)
8586 /* test that external UI handlers work correctly */
8588 INSTALLUI_HANDLERA prev;
8589 INSTALLUI_HANDLER_RECORD prev_record;
8590 MSIHANDLE hpkg, hrecord;
8591 UINT r;
8592 INT retval = 0;
8594 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8596 r = package_from_db(create_package_db(), &hpkg);
8597 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8599 skip("Not enough rights to perform tests\n");
8600 DeleteFileA(msifile);
8601 return;
8603 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8605 hrecord = MsiCreateRecord(1);
8606 ok(hrecord, "Expected a valid record\n");
8607 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
8608 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
8609 r = MsiRecordSetInteger(hrecord, 1, 12345);
8610 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
8612 externalui_ran = 0;
8613 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8614 ok(r == 0, "expected 0, got %u\n", r);
8615 ok(externalui_ran == 1, "external UI callback did not run\n");
8617 prev = MsiSetExternalUIA(prev, 0, NULL);
8618 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
8619 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record);
8620 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8622 externalui_ran = externalui_record_ran = 0;
8623 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8624 ok(r == 0, "expected 0, got %u\n", r);
8625 ok(externalui_ran == 0, "external UI callback should not have run\n");
8626 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8628 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
8630 externalui_ran = externalui_record_ran = 0;
8631 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8632 ok(r == 0, "expected 0, got %u\n", r);
8633 ok(externalui_ran == 1, "external UI callback did not run\n");
8634 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8636 retval = 1;
8637 externalui_ran = externalui_record_ran = 0;
8638 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8639 ok(r == 1, "expected 1, got %u\n", r);
8640 ok(externalui_ran == 0, "external UI callback should not have run\n");
8641 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8643 /* filter and context should be kept separately */
8644 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record);
8645 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8647 externalui_ran = externalui_record_ran = 0;
8648 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8649 ok(r == 0, "expected 0, got %u\n", r);
8650 ok(externalui_ran == 1, "external UI callback did not run\n");
8651 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
8653 MsiCloseHandle(hpkg);
8654 DeleteFileA(msifile);
8657 struct externalui_message {
8658 UINT message;
8659 int field_count;
8660 char field[4][100];
8661 int match[4]; /* should we test for a match */
8662 int optional;
8665 static struct externalui_message *sequence;
8666 static int sequence_count, sequence_size;
8668 static void add_message(const struct externalui_message *msg)
8670 if (!sequence)
8672 sequence_size = 10;
8673 sequence = malloc(sequence_size * sizeof(*sequence));
8675 if (sequence_count == sequence_size)
8677 sequence_size *= 2;
8678 sequence = realloc(sequence, sequence_size * sizeof(*sequence));
8681 assert(sequence);
8682 sequence[sequence_count++] = *msg;
8685 static void flush_sequence(void)
8687 free(sequence);
8688 sequence = NULL;
8689 sequence_count = sequence_size = 0;
8692 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
8693 const char *file, int line)
8695 static const struct externalui_message end_of_sequence = {0};
8696 const struct externalui_message *actual;
8697 int failcount = 0;
8698 int i;
8700 add_message(&end_of_sequence);
8702 actual = sequence;
8704 while (expected->message && actual->message)
8706 if (expected->message == actual->message)
8708 if (expected->field_count < actual->field_count)
8710 todo_wine_if (todo)
8711 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
8712 context, expected->message, expected->field_count, actual->field_count);
8713 failcount++;
8716 for (i = 0; i <= actual->field_count; i++)
8718 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
8720 todo_wine_if (todo)
8721 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8722 context, expected->message, i, expected->field[i], actual->field[i]);
8723 failcount++;
8727 expected++;
8728 actual++;
8730 else if (expected->optional)
8732 expected++;
8734 else
8736 todo_wine_if (todo)
8737 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8738 context, expected->message, actual->message);
8739 failcount++;
8740 if (todo)
8741 goto done;
8742 expected++;
8743 actual++;
8747 if (expected->message || actual->message)
8749 todo_wine_if (todo)
8750 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8751 context, expected->message, actual->message);
8752 failcount++;
8755 if(todo && !failcount) /* succeeded yet marked todo */
8757 todo_wine
8758 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
8761 done:
8762 flush_sequence();
8765 #define ok_sequence(exp, contx, todo) \
8766 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8768 /* don't use PROGRESS, which is timing-dependent,
8769 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8770 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE =
8771 INSTALLLOGMODE_FATALEXIT |
8772 INSTALLLOGMODE_ERROR |
8773 INSTALLLOGMODE_WARNING |
8774 INSTALLLOGMODE_USER |
8775 INSTALLLOGMODE_INFO |
8776 INSTALLLOGMODE_FILESINUSE |
8777 INSTALLLOGMODE_RESOLVESOURCE |
8778 INSTALLLOGMODE_OUTOFDISKSPACE |
8779 INSTALLLOGMODE_ACTIONSTART |
8780 INSTALLLOGMODE_ACTIONDATA |
8781 INSTALLLOGMODE_COMMONDATA |
8782 INSTALLLOGMODE_INITIALIZE |
8783 INSTALLLOGMODE_TERMINATE |
8784 INSTALLLOGMODE_RMFILESINUSE |
8785 INSTALLLOGMODE_INSTALLSTART |
8786 INSTALLLOGMODE_INSTALLEND;
8788 static const struct externalui_message empty_sequence[] = {
8792 static const struct externalui_message openpackage_nonexistent_sequence[] = {
8793 {INSTALLMESSAGE_INITIALIZE, -1},
8794 {INSTALLMESSAGE_TERMINATE, -1},
8798 static const struct externalui_message openpackage_sequence[] = {
8799 {INSTALLMESSAGE_INITIALIZE, -1},
8800 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8801 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
8802 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8803 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8807 static const struct externalui_message processmessage_info_sequence[] = {
8808 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8812 static const struct externalui_message processmessage_actionstart_sequence[] = {
8813 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8817 static const struct externalui_message processmessage_actiondata_sequence[] = {
8818 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8822 static const struct externalui_message processmessage_error_sequence[] = {
8823 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8827 static const struct externalui_message processmessage_internal_error_sequence[] = {
8828 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8829 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8833 static const struct externalui_message processmessage_error_format_sequence[] = {
8834 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8838 static const struct externalui_message doaction_costinitialize_sequence[] = {
8839 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8840 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8841 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8845 static const struct externalui_message doaction_custom_sequence[] = {
8846 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8847 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8848 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8852 static const struct externalui_message doaction_custom_fullui_sequence[] = {
8853 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8854 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
8855 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8856 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8860 static const struct externalui_message doaction_custom_cancel_sequence[] = {
8861 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8865 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
8866 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8867 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8868 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8869 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
8870 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
8871 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8875 static const struct externalui_message doaction_dialog_sequence[] = {
8876 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8877 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
8878 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8879 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
8880 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
8884 static const struct externalui_message doaction_dialog_error_sequence[] = {
8885 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
8886 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
8887 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
8891 static const struct externalui_message doaction_dialog_3_sequence[] = {
8892 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8893 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
8894 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8895 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
8899 static const struct externalui_message doaction_dialog_12345_sequence[] = {
8900 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8901 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
8902 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8903 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
8907 static const struct externalui_message closehandle_sequence[] = {
8908 {INSTALLMESSAGE_TERMINATE, -1},
8912 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
8914 INT retval = context ? *((INT *)context) : 0;
8915 struct externalui_message msg;
8917 msg.message = message;
8918 msg.field_count = 0;
8919 strcpy(msg.field[0], string);
8920 add_message(&msg);
8922 return retval;
8925 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
8927 INT retval = context ? *((INT *)context) : 0;
8928 struct externalui_message msg;
8929 char buffer[256];
8930 DWORD length;
8931 UINT r;
8932 int i;
8934 msg.message = message;
8935 if (message == INSTALLMESSAGE_TERMINATE)
8937 /* trying to access the record seems to hang on some versions of Windows */
8938 msg.field_count = -1;
8939 add_message(&msg);
8940 return 1;
8942 msg.field_count = MsiRecordGetFieldCount(hrecord);
8943 for (i = 0; i <= msg.field_count; i++)
8945 length = sizeof(buffer);
8946 r = MsiRecordGetStringA(hrecord, i, buffer, &length);
8947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8948 memcpy(msg.field[i], buffer, min(100, length+1));
8951 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
8952 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
8953 return retval;
8955 add_message(&msg);
8957 return retval;
8960 static void test_externalui_message(void)
8962 /* test that events trigger the correct sequence of messages */
8964 INSTALLUI_HANDLER_RECORD prev;
8965 MSIHANDLE hdb, hpkg, hrecord;
8966 INT retval = 1;
8967 UINT r;
8969 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
8971 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval);
8972 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev);
8974 flush_sequence();
8976 CoInitialize(NULL);
8978 hdb = create_package_db();
8979 ok(hdb, "failed to create database\n");
8981 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
8982 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
8983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8985 r = run_query(hdb, 0, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
8986 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
8987 r = run_query(hdb, 0, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
8988 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
8990 create_actiontext_table(hdb);
8991 add_actiontext_entry(hdb, "'custom', 'description', 'template'");
8992 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
8994 r = MsiOpenPackageA(NULL, &hpkg);
8995 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8996 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
8998 r = MsiOpenPackageA("nonexistent", &hpkg);
8999 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9000 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9002 r = package_from_db(hdb, &hpkg);
9003 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9005 skip("Not enough rights to perform tests\n");
9006 DeleteFileA(msifile);
9007 return;
9009 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9010 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9012 /* Test MsiProcessMessage */
9013 hrecord = MsiCreateRecord(3);
9014 ok(hrecord, "failed to create record\n");
9016 MsiRecordSetStringA(hrecord, 0, "zero");
9017 MsiRecordSetStringA(hrecord, 1, "one");
9018 MsiRecordSetStringA(hrecord, 2, "two");
9019 MsiRecordSetStringA(hrecord, 3, "three");
9020 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9021 ok(r == 1, "Expected 1, got %d\n", r);
9022 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9024 MsiRecordSetStringA(hrecord, 1, "name");
9025 MsiRecordSetStringA(hrecord, 2, "description");
9026 MsiRecordSetStringA(hrecord, 3, "template");
9027 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord);
9028 ok(r == 1, "Expected 1, got %d\n", r);
9029 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9031 MsiRecordSetStringA(hrecord, 0, "apple");
9032 MsiRecordSetStringA(hrecord, 1, "cherry");
9033 MsiRecordSetStringA(hrecord, 2, "banana");
9034 MsiRecordSetStringA(hrecord, 3, "guava");
9035 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord);
9036 ok(r == 1, "Expected 1, got %d\n", r);
9037 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9039 /* non-internal error */
9040 MsiRecordSetStringA(hrecord, 0, NULL);
9041 MsiRecordSetInteger(hrecord, 1, 1311);
9042 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9043 ok(r == 1, "Expected 1, got %d\n", r);
9044 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9046 /* internal error */
9047 MsiRecordSetStringA(hrecord, 0, NULL);
9048 MsiRecordSetInteger(hrecord, 1, 2726);
9049 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9050 ok(r == 0, "Expected 0, got %d\n", r);
9051 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9053 /* with format field */
9054 MsiRecordSetStringA(hrecord, 0, "starfruit");
9055 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9056 ok(r == 1, "Expected 1, got %d\n", r);
9057 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9059 /* Test a standard action */
9060 r = MsiDoActionA(hpkg, "CostInitialize");
9061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9062 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9064 /* Test a custom action */
9065 r = MsiDoActionA(hpkg, "custom");
9066 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9067 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9069 /* close the package */
9070 MsiCloseHandle(hpkg);
9071 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9073 /* Test dialogs */
9074 hdb = create_package_db();
9075 ok(hdb, "failed to create database\n");
9077 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9080 create_dialog_table(hdb);
9081 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9083 create_control_table(hdb);
9084 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9086 r = package_from_db(hdb, &hpkg);
9087 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9088 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9090 /* Test a custom action */
9091 r = MsiDoActionA(hpkg, "custom");
9092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9093 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9095 retval = 2;
9096 r = MsiDoActionA(hpkg, "custom");
9097 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9098 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9100 retval = 0;
9101 r = MsiDoActionA(hpkg, "custom");
9102 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9103 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9105 r = MsiDoActionA(hpkg, "dialog");
9106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9107 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9109 retval = -1;
9110 r = MsiDoActionA(hpkg, "error");
9111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9112 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9114 r = MsiDoActionA(hpkg, "error");
9115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9116 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9118 retval = -2;
9119 r = MsiDoActionA(hpkg, "custom");
9120 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9121 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9123 retval = 3;
9124 r = MsiDoActionA(hpkg, "dialog");
9125 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9126 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9128 retval = 12345;
9129 r = MsiDoActionA(hpkg, "dialog");
9130 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9131 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9133 MsiCloseHandle(hpkg);
9134 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9136 MsiCloseHandle(hrecord);
9137 CoUninitialize();
9138 DeleteFileA(msifile);
9139 DeleteFileA("forcecodepage.idt");
9142 static const struct externalui_message controlevent_spawn_sequence[] = {
9143 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9144 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9145 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9146 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9148 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9149 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9150 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9152 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9154 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9158 static const struct externalui_message controlevent_spawn2_sequence[] = {
9159 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9160 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9161 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9162 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9164 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9165 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9166 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9168 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9170 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9174 static void test_controlevent(void)
9176 INSTALLUI_HANDLER_RECORD prev;
9177 MSIHANDLE hdb, hpkg;
9178 UINT r;
9180 if (!winetest_interactive)
9182 skip("interactive ControlEvent tests\n");
9183 return;
9186 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9188 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9189 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9191 flush_sequence();
9193 CoInitialize(NULL);
9195 hdb = create_package_db();
9196 ok(hdb, "failed to create database\n");
9198 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
9199 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9202 create_dialog_table(hdb);
9203 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9204 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9205 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9206 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9208 create_control_table(hdb);
9209 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9210 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9211 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9212 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9214 create_controlevent_table(hdb);
9215 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9216 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9218 create_custom_action_table(hdb);
9219 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9221 /* SpawnDialog and EndDialog should trigger after all other events */
9222 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9223 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9225 /* Multiple dialog events cause only the last one to be triggered */
9226 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9227 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9228 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9230 r = package_from_db(hdb, &hpkg);
9231 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9232 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9234 r = MsiDoActionA(hpkg, "spawn");
9235 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9236 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9238 r = MsiDoActionA(hpkg, "spawn2");
9239 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9240 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9242 MsiCloseHandle(hpkg);
9243 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9245 CoUninitialize();
9246 DeleteFileA(msifile);
9247 DeleteFileA("forcecodepage.idt");
9250 static const struct externalui_message toplevel_install_sequence[] = {
9251 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9252 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9254 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9255 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9256 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9257 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9258 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9260 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9261 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9262 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9264 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9265 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9266 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9268 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9269 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9270 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9272 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9273 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9274 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9276 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9277 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9279 /* property dump */
9281 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9282 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9283 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9287 static const struct externalui_message toplevel_install_ui_sequence[] = {
9288 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9289 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9291 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9292 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9293 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9295 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9299 static const struct externalui_message toplevel_executeaction_install_sequence[] = {
9300 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9301 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9303 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9304 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9305 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9306 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9308 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9309 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9310 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9312 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9313 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9314 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9316 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9317 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9318 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9320 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9321 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9322 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9324 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9325 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9327 /* property dump */
9329 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9330 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9331 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9335 static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = {
9336 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9337 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9339 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9340 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9341 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9342 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9344 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9345 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9346 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9348 /* property dump */
9350 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9351 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9352 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9356 static const struct externalui_message toplevel_msiinstallproduct_sequence[] = {
9357 {INSTALLMESSAGE_INITIALIZE, -1},
9359 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9360 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9361 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9362 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9363 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9365 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9366 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9368 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9369 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9370 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9372 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9374 /* property dump */
9376 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9377 {INSTALLMESSAGE_TERMINATE, -1},
9381 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = {
9382 {INSTALLMESSAGE_INITIALIZE, -1},
9384 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9385 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9386 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9387 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9388 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9390 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9391 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9392 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9394 /* property dump */
9396 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9397 {INSTALLMESSAGE_TERMINATE, -1},
9401 /* tests involving top-level actions: INSTALL, ExecuteAction */
9402 static void test_top_level_action(void)
9404 INSTALLUI_HANDLER_RECORD prev;
9405 MSIHANDLE hdb, hpkg;
9406 UINT r;
9407 char msifile_absolute[MAX_PATH];
9409 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9411 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9412 r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9414 flush_sequence();
9416 CoInitialize(NULL);
9418 hdb = create_package_db();
9419 ok(hdb, "failed to create database\n");
9421 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") -1 );
9422 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9425 create_property_table(hdb);
9426 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9428 create_install_execute_sequence_table(hdb);
9429 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9430 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9431 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9433 create_install_ui_sequence_table(hdb);
9434 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9436 MsiDatabaseCommit(hdb);
9438 /* for some reason we have to open the package from file using an absolute path */
9439 MsiCloseHandle(hdb);
9440 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9441 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9442 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9443 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9445 /* test INSTALL */
9446 r = MsiDoActionA(hpkg, "INSTALL");
9447 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9448 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9450 /* test INSTALL with reduced+ UI */
9451 /* for some reason we need to re-open the package to change the internal UI */
9452 MsiCloseHandle(hpkg);
9453 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9454 MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL);
9455 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9456 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9457 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9459 r = MsiDoActionA(hpkg, "INSTALL");
9460 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9461 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9463 /* test ExecuteAction with EXECUTEACTION property unset */
9464 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9465 r = MsiDoActionA(hpkg, "ExecuteAction");
9466 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9467 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9469 /* test ExecuteAction with EXECUTEACTION property set */
9470 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9471 r = MsiDoActionA(hpkg, "ExecuteAction");
9472 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9473 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9475 MsiCloseHandle(hpkg);
9476 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9478 /* test MsiInstallProduct() */
9479 r = MsiInstallProductA(msifile_absolute, NULL);
9480 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9481 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9483 r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9484 todo_wine
9485 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9486 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9488 CoUninitialize();
9489 DeleteFileA(msifile);
9490 DeleteFileA("forcecodepage.idt");
9493 START_TEST(package)
9495 char temp_path[MAX_PATH], prev_path[MAX_PATH];
9496 DWORD len;
9498 if (!is_process_elevated()) restart_as_admin_elevated();
9500 IsWow64Process(GetCurrentProcess(), &is_wow64);
9502 GetCurrentDirectoryA(MAX_PATH, prev_path);
9503 GetTempPathA(MAX_PATH, temp_path);
9504 SetCurrentDirectoryA(temp_path);
9506 lstrcpyA(CURR_DIR, temp_path);
9507 len = lstrlenA(CURR_DIR);
9509 if (len && (CURR_DIR[len - 1] == '\\'))
9510 CURR_DIR[len - 1] = 0;
9512 test_createpackage();
9513 test_doaction();
9514 test_gettargetpath_bad();
9515 test_settargetpath();
9516 test_props();
9517 test_property_table();
9518 test_condition();
9519 test_msipackage();
9520 test_formatrecord2();
9521 test_formatrecord_tables();
9522 test_states();
9523 test_removefiles();
9524 test_appsearch();
9525 test_appsearch_complocator();
9526 test_appsearch_reglocator();
9527 test_appsearch_inilocator();
9528 test_appsearch_drlocator();
9529 test_featureparents();
9530 test_installprops();
9531 test_launchconditions();
9532 test_ccpsearch();
9533 test_complocator();
9534 test_MsiGetSourcePath();
9535 test_shortlongsource();
9536 test_sourcedir();
9537 test_access();
9538 test_emptypackage();
9539 test_MsiGetProductProperty();
9540 test_MsiSetProperty();
9541 test_MsiApplyMultiplePatches();
9542 test_MsiApplyPatch();
9543 test_costs();
9544 test_MsiDatabaseCommit();
9545 test_externalui();
9546 test_externalui_message();
9547 test_controlevent();
9548 test_top_level_action();
9550 SetCurrentDirectoryA(prev_path);