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
30 #include <srrestoreptapi.h>
34 #include "wine/test.h"
37 static const char msifile
[] = "winetest-package.msi";
38 static const WCHAR msifileW
[] = L
"winetest-package.msi";
39 static char CURR_DIR
[MAX_PATH
];
41 static INSTALLSTATE (WINAPI
*pMsiGetComponentPathExA
)(LPCSTR
, LPCSTR
, LPCSTR
, MSIINSTALLCONTEXT
, LPSTR
, LPDWORD
);
43 static LONG (WINAPI
*pRegDeleteKeyExA
)(HKEY
, LPCSTR
, REGSAM
, DWORD
);
44 static LONG (WINAPI
*pRegDeleteKeyExW
)(HKEY
, LPCWSTR
, REGSAM
, DWORD
);
45 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
46 static BOOL (WINAPI
*pSRRemoveRestorePoint
)(DWORD
);
47 static BOOL (WINAPI
*pSRSetRestorePointA
)(RESTOREPOINTINFOA
*, STATEMGRSTATUS
*);
49 static void init_functionpointers(void)
51 HMODULE hmsi
= GetModuleHandleA("msi.dll");
52 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
53 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
54 HMODULE hsrclient
= LoadLibraryA("srclient.dll");
56 #define GET_PROC(mod, func) \
57 p ## func = (void*)GetProcAddress(mod, #func);
59 GET_PROC(hmsi
, MsiGetComponentPathExA
);
61 GET_PROC(hadvapi32
, RegDeleteKeyExA
)
62 GET_PROC(hadvapi32
, RegDeleteKeyExW
)
63 GET_PROC(hkernel32
, IsWow64Process
)
65 GET_PROC(hsrclient
, SRRemoveRestorePoint
);
66 GET_PROC(hsrclient
, SRSetRestorePointA
);
71 static BOOL
is_process_limited(void)
73 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
78 if (!AllocateAndInitializeSid(&NtAuthority
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
79 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &Group
) ||
80 !CheckTokenMembership(NULL
, Group
, &IsInGroup
))
82 trace("Could not check if the current user is an administrator\n");
90 if (!AllocateAndInitializeSid(&NtAuthority
, 2,
91 SECURITY_BUILTIN_DOMAIN_RID
,
92 DOMAIN_ALIAS_RID_POWER_USERS
,
93 0, 0, 0, 0, 0, 0, &Group
) ||
94 !CheckTokenMembership(NULL
, Group
, &IsInGroup
))
96 trace("Could not check if the current user is a power user\n");
101 /* Only administrators and power users can be powerful */
106 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
))
109 TOKEN_ELEVATION_TYPE type
= TokenElevationTypeDefault
;
112 ret
= GetTokenInformation(token
, TokenElevationType
, &type
, sizeof(type
), &size
);
114 return (ret
&& type
== TokenElevationTypeLimited
);
119 static LONG
delete_key( HKEY key
, LPCSTR subkey
, REGSAM access
)
121 if (pRegDeleteKeyExA
)
122 return pRegDeleteKeyExA( key
, subkey
, access
, 0 );
123 return RegDeleteKeyA( key
, subkey
);
126 static char *get_user_sid(void)
131 char *usersid
= NULL
;
133 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
);
134 GetTokenInformation(token
, TokenUser
, NULL
, size
, &size
);
136 user
= HeapAlloc(GetProcessHeap(), 0, size
);
137 GetTokenInformation(token
, TokenUser
, user
, size
, &size
);
138 ConvertSidToStringSidA(user
->User
.Sid
, &usersid
);
139 HeapFree(GetProcessHeap(), 0, user
);
145 /* RegDeleteTreeW from dlls/advapi32/registry.c */
146 static LSTATUS
package_RegDeleteTreeW(HKEY hKey
, LPCWSTR lpszSubKey
, REGSAM access
)
149 DWORD dwMaxSubkeyLen
, dwMaxValueLen
;
150 DWORD dwMaxLen
, dwSize
;
151 WCHAR szNameBuf
[MAX_PATH
], *lpszName
= szNameBuf
;
156 ret
= RegOpenKeyExW(hKey
, lpszSubKey
, 0, access
, &hSubKey
);
160 ret
= RegQueryInfoKeyW(hSubKey
, NULL
, NULL
, NULL
, NULL
,
161 &dwMaxSubkeyLen
, NULL
, NULL
, &dwMaxValueLen
, NULL
, NULL
, NULL
);
162 if (ret
) goto cleanup
;
166 dwMaxLen
= max(dwMaxSubkeyLen
, dwMaxValueLen
);
167 if (dwMaxLen
> ARRAY_SIZE(szNameBuf
))
169 /* Name too big: alloc a buffer for it */
170 if (!(lpszName
= HeapAlloc( GetProcessHeap(), 0, dwMaxLen
*sizeof(WCHAR
))))
172 ret
= ERROR_NOT_ENOUGH_MEMORY
;
177 /* Recursively delete all the subkeys */
181 if (RegEnumKeyExW(hSubKey
, 0, lpszName
, &dwSize
, NULL
,
182 NULL
, NULL
, NULL
)) break;
184 ret
= package_RegDeleteTreeW(hSubKey
, lpszName
, access
);
185 if (ret
) goto cleanup
;
190 if (pRegDeleteKeyExW
)
191 ret
= pRegDeleteKeyExW(hKey
, lpszSubKey
, access
, 0);
193 ret
= RegDeleteKeyW(hKey
, lpszSubKey
);
199 if (RegEnumValueW(hKey
, 0, lpszName
, &dwSize
,
200 NULL
, NULL
, NULL
, NULL
)) break;
202 ret
= RegDeleteValueW(hKey
, lpszName
);
203 if (ret
) goto cleanup
;
207 if (lpszName
!= szNameBuf
)
208 HeapFree(GetProcessHeap(), 0, lpszName
);
210 RegCloseKey(hSubKey
);
214 static BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
219 if (FAILED(CLSIDFromString((LPCOLESTR
)in
, &guid
)))
233 out
[17+i
*2] = in
[n
++];
234 out
[16+i
*2] = in
[n
++];
239 out
[17+i
*2] = in
[n
++];
240 out
[16+i
*2] = in
[n
++];
246 static void create_test_guid(LPSTR prodcode
, LPSTR squashed
)
248 WCHAR guidW
[MAX_PATH
];
249 WCHAR squashedW
[MAX_PATH
];
254 hr
= CoCreateGuid(&guid
);
255 ok(hr
== S_OK
, "Expected S_OK, got %d\n", hr
);
257 size
= StringFromGUID2(&guid
, guidW
, MAX_PATH
);
258 ok(size
== 39, "Expected 39, got %d\n", hr
);
260 WideCharToMultiByte(CP_ACP
, 0, guidW
, size
, prodcode
, MAX_PATH
, NULL
, NULL
);
261 squash_guid(guidW
, squashedW
);
262 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
265 static void set_component_path(LPCSTR filename
, MSIINSTALLCONTEXT context
,
266 LPCSTR guid
, LPSTR usersid
, BOOL dir
)
268 WCHAR guidW
[MAX_PATH
];
269 WCHAR squashedW
[MAX_PATH
];
270 CHAR squashed
[MAX_PATH
];
271 CHAR comppath
[MAX_PATH
+ 81];
272 CHAR prodpath
[MAX_PATH
];
276 REGSAM access
= KEY_ALL_ACCESS
;
279 access
|= KEY_WOW64_64KEY
;
281 MultiByteToWideChar(CP_ACP
, 0, guid
, -1, guidW
, MAX_PATH
);
282 squash_guid(guidW
, squashedW
);
283 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
285 if (context
== MSIINSTALLCONTEXT_MACHINE
)
287 prod
= "3D0DAE300FACA1300AD792060BCDAA92";
289 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
290 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed
);
292 "SOFTWARE\\Classes\\Installer\\"
293 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
295 else if (context
== MSIINSTALLCONTEXT_USERUNMANAGED
)
297 prod
= "7D2F387510109040002000060BECB6AB";
299 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
300 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
302 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
303 "Installer\\%s\\Installer\\Products\\"
304 "7D2F387510109040002000060BECB6AB", usersid
);
306 else if (context
== MSIINSTALLCONTEXT_USERMANAGED
)
308 prod
= "7D2F387510109040002000060BECB6AB";
310 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
311 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
313 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
314 "Installer\\Managed\\%s\\Installer\\Products\\"
315 "7D2F387510109040002000060BECB6AB", usersid
);
318 RegCreateKeyExA(HKEY_LOCAL_MACHINE
, comppath
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
);
320 lstrcpyA(path
, CURR_DIR
);
321 lstrcatA(path
, "\\");
322 if (!dir
) lstrcatA(path
, filename
);
324 RegSetValueExA(hkey
, prod
, 0, REG_SZ
, (LPBYTE
)path
, lstrlenA(path
));
327 RegCreateKeyExA(HKEY_LOCAL_MACHINE
, prodpath
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
);
331 static void delete_component_path(LPCSTR guid
, MSIINSTALLCONTEXT context
, LPSTR usersid
)
333 WCHAR guidW
[MAX_PATH
];
334 WCHAR squashedW
[MAX_PATH
];
335 WCHAR substrW
[MAX_PATH
];
336 CHAR squashed
[MAX_PATH
];
337 CHAR comppath
[MAX_PATH
+ 81];
338 CHAR prodpath
[MAX_PATH
];
339 REGSAM access
= KEY_ALL_ACCESS
;
342 access
|= KEY_WOW64_64KEY
;
344 MultiByteToWideChar(CP_ACP
, 0, guid
, -1, guidW
, MAX_PATH
);
345 squash_guid(guidW
, squashedW
);
346 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
348 if (context
== MSIINSTALLCONTEXT_MACHINE
)
351 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
352 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed
);
354 "SOFTWARE\\Classes\\Installer\\"
355 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
357 else if (context
== MSIINSTALLCONTEXT_USERUNMANAGED
)
360 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
361 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
363 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
364 "Installer\\%s\\Installer\\Products\\"
365 "7D2F387510109040002000060BECB6AB", usersid
);
367 else if (context
== MSIINSTALLCONTEXT_USERMANAGED
)
370 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
371 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
373 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
374 "Installer\\Managed\\%s\\Installer\\Products\\"
375 "7D2F387510109040002000060BECB6AB", usersid
);
378 MultiByteToWideChar(CP_ACP
, 0, comppath
, -1, substrW
, MAX_PATH
);
379 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE
, substrW
, access
);
381 MultiByteToWideChar(CP_ACP
, 0, prodpath
, -1, substrW
, MAX_PATH
);
382 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE
, substrW
, access
);
385 static UINT
do_query(MSIHANDLE hdb
, const char *query
, MSIHANDLE
*phrec
)
390 /* open a select query */
391 r
= MsiDatabaseOpenViewA(hdb
, query
, &hview
);
392 if (r
!= ERROR_SUCCESS
)
394 r
= MsiViewExecute(hview
, 0);
395 if (r
!= ERROR_SUCCESS
)
397 ret
= MsiViewFetch(hview
, phrec
);
398 r
= MsiViewClose(hview
);
399 if (r
!= ERROR_SUCCESS
)
401 r
= MsiCloseHandle(hview
);
402 if (r
!= ERROR_SUCCESS
)
407 static UINT
run_query( MSIHANDLE hdb
, const char *query
)
412 r
= MsiDatabaseOpenViewA(hdb
, query
, &hview
);
413 if( r
!= ERROR_SUCCESS
)
416 r
= MsiViewExecute(hview
, 0);
417 if( r
== ERROR_SUCCESS
)
418 r
= MsiViewClose(hview
);
419 MsiCloseHandle(hview
);
423 static UINT
create_component_table( MSIHANDLE hdb
)
425 UINT r
= run_query( hdb
,
426 "CREATE TABLE `Component` ( "
427 "`Component` CHAR(72) NOT NULL, "
428 "`ComponentId` CHAR(38), "
429 "`Directory_` CHAR(72) NOT NULL, "
430 "`Attributes` SHORT NOT NULL, "
431 "`Condition` CHAR(255), "
432 "`KeyPath` CHAR(72) "
433 "PRIMARY KEY `Component`)" );
434 ok(r
== ERROR_SUCCESS
, "Failed to create Component table: %u\n", r
);
438 static UINT
create_feature_table( MSIHANDLE hdb
)
440 UINT r
= run_query( hdb
,
441 "CREATE TABLE `Feature` ( "
442 "`Feature` CHAR(38) NOT NULL, "
443 "`Feature_Parent` CHAR(38), "
445 "`Description` CHAR(255), "
446 "`Display` SHORT NOT NULL, "
447 "`Level` SHORT NOT NULL, "
448 "`Directory_` CHAR(72), "
449 "`Attributes` SHORT NOT NULL "
450 "PRIMARY KEY `Feature`)" );
451 ok(r
== ERROR_SUCCESS
, "Failed to create Feature table: %u\n", r
);
455 static UINT
create_feature_components_table( MSIHANDLE hdb
)
457 UINT r
= run_query( hdb
,
458 "CREATE TABLE `FeatureComponents` ( "
459 "`Feature_` CHAR(38) NOT NULL, "
460 "`Component_` CHAR(72) NOT NULL "
461 "PRIMARY KEY `Feature_`, `Component_` )" );
462 ok(r
== ERROR_SUCCESS
, "Failed to create FeatureComponents table: %u\n", r
);
466 static UINT
create_file_table( MSIHANDLE hdb
)
468 UINT r
= run_query( hdb
,
469 "CREATE TABLE `File` ("
470 "`File` CHAR(72) NOT NULL, "
471 "`Component_` CHAR(72) NOT NULL, "
472 "`FileName` CHAR(255) NOT NULL, "
473 "`FileSize` LONG NOT NULL, "
474 "`Version` CHAR(72), "
475 "`Language` CHAR(20), "
476 "`Attributes` SHORT, "
477 "`Sequence` SHORT NOT NULL "
478 "PRIMARY KEY `File`)" );
479 ok(r
== ERROR_SUCCESS
, "Failed to create File table: %u\n", r
);
483 static UINT
create_remove_file_table( MSIHANDLE hdb
)
485 UINT r
= run_query( hdb
,
486 "CREATE TABLE `RemoveFile` ("
487 "`FileKey` CHAR(72) NOT NULL, "
488 "`Component_` CHAR(72) NOT NULL, "
489 "`FileName` CHAR(255) LOCALIZABLE, "
490 "`DirProperty` CHAR(72) NOT NULL, "
491 "`InstallMode` SHORT NOT NULL "
492 "PRIMARY KEY `FileKey`)" );
493 ok(r
== ERROR_SUCCESS
, "Failed to create RemoveFile table: %u\n", r
);
497 static UINT
create_appsearch_table( MSIHANDLE hdb
)
499 UINT r
= run_query( hdb
,
500 "CREATE TABLE `AppSearch` ("
501 "`Property` CHAR(72) NOT NULL, "
502 "`Signature_` CHAR(72) NOT NULL "
503 "PRIMARY KEY `Property`, `Signature_`)" );
504 ok(r
== ERROR_SUCCESS
, "Failed to create AppSearch table: %u\n", r
);
508 static UINT
create_reglocator_table( MSIHANDLE hdb
)
510 UINT r
= run_query( hdb
,
511 "CREATE TABLE `RegLocator` ("
512 "`Signature_` CHAR(72) NOT NULL, "
513 "`Root` SHORT NOT NULL, "
514 "`Key` CHAR(255) NOT NULL, "
517 "PRIMARY KEY `Signature_`)" );
518 ok(r
== ERROR_SUCCESS
, "Failed to create RegLocator table: %u\n", r
);
522 static UINT
create_signature_table( MSIHANDLE hdb
)
524 UINT r
= run_query( hdb
,
525 "CREATE TABLE `Signature` ("
526 "`Signature` CHAR(72) NOT NULL, "
527 "`FileName` CHAR(255) NOT NULL, "
528 "`MinVersion` CHAR(20), "
529 "`MaxVersion` CHAR(20), "
534 "`Languages` CHAR(255) "
535 "PRIMARY KEY `Signature`)" );
536 ok(r
== ERROR_SUCCESS
, "Failed to create Signature table: %u\n", r
);
540 static UINT
create_launchcondition_table( MSIHANDLE hdb
)
542 UINT r
= run_query( hdb
,
543 "CREATE TABLE `LaunchCondition` ("
544 "`Condition` CHAR(255) NOT NULL, "
545 "`Description` CHAR(255) NOT NULL "
546 "PRIMARY KEY `Condition`)" );
547 ok(r
== ERROR_SUCCESS
, "Failed to create LaunchCondition table: %u\n", r
);
551 static UINT
create_property_table( MSIHANDLE hdb
)
553 UINT r
= run_query( hdb
,
554 "CREATE TABLE `Property` ("
555 "`Property` CHAR(72) NOT NULL, "
557 "PRIMARY KEY `Property`)" );
558 ok(r
== ERROR_SUCCESS
, "Failed to create Property table: %u\n", r
);
562 static UINT
create_install_execute_sequence_table( MSIHANDLE hdb
)
564 UINT r
= run_query( hdb
,
565 "CREATE TABLE `InstallExecuteSequence` ("
566 "`Action` CHAR(72) NOT NULL, "
567 "`Condition` CHAR(255), "
569 "PRIMARY KEY `Action`)" );
570 ok(r
== ERROR_SUCCESS
, "Failed to create InstallExecuteSequence table: %u\n", r
);
574 static UINT
create_install_ui_sequence_table( MSIHANDLE hdb
)
576 UINT r
= run_query( hdb
,
577 "CREATE TABLE `InstallUISequence` ("
578 "`Action` CHAR(72) NOT NULL, "
579 "`Condition` CHAR(255), "
581 "PRIMARY KEY `Action`)" );
582 ok(r
== ERROR_SUCCESS
, "Failed to create InstallUISequence table: %u\n", r
);
586 static UINT
create_media_table( MSIHANDLE hdb
)
588 UINT r
= run_query( hdb
,
589 "CREATE TABLE `Media` ("
590 "`DiskId` SHORT NOT NULL, "
591 "`LastSequence` SHORT NOT NULL, "
592 "`DiskPrompt` CHAR(64), "
593 "`Cabinet` CHAR(255), "
594 "`VolumeLabel` CHAR(32), "
596 "PRIMARY KEY `DiskId`)" );
597 ok(r
== ERROR_SUCCESS
, "Failed to create Media table: %u\n", r
);
601 static UINT
create_ccpsearch_table( MSIHANDLE hdb
)
603 UINT r
= run_query( hdb
,
604 "CREATE TABLE `CCPSearch` ("
605 "`Signature_` CHAR(72) NOT NULL "
606 "PRIMARY KEY `Signature_`)" );
607 ok(r
== ERROR_SUCCESS
, "Failed to create CCPSearch table: %u\n", r
);
611 static UINT
create_drlocator_table( MSIHANDLE hdb
)
613 UINT r
= run_query( hdb
,
614 "CREATE TABLE `DrLocator` ("
615 "`Signature_` CHAR(72) NOT NULL, "
616 "`Parent` CHAR(72), "
619 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
620 ok(r
== ERROR_SUCCESS
, "Failed to create DrLocator table: %u\n", r
);
624 static UINT
create_complocator_table( MSIHANDLE hdb
)
626 UINT r
= run_query( hdb
,
627 "CREATE TABLE `CompLocator` ("
628 "`Signature_` CHAR(72) NOT NULL, "
629 "`ComponentId` CHAR(38) NOT NULL, "
631 "PRIMARY KEY `Signature_`)" );
632 ok(r
== ERROR_SUCCESS
, "Failed to create CompLocator table: %u\n", r
);
636 static UINT
create_inilocator_table( MSIHANDLE hdb
)
638 UINT r
= run_query( hdb
,
639 "CREATE TABLE `IniLocator` ("
640 "`Signature_` CHAR(72) NOT NULL, "
641 "`FileName` CHAR(255) NOT NULL, "
642 "`Section` CHAR(96)NOT NULL, "
643 "`Key` CHAR(128)NOT NULL, "
646 "PRIMARY KEY `Signature_`)" );
647 ok(r
== ERROR_SUCCESS
, "Failed to create IniLocator table: %u\n", r
);
651 static UINT
create_custom_action_table( MSIHANDLE hdb
)
653 UINT r
= run_query( hdb
,
654 "CREATE TABLE `CustomAction` ("
655 "`Action` CHAR(72) NOT NULL, "
656 "`Type` SHORT NOT NULL, "
657 "`Source` CHAR(75), "
658 "`Target` CHAR(255) "
659 "PRIMARY KEY `Action`)" );
660 ok(r
== ERROR_SUCCESS
, "Failed to create CustomAction table: %u\n", r
);
664 static UINT
create_dialog_table( MSIHANDLE hdb
)
666 UINT r
= run_query(hdb
,
667 "CREATE TABLE `Dialog` ("
668 "`Dialog` CHAR(72) NOT NULL, "
669 "`HCentering` SHORT NOT NULL, "
670 "`VCentering` SHORT NOT NULL, "
671 "`Width` SHORT NOT NULL, "
672 "`Height` SHORT NOT NULL, "
673 "`Attributes` LONG, "
674 "`Title` CHAR(128) LOCALIZABLE, "
675 "`Control_First` CHAR(50) NOT NULL, "
676 "`Control_Default` CHAR(50), "
677 "`Control_Cancel` CHAR(50) "
678 "PRIMARY KEY `Dialog`)");
679 ok(r
== ERROR_SUCCESS
, "Failed to create Dialog table: %u\n", r
);
683 static UINT
create_control_table( MSIHANDLE hdb
)
685 UINT r
= run_query(hdb
,
686 "CREATE TABLE `Control` ("
687 "`Dialog_` CHAR(72) NOT NULL, "
688 "`Control` CHAR(50) NOT NULL, "
689 "`Type` CHAR(20) NOT NULL, "
690 "`X` SHORT NOT NULL, "
691 "`Y` SHORT NOT NULL, "
692 "`Width` SHORT NOT NULL, "
693 "`Height` SHORT NOT NULL, "
694 "`Attributes` LONG, "
695 "`Property` CHAR(50), "
696 "`Text` CHAR(0) LOCALIZABLE, "
697 "`Control_Next` CHAR(50), "
698 "`Help` CHAR(255) LOCALIZABLE "
699 "PRIMARY KEY `Dialog_`, `Control`)");
700 ok(r
== ERROR_SUCCESS
, "Failed to create Control table: %u\n", r
);
704 static UINT
create_controlevent_table( MSIHANDLE hdb
)
706 UINT r
= run_query(hdb
,
707 "CREATE TABLE `ControlEvent` ("
708 "`Dialog_` CHAR(72) NOT NULL, "
709 "`Control_` CHAR(50) NOT NULL, "
710 "`Event` CHAR(50) NOT NULL, "
711 "`Argument` CHAR(255) NOT NULL, "
712 "`Condition` CHAR(255), "
714 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
715 ok(r
== ERROR_SUCCESS
, "Failed to create ControlEvent table: %u\n", r
);
719 static UINT
create_actiontext_table( MSIHANDLE hdb
)
721 UINT r
= run_query(hdb
,
722 "CREATE TABLE `ActionText` ("
723 "`Action` CHAR(72) NOT NULL, "
724 "`Description` CHAR(64) LOCALIZABLE, "
725 "`Template` CHAR(128) LOCALIZABLE "
726 "PRIMARY KEY `Action`)");
727 ok(r
== ERROR_SUCCESS
, "Failed to create ActionText table: %u\n", r
);
731 static UINT
create_upgrade_table( MSIHANDLE hdb
)
733 UINT r
= run_query( hdb
,
734 "CREATE TABLE `Upgrade` ("
735 "`UpgradeCode` CHAR(38) NOT NULL, "
736 "`VersionMin` CHAR(20), "
737 "`VersionMax` CHAR(20), "
738 "`Language` CHAR(255), "
739 "`Attributes` SHORT, "
740 "`Remove` CHAR(255), "
741 "`ActionProperty` CHAR(72) NOT NULL "
742 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
743 ok(r
== ERROR_SUCCESS
, "Failed to create Upgrade table: %u\n", r
);
747 static inline UINT
add_entry(const char *file
, int line
, const char *type
, MSIHANDLE hdb
, const char *values
, const char *insert
)
752 sz
= strlen(values
) + strlen(insert
) + 1;
753 query
= HeapAlloc(GetProcessHeap(), 0, sz
);
754 sprintf(query
, insert
, values
);
755 r
= run_query(hdb
, query
);
756 HeapFree(GetProcessHeap(), 0, query
);
757 ok_(file
, line
)(r
== ERROR_SUCCESS
, "failed to insert into %s table: %u\n", type
, r
);
761 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
762 "INSERT INTO `Component` " \
763 "(`Component`, `ComponentId`, `Directory_`, " \
764 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
766 #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
767 "INSERT INTO `Directory` " \
768 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
770 #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
771 "INSERT INTO `Feature` " \
772 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
773 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
775 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
776 "INSERT INTO `FeatureComponents` " \
777 "(`Feature_`, `Component_`) VALUES( %s )")
779 #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
780 "INSERT INTO `File` " \
781 "(`File`, `Component_`, `FileName`, `FileSize`, " \
782 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
784 #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
785 "INSERT INTO `AppSearch` " \
786 "(`Property`, `Signature_`) VALUES( %s )")
788 #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
789 "INSERT INTO `Signature` " \
790 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
791 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
794 #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
795 "INSERT INTO `LaunchCondition` " \
796 "(`Condition`, `Description`) VALUES( %s )")
798 #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
799 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
801 #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
802 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
804 #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
805 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
807 #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
808 "INSERT INTO `InstallExecuteSequence` " \
809 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
811 #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
812 "INSERT INTO `InstallUISequence` " \
813 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
815 #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
816 "INSERT INTO `Media` " \
817 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
818 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
820 #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
821 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
823 #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
824 "INSERT INTO `DrLocator` " \
825 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
827 #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
828 "INSERT INTO `CompLocator` " \
829 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
831 #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
832 "INSERT INTO `IniLocator` " \
833 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
836 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
837 "INSERT INTO `CustomAction` " \
838 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
840 #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
841 "INSERT INTO `Dialog` " \
842 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
844 #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
845 "INSERT INTO `Control` " \
846 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
848 #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
849 "INSERT INTO `ControlEvent` " \
850 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
852 #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
853 "INSERT INTO `ActionText` " \
854 "(`Action`, `Description`, `Template`) VALUES( %s )");
856 #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
857 "INSERT INTO `Upgrade` " \
858 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
860 static UINT
add_reglocator_entry( MSIHANDLE hdb
, const char *sig
, UINT root
, const char *path
,
861 const char *name
, UINT type
)
863 const char insert
[] =
864 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
865 "VALUES( '%s', %u, '%s', '%s', %u )";
869 sz
= strlen( sig
) + 10 + strlen( path
) + strlen( name
) + 10 + sizeof( insert
);
870 query
= HeapAlloc( GetProcessHeap(), 0, sz
);
871 sprintf( query
, insert
, sig
, root
, path
, name
, type
);
872 r
= run_query( hdb
, query
);
873 HeapFree( GetProcessHeap(), 0, query
);
874 ok(r
== ERROR_SUCCESS
, "failed to insert into reglocator table: %u\n", r
); \
878 static UINT
set_summary_info(MSIHANDLE hdb
)
883 /* build summary info */
884 res
= MsiGetSummaryInformationA(hdb
, NULL
, 7, &suminfo
);
885 ok( res
== ERROR_SUCCESS
, "Failed to open summaryinfo\n" );
887 res
= MsiSummaryInfoSetPropertyA(suminfo
,2, VT_LPSTR
, 0,NULL
,
888 "Installation Database");
889 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
891 res
= MsiSummaryInfoSetPropertyA(suminfo
,3, VT_LPSTR
, 0,NULL
,
892 "Installation Database");
893 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
895 res
= MsiSummaryInfoSetPropertyA(suminfo
,4, VT_LPSTR
, 0,NULL
,
897 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
899 res
= MsiSummaryInfoSetPropertyA(suminfo
,7, VT_LPSTR
, 0,NULL
,
901 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
903 res
= MsiSummaryInfoSetPropertyA(suminfo
,9, VT_LPSTR
, 0,NULL
,
904 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
905 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
907 res
= MsiSummaryInfoSetPropertyA(suminfo
, 14, VT_I4
, 100, NULL
, NULL
);
908 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
910 res
= MsiSummaryInfoSetPropertyA(suminfo
, 15, VT_I4
, 0, NULL
, NULL
);
911 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
913 res
= MsiSummaryInfoPersist(suminfo
);
914 ok( res
== ERROR_SUCCESS
, "Failed to make summary info persist\n" );
916 res
= MsiCloseHandle( suminfo
);
917 ok( res
== ERROR_SUCCESS
, "Failed to close suminfo\n" );
923 static MSIHANDLE
create_package_db(void)
928 DeleteFileA(msifile
);
930 /* create an empty database */
931 res
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
932 ok( res
== ERROR_SUCCESS
, "Failed to create database %u\n", res
);
933 if( res
!= ERROR_SUCCESS
)
936 res
= MsiDatabaseCommit( hdb
);
937 ok( res
== ERROR_SUCCESS
, "Failed to commit database\n" );
939 res
= set_summary_info(hdb
);
940 ok( res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", res
);
942 res
= run_query( hdb
,
943 "CREATE TABLE `Directory` ( "
944 "`Directory` CHAR(255) NOT NULL, "
945 "`Directory_Parent` CHAR(255), "
946 "`DefaultDir` CHAR(255) NOT NULL "
947 "PRIMARY KEY `Directory`)" );
948 ok( res
== ERROR_SUCCESS
, "Failed to create directory table\n" );
953 static UINT
package_from_db(MSIHANDLE hdb
, MSIHANDLE
*handle
)
959 sprintf(szPackage
, "#%u", hdb
);
960 res
= MsiOpenPackageA(szPackage
, &hPackage
);
961 if (res
!= ERROR_SUCCESS
)
967 res
= MsiCloseHandle(hdb
);
968 if (res
!= ERROR_SUCCESS
)
970 MsiCloseHandle(hPackage
);
975 return ERROR_SUCCESS
;
978 static void create_file_data(LPCSTR name
, LPCSTR data
)
983 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
984 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file %s\n", name
);
985 if (file
== INVALID_HANDLE_VALUE
)
988 WriteFile(file
, data
, strlen(data
), &written
, NULL
);
989 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
994 static void create_test_file(const CHAR
*name
)
996 create_file_data(name
, name
);
999 typedef struct _tagVS_VERSIONINFO
1006 VS_FIXEDFILEINFO Value
;
1011 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
1012 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
1014 static BOOL
create_file_with_version(const CHAR
*name
, LONG ms
, LONG ls
)
1016 VS_VERSIONINFO
*pVerInfo
;
1017 VS_FIXEDFILEINFO
*pFixedInfo
;
1019 CHAR path
[MAX_PATH
];
1024 GetSystemDirectoryA(path
, MAX_PATH
);
1025 /* Some dlls can't be updated on Vista/W2K8 */
1026 lstrcatA(path
, "\\version.dll");
1028 CopyFileA(path
, name
, FALSE
);
1030 size
= GetFileVersionInfoSizeA(path
, &handle
);
1031 buffer
= HeapAlloc(GetProcessHeap(), 0, size
);
1033 GetFileVersionInfoA(path
, 0, size
, buffer
);
1035 pVerInfo
= (VS_VERSIONINFO
*)buffer
;
1036 ofs
= (BYTE
*)&pVerInfo
->szKey
[lstrlenW(pVerInfo
->szKey
) + 1];
1037 pFixedInfo
= (VS_FIXEDFILEINFO
*)roundpos(pVerInfo
, ofs
, 4);
1039 pFixedInfo
->dwFileVersionMS
= ms
;
1040 pFixedInfo
->dwFileVersionLS
= ls
;
1041 pFixedInfo
->dwProductVersionMS
= ms
;
1042 pFixedInfo
->dwProductVersionLS
= ls
;
1044 resource
= BeginUpdateResourceA(name
, FALSE
);
1048 if (!UpdateResourceA(resource
, (LPCSTR
)RT_VERSION
, (LPCSTR
)MAKEINTRESOURCE(VS_VERSION_INFO
),
1049 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), buffer
, size
))
1052 if (!EndUpdateResourceA(resource
, FALSE
))
1058 HeapFree(GetProcessHeap(), 0, buffer
);
1062 static BOOL
notify_system_change(DWORD event_type
, STATEMGRSTATUS
*status
)
1064 RESTOREPOINTINFOA spec
;
1066 spec
.dwEventType
= event_type
;
1067 spec
.dwRestorePtType
= APPLICATION_INSTALL
;
1068 spec
.llSequenceNumber
= status
->llSequenceNumber
;
1069 lstrcpyA(spec
.szDescription
, "msitest restore point");
1071 return pSRSetRestorePointA(&spec
, status
);
1074 static void remove_restore_point(DWORD seq_number
)
1078 res
= pSRRemoveRestorePoint(seq_number
);
1079 if (res
!= ERROR_SUCCESS
)
1080 trace("Failed to remove the restore point : %08x\n", res
);
1083 static BOOL
is_root(const char *path
)
1085 return (isalpha(path
[0]) && path
[1] == ':' && path
[2] == '\\' && !path
[3]);
1088 static void test_createpackage(void)
1090 MSIHANDLE hPackage
= 0;
1093 res
= package_from_db(create_package_db(), &hPackage
);
1094 if (res
== ERROR_INSTALL_PACKAGE_REJECTED
)
1096 skip("Not enough rights to perform tests\n");
1097 DeleteFileA(msifile
);
1100 ok( res
== ERROR_SUCCESS
, " Failed to create package %u\n", res
);
1102 res
= MsiCloseHandle( hPackage
);
1103 ok( res
== ERROR_SUCCESS
, "Failed to close package\n" );
1104 DeleteFileA(msifile
);
1107 static void test_doaction( void )
1112 r
= MsiDoActionA( -1, NULL
);
1113 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1115 r
= package_from_db(create_package_db(), &hpkg
);
1116 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1118 skip("Not enough rights to perform tests\n");
1119 DeleteFileA(msifile
);
1122 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1124 r
= MsiDoActionA(hpkg
, NULL
);
1125 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1127 r
= MsiDoActionA(0, "boo");
1128 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1130 r
= MsiDoActionA(hpkg
, "boo");
1131 ok( r
== ERROR_FUNCTION_NOT_CALLED
, "wrong return val\n");
1133 MsiCloseHandle( hpkg
);
1134 DeleteFileA(msifile
);
1137 static void test_gettargetpath_bad(void)
1140 WCHAR bufferW
[0x80];
1145 r
= package_from_db(create_package_db(), &hpkg
);
1146 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1148 skip("Not enough rights to perform tests\n");
1149 DeleteFileA(msifile
);
1152 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1154 r
= MsiGetTargetPathA( 0, NULL
, NULL
, NULL
);
1155 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1157 r
= MsiGetTargetPathA( 0, NULL
, NULL
, &sz
);
1158 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1160 r
= MsiGetTargetPathA( 0, "boo", NULL
, NULL
);
1161 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1163 r
= MsiGetTargetPathA( 0, "boo", NULL
, NULL
);
1164 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1166 r
= MsiGetTargetPathA( hpkg
, "boo", NULL
, NULL
);
1167 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1169 r
= MsiGetTargetPathA( hpkg
, "boo", buffer
, NULL
);
1170 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1173 r
= MsiGetTargetPathA( hpkg
, "", buffer
, &sz
);
1174 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1176 r
= MsiGetTargetPathW( 0, NULL
, NULL
, NULL
);
1177 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1179 r
= MsiGetTargetPathW( 0, NULL
, NULL
, &sz
);
1180 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1182 r
= MsiGetTargetPathW( 0, L
"boo", NULL
, NULL
);
1183 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1185 r
= MsiGetTargetPathW( 0, L
"boo", NULL
, NULL
);
1186 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1188 r
= MsiGetTargetPathW( hpkg
, L
"boo", NULL
, NULL
);
1189 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1191 r
= MsiGetTargetPathW( hpkg
, L
"boo", bufferW
, NULL
);
1192 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1195 r
= MsiGetTargetPathW( hpkg
, L
"", bufferW
, &sz
);
1196 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1198 MsiCloseHandle( hpkg
);
1199 DeleteFileA(msifile
);
1202 static void query_file_path(MSIHANDLE hpkg
, LPCSTR file
, LPSTR buff
)
1208 rec
= MsiCreateRecord( 1 );
1209 ok(rec
, "MsiCreate record failed\n");
1211 r
= MsiRecordSetStringA( rec
, 0, file
);
1212 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
1215 r
= MsiFormatRecordA( hpkg
, rec
, buff
, &size
);
1216 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
1218 MsiCloseHandle( rec
);
1221 static void test_settargetpath(void)
1223 char tempdir
[MAX_PATH
+8], buffer
[MAX_PATH
], file
[MAX_PATH
+ 20];
1229 hdb
= create_package_db();
1230 ok ( hdb
, "failed to create package database\n" );
1232 add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'" );
1234 create_component_table( hdb
);
1235 add_component_entry( hdb
, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1236 add_component_entry( hdb
, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1238 create_feature_table( hdb
);
1239 add_feature_entry( hdb
, "'TestFeature', '', '', '', 0, 1, '', 0" );
1241 create_feature_components_table( hdb
);
1242 add_feature_components_entry( hdb
, "'TestFeature', 'RootComp'" );
1243 add_feature_components_entry( hdb
, "'TestFeature', 'TestComp'" );
1245 add_directory_entry( hdb
, "'TestParent', 'TARGETDIR', 'TestParent'" );
1246 add_directory_entry( hdb
, "'TestDir', 'TestParent', 'TestDir'" );
1248 create_file_table( hdb
);
1249 add_file_entry( hdb
, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1250 add_file_entry( hdb
, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1252 r
= package_from_db( hdb
, &hpkg
);
1253 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1255 skip("Not enough rights to perform tests\n");
1256 DeleteFileA(msifile
);
1259 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1261 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
1263 r
= MsiDoActionA( hpkg
, "CostInitialize");
1264 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
1266 r
= MsiDoActionA( hpkg
, "FileCost");
1267 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
1269 r
= MsiDoActionA( hpkg
, "CostFinalize");
1270 ok( r
== ERROR_SUCCESS
, "cost finalize failed\n");
1273 sz
= sizeof(buffer
);
1274 r
= MsiGetPropertyA( hpkg
, "OutOfNoRbDiskSpace", buffer
, &sz
);
1275 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1276 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer
);
1278 r
= MsiSetTargetPathA( 0, NULL
, NULL
);
1279 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1281 r
= MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1282 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1284 r
= MsiSetTargetPathA( hpkg
, "boo", NULL
);
1285 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1287 r
= MsiSetTargetPathA( hpkg
, "boo", "c:\\bogusx" );
1288 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1290 sz
= sizeof tempdir
- 1;
1291 r
= MsiGetTargetPathA( hpkg
, "TARGETDIR", tempdir
, &sz
);
1292 sprintf( file
, "%srootfile.txt", tempdir
);
1294 query_file_path( hpkg
, "[#RootFile]", buffer
);
1295 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1296 ok( !lstrcmpA(buffer
, file
), "Expected %s, got %s\n", file
, buffer
);
1298 GetTempFileNameA( tempdir
, "_wt", 0, buffer
);
1299 sprintf( tempdir
, "%s\\subdir", buffer
);
1301 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", buffer
);
1302 ok( r
== ERROR_SUCCESS
|| r
== ERROR_DIRECTORY
,
1303 "MsiSetTargetPath on file returned %d\n", r
);
1305 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", tempdir
);
1306 ok( r
== ERROR_SUCCESS
|| r
== ERROR_DIRECTORY
,
1307 "MsiSetTargetPath on 'subdir' of file returned %d\n", r
);
1309 DeleteFileA( buffer
);
1311 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", buffer
);
1312 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1314 r
= GetFileAttributesA( buffer
);
1315 ok ( r
== INVALID_FILE_ATTRIBUTES
, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r
);
1317 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", tempdir
);
1318 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath on subsubdir returned %d\n", r
);
1321 sz
= sizeof buffer
- 1;
1322 lstrcatA( tempdir
, "\\" );
1323 r
= MsiGetTargetPathA( hpkg
, "TARGETDIR", buffer
, &sz
);
1324 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1325 ok( !lstrcmpA(buffer
, tempdir
), "Expected %s, got %s\n", tempdir
, buffer
);
1327 sprintf( file
, "%srootfile.txt", tempdir
);
1328 query_file_path( hpkg
, "[#RootFile]", buffer
);
1329 ok( !lstrcmpA(buffer
, file
), "Expected %s, got %s\n", file
, buffer
);
1332 sz
= sizeof(buffer
);
1333 r
= MsiGetPropertyA( hpkg
, "TestParent", buffer
, &sz
);
1334 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1335 lstrcatA( tempdir
, "TestParent\\" );
1336 ok( !lstrcmpiA(buffer
, tempdir
), "Expected \"%s\", got \"%s\"\n", tempdir
, buffer
);
1338 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\one\\two" );
1339 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1342 sz
= sizeof(buffer
);
1343 r
= MsiGetPropertyA( hpkg
, "TestParent", buffer
, &sz
);
1344 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1345 ok( lstrcmpiA(buffer
, "C:\\one\\two\\TestDir\\"),
1346 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer
);
1349 query_file_path( hpkg
, "[#TestFile]", buffer
);
1350 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\TestDir\\testfile.txt"),
1351 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer
);
1354 sz
= sizeof buffer
- 1;
1355 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1356 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1357 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer
);
1359 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\one\\two\\three" );
1360 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1363 sz
= sizeof buffer
- 1;
1364 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1365 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1366 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer
);
1368 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\\\one\\\\two " );
1369 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1372 sz
= sizeof buffer
- 1;
1373 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1374 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1375 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer
);
1377 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\\\ Program Files \\\\ " );
1378 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1381 sz
= sizeof buffer
- 1;
1382 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1383 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1384 ok( !lstrcmpiA(buffer
, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer
);
1386 MsiCloseHandle( hpkg
);
1389 static void test_condition(void)
1394 r
= package_from_db(create_package_db(), &hpkg
);
1395 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1397 skip("Not enough rights to perform tests\n");
1398 DeleteFileA(msifile
);
1401 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1403 r
= MsiEvaluateConditionA(0, NULL
);
1404 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1406 r
= MsiEvaluateConditionA(hpkg
, NULL
);
1407 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1409 r
= MsiEvaluateConditionA(hpkg
, "");
1410 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1412 r
= MsiEvaluateConditionA(hpkg
, "1");
1413 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1415 r
= MsiEvaluateConditionA(hpkg
, "0");
1416 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1418 r
= MsiEvaluateConditionA(hpkg
, "-1");
1419 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1421 r
= MsiEvaluateConditionA(hpkg
, "0 = 0");
1422 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1424 r
= MsiEvaluateConditionA(hpkg
, "0 <> 0");
1425 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1427 r
= MsiEvaluateConditionA(hpkg
, "0 = 1");
1428 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1430 r
= MsiEvaluateConditionA(hpkg
, "0 > 1");
1431 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1433 r
= MsiEvaluateConditionA(hpkg
, "0 ~> 1");
1434 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1436 r
= MsiEvaluateConditionA(hpkg
, "1 > 1");
1437 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1439 r
= MsiEvaluateConditionA(hpkg
, "1 ~> 1");
1440 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1442 r
= MsiEvaluateConditionA(hpkg
, "0 >= 1");
1443 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1445 r
= MsiEvaluateConditionA(hpkg
, "0 ~>= 1");
1446 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1448 r
= MsiEvaluateConditionA(hpkg
, "1 >= 1");
1449 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1451 r
= MsiEvaluateConditionA(hpkg
, "1 ~>= 1");
1452 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1454 r
= MsiEvaluateConditionA(hpkg
, "0 < 1");
1455 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1457 r
= MsiEvaluateConditionA(hpkg
, "0 ~< 1");
1458 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1460 r
= MsiEvaluateConditionA(hpkg
, "1 < 1");
1461 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1463 r
= MsiEvaluateConditionA(hpkg
, "1 ~< 1");
1464 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1466 r
= MsiEvaluateConditionA(hpkg
, "0 <= 1");
1467 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1469 r
= MsiEvaluateConditionA(hpkg
, "0 ~<= 1");
1470 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1472 r
= MsiEvaluateConditionA(hpkg
, "1 <= 1");
1473 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1475 r
= MsiEvaluateConditionA(hpkg
, "1 ~<= 1");
1476 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1478 r
= MsiEvaluateConditionA(hpkg
, "0 >=");
1479 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1481 r
= MsiEvaluateConditionA(hpkg
, " ");
1482 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1484 r
= MsiEvaluateConditionA(hpkg
, "LicView <> \"1\"");
1485 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1487 r
= MsiEvaluateConditionA(hpkg
, "LicView <> \"0\"");
1488 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1490 r
= MsiEvaluateConditionA(hpkg
, "LicView <> LicView");
1491 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1493 r
= MsiEvaluateConditionA(hpkg
, "not 0");
1494 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1496 r
= MsiEvaluateConditionA(hpkg
, "not LicView");
1497 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1499 r
= MsiEvaluateConditionA(hpkg
, "\"Testing\" ~<< \"Testing\"");
1500 ok (r
== MSICONDITION_TRUE
, "wrong return val\n");
1502 r
= MsiEvaluateConditionA(hpkg
, "LicView ~<< \"Testing\"");
1503 ok (r
== MSICONDITION_FALSE
, "wrong return val\n");
1505 r
= MsiEvaluateConditionA(hpkg
, "Not LicView ~<< \"Testing\"");
1506 ok (r
== MSICONDITION_TRUE
, "wrong return val\n");
1508 r
= MsiEvaluateConditionA(hpkg
, "not \"A\"");
1509 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1511 r
= MsiEvaluateConditionA(hpkg
, "~not \"A\"");
1512 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1514 r
= MsiEvaluateConditionA(hpkg
, "\"0\"");
1515 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1517 r
= MsiEvaluateConditionA(hpkg
, "1 and 2");
1518 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1520 r
= MsiEvaluateConditionA(hpkg
, "not 0 and 3");
1521 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1523 r
= MsiEvaluateConditionA(hpkg
, "not 0 and 0");
1524 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1526 r
= MsiEvaluateConditionA(hpkg
, "not 0 or 1");
1527 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1529 r
= MsiEvaluateConditionA(hpkg
, "(0)");
1530 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1532 r
= MsiEvaluateConditionA(hpkg
, "(((((1))))))");
1533 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1535 r
= MsiEvaluateConditionA(hpkg
, "(((((1)))))");
1536 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1538 r
= MsiEvaluateConditionA(hpkg
, " \"A\" < \"B\" ");
1539 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1541 r
= MsiEvaluateConditionA(hpkg
, " \"A\" > \"B\" ");
1542 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1544 r
= MsiEvaluateConditionA(hpkg
, " \"1\" > \"12\" ");
1545 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1547 r
= MsiEvaluateConditionA(hpkg
, " \"100\" < \"21\" ");
1548 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1550 r
= MsiEvaluateConditionA(hpkg
, "0 < > 0");
1551 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1553 r
= MsiEvaluateConditionA(hpkg
, "(1<<1) == 2");
1554 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1556 r
= MsiEvaluateConditionA(hpkg
, " \"A\" = \"a\" ");
1557 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1559 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~ = \"a\" ");
1560 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1562 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~= \"a\" ");
1563 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1565 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~= 1 ");
1566 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1568 r
= MsiEvaluateConditionA(hpkg
, " \"A\" = 1 ");
1569 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1571 r
= MsiEvaluateConditionA(hpkg
, " 1 ~= 1 ");
1572 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1574 r
= MsiEvaluateConditionA(hpkg
, " 1 ~= \"1\" ");
1575 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1577 r
= MsiEvaluateConditionA(hpkg
, " 1 = \"1\" ");
1578 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1580 r
= MsiEvaluateConditionA(hpkg
, " 0 = \"1\" ");
1581 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1583 r
= MsiEvaluateConditionA(hpkg
, " 0 < \"100\" ");
1584 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1586 r
= MsiEvaluateConditionA(hpkg
, " 100 > \"0\" ");
1587 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1589 r
= MsiEvaluateConditionA(hpkg
, "1 XOR 1");
1590 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1592 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 1");
1593 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1595 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 0");
1596 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1598 r
= MsiEvaluateConditionA(hpkg
, "0 IMP 0");
1599 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1601 r
= MsiEvaluateConditionA(hpkg
, "0 EQV 0");
1602 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1604 r
= MsiEvaluateConditionA(hpkg
, "0 EQV 1");
1605 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1607 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 1 OR 0");
1608 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1610 r
= MsiEvaluateConditionA(hpkg
, "1 IMPL 1");
1611 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1613 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" >< \"S\" ");
1614 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1616 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"s\" ");
1617 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1619 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"\" ");
1620 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1622 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"sss\" ");
1623 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1625 MsiSetPropertyA(hpkg
, "mm", "5" );
1627 r
= MsiEvaluateConditionA(hpkg
, "mm = 5");
1628 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1630 r
= MsiEvaluateConditionA(hpkg
, "mm < 6");
1631 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1633 r
= MsiEvaluateConditionA(hpkg
, "mm <= 5");
1634 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1636 r
= MsiEvaluateConditionA(hpkg
, "mm > 4");
1637 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1639 r
= MsiEvaluateConditionA(hpkg
, "mm < 12");
1640 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1642 r
= MsiEvaluateConditionA(hpkg
, "mm = \"5\"");
1643 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1645 r
= MsiEvaluateConditionA(hpkg
, "0 = \"\"");
1646 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1648 r
= MsiEvaluateConditionA(hpkg
, "0 AND \"\"");
1649 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1651 r
= MsiEvaluateConditionA(hpkg
, "1 AND \"\"");
1652 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1654 r
= MsiEvaluateConditionA(hpkg
, "1 AND \"1\"");
1655 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1657 r
= MsiEvaluateConditionA(hpkg
, "3 >< 1");
1658 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1660 r
= MsiEvaluateConditionA(hpkg
, "3 >< 4");
1661 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1663 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 0");
1664 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1666 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 1");
1667 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1669 r
= MsiEvaluateConditionA(hpkg
, "NOT 1 OR 0");
1670 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1672 r
= MsiEvaluateConditionA(hpkg
, "0 AND 1 OR 1");
1673 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1675 r
= MsiEvaluateConditionA(hpkg
, "0 AND 0 OR 1");
1676 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1678 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 1 OR 0");
1679 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1681 r
= MsiEvaluateConditionA(hpkg
, "_1 = _1");
1682 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1684 r
= MsiEvaluateConditionA(hpkg
, "( 1 AND 1 ) = 2");
1685 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1687 r
= MsiEvaluateConditionA(hpkg
, "NOT ( 1 AND 1 )");
1688 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1690 r
= MsiEvaluateConditionA(hpkg
, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1691 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1693 r
= MsiEvaluateConditionA(hpkg
, "Installed<>\"\"");
1694 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1696 r
= MsiEvaluateConditionA(hpkg
, "NOT 1 AND 0");
1697 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1699 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1700 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1702 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<>0");
1703 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1705 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<0");
1706 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1708 r
= MsiEvaluateConditionA(hpkg
, "bandalmael>0");
1709 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1711 r
= MsiEvaluateConditionA(hpkg
, "bandalmael>=0");
1712 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1714 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<=0");
1715 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1717 r
= MsiEvaluateConditionA(hpkg
, "bandalmael~<>0");
1718 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1720 MsiSetPropertyA(hpkg
, "bandalmael", "0" );
1721 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1722 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1724 MsiSetPropertyA(hpkg
, "bandalmael", "" );
1725 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1726 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1728 MsiSetPropertyA(hpkg
, "bandalmael", "asdf" );
1729 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1730 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1732 MsiSetPropertyA(hpkg
, "bandalmael", "0asdf" );
1733 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1734 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1736 MsiSetPropertyA(hpkg
, "bandalmael", "0 " );
1737 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1738 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1740 MsiSetPropertyA(hpkg
, "bandalmael", "-0" );
1741 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1742 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1744 MsiSetPropertyA(hpkg
, "bandalmael", "0000000000000" );
1745 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1746 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1748 MsiSetPropertyA(hpkg
, "bandalmael", "--0" );
1749 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1750 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1752 MsiSetPropertyA(hpkg
, "bandalmael", "0x00" );
1753 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1754 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1756 MsiSetPropertyA(hpkg
, "bandalmael", "-" );
1757 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1758 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1760 MsiSetPropertyA(hpkg
, "bandalmael", "+0" );
1761 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1762 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1764 MsiSetPropertyA(hpkg
, "bandalmael", "0.0" );
1765 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1766 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1767 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<>0");
1768 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1770 MsiSetPropertyA(hpkg
, "one", "hi");
1771 MsiSetPropertyA(hpkg
, "two", "hithere");
1772 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1773 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1775 MsiSetPropertyA(hpkg
, "one", "hithere");
1776 MsiSetPropertyA(hpkg
, "two", "hi");
1777 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1778 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1780 MsiSetPropertyA(hpkg
, "one", "hello");
1781 MsiSetPropertyA(hpkg
, "two", "hi");
1782 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1783 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1785 MsiSetPropertyA(hpkg
, "one", "hellohithere");
1786 MsiSetPropertyA(hpkg
, "two", "hi");
1787 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1788 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1790 MsiSetPropertyA(hpkg
, "one", "");
1791 MsiSetPropertyA(hpkg
, "two", "hi");
1792 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1793 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1795 MsiSetPropertyA(hpkg
, "one", "hi");
1796 MsiSetPropertyA(hpkg
, "two", "");
1797 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1798 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1800 MsiSetPropertyA(hpkg
, "one", "");
1801 MsiSetPropertyA(hpkg
, "two", "");
1802 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1803 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1805 MsiSetPropertyA(hpkg
, "one", "1234");
1806 MsiSetPropertyA(hpkg
, "two", "1");
1807 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1808 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1810 MsiSetPropertyA(hpkg
, "one", "one 1234");
1811 MsiSetPropertyA(hpkg
, "two", "1");
1812 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1813 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1815 MsiSetPropertyA(hpkg
, "one", "hithere");
1816 MsiSetPropertyA(hpkg
, "two", "hi");
1817 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1818 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1820 MsiSetPropertyA(hpkg
, "one", "hi");
1821 MsiSetPropertyA(hpkg
, "two", "hithere");
1822 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1823 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1825 MsiSetPropertyA(hpkg
, "one", "hi");
1826 MsiSetPropertyA(hpkg
, "two", "hi");
1827 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1828 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1830 MsiSetPropertyA(hpkg
, "one", "abcdhithere");
1831 MsiSetPropertyA(hpkg
, "two", "hi");
1832 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1833 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1835 MsiSetPropertyA(hpkg
, "one", "");
1836 MsiSetPropertyA(hpkg
, "two", "hi");
1837 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1838 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1840 MsiSetPropertyA(hpkg
, "one", "hithere");
1841 MsiSetPropertyA(hpkg
, "two", "");
1842 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1843 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1845 MsiSetPropertyA(hpkg
, "one", "");
1846 MsiSetPropertyA(hpkg
, "two", "");
1847 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1848 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1850 MsiSetPropertyA(hpkg
, "one", "1234");
1851 MsiSetPropertyA(hpkg
, "two", "1");
1852 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1853 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1855 MsiSetPropertyA(hpkg
, "one", "1234 one");
1856 MsiSetPropertyA(hpkg
, "two", "1");
1857 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1858 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1860 MsiSetPropertyA(hpkg
, "one", "hithere");
1861 MsiSetPropertyA(hpkg
, "two", "there");
1862 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1863 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1865 MsiSetPropertyA(hpkg
, "one", "hithere");
1866 MsiSetPropertyA(hpkg
, "two", "hi");
1867 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1868 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1870 MsiSetPropertyA(hpkg
, "one", "there");
1871 MsiSetPropertyA(hpkg
, "two", "hithere");
1872 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1873 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1875 MsiSetPropertyA(hpkg
, "one", "there");
1876 MsiSetPropertyA(hpkg
, "two", "there");
1877 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1878 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1880 MsiSetPropertyA(hpkg
, "one", "abcdhithere");
1881 MsiSetPropertyA(hpkg
, "two", "hi");
1882 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1883 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1885 MsiSetPropertyA(hpkg
, "one", "");
1886 MsiSetPropertyA(hpkg
, "two", "there");
1887 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1888 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1890 MsiSetPropertyA(hpkg
, "one", "there");
1891 MsiSetPropertyA(hpkg
, "two", "");
1892 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1893 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1895 MsiSetPropertyA(hpkg
, "one", "");
1896 MsiSetPropertyA(hpkg
, "two", "");
1897 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1898 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1900 MsiSetPropertyA(hpkg
, "one", "1234");
1901 MsiSetPropertyA(hpkg
, "two", "4");
1902 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1903 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1905 MsiSetPropertyA(hpkg
, "one", "one 1234");
1906 MsiSetPropertyA(hpkg
, "two", "4");
1907 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1908 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1910 MsiSetPropertyA(hpkg
, "MsiNetAssemblySupport", NULL
); /* make sure it's empty */
1912 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322\"");
1913 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1915 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport > \"1.1.4322\"");
1916 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1918 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport >= \"1.1.4322\"");
1919 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1921 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport <= \"1.1.4322\"");
1922 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1924 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport <> \"1.1.4322\"");
1925 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1927 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1928 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1930 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"abcd\"");
1931 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1933 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a1.1.4322\"");
1934 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1936 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322a\"");
1937 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1939 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1940 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1942 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1943 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1945 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1946 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1948 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"1.1");
1949 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
1951 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"1.1\"");
1952 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1954 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"12.1\"");
1955 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1957 r
= MsiEvaluateConditionA(hpkg
, "\"02.1\" < \"2.11\"");
1958 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1960 r
= MsiEvaluateConditionA(hpkg
, "\"02.1.1\" < \"2.1\"");
1961 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1963 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1\"");
1964 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1966 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1\"");
1967 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1969 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"0\"");
1970 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1972 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"-1\"");
1973 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1975 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a\"");
1976 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1978 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"!\"");
1979 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1981 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"!\"");
1982 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1984 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"/\"");
1985 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1987 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \" \"");
1988 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1990 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"azAZ_\"");
1991 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1993 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a[a]\"");
1994 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1996 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a[a]a\"");
1997 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1999 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a]\"");
2000 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2002 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a]a\"");
2003 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2005 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"{a}\"");
2006 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2008 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"{a\"");
2009 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2011 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a\"");
2012 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2014 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a{\"");
2015 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2017 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a]\"");
2018 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2020 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"A\"");
2021 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2023 MsiSetPropertyA(hpkg
, "MsiNetAssemblySupport", "1.1.4322");
2024 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322\"");
2025 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2027 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.14322\"");
2028 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2030 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.5\"");
2031 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2033 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1\"");
2034 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2036 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1\"");
2037 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2039 MsiSetPropertyA(hpkg
, "one", "1");
2040 r
= MsiEvaluateConditionA(hpkg
, "one < \"1\"");
2041 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
2043 MsiSetPropertyA(hpkg
, "X", "5.0");
2045 r
= MsiEvaluateConditionA(hpkg
, "X != \"\"");
2046 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
2048 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.0\"");
2049 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2051 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.1\"");
2052 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2054 r
= MsiEvaluateConditionA(hpkg
, "X =\"6.0\"");
2055 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2057 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
2058 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2060 r
= MsiEvaluateConditionA(hpkg
, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2061 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2063 r
= MsiEvaluateConditionA(hpkg
, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2064 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
2066 /* feature doesn't exist */
2067 r
= MsiEvaluateConditionA(hpkg
, "&nofeature");
2068 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2069 r
= MsiEvaluateConditionA(hpkg
, "&nofeature=\"\"");
2070 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2071 r
= MsiEvaluateConditionA(hpkg
, "&nofeature<>3");
2072 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2073 r
= MsiEvaluateConditionA(hpkg
, "\"\"<>3");
2074 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2075 r
= MsiEvaluateConditionA(hpkg
, "!nofeature=\"\"");
2076 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2077 r
= MsiEvaluateConditionA(hpkg
, "$nocomponent=\"\"");
2078 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2079 r
= MsiEvaluateConditionA(hpkg
, "?nocomponent=\"\"");
2080 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2082 MsiSetPropertyA(hpkg
, "A", "2");
2083 MsiSetPropertyA(hpkg
, "X", "50");
2085 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
2086 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2088 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
2089 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2091 r
= MsiEvaluateConditionA(hpkg
, "A <= 50");
2092 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2094 MsiSetPropertyA(hpkg
, "X", "50val");
2096 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
2097 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2099 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
2100 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2102 MsiSetPropertyA(hpkg
, "A", "7");
2103 MsiSetPropertyA(hpkg
, "X", "50");
2105 r
= MsiEvaluateConditionA(hpkg
, "7 <= X");
2106 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2108 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
2109 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2111 r
= MsiEvaluateConditionA(hpkg
, "A <= 50");
2112 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
2114 MsiSetPropertyA(hpkg
, "X", "50val");
2116 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
2117 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2119 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
2120 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
2122 r
= MsiEvaluateConditionW(hpkg
, L
"\"a\x30a\"<\"\xe5\"");
2123 ok( r
== MSICONDITION_TRUE
|| broken(r
== MSICONDITION_FALSE
),
2124 "wrong return val (%d)\n", r
);
2126 r
= MsiEvaluateConditionW(hpkg
, L
"\"a\x30a\">\"\xe5\"");
2127 ok( r
== MSICONDITION_FALSE
|| broken(r
== MSICONDITION_TRUE
),
2128 "wrong return val (%d)\n", r
);
2130 r
= MsiEvaluateConditionW(hpkg
, L
"\"a\x30a\"<>\"\xe5\"");
2131 ok( r
== MSICONDITION_TRUE
|| broken(r
== MSICONDITION_FALSE
),
2132 "wrong return val (%d)\n", r
);
2134 r
= MsiEvaluateConditionW(hpkg
, L
"\"a\x30a\"=\"\xe5\"");
2135 ok( r
== MSICONDITION_FALSE
|| broken(r
== MSICONDITION_TRUE
),
2136 "wrong return val (%d)\n", r
);
2138 MsiCloseHandle( hpkg
);
2139 DeleteFileA(msifile
);
2142 static void check_prop(MSIHANDLE hpkg
, const char *prop
, const char *expect
, int match_case
)
2144 char buffer
[MAX_PATH
] = "x";
2145 DWORD sz
= sizeof(buffer
);
2146 UINT r
= MsiGetPropertyA(hpkg
, prop
, buffer
, &sz
);
2147 ok(!r
, "'%s': got %u\n", prop
, r
);
2148 ok(sz
== lstrlenA(buffer
), "'%s': expected %u, got %u\n", prop
, lstrlenA(buffer
), sz
);
2150 ok(!strcmp(buffer
, expect
), "'%s': expected '%s', got '%s'\n", prop
, expect
, buffer
);
2152 ok(!_stricmp(buffer
, expect
), "'%s': expected '%s', got '%s'\n", prop
, expect
, buffer
);
2155 static void test_props(void)
2157 MSIHANDLE hpkg
, hdb
;
2163 hdb
= create_package_db();
2165 create_property_table(hdb
);
2166 add_property_entry(hdb
, "'MetadataCompName', 'Photoshop.dll'");
2168 r
= package_from_db( hdb
, &hpkg
);
2169 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2171 skip("Not enough rights to perform tests\n");
2172 DeleteFileA(msifile
);
2175 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2177 /* test invalid values */
2178 r
= MsiGetPropertyA( 0, NULL
, NULL
, NULL
);
2179 ok(r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
2181 r
= MsiGetPropertyA( hpkg
, NULL
, NULL
, NULL
);
2182 ok(r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
2184 r
= MsiGetPropertyA( hpkg
, "boo", NULL
, NULL
);
2185 ok(!r
, "got %u\n", r
);
2187 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, NULL
);
2188 ok(r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
2190 /* test retrieving an empty/nonexistent property */
2192 r
= MsiGetPropertyA( hpkg
, "boo", NULL
, &sz
);
2193 ok(!r
, "got %u\n", r
);
2194 ok(sz
== 0, "got size %d\n", sz
);
2198 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2199 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2200 ok(!strcmp(buffer
,"x"), "got \"%s\"\n", buffer
);
2201 ok(sz
== 0, "got size %u\n", sz
);
2205 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2206 ok(!r
, "got %u\n", r
);
2207 ok(!buffer
[0], "got \"%s\"\n", buffer
);
2208 ok(sz
== 0, "got size %u\n", sz
);
2210 /* set the property to something */
2211 r
= MsiSetPropertyA( 0, NULL
, NULL
);
2212 ok(r
== ERROR_INVALID_HANDLE
, "got %u\n", r
);
2214 r
= MsiSetPropertyA( hpkg
, NULL
, NULL
);
2215 ok(r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
2217 r
= MsiSetPropertyA( hpkg
, "", NULL
);
2218 ok(!r
, "got %u\n", r
);
2220 r
= MsiSetPropertyA( hpkg
, "", "asdf" );
2221 ok(r
== ERROR_FUNCTION_FAILED
, "got %u\n", r
);
2223 r
= MsiSetPropertyA( hpkg
, "=", "asdf" );
2224 ok(!r
, "got %u\n", r
);
2225 check_prop(hpkg
, "=", "asdf", 1);
2227 r
= MsiSetPropertyA( hpkg
, " ", "asdf" );
2228 ok(!r
, "got %u\n", r
);
2229 check_prop(hpkg
, " ", "asdf", 1);
2231 r
= MsiSetPropertyA( hpkg
, "'", "asdf" );
2232 ok(!r
, "got %u\n", r
);
2233 check_prop(hpkg
, "'", "asdf", 1);
2235 /* set empty values */
2236 r
= MsiSetPropertyA( hpkg
, "boo", NULL
);
2237 ok(!r
, "got %u\n", r
);
2238 check_prop(hpkg
, "boo", "", 1);
2240 r
= MsiSetPropertyA( hpkg
, "boo", "" );
2241 ok(!r
, "got %u\n", r
);
2242 check_prop(hpkg
, "boo", "", 1);
2244 /* set a non-empty value */
2245 r
= MsiSetPropertyA( hpkg
, "boo", "xyz" );
2246 ok(!r
, "got %u\n", r
);
2247 check_prop(hpkg
, "boo", "xyz", 1);
2249 r
= MsiGetPropertyA(hpkg
, "boo", NULL
, NULL
);
2250 ok(!r
, "got %u\n", r
);
2252 r
= MsiGetPropertyA(hpkg
, "boo", buffer
, NULL
);
2253 ok(r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
2256 r
= MsiGetPropertyA(hpkg
, "boo", NULL
, &sz
);
2257 ok(!r
, "got %u\n", r
);
2258 ok(sz
== 3, "got size %u\n", sz
);
2261 strcpy(buffer
, "q");
2262 r
= MsiGetPropertyA(hpkg
, "boo", buffer
, &sz
);
2263 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2264 ok(!strcmp(buffer
, "q"), "got \"%s\"", buffer
);
2265 ok(sz
== 3, "got size %u\n", sz
);
2269 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2270 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2271 ok(!buffer
[0], "got \"%s\"\n", buffer
);
2272 ok(sz
== 3, "got size %u\n", sz
);
2276 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2277 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2278 ok(!strcmp(buffer
,"xy"), "got \"%s\"\n", buffer
);
2279 ok(sz
== 3, "got size %u\n", sz
);
2283 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2284 ok(!r
, "got %u\n", r
);
2285 ok(!strcmp(buffer
,"xyz"), "got \"%s\"\n", buffer
);
2286 ok(sz
== 3, "got size %u\n", sz
);
2289 r
= MsiGetPropertyW(hpkg
, L
"boo", NULL
, &sz
);
2290 ok(!r
, "got %u\n", r
);
2291 ok(sz
== 3, "got size %u\n", sz
);
2294 lstrcpyW(bufferW
, L
"boo");
2295 r
= MsiGetPropertyW(hpkg
, L
"boo", bufferW
, &sz
);
2296 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2297 ok(!lstrcmpW(bufferW
, L
"boo"), "got %s\n", wine_dbgstr_w(bufferW
));
2298 ok(sz
== 3, "got size %u\n", sz
);
2301 lstrcpyW(bufferW
, L
"boo");
2302 r
= MsiGetPropertyW(hpkg
, L
"boo", bufferW
, &sz
);
2303 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2304 ok(!bufferW
[0], "got %s\n", wine_dbgstr_w(bufferW
));
2305 ok(sz
== 3, "got size %u\n", sz
);
2308 lstrcpyW(bufferW
, L
"boo");
2309 r
= MsiGetPropertyW(hpkg
, L
"boo", bufferW
, &sz
);
2310 ok(r
== ERROR_MORE_DATA
, "got %u\n", r
);
2311 ok(!lstrcmpW(bufferW
, L
"xy"), "got %s\n", wine_dbgstr_w(bufferW
));
2312 ok(sz
== 3, "got size %u\n", sz
);
2315 lstrcpyW(bufferW
, L
"boo");
2316 r
= MsiGetPropertyW(hpkg
, L
"boo", bufferW
, &sz
);
2317 ok(!r
, "got %u\n", r
);
2318 ok(!lstrcmpW(bufferW
, L
"xyz"), "got %s\n", wine_dbgstr_w(bufferW
));
2319 ok(sz
== 3, "got size %u\n", sz
);
2321 /* properties are case-sensitive */
2322 check_prop(hpkg
, "BOO", "", 1);
2324 /* properties set in Property table should work */
2325 check_prop(hpkg
, "MetadataCompName", "Photoshop.dll", 1);
2327 MsiCloseHandle( hpkg
);
2328 DeleteFileA(msifile
);
2331 static BOOL
find_prop_in_property(MSIHANDLE hdb
, LPCSTR prop
, LPCSTR val
, int len
)
2333 MSIHANDLE hview
, hrec
;
2335 CHAR buffer
[MAX_PATH
];
2339 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Property`", &hview
);
2340 ok(r
== ERROR_SUCCESS
, "MsiDatabaseOpenView failed\n");
2341 r
= MsiViewExecute(hview
, 0);
2342 ok(r
== ERROR_SUCCESS
, "MsiViewExecute failed\n");
2344 if (len
< 0) len
= lstrlenA(val
);
2346 while (r
== ERROR_SUCCESS
&& !found
)
2348 r
= MsiViewFetch(hview
, &hrec
);
2349 if (r
!= ERROR_SUCCESS
) break;
2352 r
= MsiRecordGetStringA(hrec
, 1, buffer
, &sz
);
2353 if (r
== ERROR_SUCCESS
&& !lstrcmpA(buffer
, prop
))
2356 r
= MsiRecordGetStringA(hrec
, 2, buffer
, &sz
);
2357 if (r
== ERROR_SUCCESS
&& !memcmp(buffer
, val
, len
) && !buffer
[len
])
2359 ok(sz
== len
, "wrong size %u\n", sz
);
2364 MsiCloseHandle(hrec
);
2366 MsiViewClose(hview
);
2367 MsiCloseHandle(hview
);
2371 static void test_property_table(void)
2375 MSIHANDLE hpkg
, hdb
, hrec
;
2376 char buffer
[MAX_PATH
], package
[10];
2380 hdb
= create_package_db();
2381 ok( hdb
, "failed to create package\n");
2383 r
= package_from_db(hdb
, &hpkg
);
2384 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2386 skip("Not enough rights to perform tests\n");
2387 DeleteFileA(msifile
);
2390 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2392 MsiCloseHandle(hdb
);
2394 hdb
= MsiGetActiveDatabase(hpkg
);
2396 query
= "CREATE TABLE `_Property` ( "
2397 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2398 r
= run_query(hdb
, query
);
2399 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
2401 MsiCloseHandle(hdb
);
2402 MsiCloseHandle(hpkg
);
2403 DeleteFileA(msifile
);
2405 hdb
= create_package_db();
2406 ok( hdb
, "failed to create package\n");
2408 query
= "CREATE TABLE `_Property` ( "
2409 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2410 r
= run_query(hdb
, query
);
2411 ok(r
== ERROR_SUCCESS
, "failed to create table\n");
2413 query
= "ALTER `_Property` ADD `foo` INTEGER";
2414 r
= run_query(hdb
, query
);
2415 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "failed to add column\n");
2417 query
= "ALTER TABLE `_Property` ADD `foo` INTEGER";
2418 r
= run_query(hdb
, query
);
2419 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "failed to add column\n");
2421 query
= "ALTER TABLE `_Property` ADD `extra` INTEGER";
2422 r
= run_query(hdb
, query
);
2423 ok(r
== ERROR_SUCCESS
, "failed to add column\n");
2425 sprintf(package
, "#%i", hdb
);
2426 r
= MsiOpenPackageA(package
, &hpkg
);
2427 ok(r
!= ERROR_SUCCESS
, "MsiOpenPackage succeeded\n");
2428 if (r
== ERROR_SUCCESS
)
2429 MsiCloseHandle(hpkg
);
2431 r
= MsiCloseHandle(hdb
);
2432 ok(r
== ERROR_SUCCESS
, "MsiCloseHandle failed %u\n", r
);
2434 hdb
= create_package_db();
2435 ok (hdb
, "failed to create package database\n");
2437 create_property_table(hdb
);
2438 add_property_entry(hdb
, "'prop', 'val'");
2440 create_custom_action_table(hdb
);
2441 add_custom_action_entry( hdb
, "'EmbedNull', 51, 'prop2', '[~]np'" );
2443 r
= package_from_db(hdb
, &hpkg
);
2444 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2446 MsiCloseHandle(hdb
);
2449 r
= MsiGetPropertyA(hpkg
, "prop", buffer
, &sz
);
2450 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2451 ok(!lstrcmpA(buffer
, "val"), "Expected val, got %s\n", buffer
);
2453 hdb
= MsiGetActiveDatabase(hpkg
);
2455 found
= find_prop_in_property(hdb
, "prop", "val", -1);
2456 ok(found
, "prop should be in the _Property table\n");
2458 add_property_entry(hdb
, "'dantes', 'mercedes'");
2460 query
= "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2461 r
= do_query(hdb
, query
, &hrec
);
2462 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
2464 found
= find_prop_in_property(hdb
, "dantes", "mercedes", -1);
2465 ok(found
== FALSE
, "dantes should not be in the _Property table\n");
2468 lstrcpyA(buffer
, "aaa");
2469 r
= MsiGetPropertyA(hpkg
, "dantes", buffer
, &sz
);
2470 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2471 ok(!buffer
[0], "Expected empty string, got %s\n", buffer
);
2473 r
= MsiSetPropertyA(hpkg
, "dantes", "mercedes");
2474 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2476 found
= find_prop_in_property(hdb
, "dantes", "mercedes", -1);
2477 ok(found
== TRUE
, "dantes should be in the _Property table\n");
2479 r
= MsiDoActionA( hpkg
, "EmbedNull" );
2480 ok( r
== ERROR_SUCCESS
, "EmbedNull failed: %d\n", r
);
2483 memset( buffer
, 'a', sizeof(buffer
) );
2484 r
= MsiGetPropertyA( hpkg
, "prop2", buffer
, &sz
);
2485 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2486 ok( !memcmp( buffer
, "\0np", sizeof("\0np") ), "wrong value\n");
2487 ok( sz
== sizeof("\0np") - 1, "got %u\n", sz
);
2489 found
= find_prop_in_property(hdb
, "prop2", "\0np", 3);
2490 ok(found
== TRUE
, "prop2 should be in the _Property table\n");
2492 MsiCloseHandle(hdb
);
2493 MsiCloseHandle(hpkg
);
2494 DeleteFileA(msifile
);
2497 static UINT
try_query_param( MSIHANDLE hdb
, LPCSTR szQuery
, MSIHANDLE hrec
)
2502 res
= MsiDatabaseOpenViewA( hdb
, szQuery
, &htab
);
2503 if( res
== ERROR_SUCCESS
)
2507 r
= MsiViewExecute( htab
, hrec
);
2508 if( r
!= ERROR_SUCCESS
)
2511 fprintf(stderr
,"MsiViewExecute failed %08x\n", res
);
2514 r
= MsiViewClose( htab
);
2515 if( r
!= ERROR_SUCCESS
)
2518 r
= MsiCloseHandle( htab
);
2519 if( r
!= ERROR_SUCCESS
)
2525 static UINT
try_query( MSIHANDLE hdb
, LPCSTR szQuery
)
2527 return try_query_param( hdb
, szQuery
, 0 );
2530 static void set_summary_str(MSIHANDLE hdb
, DWORD pid
, LPCSTR value
)
2535 r
= MsiGetSummaryInformationA(hdb
, NULL
, 1, &summary
);
2536 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2538 r
= MsiSummaryInfoSetPropertyA(summary
, pid
, VT_LPSTR
, 0, NULL
, value
);
2539 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2541 r
= MsiSummaryInfoPersist(summary
);
2542 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2544 MsiCloseHandle(summary
);
2547 static void set_summary_dword(MSIHANDLE hdb
, DWORD pid
, DWORD value
)
2552 r
= MsiGetSummaryInformationA(hdb
, NULL
, 1, &summary
);
2553 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2555 r
= MsiSummaryInfoSetPropertyA(summary
, pid
, VT_I4
, value
, NULL
, NULL
);
2556 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2558 r
= MsiSummaryInfoPersist(summary
);
2559 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2561 MsiCloseHandle(summary
);
2564 static void test_msipackage(void)
2566 MSIHANDLE hdb
= 0, hpack
= 100;
2571 /* NULL szPackagePath */
2572 r
= MsiOpenPackageA(NULL
, &hpack
);
2573 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
2575 /* empty szPackagePath */
2576 r
= MsiOpenPackageA("", &hpack
);
2577 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2579 skip("Not enough rights to perform tests\n");
2584 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2587 if (r
== ERROR_SUCCESS
)
2588 MsiCloseHandle(hpack
);
2590 /* nonexistent szPackagePath */
2591 r
= MsiOpenPackageA("nonexistent", &hpack
);
2592 ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r
);
2595 r
= MsiOpenPackageA(msifile
, NULL
);
2596 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
2600 r
= MsiOpenPackageA(name
, &hpack
);
2601 ok(r
== ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
2603 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
2604 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2606 /* database exists, but is empty */
2607 sprintf(name
, "#%d", hdb
);
2608 r
= MsiOpenPackageA(name
, &hpack
);
2609 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2610 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2612 query
= "CREATE TABLE `Property` ( "
2613 "`Property` CHAR(72), `Value` CHAR(0) "
2614 "PRIMARY KEY `Property`)";
2615 r
= try_query(hdb
, query
);
2616 ok(r
== ERROR_SUCCESS
, "failed to create Properties table\n");
2618 query
= "CREATE TABLE `InstallExecuteSequence` ("
2619 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2620 "PRIMARY KEY `Action`)";
2621 r
= try_query(hdb
, query
);
2622 ok(r
== ERROR_SUCCESS
, "failed to create InstallExecuteSequence table\n");
2624 /* a few key tables exist */
2625 sprintf(name
, "#%d", hdb
);
2626 r
= MsiOpenPackageA(name
, &hpack
);
2627 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2628 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2630 MsiCloseHandle(hdb
);
2631 DeleteFileA(msifile
);
2633 /* start with a clean database to show what constitutes a valid package */
2634 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
2635 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2637 sprintf(name
, "#%d", hdb
);
2639 /* The following summary information props must exist:
2644 set_summary_dword(hdb
, PID_PAGECOUNT
, 100);
2645 r
= MsiOpenPackageA(name
, &hpack
);
2646 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2647 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2649 set_summary_str(hdb
, PID_REVNUMBER
, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2650 r
= MsiOpenPackageA(name
, &hpack
);
2651 ok(r
== ERROR_SUCCESS
,
2652 "Expected ERROR_SUCCESS, got %d\n", r
);
2654 MsiCloseHandle(hpack
);
2655 MsiCloseHandle(hdb
);
2656 DeleteFileA(msifile
);
2659 static void test_formatrecord2(void)
2661 MSIHANDLE hpkg
, hrec
;
2666 r
= package_from_db(create_package_db(), &hpkg
);
2667 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2669 skip("Not enough rights to perform tests\n");
2670 DeleteFileA(msifile
);
2673 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2675 r
= MsiSetPropertyA(hpkg
, "Manufacturer", " " );
2676 ok( r
== ERROR_SUCCESS
, "set property failed\n");
2678 hrec
= MsiCreateRecord(2);
2679 ok(hrec
, "create record failed\n");
2681 r
= MsiRecordSetStringA( hrec
, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2682 ok( r
== ERROR_SUCCESS
, "format record failed\n");
2686 r
= MsiFormatRecordA( hpkg
, hrec
, buffer
, &sz
);
2687 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2689 r
= MsiRecordSetStringA(hrec
, 0, "[foo][1]");
2690 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2691 r
= MsiRecordSetStringA(hrec
, 1, "hoo");
2692 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2694 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2695 ok( sz
== 3, "size wrong\n");
2696 ok( 0 == strcmp(buffer
,"hoo"), "wrong output %s\n",buffer
);
2697 ok( r
== ERROR_SUCCESS
, "format failed\n");
2699 r
= MsiRecordSetStringA(hrec
, 0, "x[~]x");
2700 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2702 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2703 ok( sz
== 3, "size wrong\n");
2704 ok( 0 == strcmp(buffer
,"x"), "wrong output %s\n",buffer
);
2705 ok( r
== ERROR_SUCCESS
, "format failed\n");
2707 r
= MsiRecordSetStringA(hrec
, 0, "[foo.$%}][1]");
2708 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2709 r
= MsiRecordSetStringA(hrec
, 1, "hoo");
2710 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2712 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2713 ok( sz
== 3, "size wrong\n");
2714 ok( 0 == strcmp(buffer
,"hoo"), "wrong output %s\n",buffer
);
2715 ok( r
== ERROR_SUCCESS
, "format failed\n");
2717 r
= MsiRecordSetStringA(hrec
, 0, "[\\[]");
2718 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2720 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2721 ok( sz
== 1, "size wrong\n");
2722 ok( 0 == strcmp(buffer
,"["), "wrong output %s\n",buffer
);
2723 ok( r
== ERROR_SUCCESS
, "format failed\n");
2725 SetEnvironmentVariableA("FOO", "BAR");
2726 r
= MsiRecordSetStringA(hrec
, 0, "[%FOO]");
2727 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2729 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2730 ok( sz
== 3, "size wrong\n");
2731 ok( 0 == strcmp(buffer
,"BAR"), "wrong output %s\n",buffer
);
2732 ok( r
== ERROR_SUCCESS
, "format failed\n");
2734 r
= MsiRecordSetStringA(hrec
, 0, "[[1]]");
2735 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2736 r
= MsiRecordSetStringA(hrec
, 1, "%FOO");
2737 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2739 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2740 ok( sz
== 3, "size wrong\n");
2741 ok( 0 == strcmp(buffer
,"BAR"), "wrong output %s\n",buffer
);
2742 ok( r
== ERROR_SUCCESS
, "format failed\n");
2744 MsiCloseHandle( hrec
);
2745 MsiCloseHandle( hpkg
);
2746 DeleteFileA(msifile
);
2749 static void test_formatrecord_tables(void)
2751 MSIHANDLE hdb
, hrec
, hpkg
= 0;
2752 CHAR buf
[MAX_PATH
+ 41];
2753 CHAR curr_dir
[MAX_PATH
];
2754 CHAR expected
[MAX_PATH
+ 45];
2755 CHAR root
[MAX_PATH
];
2759 GetCurrentDirectoryA( MAX_PATH
, curr_dir
);
2761 hdb
= create_package_db();
2762 ok ( hdb
, "failed to create package database\n");
2764 add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'" );
2765 add_directory_entry( hdb
, "'ReallyLongDir', 'TARGETDIR', "
2766 "'I am a really long directory'" );
2768 create_feature_table( hdb
);
2769 add_feature_entry( hdb
, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2771 create_component_table( hdb
);
2772 add_component_entry( hdb
, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2773 add_component_entry( hdb
, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2774 add_component_entry( hdb
, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2776 create_feature_components_table( hdb
);
2777 add_feature_components_entry( hdb
, "'occipitofrontalis', 'frontal'" );
2778 add_feature_components_entry( hdb
, "'occipitofrontalis', 'parietal'" );
2779 add_feature_components_entry( hdb
, "'occipitofrontalis', 'temporal'" );
2781 create_file_table( hdb
);
2782 add_file_entry( hdb
, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2783 add_file_entry( hdb
, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2784 add_file_entry( hdb
, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2786 create_custom_action_table( hdb
);
2787 add_custom_action_entry( hdb
, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2788 add_custom_action_entry( hdb
, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2789 add_custom_action_entry( hdb
, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2790 add_custom_action_entry( hdb
, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2791 add_custom_action_entry( hdb
, "'EmbedNull', 51, 'prop', '[~]np'" );
2793 r
= package_from_db( hdb
, &hpkg
);
2794 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2796 skip("Not enough rights to perform tests\n");
2797 MsiCloseHandle( hdb
);
2798 DeleteFileA( msifile
);
2801 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2803 MsiCloseHandle( hdb
);
2805 r
= MsiSetPropertyA( hpkg
, "imaprop", "ringer" );
2806 ok( r
== ERROR_SUCCESS
, "cannot set property: %d\n", r
);
2808 hrec
= MsiCreateRecord( 1 );
2810 /* property doesn't exist */
2812 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2813 MsiRecordSetStringA( hrec
, 1, "[idontexist]" );
2814 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2815 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2816 ok( !lstrcmpA( buf
, "1: " ), "Expected '1: ', got %s\n", buf
);
2818 /* property exists */
2820 MsiRecordSetStringA( hrec
, 1, "[imaprop]" );
2821 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2822 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2823 ok( !lstrcmpA( buf
, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf
);
2826 MsiRecordSetStringA( hrec
, 0, "1: [1] " );
2827 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2828 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2829 ok( !lstrcmpA( buf
, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf
);
2831 /* environment variable doesn't exist */
2833 MsiRecordSetStringA( hrec
, 1, "[%idontexist]" );
2834 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2835 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2836 ok( !lstrcmpA( buf
, "1: " ), "Expected '1: ', got %s\n", buf
);
2838 /* environment variable exists */
2840 SetEnvironmentVariableA( "crazyvar", "crazyval" );
2841 MsiRecordSetStringA( hrec
, 1, "[%crazyvar]" );
2842 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2843 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2844 ok( !lstrcmpA( buf
, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf
);
2846 /* file key before CostInitialize */
2848 MsiRecordSetStringA( hrec
, 1, "[#frontal_file]" );
2849 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2850 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2851 ok( !lstrcmpA( buf
, "1: " ), "Expected '1: ', got %s\n", buf
);
2853 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
2855 r
= MsiDoActionA(hpkg
, "CostInitialize");
2856 ok( r
== ERROR_SUCCESS
, "CostInitialize failed: %d\n", r
);
2858 r
= MsiDoActionA(hpkg
, "FileCost");
2859 ok( r
== ERROR_SUCCESS
, "FileCost failed: %d\n", r
);
2861 r
= MsiDoActionA(hpkg
, "CostFinalize");
2862 ok( r
== ERROR_SUCCESS
, "CostFinalize failed: %d\n", r
);
2865 MsiGetPropertyA( hpkg
, "ROOTDRIVE", root
, &size
);
2867 sprintf( expected
, "1: %sfrontal.txt ", root
);
2869 /* frontal full file key */
2871 MsiRecordSetStringA( hrec
, 1, "[#frontal_file]" );
2872 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2873 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2874 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2876 /* frontal short file key */
2878 MsiRecordSetStringA( hrec
, 1, "[!frontal_file]" );
2879 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2880 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2881 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2883 sprintf( expected
, "1: %sI am a really long directory\\temporal.txt ", root
);
2885 /* temporal full file key */
2887 MsiRecordSetStringA( hrec
, 1, "[#temporal_file]" );
2888 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2889 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2890 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2892 /* temporal short file key */
2894 MsiRecordSetStringA( hrec
, 1, "[!temporal_file]" );
2895 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2896 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2897 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2899 /* custom action 51, files don't exist */
2900 r
= MsiDoActionA( hpkg
, "MyCustom" );
2901 ok( r
== ERROR_SUCCESS
, "MyCustom failed: %d\n", r
);
2903 sprintf( expected
, "%sI am a really long directory\\temporal.txt", root
);
2906 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2907 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2908 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2910 sprintf( buf
, "%sI am a really long directory", root
);
2911 CreateDirectoryA( buf
, NULL
);
2913 lstrcatA( buf
, "\\temporal.txt" );
2914 create_test_file( buf
);
2916 /* custom action 51, files exist */
2917 r
= MsiDoActionA( hpkg
, "MyCustom" );
2918 ok( r
== ERROR_SUCCESS
, "MyCustom failed: %d\n", r
);
2921 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2922 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2925 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2928 /* custom action 51, escaped text 1 */
2929 r
= MsiDoActionA( hpkg
, "EscapeIt1" );
2930 ok( r
== ERROR_SUCCESS
, "EscapeIt1 failed: %d\n", r
);
2933 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2934 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2935 ok( !lstrcmpA( buf
, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf
);
2937 /* custom action 51, escaped text 2 */
2938 r
= MsiDoActionA( hpkg
, "EscapeIt2" );
2939 ok( r
== ERROR_SUCCESS
, "EscapeIt2 failed: %d\n", r
);
2942 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2943 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2944 ok( !lstrcmpA( buf
, "x" ), "Expected 'x', got %s\n", buf
);
2946 /* custom action 51, escaped text 3 */
2947 r
= MsiDoActionA( hpkg
, "EscapeIt3" );
2948 ok( r
== ERROR_SUCCESS
, "EscapeIt3 failed: %d\n", r
);
2951 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2952 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2953 ok( !lstrcmpA( buf
, "" ), "Expected '', got %s\n", buf
);
2955 /* custom action 51, embedded null */
2956 r
= MsiDoActionA( hpkg
, "EmbedNull" );
2957 ok( r
== ERROR_SUCCESS
, "EmbedNull failed: %d\n", r
);
2960 memset( buf
, 'a', sizeof(buf
) );
2961 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2962 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2963 ok( !memcmp( buf
, "\0np", sizeof("\0np") ), "wrong value\n");
2964 ok( size
== sizeof("\0np") - 1, "got %u\n", size
);
2966 r
= MsiSetPropertyA( hpkg
, "prop", "[~]np" );
2967 ok( r
== ERROR_SUCCESS
, "cannot set property: %d\n", r
);
2970 memset( buf
, 'a', sizeof(buf
) );
2971 r
= MsiGetPropertyA( hpkg
, "prop", buf
, &size
);
2972 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2973 ok( !lstrcmpA( buf
, "[~]np" ), "Expected '[~]np', got %s\n", buf
);
2975 sprintf( expected
, "1: %sI am a really long directory\\ ", root
);
2977 /* component with INSTALLSTATE_LOCAL */
2979 MsiRecordSetStringA( hrec
, 1, "[$temporal]" );
2980 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2981 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2982 ok( !lstrcmpA( buf
, expected
), "Expected \"%s\", got \"%s\"\n", expected
, buf
);
2984 r
= MsiSetComponentStateA( hpkg
, "temporal", INSTALLSTATE_SOURCE
);
2985 ok( r
== ERROR_SUCCESS
, "failed to set install state: %d\n", r
);
2987 /* component with INSTALLSTATE_SOURCE */
2988 lstrcpyA( expected
, "1: " );
2989 lstrcatA( expected
, curr_dir
);
2990 if (strlen(curr_dir
) > 3) lstrcatA( expected
, "\\" );
2991 lstrcatA( expected
, " " );
2993 MsiRecordSetStringA( hrec
, 1, "[$parietal]" );
2994 r
= MsiFormatRecordA( hpkg
, hrec
, buf
, &size
);
2995 ok( r
== ERROR_SUCCESS
, "format record failed: %d\n", r
);
2996 ok( !lstrcmpA( buf
, expected
), "Expected '%s', got '%s'\n", expected
, buf
);
2998 sprintf( buf
, "%sI am a really long directory\\temporal.txt", root
);
3001 sprintf( buf
, "%sI am a really long directory", root
);
3002 RemoveDirectoryA( buf
);
3004 MsiCloseHandle( hrec
);
3005 MsiCloseHandle( hpkg
);
3006 DeleteFileA( msifile
);
3009 static void test_feature_states( UINT line
, MSIHANDLE package
, const char *feature
, UINT error
,
3010 INSTALLSTATE expected_state
, INSTALLSTATE expected_action
, BOOL todo
)
3013 INSTALLSTATE state
= 0xdeadbee;
3014 INSTALLSTATE action
= 0xdeadbee;
3016 r
= MsiGetFeatureStateA( package
, feature
, &state
, &action
);
3017 ok( r
== error
, "%u: expected %d got %d\n", line
, error
, r
);
3018 if (r
== ERROR_SUCCESS
)
3020 ok( state
== expected_state
, "%u: expected state %d got %d\n",
3021 line
, expected_state
, state
);
3023 ok( action
== expected_action
, "%u: expected action %d got %d\n",
3024 line
, expected_action
, action
);
3028 ok( state
== 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line
, state
);
3030 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line
, action
);
3035 static void test_component_states( UINT line
, MSIHANDLE package
, const char *component
, UINT error
,
3036 INSTALLSTATE expected_state
, INSTALLSTATE expected_action
, BOOL todo
)
3039 INSTALLSTATE state
= 0xdeadbee;
3040 INSTALLSTATE action
= 0xdeadbee;
3042 r
= MsiGetComponentStateA( package
, component
, &state
, &action
);
3043 ok( r
== error
, "%u: expected %d got %d\n", line
, error
, r
);
3044 if (r
== ERROR_SUCCESS
)
3046 ok( state
== expected_state
, "%u: expected state %d got %d\n",
3047 line
, expected_state
, state
);
3049 ok( action
== expected_action
, "%u: expected action %d got %d\n",
3050 line
, expected_action
, action
);
3054 ok( state
== 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
3057 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
3062 static void test_states(void)
3064 static const char msifile2
[] = "winetest2-package.msi";
3065 static const char msifile3
[] = "winetest3-package.msi";
3066 static const char msifile4
[] = "winetest4-package.msi";
3067 static const WCHAR msifile2W
[] = L
"winetest2-package.msi";
3068 static const WCHAR msifile3W
[] = L
"winetest3-package.msi";
3069 static const WCHAR msifile4W
[] = L
"winetest4-package.msi";
3070 char msi_cache_file
[MAX_PATH
];
3071 DWORD cache_file_name_len
;
3073 MSIHANDLE hpkg
, hprod
;
3077 char value
[MAX_PATH
];
3080 if (is_process_limited())
3082 skip("process is limited\n");
3086 hdb
= create_package_db();
3087 ok ( hdb
, "failed to create package database\n" );
3089 add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'");
3091 create_property_table( hdb
);
3092 add_property_entry( hdb
, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
3093 add_property_entry( hdb
, "'ProductLanguage', '1033'" );
3094 add_property_entry( hdb
, "'ProductName', 'MSITEST'" );
3095 add_property_entry( hdb
, "'ProductVersion', '1.1.1'" );
3096 add_property_entry( hdb
, "'MSIFASTINSTALL', '1'" );
3097 add_property_entry( hdb
, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
3099 create_install_execute_sequence_table( hdb
);
3100 add_install_execute_sequence_entry( hdb
, "'CostInitialize', '', '800'" );
3101 add_install_execute_sequence_entry( hdb
, "'FileCost', '', '900'" );
3102 add_install_execute_sequence_entry( hdb
, "'CostFinalize', '', '1000'" );
3103 add_install_execute_sequence_entry( hdb
, "'InstallValidate', '', '1400'" );
3104 add_install_execute_sequence_entry( hdb
, "'InstallInitialize', '', '1500'" );
3105 add_install_execute_sequence_entry( hdb
, "'ProcessComponents', '', '1600'" );
3106 add_install_execute_sequence_entry( hdb
, "'UnpublishFeatures', '', '1800'" );
3107 add_install_execute_sequence_entry( hdb
, "'RegisterProduct', '', '6100'" );
3108 add_install_execute_sequence_entry( hdb
, "'PublishFeatures', '', '6300'" );
3109 add_install_execute_sequence_entry( hdb
, "'PublishProduct', '', '6400'" );
3110 add_install_execute_sequence_entry( hdb
, "'InstallFinalize', '', '6600'" );
3112 create_media_table( hdb
);
3113 add_media_entry( hdb
, "'1', '3', '', '', 'DISK1', ''");
3115 create_feature_table( hdb
);
3117 create_component_table( hdb
);
3119 /* msidbFeatureAttributesFavorLocal */
3120 add_feature_entry( hdb
, "'one', '', '', '', 2, 1, '', 0" );
3122 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
3123 add_component_entry( hdb
, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
3125 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
3126 add_component_entry( hdb
, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
3128 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
3129 add_component_entry( hdb
, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
3131 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
3132 add_component_entry( hdb
, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
3134 /* msidbFeatureAttributesFavorSource */
3135 add_feature_entry( hdb
, "'two', '', '', '', 2, 1, '', 1" );
3137 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
3138 add_component_entry( hdb
, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
3140 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3141 add_component_entry( hdb
, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
3143 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
3144 add_component_entry( hdb
, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
3146 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
3147 add_component_entry( hdb
, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
3149 /* msidbFeatureAttributesFavorSource */
3150 add_feature_entry( hdb
, "'three', '', '', '', 2, 1, '', 1" );
3152 /* msidbFeatureAttributesFavorLocal */
3153 add_feature_entry( hdb
, "'four', '', '', '', 2, 1, '', 0" );
3156 add_feature_entry( hdb
, "'five', '', '', '', 2, 0, '', 1" );
3158 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3159 add_component_entry( hdb
, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3161 /* no feature parent:msidbComponentAttributesLocalOnly */
3162 add_component_entry( hdb
, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3164 /* msidbFeatureAttributesFavorLocal:removed */
3165 add_feature_entry( hdb
, "'six', '', '', '', 2, 1, '', 0" );
3167 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3168 add_component_entry( hdb
, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3170 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3171 add_component_entry( hdb
, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3173 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3174 add_component_entry( hdb
, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3176 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3177 add_component_entry( hdb
, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3179 /* msidbFeatureAttributesFavorSource:removed */
3180 add_feature_entry( hdb
, "'seven', '', '', '', 2, 1, '', 1" );
3182 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3183 add_component_entry( hdb
, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3185 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3186 add_component_entry( hdb
, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3188 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3189 add_component_entry( hdb
, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3191 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3192 add_component_entry( hdb
, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3194 /* msidbFeatureAttributesFavorLocal */
3195 add_feature_entry( hdb
, "'eight', '', '', '', 2, 1, '', 0" );
3197 add_component_entry( hdb
, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3199 /* msidbFeatureAttributesFavorSource */
3200 add_feature_entry( hdb
, "'nine', '', '', '', 2, 1, '', 1" );
3202 add_component_entry( hdb
, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3204 /* msidbFeatureAttributesFavorAdvertise */
3205 add_feature_entry( hdb
, "'ten', '', '', '', 2, 1, '', 4" );
3207 add_component_entry( hdb
, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3209 /* msidbFeatureAttributesUIDisallowAbsent */
3210 add_feature_entry( hdb
, "'eleven', '', '', '', 2, 1, '', 16" );
3212 add_component_entry( hdb
, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3214 /* high install level */
3215 add_feature_entry( hdb
, "'twelve', '', '', '', 2, 2, '', 0" );
3217 add_component_entry( hdb
, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3219 /* msidbFeatureAttributesFollowParent */
3220 add_feature_entry( hdb
, "'thirteen', '', '', '', 2, 2, '', 2" );
3222 create_feature_components_table( hdb
);
3223 add_feature_components_entry( hdb
, "'one', 'alpha'" );
3224 add_feature_components_entry( hdb
, "'one', 'beta'" );
3225 add_feature_components_entry( hdb
, "'one', 'gamma'" );
3226 add_feature_components_entry( hdb
, "'one', 'theta'" );
3227 add_feature_components_entry( hdb
, "'two', 'delta'" );
3228 add_feature_components_entry( hdb
, "'two', 'epsilon'" );
3229 add_feature_components_entry( hdb
, "'two', 'zeta'" );
3230 add_feature_components_entry( hdb
, "'two', 'iota'" );
3231 add_feature_components_entry( hdb
, "'three', 'eta'" );
3232 add_feature_components_entry( hdb
, "'four', 'eta'" );
3233 add_feature_components_entry( hdb
, "'five', 'eta'" );
3234 add_feature_components_entry( hdb
, "'six', 'lambda'" );
3235 add_feature_components_entry( hdb
, "'six', 'mu'" );
3236 add_feature_components_entry( hdb
, "'six', 'nu'" );
3237 add_feature_components_entry( hdb
, "'six', 'xi'" );
3238 add_feature_components_entry( hdb
, "'seven', 'omicron'" );
3239 add_feature_components_entry( hdb
, "'seven', 'pi'" );
3240 add_feature_components_entry( hdb
, "'seven', 'rho'" );
3241 add_feature_components_entry( hdb
, "'seven', 'sigma'" );
3242 add_feature_components_entry( hdb
, "'eight', 'tau'" );
3243 add_feature_components_entry( hdb
, "'nine', 'phi'" );
3244 add_feature_components_entry( hdb
, "'ten', 'chi'" );
3245 add_feature_components_entry( hdb
, "'eleven', 'psi'" );
3246 add_feature_components_entry( hdb
, "'twelve', 'upsilon'" );
3247 add_feature_components_entry( hdb
, "'thirteen', 'upsilon'" );
3249 create_file_table( hdb
);
3250 add_file_entry( hdb
, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3251 add_file_entry( hdb
, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3252 add_file_entry( hdb
, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3253 add_file_entry( hdb
, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3254 add_file_entry( hdb
, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3255 add_file_entry( hdb
, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3256 add_file_entry( hdb
, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3257 add_file_entry( hdb
, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3259 /* compressed file */
3260 add_file_entry( hdb
, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3262 add_file_entry( hdb
, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3263 add_file_entry( hdb
, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3264 add_file_entry( hdb
, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3265 add_file_entry( hdb
, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3266 add_file_entry( hdb
, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3267 add_file_entry( hdb
, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3268 add_file_entry( hdb
, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3269 add_file_entry( hdb
, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3270 add_file_entry( hdb
, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3271 add_file_entry( hdb
, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3272 add_file_entry( hdb
, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3273 add_file_entry( hdb
, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3274 add_file_entry( hdb
, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3275 add_file_entry( hdb
, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3277 r
= MsiDatabaseCommit(hdb
);
3278 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3280 /* these properties must not be in the saved msi file */
3281 add_property_entry( hdb
, "'ADDLOCAL', 'one,four'");
3282 add_property_entry( hdb
, "'ADDSOURCE', 'two,three'");
3283 add_property_entry( hdb
, "'REMOVE', 'six,seven'");
3284 add_property_entry( hdb
, "'REINSTALL', 'eight,nine,ten'");
3285 add_property_entry( hdb
, "'REINSTALLMODE', 'omus'");
3287 r
= package_from_db( hdb
, &hpkg
);
3288 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
3290 skip("Not enough rights to perform tests\n");
3291 DeleteFileA(msifile
);
3294 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3296 MsiCloseHandle(hdb
);
3298 CopyFileA(msifile
, msifile2
, FALSE
);
3299 CopyFileA(msifile
, msifile3
, FALSE
);
3300 CopyFileA(msifile
, msifile4
, FALSE
);
3302 size
= sizeof(value
);
3303 memset(value
, 0, sizeof(value
));
3304 r
= MsiGetPropertyA(hpkg
, "ProductToBeRegistered", value
, &size
);
3305 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
3306 ok(!value
[0], "ProductToBeRegistered = %s\n", value
);
3308 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3309 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_UNKNOWN_COMPONENT
, 0, 0, FALSE
);
3311 r
= MsiDoActionA( hpkg
, "CostInitialize");
3312 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3314 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3315 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3317 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
3319 r
= MsiDoActionA( hpkg
, "FileCost");
3320 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
3322 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3323 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3325 r
= MsiDoActionA( hpkg
, "CostFinalize");
3326 ok( r
== ERROR_SUCCESS
, "cost finalize failed: %d\n", r
);
3328 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3329 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
3330 test_feature_states( __LINE__
, hpkg
, "three", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3331 test_feature_states( __LINE__
, hpkg
, "four", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3332 test_feature_states( __LINE__
, hpkg
, "five", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3333 test_feature_states( __LINE__
, hpkg
, "six", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3334 test_feature_states( __LINE__
, hpkg
, "seven", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3335 test_feature_states( __LINE__
, hpkg
, "eight", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3336 test_feature_states( __LINE__
, hpkg
, "nine", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3337 test_feature_states( __LINE__
, hpkg
, "ten", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3338 test_feature_states( __LINE__
, hpkg
, "eleven", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3339 test_feature_states( __LINE__
, hpkg
, "twelve", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3340 test_feature_states( __LINE__
, hpkg
, "thirteen", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3342 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3343 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
3344 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3345 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3346 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3347 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
3348 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
3349 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3350 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
3351 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3352 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3353 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3354 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3355 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3356 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3357 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3358 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3359 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3360 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3361 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3362 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3363 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3364 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3366 MsiCloseHandle( hpkg
);
3368 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
3370 /* publish the features and components */
3371 r
= MsiInstallProductA(msifile
, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3372 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3374 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_DIRECT
, &hdb
);
3375 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3377 /* these properties must not be in the saved msi file */
3378 add_property_entry( hdb
, "'ADDLOCAL', 'one,four'");
3379 add_property_entry( hdb
, "'ADDSOURCE', 'two,three'");
3380 add_property_entry( hdb
, "'REMOVE', 'six,seven'");
3381 add_property_entry( hdb
, "'REINSTALL', 'eight,nine,ten'");
3383 r
= package_from_db( hdb
, &hpkg
);
3384 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3386 MsiCloseHandle(hdb
);
3388 size
= sizeof(value
);
3389 memset(value
, 0, sizeof(value
));
3390 r
= MsiGetPropertyA(hpkg
, "ProductToBeRegistered", value
, &size
);
3391 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
3392 ok(value
[0]=='1' && !value
[1], "ProductToBeRegistered = %s\n", value
);
3394 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3395 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_UNKNOWN_COMPONENT
, 0, 0, FALSE
);
3397 r
= MsiDoActionA( hpkg
, "CostInitialize");
3398 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3400 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3401 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3403 r
= MsiDoActionA( hpkg
, "FileCost");
3404 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
3406 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3407 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3409 r
= MsiDoActionA( hpkg
, "CostFinalize");
3410 ok( r
== ERROR_SUCCESS
, "cost finalize failed: %d\n", r
);
3412 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_LOCAL
, FALSE
);
3413 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3414 test_feature_states( __LINE__
, hpkg
, "three", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3415 test_feature_states( __LINE__
, hpkg
, "four", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3416 test_feature_states( __LINE__
, hpkg
, "five", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3417 test_feature_states( __LINE__
, hpkg
, "six", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3418 test_feature_states( __LINE__
, hpkg
, "seven", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3419 test_feature_states( __LINE__
, hpkg
, "eight", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3420 test_feature_states( __LINE__
, hpkg
, "nine", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3421 test_feature_states( __LINE__
, hpkg
, "ten", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3422 test_feature_states( __LINE__
, hpkg
, "eleven", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3423 test_feature_states( __LINE__
, hpkg
, "twelve", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3424 test_feature_states( __LINE__
, hpkg
, "thirteen", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3426 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3427 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3428 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3429 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3430 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3431 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3432 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3433 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3434 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3435 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3436 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3437 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3438 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3439 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3440 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3441 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3442 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3443 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3444 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3445 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3446 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3447 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3448 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3450 MsiCloseHandle(hpkg
);
3452 /* uninstall the product */
3453 r
= MsiInstallProductA(msifile
, "REMOVE=ALL");
3454 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3456 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3457 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3458 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3459 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3461 /* all features installed locally */
3462 r
= MsiInstallProductA(msifile2
, "ADDLOCAL=ALL");
3463 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3465 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3466 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3467 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3468 ok(state
== INSTALLSTATE_LOCAL
, "state = %d\n", state
);
3470 r
= MsiOpenDatabaseW(msifile2W
, MSIDBOPEN_DIRECT
, &hdb
);
3471 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3473 /* these properties must not be in the saved msi file */
3474 add_property_entry( hdb
, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3476 r
= package_from_db( hdb
, &hpkg
);
3477 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3479 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3480 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_UNKNOWN_COMPONENT
, 0, 0, FALSE
);
3482 r
= MsiDoActionA( hpkg
, "CostInitialize");
3483 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3485 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3486 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3488 r
= MsiDoActionA( hpkg
, "CostFinalize");
3489 ok( r
== ERROR_SUCCESS
, "cost finalize failed: %d\n", r
);
3491 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_LOCAL
, FALSE
);
3492 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_LOCAL
, FALSE
);
3493 test_feature_states( __LINE__
, hpkg
, "three", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3494 test_feature_states( __LINE__
, hpkg
, "four", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3495 test_feature_states( __LINE__
, hpkg
, "five", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3496 test_feature_states( __LINE__
, hpkg
, "six", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_LOCAL
, FALSE
);
3497 test_feature_states( __LINE__
, hpkg
, "seven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_LOCAL
, FALSE
);
3498 test_feature_states( __LINE__
, hpkg
, "eight", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, TRUE
);
3499 test_feature_states( __LINE__
, hpkg
, "nine", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, TRUE
);
3500 test_feature_states( __LINE__
, hpkg
, "ten", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, TRUE
);
3501 test_feature_states( __LINE__
, hpkg
, "eleven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3502 test_feature_states( __LINE__
, hpkg
, "twelve", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3503 test_feature_states( __LINE__
, hpkg
, "thirteen", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_UNKNOWN
, FALSE
);
3505 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3506 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3507 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3508 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3509 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3510 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3511 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3512 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3513 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3514 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3515 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3516 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3517 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3518 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3519 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3520 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3521 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3522 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3523 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3524 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3525 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3526 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3527 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3529 MsiCloseHandle(hpkg
);
3531 /* uninstall the product */
3532 r
= MsiInstallProductA(msifile2
, "REMOVE=ALL");
3533 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3535 /* all features installed from source */
3536 r
= MsiInstallProductA(msifile3
, "ADDSOURCE=ALL");
3537 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3539 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3540 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3541 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3542 ok(state
== INSTALLSTATE_LOCAL
, "state = %d\n", state
);
3544 r
= MsiOpenDatabaseW(msifile3W
, MSIDBOPEN_DIRECT
, &hdb
);
3545 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3547 /* this property must not be in the saved msi file */
3548 add_property_entry( hdb
, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3550 r
= package_from_db( hdb
, &hpkg
);
3551 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3553 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3554 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_UNKNOWN_COMPONENT
, 0, 0, FALSE
);
3556 r
= MsiDoActionA( hpkg
, "CostInitialize");
3557 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3559 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3560 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3562 r
= MsiDoActionA( hpkg
, "FileCost");
3563 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
3565 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3566 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3568 r
= MsiDoActionA( hpkg
, "CostFinalize");
3569 ok( r
== ERROR_SUCCESS
, "cost finalize failed: %d\n", r
);
3571 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3572 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3573 test_feature_states( __LINE__
, hpkg
, "three", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3574 test_feature_states( __LINE__
, hpkg
, "four", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3575 test_feature_states( __LINE__
, hpkg
, "five", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3576 test_feature_states( __LINE__
, hpkg
, "six", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3577 test_feature_states( __LINE__
, hpkg
, "seven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3578 test_feature_states( __LINE__
, hpkg
, "eight", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3579 test_feature_states( __LINE__
, hpkg
, "nine", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3580 test_feature_states( __LINE__
, hpkg
, "ten", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3581 test_feature_states( __LINE__
, hpkg
, "eleven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3582 test_feature_states( __LINE__
, hpkg
, "twelve", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_UNKNOWN
, FALSE
);
3583 test_feature_states( __LINE__
, hpkg
, "thirteen", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_UNKNOWN
, FALSE
);
3585 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3586 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3587 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3588 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3589 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3590 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3591 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3592 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3593 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3594 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3595 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3596 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3597 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3598 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3599 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3600 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3601 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3602 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3603 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3604 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3605 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3606 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3607 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3609 MsiCloseHandle(hpkg
);
3611 /* reinstall the product */
3612 r
= MsiInstallProductA(msifile3
, "REINSTALL=ALL");
3613 is_broken
= (r
== ERROR_INSTALL_FAILURE
);
3614 ok(r
== ERROR_SUCCESS
|| broken(is_broken
) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r
);
3616 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3617 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3618 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3619 ok(state
== INSTALLSTATE_LOCAL
, "state = %d\n", state
);
3621 r
= MsiOpenDatabaseW(msifile4W
, MSIDBOPEN_DIRECT
, &hdb
);
3622 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3624 /* this property must not be in the saved msi file */
3625 add_property_entry( hdb
, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3627 r
= package_from_db( hdb
, &hpkg
);
3628 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3630 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3631 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_UNKNOWN_COMPONENT
, 0, 0, FALSE
);
3633 r
= MsiDoActionA( hpkg
, "CostInitialize");
3634 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3636 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3637 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3639 r
= MsiDoActionA( hpkg
, "FileCost");
3640 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
3642 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3643 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3645 r
= MsiDoActionA( hpkg
, "CostFinalize");
3646 ok( r
== ERROR_SUCCESS
, "cost finalize failed: %d\n", r
);
3648 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3649 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3650 test_feature_states( __LINE__
, hpkg
, "three", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3651 test_feature_states( __LINE__
, hpkg
, "four", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3652 test_feature_states( __LINE__
, hpkg
, "five", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3653 test_feature_states( __LINE__
, hpkg
, "six", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3654 test_feature_states( __LINE__
, hpkg
, "seven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3655 test_feature_states( __LINE__
, hpkg
, "eight", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3656 test_feature_states( __LINE__
, hpkg
, "nine", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3657 test_feature_states( __LINE__
, hpkg
, "ten", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_SOURCE
, FALSE
);
3658 test_feature_states( __LINE__
, hpkg
, "eleven", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, TRUE
);
3659 test_feature_states( __LINE__
, hpkg
, "twelve", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_UNKNOWN
, FALSE
);
3660 test_feature_states( __LINE__
, hpkg
, "thirteen", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_UNKNOWN
, FALSE
);
3662 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3663 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3664 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3665 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3666 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3667 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3668 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3669 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3670 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3671 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3672 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3673 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3674 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3675 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3676 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3677 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3678 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3679 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3680 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3681 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3682 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3683 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3684 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3686 MsiCloseHandle(hpkg
);
3688 /* test source only install */
3689 r
= MsiInstallProductA(msifile
, "REMOVE=ALL");
3690 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3691 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3692 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3693 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3694 ok(state
== INSTALLSTATE_UNKNOWN
, "state = %d\n", state
);
3696 r
= MsiInstallProductA(msifile
, "ADDSOURCE=one");
3697 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3698 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3699 ok(state
== INSTALLSTATE_SOURCE
, "state = %d\n", state
);
3700 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3701 ok(state
== INSTALLSTATE_ABSENT
, "state = %d\n", state
);
3703 /* no arguments test */
3704 cache_file_name_len
= sizeof(msi_cache_file
);
3705 r
= MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3706 INSTALLPROPERTY_LOCALPACKAGEA
, msi_cache_file
, &cache_file_name_len
);
3707 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3708 r
= MsiOpenDatabaseA(msi_cache_file
, (const char*)MSIDBOPEN_DIRECT
, &hdb
);
3709 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3711 create_custom_action_table( hdb
);
3712 add_custom_action_entry( hdb
, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3713 add_custom_action_entry( hdb
, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3714 add_custom_action_entry( hdb
, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3715 add_custom_action_entry( hdb
, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3716 add_custom_action_entry( hdb
, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3717 add_custom_action_entry( hdb
, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3718 add_custom_action_entry( hdb
, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3719 add_custom_action_entry( hdb
, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3720 add_custom_action_entry( hdb
,
3721 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3723 add_install_execute_sequence_entry( hdb
, "'ConditionCheck1', 'REINSTALL', '798'" );
3724 add_install_execute_sequence_entry( hdb
, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3725 add_install_execute_sequence_entry( hdb
, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3726 add_install_execute_sequence_entry( hdb
, "'ConditionCheck3', 'REINSTALL', '6598'" );
3727 add_install_execute_sequence_entry( hdb
, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3728 add_install_execute_sequence_entry( hdb
, "'ConditionCheck5', 'REINSTALL', '6601'" );
3729 add_install_execute_sequence_entry( hdb
, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3730 /* Add "one" feature action tests */
3731 add_install_execute_sequence_entry( hdb
, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3732 add_install_execute_sequence_entry( hdb
, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3733 r
= MsiDatabaseCommit(hdb
);
3734 ok(r
== ERROR_SUCCESS
, "MsiDatabaseCommit failed: %d\n", r
);
3735 r
= package_from_db( hdb
, &hpkg
);
3736 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3737 MsiCloseHandle(hdb
);
3739 test_feature_states( __LINE__
, hpkg
, "one", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3740 test_feature_states( __LINE__
, hpkg
, "two", ERROR_UNKNOWN_FEATURE
, 0, 0, FALSE
);
3741 r
= MsiDoActionA( hpkg
, "CostInitialize");
3742 ok( r
== ERROR_SUCCESS
, "CostInitialize failed\n");
3743 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3744 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3746 r
= MsiDoActionA( hpkg
, "FileCost");
3747 ok( r
== ERROR_SUCCESS
, "FileCost failed\n");
3748 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3749 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
3751 r
= MsiDoActionA( hpkg
, "CostFinalize");
3752 ok( r
== ERROR_SUCCESS
, "CostFinalize failed\n");
3753 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3754 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3755 test_component_states( __LINE__
, hpkg
, "alpha", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3756 test_component_states( __LINE__
, hpkg
, "beta", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3757 test_component_states( __LINE__
, hpkg
, "gamma", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3758 test_component_states( __LINE__
, hpkg
, "theta", ERROR_SUCCESS
, INSTALLSTATE_LOCAL
, INSTALLSTATE_LOCAL
, FALSE
);
3759 test_component_states( __LINE__
, hpkg
, "delta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3760 test_component_states( __LINE__
, hpkg
, "epsilon", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3761 test_component_states( __LINE__
, hpkg
, "zeta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3762 test_component_states( __LINE__
, hpkg
, "iota", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3763 test_component_states( __LINE__
, hpkg
, "eta", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3764 test_component_states( __LINE__
, hpkg
, "kappa", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3765 test_component_states( __LINE__
, hpkg
, "lambda", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3766 test_component_states( __LINE__
, hpkg
, "mu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3767 test_component_states( __LINE__
, hpkg
, "nu", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3768 test_component_states( __LINE__
, hpkg
, "xi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3769 test_component_states( __LINE__
, hpkg
, "omicron", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3770 test_component_states( __LINE__
, hpkg
, "pi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3771 test_component_states( __LINE__
, hpkg
, "rho", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3772 test_component_states( __LINE__
, hpkg
, "sigma", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3773 test_component_states( __LINE__
, hpkg
, "tau", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3774 test_component_states( __LINE__
, hpkg
, "phi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3775 test_component_states( __LINE__
, hpkg
, "chi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3776 test_component_states( __LINE__
, hpkg
, "psi", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3777 test_component_states( __LINE__
, hpkg
, "upsilon", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3779 r
= MsiDoActionA( hpkg
, "InstallValidate");
3780 ok( r
== ERROR_SUCCESS
, "InstallValidate failed %d\n", r
);
3781 test_feature_states( __LINE__
, hpkg
, "one", ERROR_SUCCESS
, INSTALLSTATE_SOURCE
, INSTALLSTATE_UNKNOWN
, FALSE
);
3782 test_feature_states( __LINE__
, hpkg
, "two", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
3783 MsiCloseHandle( hpkg
);
3785 r
= MsiInstallProductA(msifile
, "");
3786 ok(r
== ERROR_SUCCESS
|| (is_broken
&& r
== ERROR_INSTALL_FAILURE
) /* win2k3 */,
3787 "Expected ERROR_SUCCESS, got %d\n", r
);
3788 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3789 ok(state
== INSTALLSTATE_SOURCE
, "state = %d\n", state
);
3790 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3791 ok(state
== INSTALLSTATE_ABSENT
, "state = %d\n", state
);
3792 state
= MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3793 ok(state
== INSTALLSTATE_LOCAL
, "state = %d\n", state
);
3795 /* minor upgrade test with no REINSTALL argument */
3796 r
= MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod
);
3797 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3799 r
= MsiGetProductPropertyA(hprod
, "ProductVersion", value
, &size
);
3800 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3801 ok(!strcmp(value
, "1.1.1"), "ProductVersion = %s\n", value
);
3802 MsiCloseHandle(hprod
);
3804 r
= MsiOpenDatabaseA(msifile2
, (const char*)MSIDBOPEN_DIRECT
, &hdb
);
3805 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3806 update_ProductVersion_property( hdb
, "1.1.2" );
3807 set_summary_str(hdb
, PID_REVNUMBER
, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3808 r
= MsiDatabaseCommit(hdb
);
3809 ok(r
== ERROR_SUCCESS
, "MsiDatabaseCommit failed: %d\n", r
);
3810 MsiCloseHandle(hdb
);
3812 r
= MsiInstallProductA(msifile2
, "");
3813 ok(r
== ERROR_PRODUCT_VERSION
, "Expected ERROR_PRODUCT_VERSION, got %d\n", r
);
3815 r
= MsiInstallProductA(msifile2
, "REINSTALLMODe=V");
3816 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3818 r
= MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod
);
3819 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3821 r
= MsiGetProductPropertyA(hprod
, "ProductVersion", value
, &size
);
3822 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3823 ok(!strcmp(value
, "1.1.2"), "ProductVersion = %s\n", value
);
3824 MsiCloseHandle(hprod
);
3826 /* major upgrade test */
3827 r
= MsiOpenDatabaseA(msifile2
, (const char*)MSIDBOPEN_DIRECT
, &hdb
);
3828 ok(r
== ERROR_SUCCESS
, "failed to open database: %d\n", r
);
3829 add_install_execute_sequence_entry( hdb
, "'FindRelatedProducts', '', '100'" );
3830 add_install_execute_sequence_entry( hdb
, "'RemoveExistingProducts', '', '1401'" );
3831 create_upgrade_table( hdb
);
3832 add_upgrade_entry( hdb
, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3833 update_ProductCode_property( hdb
, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3834 update_ProductVersion_property( hdb
, "1.1.3" );
3835 set_summary_str(hdb
, PID_REVNUMBER
, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3836 r
= MsiDatabaseCommit(hdb
);
3837 ok(r
== ERROR_SUCCESS
, "MsiDatabaseCommit failed: %d\n", r
);
3838 MsiCloseHandle(hdb
);
3840 r
= MsiInstallProductA(msifile2
, "");
3841 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3843 r
= MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod
);
3844 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
3845 r
= MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod
);
3846 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3848 r
= MsiGetProductPropertyA(hprod
, "ProductVersion", value
, &size
);
3849 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3850 ok(!strcmp(value
, "1.1.3"), "ProductVersion = %s\n", value
);
3851 MsiCloseHandle(hprod
);
3853 /* uninstall the product */
3854 r
= MsiInstallProductA(msifile2
, "REMOVE=ALL");
3855 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
3857 DeleteFileA(msifile
);
3858 DeleteFileA(msifile2
);
3859 DeleteFileA(msifile3
);
3860 DeleteFileA(msifile4
);
3863 static void test_removefiles(void)
3868 INSTALLSTATE installed
, action
;
3870 hdb
= create_package_db();
3871 ok ( hdb
, "failed to create package database\n" );
3873 add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'");
3875 create_feature_table( hdb
);
3876 add_feature_entry( hdb
, "'one', '', '', '', 2, 1, '', 0" );
3878 create_component_table( hdb
);
3879 add_component_entry( hdb
, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3880 add_component_entry( hdb
, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3881 add_component_entry( hdb
, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3882 add_component_entry( hdb
, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3883 add_component_entry( hdb
, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3884 add_component_entry( hdb
, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3885 add_component_entry( hdb
, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3887 create_feature_components_table( hdb
);
3888 add_feature_components_entry( hdb
, "'one', 'hydrogen'" );
3889 add_feature_components_entry( hdb
, "'one', 'helium'" );
3890 add_feature_components_entry( hdb
, "'one', 'lithium'" );
3891 add_feature_components_entry( hdb
, "'one', 'beryllium'" );
3892 add_feature_components_entry( hdb
, "'one', 'boron'" );
3893 add_feature_components_entry( hdb
, "'one', 'carbon'" );
3894 add_feature_components_entry( hdb
, "'one', 'oxygen'" );
3896 create_file_table( hdb
);
3897 add_file_entry( hdb
, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3898 add_file_entry( hdb
, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3899 add_file_entry( hdb
, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3900 add_file_entry( hdb
, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3901 add_file_entry( hdb
, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3902 add_file_entry( hdb
, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3903 add_file_entry( hdb
, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3905 create_remove_file_table( hdb
);
3907 r
= package_from_db( hdb
, &hpkg
);
3908 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
3910 skip("Not enough rights to perform tests\n");
3911 DeleteFileA(msifile
);
3914 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
3916 MsiCloseHandle( hdb
);
3918 create_test_file( "hydrogen.txt" );
3919 create_test_file( "helium.txt" );
3920 create_test_file( "lithium.txt" );
3921 create_test_file( "beryllium.txt" );
3922 create_test_file( "boron.txt" );
3923 create_test_file( "carbon.txt" );
3924 create_test_file( "oxygen.txt" );
3926 r
= MsiSetPropertyA( hpkg
, "TARGETDIR", CURR_DIR
);
3927 ok( r
== ERROR_SUCCESS
, "set property failed\n");
3929 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
3931 r
= MsiGetComponentStateA( hpkg
, "oxygen", &installed
, &action
);
3932 ok( r
== ERROR_UNKNOWN_COMPONENT
, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r
);
3934 r
= MsiDoActionA( hpkg
, "CostInitialize");
3935 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
3937 r
= MsiDoActionA( hpkg
, "FileCost");
3938 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
3940 installed
= action
= 0xdeadbeef;
3941 r
= MsiGetComponentStateA( hpkg
, "oxygen", &installed
, &action
);
3942 ok( r
== ERROR_SUCCESS
, "failed to get component state %u\n", r
);
3943 ok( installed
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed
);
3944 ok( action
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", action
);
3946 r
= MsiDoActionA( hpkg
, "CostFinalize");
3947 ok( r
== ERROR_SUCCESS
, "cost finalize failed\n");
3949 r
= MsiDoActionA( hpkg
, "InstallValidate");
3950 ok( r
== ERROR_SUCCESS
, "install validate failed\n");
3952 r
= MsiSetComponentStateA( hpkg
, "hydrogen", INSTALLSTATE_ABSENT
);
3953 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3955 installed
= action
= 0xdeadbeef;
3956 r
= MsiGetComponentStateA( hpkg
, "hydrogen", &installed
, &action
);
3957 ok( r
== ERROR_SUCCESS
, "failed to get component state %u\n", r
);
3958 ok( installed
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed
);
3959 todo_wine
ok( action
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", action
);
3961 r
= MsiSetComponentStateA( hpkg
, "helium", INSTALLSTATE_LOCAL
);
3962 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3964 r
= MsiSetComponentStateA( hpkg
, "lithium", INSTALLSTATE_SOURCE
);
3965 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3967 r
= MsiSetComponentStateA( hpkg
, "beryllium", INSTALLSTATE_ABSENT
);
3968 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3970 r
= MsiSetComponentStateA( hpkg
, "boron", INSTALLSTATE_LOCAL
);
3971 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3973 r
= MsiSetComponentStateA( hpkg
, "carbon", INSTALLSTATE_SOURCE
);
3974 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3976 installed
= action
= 0xdeadbeef;
3977 r
= MsiGetComponentStateA( hpkg
, "oxygen", &installed
, &action
);
3978 ok( r
== ERROR_SUCCESS
, "failed to get component state %u\n", r
);
3979 ok( installed
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed
);
3980 ok( action
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", action
);
3982 r
= MsiSetComponentStateA( hpkg
, "oxygen", INSTALLSTATE_ABSENT
);
3983 ok( r
== ERROR_SUCCESS
, "failed to set component state: %d\n", r
);
3985 installed
= action
= 0xdeadbeef;
3986 r
= MsiGetComponentStateA( hpkg
, "oxygen", &installed
, &action
);
3987 ok( r
== ERROR_SUCCESS
, "failed to get component state %u\n", r
);
3988 ok( installed
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed
);
3989 ok( action
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", action
);
3991 r
= MsiDoActionA( hpkg
, "RemoveFiles");
3992 ok( r
== ERROR_SUCCESS
, "remove files failed\n");
3994 installed
= action
= 0xdeadbeef;
3995 r
= MsiGetComponentStateA( hpkg
, "oxygen", &installed
, &action
);
3996 ok( r
== ERROR_SUCCESS
, "failed to get component state %u\n", r
);
3997 ok( installed
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed
);
3998 ok( action
== INSTALLSTATE_UNKNOWN
, "expected INSTALLSTATE_UNKNOWN, got %d\n", action
);
4000 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
4001 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
4002 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
4003 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
4004 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
4005 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
4006 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
4008 MsiCloseHandle( hpkg
);
4009 DeleteFileA(msifile
);
4012 static void test_appsearch(void)
4017 CHAR prop
[MAX_PATH
];
4020 const char reg_expand_value
[] = "%systemroot%\\system32\\notepad.exe";
4022 hdb
= create_package_db();
4023 ok ( hdb
, "failed to create package database\n" );
4025 create_appsearch_table( hdb
);
4026 add_appsearch_entry( hdb
, "'WEBBROWSERPROG', 'NewSignature1'" );
4027 add_appsearch_entry( hdb
, "'NOTEPAD', 'NewSignature2'" );
4028 add_appsearch_entry( hdb
, "'REGEXPANDVAL', 'NewSignature3'" );
4029 add_appsearch_entry( hdb
, "'32KEYVAL', 'NewSignature4'" );
4030 add_appsearch_entry( hdb
, "'64KEYVAL', 'NewSignature5'" );
4032 create_reglocator_table( hdb
);
4033 add_reglocator_entry( hdb
, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
4035 r
= RegCreateKeyExA(HKEY_CURRENT_USER
, "Software\\Winetest_msi", 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
4036 ok( r
== ERROR_SUCCESS
, "Could not create key: %d.\n", r
);
4037 r
= RegSetValueExA(hkey
, NULL
, 0, REG_EXPAND_SZ
, (const BYTE
*)reg_expand_value
, strlen(reg_expand_value
) + 1);
4038 ok( r
== ERROR_SUCCESS
, "Could not set key value: %d.\n", r
);
4040 add_reglocator_entry( hdb
, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName
);
4042 r
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
, "Software\\Winetest_msi", 0, NULL
, 0, KEY_ALL_ACCESS
|KEY_WOW64_32KEY
,
4044 if (r
== ERROR_ACCESS_DENIED
)
4046 skip("insufficient rights\n");
4047 RegDeleteKeyA(HKEY_CURRENT_USER
, "Software\\Winetest_msi");
4048 MsiCloseHandle(hdb
);
4049 DeleteFileA(msifile
);
4052 ok( r
== ERROR_SUCCESS
, "Could not create key: %d.\n", r
);
4054 r
= RegSetValueExA(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*)"c:\\windows\\system32\\notepad.exe",
4055 sizeof("c:\\windows\\system32\\notepad.exe"));
4056 ok( r
== ERROR_SUCCESS
, "Could not set key value: %d.\n", r
);
4058 add_reglocator_entry( hdb
, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName
);
4060 r
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
, "Software\\Winetest_msi", 0, NULL
, 0, KEY_ALL_ACCESS
|KEY_WOW64_64KEY
,
4062 ok( r
== ERROR_SUCCESS
, "Could not create key: %d.\n", r
);
4063 r
= RegSetValueExA(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*)"c:\\windows\\system32\\notepad.exe",
4064 sizeof("c:\\windows\\system32\\notepad.exe"));
4065 ok( r
== ERROR_SUCCESS
, "Could not set key value: %d.\n", r
);
4067 add_reglocator_entry( hdb
, "NewSignature5", 2, "Software\\Winetest_msi", "",
4068 msidbLocatorTypeFileName
|msidbLocatorType64bit
);
4070 create_drlocator_table( hdb
);
4071 add_drlocator_entry( hdb
, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
4073 create_signature_table( hdb
);
4074 add_signature_entry( hdb
, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
4075 add_signature_entry( hdb
, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4076 add_signature_entry( hdb
, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4077 add_signature_entry( hdb
, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4078 add_signature_entry( hdb
, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4080 r
= package_from_db( hdb
, &hpkg
);
4081 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
4083 skip("Not enough rights to perform tests\n");
4084 DeleteFileA(msifile
);
4087 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
4088 MsiCloseHandle( hdb
);
4089 if (r
!= ERROR_SUCCESS
)
4092 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
4094 r
= MsiDoActionA( hpkg
, "AppSearch" );
4095 ok( r
== ERROR_SUCCESS
, "AppSearch failed: %d\n", r
);
4097 size
= sizeof(prop
);
4098 r
= MsiGetPropertyA( hpkg
, "WEBBROWSERPROG", prop
, &size
);
4099 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
4100 ok( lstrlenA(prop
) != 0, "Expected non-zero length\n");
4102 size
= sizeof(prop
);
4103 r
= MsiGetPropertyA( hpkg
, "NOTEPAD", prop
, &size
);
4104 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
4106 size
= sizeof(prop
);
4107 r
= MsiGetPropertyA( hpkg
, "REGEXPANDVAL", prop
, &size
);
4108 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
4109 ok( lstrlenA(prop
) != 0, "Expected non-zero length\n");
4111 size
= sizeof(prop
);
4112 r
= MsiGetPropertyA( hpkg
, "32KEYVAL", prop
, &size
);
4113 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
4114 ok( lstrlenA(prop
) != 0, "Expected non-zero length\n");
4116 size
= sizeof(prop
);
4117 r
= MsiGetPropertyA( hpkg
, "64KEYVAL", prop
, &size
);
4118 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
4119 ok( lstrlenA(prop
) != 0, "Expected non-zero length\n");
4122 MsiCloseHandle( hpkg
);
4123 DeleteFileA(msifile
);
4124 RegDeleteKeyA(HKEY_CURRENT_USER
, "Software\\Winetest_msi");
4125 delete_key(HKEY_LOCAL_MACHINE
, "Software\\Winetest_msi", KEY_WOW64_32KEY
);
4126 delete_key(HKEY_LOCAL_MACHINE
, "Software\\Winetest_msi", KEY_WOW64_64KEY
);
4129 static void test_appsearch_complocator(void)
4131 MSIHANDLE hpkg
, hdb
;
4132 char path
[MAX_PATH
+ 15], expected
[MAX_PATH
], prop
[MAX_PATH
];
4137 if (!(usersid
= get_user_sid()))
4140 if (is_process_limited())
4142 skip("process is limited\n");
4146 create_test_file("FileName1");
4147 create_test_file("FileName4");
4148 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE
,
4149 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL
, FALSE
);
4151 create_test_file("FileName2");
4152 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED
,
4153 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid
, FALSE
);
4155 create_test_file("FileName3");
4156 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED
,
4157 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid
, FALSE
);
4159 create_test_file("FileName5");
4160 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE
,
4161 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL
, TRUE
);
4163 create_test_file("FileName6");
4164 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE
,
4165 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL
, TRUE
);
4167 create_test_file("FileName7");
4168 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE
,
4169 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL
, FALSE
);
4171 /* dir is FALSE, but we're pretending it's a directory */
4172 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE
,
4173 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL
, FALSE
);
4175 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4176 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE
,
4177 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL
, FALSE
);
4179 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4180 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE
,
4181 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL
, FALSE
);
4183 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4184 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE
,
4185 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL
, FALSE
);
4187 hdb
= create_package_db();
4188 ok(hdb
, "Expected a valid database handle\n");
4190 create_appsearch_table(hdb
);
4191 add_appsearch_entry(hdb
, "'SIGPROP1', 'NewSignature1'");
4192 add_appsearch_entry(hdb
, "'SIGPROP2', 'NewSignature2'");
4193 add_appsearch_entry(hdb
, "'SIGPROP3', 'NewSignature3'");
4194 add_appsearch_entry(hdb
, "'SIGPROP4', 'NewSignature4'");
4195 add_appsearch_entry(hdb
, "'SIGPROP5', 'NewSignature5'");
4196 add_appsearch_entry(hdb
, "'SIGPROP6', 'NewSignature6'");
4197 add_appsearch_entry(hdb
, "'SIGPROP7', 'NewSignature7'");
4198 add_appsearch_entry(hdb
, "'SIGPROP8', 'NewSignature8'");
4199 add_appsearch_entry(hdb
, "'SIGPROP9', 'NewSignature9'");
4200 add_appsearch_entry(hdb
, "'SIGPROP10', 'NewSignature10'");
4201 add_appsearch_entry(hdb
, "'SIGPROP11', 'NewSignature11'");
4202 add_appsearch_entry(hdb
, "'SIGPROP12', 'NewSignature12'");
4204 create_complocator_table(hdb
);
4206 /* published component, machine, file, signature, misdbLocatorTypeFile */
4207 add_complocator_entry(hdb
, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4209 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4210 add_complocator_entry(hdb
, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4212 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4213 add_complocator_entry(hdb
, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4215 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4216 add_complocator_entry(hdb
, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4218 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4219 add_complocator_entry(hdb
, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4221 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4222 add_complocator_entry(hdb
, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4224 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4225 add_complocator_entry(hdb
, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4227 /* unpublished component, no signature, misdbLocatorTypeDir */
4228 add_complocator_entry(hdb
, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4230 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4231 add_complocator_entry(hdb
, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4233 /* published component, signature w/ ver, misdbLocatorTypeFile */
4234 add_complocator_entry(hdb
, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4236 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4237 add_complocator_entry(hdb
, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4239 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4240 add_complocator_entry(hdb
, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4242 create_signature_table(hdb
);
4243 add_signature_entry(hdb
, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4244 add_signature_entry(hdb
, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4245 add_signature_entry(hdb
, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4246 add_signature_entry(hdb
, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4247 add_signature_entry(hdb
, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4248 add_signature_entry(hdb
, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4249 add_signature_entry(hdb
, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4250 add_signature_entry(hdb
, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4252 r
= package_from_db(hdb
, &hpkg
);
4253 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
4255 skip("Not enough rights to perform tests\n");
4258 ok(r
== ERROR_SUCCESS
, "Expected a valid package handle %u\n", r
);
4260 r
= MsiSetPropertyA(hpkg
, "SIGPROP8", "october");
4261 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4263 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
4265 r
= MsiDoActionA(hpkg
, "AppSearch");
4266 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4268 strcpy(expected
, CURR_DIR
);
4269 if (is_root(CURR_DIR
)) expected
[2] = 0;
4272 sprintf(path
, "%s\\FileName1", expected
);
4273 r
= MsiGetPropertyA(hpkg
, "SIGPROP1", prop
, &size
);
4274 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4275 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4278 sprintf(path
, "%s\\FileName2", expected
);
4279 r
= MsiGetPropertyA(hpkg
, "SIGPROP2", prop
, &size
);
4280 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4281 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4284 sprintf(path
, "%s\\FileName3", expected
);
4285 r
= MsiGetPropertyA(hpkg
, "SIGPROP3", prop
, &size
);
4286 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4287 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4290 sprintf(path
, "%s\\FileName4", expected
);
4291 r
= MsiGetPropertyA(hpkg
, "SIGPROP4", prop
, &size
);
4292 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4293 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4296 sprintf(path
, "%s\\FileName5", expected
);
4297 r
= MsiGetPropertyA(hpkg
, "SIGPROP5", prop
, &size
);
4298 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4299 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4302 sprintf(path
, "%s\\", expected
);
4303 r
= MsiGetPropertyA(hpkg
, "SIGPROP6", prop
, &size
);
4304 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4305 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4308 sprintf(path
, "%s\\", expected
);
4309 r
= MsiGetPropertyA(hpkg
, "SIGPROP7", prop
, &size
);
4310 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4311 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4314 r
= MsiGetPropertyA(hpkg
, "SIGPROP8", prop
, &size
);
4315 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4316 ok(!lstrcmpA(prop
, "october"), "Expected \"october\", got \"%s\"\n", prop
);
4319 r
= MsiGetPropertyA(hpkg
, "SIGPROP9", prop
, &size
);
4320 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4321 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4324 sprintf(path
, "%s\\FileName8.dll", expected
);
4325 r
= MsiGetPropertyA(hpkg
, "SIGPROP10", prop
, &size
);
4326 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4327 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4330 r
= MsiGetPropertyA(hpkg
, "SIGPROP11", prop
, &size
);
4331 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4332 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4335 sprintf(path
, "%s\\FileName10.dll", expected
);
4336 r
= MsiGetPropertyA(hpkg
, "SIGPROP12", prop
, &size
);
4337 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4338 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4340 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4341 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4342 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4343 MSIINSTALLCONTEXT_USERUNMANAGED
, usersid
);
4344 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4345 MSIINSTALLCONTEXT_USERMANAGED
, usersid
);
4346 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4347 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4348 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4349 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4350 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4351 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4352 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4353 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4354 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4355 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4356 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4357 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4358 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4359 MSIINSTALLCONTEXT_MACHINE
, NULL
);
4361 MsiCloseHandle(hpkg
);
4364 DeleteFileA("FileName1");
4365 DeleteFileA("FileName2");
4366 DeleteFileA("FileName3");
4367 DeleteFileA("FileName4");
4368 DeleteFileA("FileName5");
4369 DeleteFileA("FileName6");
4370 DeleteFileA("FileName7");
4371 DeleteFileA("FileName8.dll");
4372 DeleteFileA("FileName9.dll");
4373 DeleteFileA("FileName10.dll");
4374 DeleteFileA(msifile
);
4378 static void test_appsearch_reglocator(void)
4380 MSIHANDLE hpkg
, hdb
;
4381 char path
[MAX_PATH
+ 20], expected
[MAX_PATH
], prop
[MAX_PATH
];
4382 DWORD binary
[2], size
, val
;
4383 BOOL space
, version
, is_64bit
= sizeof(void *) > sizeof(int);
4384 HKEY hklm
, classes
, hkcu
, users
;
4385 LPSTR pathdata
, pathvar
, ptr
;
4391 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4394 DeleteFileA("test.dll");
4396 res
= RegCreateKeyA(HKEY_CLASSES_ROOT
, "Software\\Wine", &classes
);
4397 if (res
== ERROR_ACCESS_DENIED
)
4399 skip("Not enough rights to perform tests\n");
4402 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4404 res
= RegSetValueExA(classes
, "Value1", 0, REG_SZ
,
4405 (const BYTE
*)"regszdata", 10);
4406 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4408 res
= RegCreateKeyA(HKEY_CURRENT_USER
, "Software\\Wine", &hkcu
);
4409 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4411 res
= RegSetValueExA(hkcu
, "Value1", 0, REG_SZ
,
4412 (const BYTE
*)"regszdata", 10);
4413 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4416 res
= RegCreateKeyA(HKEY_USERS
, "S-1-5-18\\Software\\Wine", &users
);
4417 ok(res
== ERROR_SUCCESS
||
4418 broken(res
== ERROR_INVALID_PARAMETER
),
4419 "Expected ERROR_SUCCESS, got %d\n", res
);
4421 if (res
== ERROR_SUCCESS
)
4423 res
= RegSetValueExA(users
, "Value1", 0, REG_SZ
,
4424 (const BYTE
*)"regszdata", 10);
4425 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4428 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, "Software\\Wine", &hklm
);
4429 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4431 res
= RegSetValueA(hklm
, NULL
, REG_SZ
, "defvalue", 8);
4432 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4434 res
= RegSetValueExA(hklm
, "Value1", 0, REG_SZ
,
4435 (const BYTE
*)"regszdata", 10);
4436 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4439 res
= RegSetValueExA(hklm
, "Value2", 0, REG_DWORD
,
4440 (const BYTE
*)&val
, sizeof(DWORD
));
4441 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4444 res
= RegSetValueExA(hklm
, "Value3", 0, REG_DWORD
,
4445 (const BYTE
*)&val
, sizeof(DWORD
));
4446 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4448 res
= RegSetValueExA(hklm
, "Value4", 0, REG_EXPAND_SZ
,
4449 (const BYTE
*)"%PATH%", 7);
4450 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4452 res
= RegSetValueExA(hklm
, "Value5", 0, REG_EXPAND_SZ
,
4453 (const BYTE
*)"my%NOVAR%", 10);
4454 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4456 res
= RegSetValueExA(hklm
, "Value6", 0, REG_MULTI_SZ
,
4457 (const BYTE
*)"one\0two\0", 9);
4458 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4460 binary
[0] = 0x1234abcd;
4461 binary
[1] = 0x567890ef;
4462 res
= RegSetValueExA(hklm
, "Value7", 0, REG_BINARY
,
4463 (const BYTE
*)binary
, sizeof(binary
));
4464 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4466 res
= RegSetValueExA(hklm
, "Value8", 0, REG_SZ
,
4467 (const BYTE
*)"#regszdata", 11);
4468 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4470 strcpy(expected
, CURR_DIR
);
4471 if (is_root(CURR_DIR
)) expected
[2] = 0;
4473 create_test_file("FileName1");
4474 sprintf(path
, "%s\\FileName1", expected
);
4475 res
= RegSetValueExA(hklm
, "Value9", 0, REG_SZ
,
4476 (const BYTE
*)path
, lstrlenA(path
) + 1);
4477 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4479 sprintf(path
, "%s\\FileName2", expected
);
4480 res
= RegSetValueExA(hklm
, "Value10", 0, REG_SZ
,
4481 (const BYTE
*)path
, lstrlenA(path
) + 1);
4482 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4484 lstrcpyA(path
, expected
);
4485 res
= RegSetValueExA(hklm
, "Value11", 0, REG_SZ
,
4486 (const BYTE
*)path
, lstrlenA(path
) + 1);
4487 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4489 res
= RegSetValueExA(hklm
, "Value12", 0, REG_SZ
,
4490 (const BYTE
*)"", 1);
4491 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4493 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4494 sprintf(path
, "%s\\FileName3.dll", expected
);
4495 res
= RegSetValueExA(hklm
, "Value13", 0, REG_SZ
,
4496 (const BYTE
*)path
, lstrlenA(path
) + 1);
4497 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4499 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4500 sprintf(path
, "%s\\FileName4.dll", expected
);
4501 res
= RegSetValueExA(hklm
, "Value14", 0, REG_SZ
,
4502 (const BYTE
*)path
, lstrlenA(path
) + 1);
4503 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4505 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4506 sprintf(path
, "%s\\FileName5.dll", expected
);
4507 res
= RegSetValueExA(hklm
, "Value15", 0, REG_SZ
,
4508 (const BYTE
*)path
, lstrlenA(path
) + 1);
4509 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
4511 sprintf(path
, "\"%s\\FileName1\" -option", expected
);
4512 res
= RegSetValueExA(hklm
, "value16", 0, REG_SZ
,
4513 (const BYTE
*)path
, lstrlenA(path
) + 1);
4514 ok( res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", res
);
4516 space
= strchr(expected
, ' ') != NULL
;
4517 sprintf(path
, "%s\\FileName1 -option", expected
);
4518 res
= RegSetValueExA(hklm
, "value17", 0, REG_SZ
,
4519 (const BYTE
*)path
, lstrlenA(path
) + 1);
4520 ok( res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", res
);
4522 hdb
= create_package_db();
4523 ok(hdb
, "Expected a valid database handle\n");
4525 create_appsearch_table(hdb
);
4526 add_appsearch_entry(hdb
, "'SIGPROP1', 'NewSignature1'");
4527 add_appsearch_entry(hdb
, "'SIGPROP2', 'NewSignature2'");
4528 add_appsearch_entry(hdb
, "'SIGPROP3', 'NewSignature3'");
4529 add_appsearch_entry(hdb
, "'SIGPROP4', 'NewSignature4'");
4530 add_appsearch_entry(hdb
, "'SIGPROP5', 'NewSignature5'");
4531 add_appsearch_entry(hdb
, "'SIGPROP6', 'NewSignature6'");
4532 add_appsearch_entry(hdb
, "'SIGPROP7', 'NewSignature7'");
4533 add_appsearch_entry(hdb
, "'SIGPROP8', 'NewSignature8'");
4534 add_appsearch_entry(hdb
, "'SIGPROP9', 'NewSignature9'");
4535 add_appsearch_entry(hdb
, "'SIGPROP10', 'NewSignature10'");
4536 add_appsearch_entry(hdb
, "'SIGPROP11', 'NewSignature11'");
4537 add_appsearch_entry(hdb
, "'SIGPROP12', 'NewSignature12'");
4538 add_appsearch_entry(hdb
, "'SIGPROP13', 'NewSignature13'");
4539 add_appsearch_entry(hdb
, "'SIGPROP14', 'NewSignature14'");
4540 add_appsearch_entry(hdb
, "'SIGPROP15', 'NewSignature15'");
4541 add_appsearch_entry(hdb
, "'SIGPROP16', 'NewSignature16'");
4542 add_appsearch_entry(hdb
, "'SIGPROP17', 'NewSignature17'");
4543 add_appsearch_entry(hdb
, "'SIGPROP18', 'NewSignature18'");
4544 add_appsearch_entry(hdb
, "'SIGPROP19', 'NewSignature19'");
4545 add_appsearch_entry(hdb
, "'SIGPROP20', 'NewSignature20'");
4546 add_appsearch_entry(hdb
, "'SIGPROP21', 'NewSignature21'");
4547 add_appsearch_entry(hdb
, "'SIGPROP22', 'NewSignature22'");
4548 add_appsearch_entry(hdb
, "'SIGPROP23', 'NewSignature23'");
4549 add_appsearch_entry(hdb
, "'SIGPROP24', 'NewSignature24'");
4550 add_appsearch_entry(hdb
, "'SIGPROP25', 'NewSignature25'");
4551 add_appsearch_entry(hdb
, "'SIGPROP26', 'NewSignature26'");
4552 add_appsearch_entry(hdb
, "'SIGPROP27', 'NewSignature27'");
4553 add_appsearch_entry(hdb
, "'SIGPROP28', 'NewSignature28'");
4554 add_appsearch_entry(hdb
, "'SIGPROP29', 'NewSignature29'");
4555 add_appsearch_entry(hdb
, "'SIGPROP30', 'NewSignature30'");
4557 create_reglocator_table(hdb
);
4559 type
= msidbLocatorTypeRawValue
;
4561 type
|= msidbLocatorType64bit
;
4563 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4564 add_reglocator_entry(hdb
, "NewSignature1", 2, "Software\\Wine", "Value1", type
);
4566 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4567 add_reglocator_entry(hdb
, "NewSignature2", 2, "Software\\Wine", "Value2", type
);
4569 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4570 add_reglocator_entry(hdb
, "NewSignature3", 2, "Software\\Wine", "Value3", type
);
4572 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4573 add_reglocator_entry(hdb
, "NewSignature4", 2, "Software\\Wine", "Value4", type
);
4575 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4576 add_reglocator_entry(hdb
, "NewSignature5", 2, "Software\\Wine", "Value5", type
);
4578 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4579 add_reglocator_entry(hdb
, "NewSignature6", 2, "Software\\Wine", "Value6", type
);
4581 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4582 add_reglocator_entry(hdb
, "NewSignature7", 2, "Software\\Wine", "Value7", type
);
4584 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4585 add_reglocator_entry(hdb
, "NewSignature8", 2, "Software\\Wine", "Value8", type
);
4587 type
= msidbLocatorTypeFileName
;
4589 type
|= msidbLocatorType64bit
;
4591 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4592 add_reglocator_entry(hdb
, "NewSignature9", 2, "Software\\Wine", "Value9", type
);
4594 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4595 add_reglocator_entry(hdb
, "NewSignature10", 2, "Software\\Wine", "Value10", type
);
4597 /* HKLM, msidbLocatorTypeFileName, no signature */
4598 add_reglocator_entry(hdb
, "NewSignature11", 2, "Software\\Wine", "Value9", type
);
4600 type
= msidbLocatorTypeDirectory
;
4602 type
|= msidbLocatorType64bit
;
4604 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4605 add_reglocator_entry(hdb
, "NewSignature12", 2, "Software\\Wine", "Value9", type
);
4607 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4608 add_reglocator_entry(hdb
, "NewSignature13", 2, "Software\\Wine", "Value11", type
);
4610 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4611 add_reglocator_entry(hdb
, "NewSignature14", 2, "Software\\Wine", "Value9", type
);
4613 type
= msidbLocatorTypeRawValue
;
4615 type
|= msidbLocatorType64bit
;
4617 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4618 add_reglocator_entry(hdb
, "NewSignature15", 0, "Software\\Wine", "Value1", type
);
4620 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4621 add_reglocator_entry(hdb
, "NewSignature16", 1, "Software\\Wine", "Value1", type
);
4623 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4624 add_reglocator_entry(hdb
, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type
);
4626 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4627 add_reglocator_entry(hdb
, "NewSignature18", 2, "Software\\Wine", "", type
);
4629 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4630 add_reglocator_entry(hdb
, "NewSignature19", 2, "Software\\IDontExist", "", type
);
4632 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4633 add_reglocator_entry(hdb
, "NewSignature20", 2, "Software\\Wine", "Value12", type
);
4635 type
= msidbLocatorTypeFileName
;
4637 type
|= msidbLocatorType64bit
;
4639 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4640 add_reglocator_entry(hdb
, "NewSignature21", 2, "Software\\Wine", "Value13", type
);
4642 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4643 add_reglocator_entry(hdb
, "NewSignature22", 2, "Software\\Wine", "Value14", type
);
4645 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4646 add_reglocator_entry(hdb
, "NewSignature23", 2, "Software\\Wine", "Value15", type
);
4648 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4649 add_reglocator_entry(hdb
, "NewSignature24", 2, "Software\\Wine", "Value11", type
);
4651 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4652 add_reglocator_entry(hdb
, "NewSignature25", 2, "Software\\Wine", "Value10", type
);
4654 type
= msidbLocatorTypeDirectory
;
4656 type
|= msidbLocatorType64bit
;
4658 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4659 add_reglocator_entry(hdb
, "NewSignature26", 2, "Software\\Wine", "Value11", type
);
4661 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4662 add_reglocator_entry(hdb
, "NewSignature27", 2, "Software\\Wine", "Value10", type
);
4664 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4665 add_reglocator_entry(hdb
, "NewSignature28", 2, "Software\\Wine", "Value10", type
);
4667 type
= msidbLocatorTypeFileName
;
4669 type
|= msidbLocatorType64bit
;
4671 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4672 add_reglocator_entry(hdb
, "NewSignature29", 2, "Software\\Wine", "Value16", type
);
4674 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4675 add_reglocator_entry(hdb
, "NewSignature30", 2, "Software\\Wine", "Value17", type
);
4677 create_signature_table(hdb
);
4678 add_signature_entry(hdb
, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4679 add_signature_entry(hdb
, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4680 add_signature_entry(hdb
, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4681 add_signature_entry(hdb
, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4682 add_signature_entry(hdb
, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4683 add_signature_entry(hdb
, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4685 if (!is_root(CURR_DIR
))
4687 ptr
= strrchr(expected
, '\\') + 1;
4688 sprintf(path
, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr
);
4689 add_signature_entry(hdb
, path
);
4691 add_signature_entry(hdb
, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4692 add_signature_entry(hdb
, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4693 add_signature_entry(hdb
, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4695 r
= package_from_db(hdb
, &hpkg
);
4696 ok(r
== ERROR_SUCCESS
, "Expected a valid package handle %u\n", r
);
4698 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
4700 r
= MsiDoActionA(hpkg
, "AppSearch");
4701 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4704 r
= MsiGetPropertyA(hpkg
, "SIGPROP1", prop
, &size
);
4705 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4706 ok(!lstrcmpA(prop
, "regszdata"),
4707 "Expected \"regszdata\", got \"%s\"\n", prop
);
4710 r
= MsiGetPropertyA(hpkg
, "SIGPROP2", prop
, &size
);
4711 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4712 ok(!lstrcmpA(prop
, "#42"), "Expected \"#42\", got \"%s\"\n", prop
);
4715 r
= MsiGetPropertyA(hpkg
, "SIGPROP3", prop
, &size
);
4716 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4717 ok(!lstrcmpA(prop
, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop
);
4719 memset(&si
, 0, sizeof(si
));
4720 GetNativeSystemInfo(&si
);
4722 if (S(U(si
)).wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_INTEL
)
4724 size
= ExpandEnvironmentStringsA("%PATH%", NULL
, 0);
4725 pathvar
= HeapAlloc(GetProcessHeap(), 0, size
);
4726 ExpandEnvironmentStringsA("%PATH%", pathvar
, size
);
4729 r
= MsiGetPropertyA(hpkg
, "SIGPROP4", NULL
, &size
);
4730 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4732 pathdata
= HeapAlloc(GetProcessHeap(), 0, ++size
);
4733 r
= MsiGetPropertyA(hpkg
, "SIGPROP4", pathdata
, &size
);
4734 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4735 ok(!lstrcmpA(pathdata
, pathvar
),
4736 "Expected \"%s\", got \"%s\"\n", pathvar
, pathdata
);
4738 HeapFree(GetProcessHeap(), 0, pathvar
);
4739 HeapFree(GetProcessHeap(), 0, pathdata
);
4743 r
= MsiGetPropertyA(hpkg
, "SIGPROP5", prop
, &size
);
4744 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4746 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop
);
4749 r
= MsiGetPropertyA(hpkg
, "SIGPROP6", prop
, &size
);
4750 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4753 ok(!memcmp(prop
, "\0one\0two\0\0", 10),
4754 "Expected \"\\0one\\0two\\0\\0\"\n");
4758 lstrcpyA(path
, "#xCDAB3412EF907856");
4759 r
= MsiGetPropertyA(hpkg
, "SIGPROP7", prop
, &size
);
4760 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4761 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4764 r
= MsiGetPropertyA(hpkg
, "SIGPROP8", prop
, &size
);
4765 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4766 ok(!lstrcmpA(prop
, "##regszdata"),
4767 "Expected \"##regszdata\", got \"%s\"\n", prop
);
4770 sprintf(path
, "%s\\FileName1", expected
);
4771 r
= MsiGetPropertyA(hpkg
, "SIGPROP9", prop
, &size
);
4772 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4773 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4776 r
= MsiGetPropertyA(hpkg
, "SIGPROP10", prop
, &size
);
4777 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4778 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4781 sprintf(path
, "%s\\", expected
);
4782 r
= MsiGetPropertyA(hpkg
, "SIGPROP11", prop
, &size
);
4783 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4784 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4787 r
= MsiGetPropertyA(hpkg
, "SIGPROP12", prop
, &size
);
4788 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4789 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4792 sprintf(path
, "%s\\", expected
);
4793 r
= MsiGetPropertyA(hpkg
, "SIGPROP13", prop
, &size
);
4794 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4795 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4798 r
= MsiGetPropertyA(hpkg
, "SIGPROP14", prop
, &size
);
4799 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4800 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4803 r
= MsiGetPropertyA(hpkg
, "SIGPROP15", prop
, &size
);
4804 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4805 ok(!lstrcmpA(prop
, "regszdata"),
4806 "Expected \"regszdata\", got \"%s\"\n", prop
);
4809 r
= MsiGetPropertyA(hpkg
, "SIGPROP16", prop
, &size
);
4810 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4811 ok(!lstrcmpA(prop
, "regszdata"),
4812 "Expected \"regszdata\", got \"%s\"\n", prop
);
4817 r
= MsiGetPropertyA(hpkg
, "SIGPROP17", prop
, &size
);
4818 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4819 ok(!lstrcmpA(prop
, "regszdata"),
4820 "Expected \"regszdata\", got \"%s\"\n", prop
);
4824 r
= MsiGetPropertyA(hpkg
, "SIGPROP18", prop
, &size
);
4825 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4826 ok(!lstrcmpA(prop
, "defvalue"),
4827 "Expected \"defvalue\", got \"%s\"\n", prop
);
4830 r
= MsiGetPropertyA(hpkg
, "SIGPROP19", prop
, &size
);
4831 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4832 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4835 r
= MsiGetPropertyA(hpkg
, "SIGPROP20", prop
, &size
);
4836 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4837 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4842 sprintf(path
, "%s\\FileName3.dll", expected
);
4843 r
= MsiGetPropertyA(hpkg
, "SIGPROP21", prop
, &size
);
4844 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4845 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4848 r
= MsiGetPropertyA(hpkg
, "SIGPROP22", prop
, &size
);
4849 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4850 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4853 sprintf(path
, "%s\\FileName5.dll", expected
);
4854 r
= MsiGetPropertyA(hpkg
, "SIGPROP23", prop
, &size
);
4855 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4856 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4859 if (!is_root(CURR_DIR
))
4862 lstrcpyA(path
, expected
);
4863 ptr
= strrchr(path
, '\\') + 1;
4865 r
= MsiGetPropertyA(hpkg
, "SIGPROP24", prop
, &size
);
4866 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4867 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4870 sprintf(path
, "%s\\", expected
);
4871 r
= MsiGetPropertyA(hpkg
, "SIGPROP25", prop
, &size
);
4872 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4873 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4876 r
= MsiGetPropertyA(hpkg
, "SIGPROP26", prop
, &size
);
4877 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4878 if (is_root(CURR_DIR
))
4879 ok(!lstrcmpA(prop
, CURR_DIR
), "Expected \"%s\", got \"%s\"\n", CURR_DIR
, prop
);
4881 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4884 r
= MsiGetPropertyA(hpkg
, "SIGPROP27", prop
, &size
);
4885 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4886 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4889 r
= MsiGetPropertyA(hpkg
, "SIGPROP28", prop
, &size
);
4890 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4891 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4894 sprintf(path
, "%s\\FileName1", expected
);
4895 r
= MsiGetPropertyA(hpkg
, "SIGPROP29", prop
, &size
);
4896 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4897 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4900 sprintf(path
, "%s\\FileName1", expected
);
4901 r
= MsiGetPropertyA(hpkg
, "SIGPROP30", prop
, &size
);
4902 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
4904 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
4906 todo_wine
ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
4908 RegSetValueA(hklm
, NULL
, REG_SZ
, "", 0);
4909 RegDeleteValueA(hklm
, "Value1");
4910 RegDeleteValueA(hklm
, "Value2");
4911 RegDeleteValueA(hklm
, "Value3");
4912 RegDeleteValueA(hklm
, "Value4");
4913 RegDeleteValueA(hklm
, "Value5");
4914 RegDeleteValueA(hklm
, "Value6");
4915 RegDeleteValueA(hklm
, "Value7");
4916 RegDeleteValueA(hklm
, "Value8");
4917 RegDeleteValueA(hklm
, "Value9");
4918 RegDeleteValueA(hklm
, "Value10");
4919 RegDeleteValueA(hklm
, "Value11");
4920 RegDeleteValueA(hklm
, "Value12");
4921 RegDeleteValueA(hklm
, "Value13");
4922 RegDeleteValueA(hklm
, "Value14");
4923 RegDeleteValueA(hklm
, "Value15");
4924 RegDeleteValueA(hklm
, "Value16");
4925 RegDeleteValueA(hklm
, "Value17");
4926 RegDeleteKeyA(hklm
, "");
4929 RegDeleteValueA(classes
, "Value1");
4930 RegDeleteKeyA(classes
, "");
4931 RegCloseKey(classes
);
4933 RegDeleteValueA(hkcu
, "Value1");
4934 RegDeleteKeyA(hkcu
, "");
4937 RegDeleteValueA(users
, "Value1");
4938 RegDeleteKeyA(users
, "");
4941 DeleteFileA("FileName1");
4942 DeleteFileA("FileName3.dll");
4943 DeleteFileA("FileName4.dll");
4944 DeleteFileA("FileName5.dll");
4945 MsiCloseHandle(hpkg
);
4946 DeleteFileA(msifile
);
4949 static void delete_win_ini(LPCSTR file
)
4951 CHAR path
[MAX_PATH
];
4953 GetWindowsDirectoryA(path
, MAX_PATH
);
4954 lstrcatA(path
, "\\");
4955 lstrcatA(path
, file
);
4960 static void test_appsearch_inilocator(void)
4962 MSIHANDLE hpkg
, hdb
;
4963 char path
[MAX_PATH
+ 14], expected
[MAX_PATH
], prop
[MAX_PATH
];
4970 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4973 DeleteFileA("test.dll");
4975 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4977 strcpy(expected
, CURR_DIR
);
4978 if (is_root(CURR_DIR
)) expected
[2] = 0;
4980 create_test_file("FileName1");
4981 sprintf(path
, "%s\\FileName1", expected
);
4982 WritePrivateProfileStringA("Section", "Key2", path
, "IniFile.ini");
4984 WritePrivateProfileStringA("Section", "Key3", expected
, "IniFile.ini");
4986 sprintf(path
, "%s\\IDontExist", expected
);
4987 WritePrivateProfileStringA("Section", "Key4", path
, "IniFile.ini");
4989 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4990 sprintf(path
, "%s\\FileName2.dll", expected
);
4991 WritePrivateProfileStringA("Section", "Key5", path
, "IniFile.ini");
4993 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4994 sprintf(path
, "%s\\FileName3.dll", expected
);
4995 WritePrivateProfileStringA("Section", "Key6", path
, "IniFile.ini");
4997 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4998 sprintf(path
, "%s\\FileName4.dll", expected
);
4999 WritePrivateProfileStringA("Section", "Key7", path
, "IniFile.ini");
5001 hdb
= create_package_db();
5002 ok(hdb
, "Expected a valid database handle\n");
5004 create_appsearch_table(hdb
);
5005 add_appsearch_entry(hdb
, "'SIGPROP1', 'NewSignature1'");
5006 add_appsearch_entry(hdb
, "'SIGPROP2', 'NewSignature2'");
5007 add_appsearch_entry(hdb
, "'SIGPROP3', 'NewSignature3'");
5008 add_appsearch_entry(hdb
, "'SIGPROP4', 'NewSignature4'");
5009 add_appsearch_entry(hdb
, "'SIGPROP5', 'NewSignature5'");
5010 add_appsearch_entry(hdb
, "'SIGPROP6', 'NewSignature6'");
5011 add_appsearch_entry(hdb
, "'SIGPROP7', 'NewSignature7'");
5012 add_appsearch_entry(hdb
, "'SIGPROP8', 'NewSignature8'");
5013 add_appsearch_entry(hdb
, "'SIGPROP9', 'NewSignature9'");
5014 add_appsearch_entry(hdb
, "'SIGPROP10', 'NewSignature10'");
5015 add_appsearch_entry(hdb
, "'SIGPROP11', 'NewSignature11'");
5016 add_appsearch_entry(hdb
, "'SIGPROP12', 'NewSignature12'");
5018 create_inilocator_table(hdb
);
5020 /* msidbLocatorTypeRawValue, field 1 */
5021 add_inilocator_entry(hdb
, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
5023 /* msidbLocatorTypeRawValue, field 2 */
5024 add_inilocator_entry(hdb
, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
5026 /* msidbLocatorTypeRawValue, entire field */
5027 add_inilocator_entry(hdb
, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
5029 /* msidbLocatorTypeFile */
5030 add_inilocator_entry(hdb
, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5032 /* msidbLocatorTypeDirectory, file */
5033 add_inilocator_entry(hdb
, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
5035 /* msidbLocatorTypeDirectory, directory */
5036 add_inilocator_entry(hdb
, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
5038 /* msidbLocatorTypeFile, file, no signature */
5039 add_inilocator_entry(hdb
, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5041 /* msidbLocatorTypeFile, dir, no signature */
5042 add_inilocator_entry(hdb
, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
5044 /* msidbLocatorTypeFile, file does not exist */
5045 add_inilocator_entry(hdb
, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
5047 /* msidbLocatorTypeFile, signature with version */
5048 add_inilocator_entry(hdb
, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
5050 /* msidbLocatorTypeFile, signature with version, ver > max */
5051 add_inilocator_entry(hdb
, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
5053 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
5054 add_inilocator_entry(hdb
, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
5056 create_signature_table(hdb
);
5057 add_signature_entry(hdb
, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
5058 add_signature_entry(hdb
, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
5059 add_signature_entry(hdb
, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5060 add_signature_entry(hdb
, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5061 add_signature_entry(hdb
, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5063 r
= package_from_db(hdb
, &hpkg
);
5064 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5066 skip("Not enough rights to perform tests\n");
5069 ok(r
== ERROR_SUCCESS
, "Expected a valid package handle %u\n", r
);
5071 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5073 r
= MsiDoActionA(hpkg
, "AppSearch");
5074 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5077 r
= MsiGetPropertyA(hpkg
, "SIGPROP1", prop
, &size
);
5078 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5079 ok(!lstrcmpA(prop
, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop
);
5082 r
= MsiGetPropertyA(hpkg
, "SIGPROP2", prop
, &size
);
5083 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5084 ok(!lstrcmpA(prop
, "field2"), "Expected \"field2\", got \"%s\"\n", prop
);
5087 r
= MsiGetPropertyA(hpkg
, "SIGPROP3", prop
, &size
);
5088 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5089 ok(!lstrcmpA(prop
, "keydata,field2"),
5090 "Expected \"keydata,field2\", got \"%s\"\n", prop
);
5093 sprintf(path
, "%s\\FileName1", expected
);
5094 r
= MsiGetPropertyA(hpkg
, "SIGPROP4", prop
, &size
);
5095 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5096 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5099 r
= MsiGetPropertyA(hpkg
, "SIGPROP5", prop
, &size
);
5100 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5101 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5104 sprintf(path
, "%s\\", expected
);
5105 r
= MsiGetPropertyA(hpkg
, "SIGPROP6", prop
, &size
);
5106 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5107 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5110 sprintf(path
, "%s\\", expected
);
5111 r
= MsiGetPropertyA(hpkg
, "SIGPROP7", prop
, &size
);
5112 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5113 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5115 if (!is_root(CURR_DIR
))
5118 lstrcpyA(path
, expected
);
5119 ptr
= strrchr(path
, '\\');
5121 r
= MsiGetPropertyA(hpkg
, "SIGPROP8", prop
, &size
);
5122 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5123 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5126 r
= MsiGetPropertyA(hpkg
, "SIGPROP9", prop
, &size
);
5127 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5128 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5133 sprintf(path
, "%s\\FileName2.dll", expected
);
5134 r
= MsiGetPropertyA(hpkg
, "SIGPROP10", prop
, &size
);
5135 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5136 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5139 r
= MsiGetPropertyA(hpkg
, "SIGPROP11", prop
, &size
);
5140 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5141 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5144 sprintf(path
, "%s\\FileName4.dll", expected
);
5145 r
= MsiGetPropertyA(hpkg
, "SIGPROP12", prop
, &size
);
5146 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5147 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5150 MsiCloseHandle(hpkg
);
5153 delete_win_ini("IniFile.ini");
5154 DeleteFileA("FileName1");
5155 DeleteFileA("FileName2.dll");
5156 DeleteFileA("FileName3.dll");
5157 DeleteFileA("FileName4.dll");
5158 DeleteFileA(msifile
);
5162 * MSI AppSearch action on DrLocator table always returns absolute paths.
5163 * If a relative path was set, it returns the first absolute path that
5164 * matches or an empty string if it didn't find anything.
5165 * This helper function replicates this behaviour.
5167 static void search_absolute_directory(LPSTR absolute
, LPCSTR relative
)
5172 size
= lstrlenA(relative
);
5173 drives
= GetLogicalDrives();
5174 lstrcpyA(absolute
, "A:\\");
5175 for (i
= 0; i
< 26; absolute
[0] = '\0', i
++)
5177 if (!(drives
& (1 << i
)))
5180 absolute
[0] = 'A' + i
;
5181 if (GetDriveTypeA(absolute
) != DRIVE_FIXED
)
5184 lstrcpynA(absolute
+ 3, relative
, size
+ 1);
5185 attr
= GetFileAttributesA(absolute
);
5186 if (attr
!= INVALID_FILE_ATTRIBUTES
&&
5187 (attr
& FILE_ATTRIBUTE_DIRECTORY
))
5189 if (absolute
[3 + size
- 1] != '\\')
5190 lstrcatA(absolute
, "\\");
5197 static void test_appsearch_drlocator(void)
5199 MSIHANDLE hpkg
, hdb
;
5200 char path
[MAX_PATH
+ 27], expected
[MAX_PATH
], prop
[MAX_PATH
];
5206 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5209 DeleteFileA("test.dll");
5211 create_test_file("FileName1");
5212 CreateDirectoryA("one", NULL
);
5213 CreateDirectoryA("one\\two", NULL
);
5214 CreateDirectoryA("one\\two\\three", NULL
);
5215 create_test_file("one\\two\\three\\FileName2");
5216 CreateDirectoryA("another", NULL
);
5217 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5218 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5219 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5221 hdb
= create_package_db();
5222 ok(hdb
, "Expected a valid database handle\n");
5224 create_appsearch_table(hdb
);
5225 add_appsearch_entry(hdb
, "'SIGPROP1', 'NewSignature1'");
5226 add_appsearch_entry(hdb
, "'SIGPROP2', 'NewSignature2'");
5227 add_appsearch_entry(hdb
, "'SIGPROP3', 'NewSignature3'");
5228 add_appsearch_entry(hdb
, "'SIGPROP4', 'NewSignature4'");
5229 add_appsearch_entry(hdb
, "'SIGPROP5', 'NewSignature5'");
5230 add_appsearch_entry(hdb
, "'SIGPROP6', 'NewSignature6'");
5231 add_appsearch_entry(hdb
, "'SIGPROP7', 'NewSignature7'");
5232 add_appsearch_entry(hdb
, "'SIGPROP8', 'NewSignature8'");
5233 add_appsearch_entry(hdb
, "'SIGPROP9', 'NewSignature9'");
5234 add_appsearch_entry(hdb
, "'SIGPROP10', 'NewSignature10'");
5235 add_appsearch_entry(hdb
, "'SIGPROP11', 'NewSignature11'");
5236 add_appsearch_entry(hdb
, "'SIGPROP13', 'NewSignature13'");
5238 create_drlocator_table(hdb
);
5240 strcpy(expected
, CURR_DIR
);
5241 if (is_root(CURR_DIR
)) expected
[2] = 0;
5243 /* no parent, full path, depth 0, signature */
5244 sprintf(path
, "'NewSignature1', '', '%s', 0", expected
);
5245 add_drlocator_entry(hdb
, path
);
5247 /* no parent, full path, depth 0, no signature */
5248 sprintf(path
, "'NewSignature2', '', '%s', 0", expected
);
5249 add_drlocator_entry(hdb
, path
);
5251 /* no parent, relative path, depth 0, no signature */
5252 sprintf(path
, "'NewSignature3', '', '%s', 0", expected
+ 3);
5253 add_drlocator_entry(hdb
, path
);
5255 /* no parent, full path, depth 2, signature */
5256 sprintf(path
, "'NewSignature4', '', '%s', 2", expected
);
5257 add_drlocator_entry(hdb
, path
);
5259 /* no parent, full path, depth 3, signature */
5260 sprintf(path
, "'NewSignature5', '', '%s', 3", expected
);
5261 add_drlocator_entry(hdb
, path
);
5263 /* no parent, full path, depth 1, signature is dir */
5264 sprintf(path
, "'NewSignature6', '', '%s', 1", expected
);
5265 add_drlocator_entry(hdb
, path
);
5267 /* parent is in DrLocator, relative path, depth 0, signature */
5268 sprintf(path
, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5269 add_drlocator_entry(hdb
, path
);
5271 /* no parent, full path, depth 0, signature w/ version */
5272 sprintf(path
, "'NewSignature8', '', '%s', 0", expected
);
5273 add_drlocator_entry(hdb
, path
);
5275 /* no parent, full path, depth 0, signature w/ version, ver > max */
5276 sprintf(path
, "'NewSignature9', '', '%s', 0", expected
);
5277 add_drlocator_entry(hdb
, path
);
5279 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5280 sprintf(path
, "'NewSignature10', '', '%s', 0", expected
);
5281 add_drlocator_entry(hdb
, path
);
5283 /* no parent, relative empty path, depth 0, no signature */
5284 sprintf(path
, "'NewSignature11', '', '', 0");
5285 add_drlocator_entry(hdb
, path
);
5287 create_reglocator_table(hdb
);
5290 add_reglocator_entry(hdb
, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5292 /* parent is in RegLocator, no path, depth 0, no signature */
5293 sprintf(path
, "'NewSignature13', 'NewSignature12', '', 0");
5294 add_drlocator_entry(hdb
, path
);
5296 create_signature_table(hdb
);
5297 add_signature_entry(hdb
, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5298 add_signature_entry(hdb
, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5299 add_signature_entry(hdb
, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5300 add_signature_entry(hdb
, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5301 add_signature_entry(hdb
, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5302 add_signature_entry(hdb
, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5303 add_signature_entry(hdb
, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5304 add_signature_entry(hdb
, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5306 r
= package_from_db(hdb
, &hpkg
);
5307 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5309 skip("Not enough rights to perform tests\n");
5312 ok(r
== ERROR_SUCCESS
, "Expected a valid package handle %u\n", r
);
5314 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5316 r
= MsiDoActionA(hpkg
, "AppSearch");
5317 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5320 sprintf(path
, "%s\\FileName1", expected
);
5321 r
= MsiGetPropertyA(hpkg
, "SIGPROP1", prop
, &size
);
5322 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5323 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5326 sprintf(path
, "%s\\", expected
);
5327 r
= MsiGetPropertyA(hpkg
, "SIGPROP2", prop
, &size
);
5328 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5329 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5332 search_absolute_directory(path
, expected
+ 3);
5333 r
= MsiGetPropertyA(hpkg
, "SIGPROP3", prop
, &size
);
5334 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5335 ok(!lstrcmpiA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5338 r
= MsiGetPropertyA(hpkg
, "SIGPROP4", prop
, &size
);
5339 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5340 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5343 sprintf(path
, "%s\\one\\two\\three\\FileName2", expected
);
5344 r
= MsiGetPropertyA(hpkg
, "SIGPROP5", prop
, &size
);
5345 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5346 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5349 r
= MsiGetPropertyA(hpkg
, "SIGPROP6", prop
, &size
);
5350 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5351 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5354 sprintf(path
, "%s\\one\\two\\three\\FileName2", expected
);
5355 r
= MsiGetPropertyA(hpkg
, "SIGPROP7", prop
, &size
);
5356 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5357 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5362 sprintf(path
, "%s\\FileName3.dll", expected
);
5363 r
= MsiGetPropertyA(hpkg
, "SIGPROP8", prop
, &size
);
5364 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5365 ok(!lstrcmpA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5368 r
= MsiGetPropertyA(hpkg
, "SIGPROP9", prop
, &size
);
5369 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5370 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5373 r
= MsiGetPropertyA(hpkg
, "SIGPROP10", prop
, &size
);
5374 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5375 ok(!lstrcmpA(prop
, ""), "Expected \"\", got \"%s\"\n", prop
);
5379 search_absolute_directory(path
, "");
5380 r
= MsiGetPropertyA(hpkg
, "SIGPROP11", prop
, &size
);
5381 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5382 ok(!lstrcmpiA(prop
, path
), "Expected \"%s\", got \"%s\"\n", path
, prop
);
5385 strcpy(path
, "c:\\");
5386 r
= MsiGetPropertyA(hpkg
, "SIGPROP13", prop
, &size
);
5387 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5388 ok(!prop
[0], "Expected \"\", got \"%s\"\n", prop
);
5390 MsiCloseHandle(hpkg
);
5393 DeleteFileA("FileName1");
5394 DeleteFileA("FileName3.dll");
5395 DeleteFileA("FileName4.dll");
5396 DeleteFileA("FileName5.dll");
5397 DeleteFileA("one\\two\\three\\FileName2");
5398 RemoveDirectoryA("one\\two\\three");
5399 RemoveDirectoryA("one\\two");
5400 RemoveDirectoryA("one");
5401 RemoveDirectoryA("another");
5402 DeleteFileA(msifile
);
5405 static void test_featureparents(void)
5411 hdb
= create_package_db();
5412 ok ( hdb
, "failed to create package database\n" );
5414 add_directory_entry(hdb
, "'TARGETDIR', '', 'SourceDir'");
5416 create_feature_table( hdb
);
5417 create_component_table( hdb
);
5418 create_feature_components_table( hdb
);
5419 create_file_table( hdb
);
5421 /* msidbFeatureAttributesFavorLocal */
5422 add_feature_entry( hdb
, "'zodiac', '', '', '', 2, 1, '', 0" );
5424 /* msidbFeatureAttributesFavorSource */
5425 add_feature_entry( hdb
, "'perseus', '', '', '', 2, 1, '', 1" );
5427 /* msidbFeatureAttributesFavorLocal */
5428 add_feature_entry( hdb
, "'orion', '', '', '', 2, 1, '', 0" );
5430 /* msidbFeatureAttributesUIDisallowAbsent */
5431 add_feature_entry( hdb
, "'lyra', '', '', '', 2, 1, '', 16" );
5433 /* disabled because of install level */
5434 add_feature_entry( hdb
, "'waters', '', '', '', 15, 101, '', 9" );
5436 /* child feature of disabled feature */
5437 add_feature_entry( hdb
, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5439 /* component of disabled feature (install level) */
5440 add_component_entry( hdb
, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5442 /* component of disabled child feature (install level) */
5443 add_component_entry( hdb
, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5445 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5446 add_component_entry( hdb
, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5448 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5449 add_component_entry( hdb
, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5451 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5452 add_component_entry( hdb
, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5454 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5455 add_component_entry( hdb
, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5457 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5458 add_component_entry( hdb
, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5460 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5461 add_component_entry( hdb
, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5463 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5464 add_component_entry( hdb
, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5466 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5467 add_component_entry( hdb
, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5469 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5470 add_component_entry( hdb
, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5472 add_feature_components_entry( hdb
, "'zodiac', 'leo'" );
5473 add_feature_components_entry( hdb
, "'zodiac', 'virgo'" );
5474 add_feature_components_entry( hdb
, "'zodiac', 'libra'" );
5475 add_feature_components_entry( hdb
, "'perseus', 'cassiopeia'" );
5476 add_feature_components_entry( hdb
, "'perseus', 'cepheus'" );
5477 add_feature_components_entry( hdb
, "'perseus', 'andromeda'" );
5478 add_feature_components_entry( hdb
, "'orion', 'leo'" );
5479 add_feature_components_entry( hdb
, "'orion', 'virgo'" );
5480 add_feature_components_entry( hdb
, "'orion', 'libra'" );
5481 add_feature_components_entry( hdb
, "'orion', 'cassiopeia'" );
5482 add_feature_components_entry( hdb
, "'orion', 'cepheus'" );
5483 add_feature_components_entry( hdb
, "'orion', 'andromeda'" );
5484 add_feature_components_entry( hdb
, "'orion', 'canis'" );
5485 add_feature_components_entry( hdb
, "'orion', 'monoceros'" );
5486 add_feature_components_entry( hdb
, "'orion', 'lepus'" );
5487 add_feature_components_entry( hdb
, "'waters', 'delphinus'" );
5488 add_feature_components_entry( hdb
, "'bayer', 'hydrus'" );
5490 add_file_entry( hdb
, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5491 add_file_entry( hdb
, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5492 add_file_entry( hdb
, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5493 add_file_entry( hdb
, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5494 add_file_entry( hdb
, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5495 add_file_entry( hdb
, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5496 add_file_entry( hdb
, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5497 add_file_entry( hdb
, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5498 add_file_entry( hdb
, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5499 add_file_entry( hdb
, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5500 add_file_entry( hdb
, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5502 r
= package_from_db( hdb
, &hpkg
);
5503 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5505 skip("Not enough rights to perform tests\n");
5506 DeleteFileA(msifile
);
5509 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
5511 MsiCloseHandle( hdb
);
5513 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5515 r
= MsiDoActionA( hpkg
, "CostInitialize");
5516 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
5518 r
= MsiDoActionA( hpkg
, "FileCost");
5519 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
5521 r
= MsiDoActionA( hpkg
, "CostFinalize");
5522 ok( r
== ERROR_SUCCESS
, "cost finalize failed\n");
5524 test_feature_states( __LINE__
, hpkg
, "zodiac", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
5525 test_feature_states( __LINE__
, hpkg
, "perseus", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
5526 test_feature_states( __LINE__
, hpkg
, "orion", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
5527 test_feature_states( __LINE__
, hpkg
, "lyra", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
5528 test_feature_states( __LINE__
, hpkg
, "waters", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
5529 test_feature_states( __LINE__
, hpkg
, "bayer", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
5531 test_component_states( __LINE__
, hpkg
, "leo", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5532 test_component_states( __LINE__
, hpkg
, "virgo", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5533 test_component_states( __LINE__
, hpkg
, "libra", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5534 test_component_states( __LINE__
, hpkg
, "cassiopeia", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5535 test_component_states( __LINE__
, hpkg
, "cepheus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5536 test_component_states( __LINE__
, hpkg
, "andromeda", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5537 test_component_states( __LINE__
, hpkg
, "canis", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5538 test_component_states( __LINE__
, hpkg
, "monoceros", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5539 test_component_states( __LINE__
, hpkg
, "lepus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5540 test_component_states( __LINE__
, hpkg
, "delphinus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5541 test_component_states( __LINE__
, hpkg
, "hydrus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5543 r
= MsiSetFeatureStateA(hpkg
, "orion", INSTALLSTATE_ABSENT
);
5544 ok( r
== ERROR_SUCCESS
, "failed to set feature state: %d\n", r
);
5546 r
= MsiSetFeatureStateA(hpkg
, "lyra", INSTALLSTATE_ABSENT
);
5547 ok( r
== ERROR_SUCCESS
, "failed to set feature state: %d\n", r
);
5549 r
= MsiSetFeatureStateA(hpkg
, "nosuchfeature", INSTALLSTATE_ABSENT
);
5550 ok( r
== ERROR_UNKNOWN_FEATURE
, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r
);
5552 test_feature_states( __LINE__
, hpkg
, "zodiac", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_LOCAL
, FALSE
);
5553 test_feature_states( __LINE__
, hpkg
, "perseus", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_SOURCE
, FALSE
);
5554 test_feature_states( __LINE__
, hpkg
, "orion", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_ABSENT
, FALSE
);
5555 test_feature_states( __LINE__
, hpkg
, "lyra", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_ABSENT
, FALSE
);
5556 test_feature_states( __LINE__
, hpkg
, "waters", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
5557 test_feature_states( __LINE__
, hpkg
, "bayer", ERROR_SUCCESS
, INSTALLSTATE_ABSENT
, INSTALLSTATE_UNKNOWN
, FALSE
);
5559 test_component_states( __LINE__
, hpkg
, "leo", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5560 test_component_states( __LINE__
, hpkg
, "virgo", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5561 test_component_states( __LINE__
, hpkg
, "libra", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5562 test_component_states( __LINE__
, hpkg
, "cassiopeia", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_LOCAL
, FALSE
);
5563 test_component_states( __LINE__
, hpkg
, "cepheus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5564 test_component_states( __LINE__
, hpkg
, "andromeda", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_SOURCE
, FALSE
);
5565 test_component_states( __LINE__
, hpkg
, "canis", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5566 test_component_states( __LINE__
, hpkg
, "monoceros", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5567 test_component_states( __LINE__
, hpkg
, "lepus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5568 test_component_states( __LINE__
, hpkg
, "delphinus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5569 test_component_states( __LINE__
, hpkg
, "hydrus", ERROR_SUCCESS
, INSTALLSTATE_UNKNOWN
, INSTALLSTATE_UNKNOWN
, FALSE
);
5571 MsiCloseHandle(hpkg
);
5572 DeleteFileA(msifile
);
5575 static void test_installprops(void)
5577 MSIHANDLE hpkg
, hdb
;
5578 CHAR path
[MAX_PATH
], buf
[MAX_PATH
];
5581 HKEY hkey1
, hkey2
, pathkey
;
5584 REGSAM access
= KEY_ALL_ACCESS
;
5586 INSTALLUILEVEL uilevel
;
5589 access
|= KEY_WOW64_64KEY
;
5591 lstrcpyA(path
, CURR_DIR
);
5592 if (!is_root(CURR_DIR
)) lstrcatA(path
, "\\");
5593 lstrcatA(path
, msifile
);
5595 uilevel
= MsiSetInternalUI(INSTALLUILEVEL_BASIC
|INSTALLUILEVEL_SOURCERESONLY
, NULL
);
5597 hdb
= create_package_db();
5598 ok( hdb
, "failed to create database\n");
5600 r
= package_from_db(hdb
, &hpkg
);
5601 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5603 skip("Not enough rights to perform tests\n");
5604 MsiSetInternalUI(uilevel
, NULL
);
5605 DeleteFileA(msifile
);
5608 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
5610 MsiCloseHandle(hdb
);
5614 r
= MsiGetPropertyA(hpkg
, "UILevel", buf
, &size
);
5615 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5616 ok( !lstrcmpA(buf
, "3"), "Expected \"3\", got \"%s\"\n", buf
);
5618 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5622 r
= MsiGetPropertyA(hpkg
, "UILevel", buf
, &size
);
5623 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5624 ok( !lstrcmpA(buf
, "3"), "Expected \"3\", got \"%s\"\n", buf
);
5628 r
= MsiGetPropertyA(hpkg
, "DATABASE", buf
, &size
);
5629 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5630 ok( !lstrcmpA(buf
, path
), "Expected %s, got %s\n", path
, buf
);
5632 RegOpenKeyA(HKEY_CURRENT_USER
, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1
);
5633 RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access
, &hkey2
);
5634 RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5635 0, KEY_QUERY_VALUE
| KEY_WOW64_64KEY
, &pathkey
);
5640 if (RegQueryValueExA(hkey1
, "DefName", NULL
, &type
, (LPBYTE
)path
, &size
) != ERROR_SUCCESS
)
5644 RegQueryValueExA(hkey2
, "RegisteredOwner", NULL
, &type
, (LPBYTE
)path
, &size
);
5649 r
= MsiGetPropertyA(hpkg
, "USERNAME", buf
, &size
);
5650 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5651 ok( !lstrcmpA(buf
, path
), "Expected %s, got %s\n", path
, buf
);
5656 if (RegQueryValueExA(hkey1
, "DefCompany", NULL
, &type
, (LPBYTE
)path
, &size
) != ERROR_SUCCESS
)
5660 RegQueryValueExA(hkey2
, "RegisteredOrganization", NULL
, &type
, (LPBYTE
)path
, &size
);
5667 r
= MsiGetPropertyA(hpkg
, "COMPANYNAME", buf
, &size
);
5668 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5669 ok( !lstrcmpA(buf
, path
), "Expected %s, got %s\n", path
, buf
);
5674 r
= MsiGetPropertyA(hpkg
, "VersionDatabase", buf
, &size
);
5675 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5676 trace("VersionDatabase = %s\n", buf
);
5680 r
= MsiGetPropertyA(hpkg
, "VersionMsi", buf
, &size
);
5681 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5682 trace("VersionMsi = %s\n", buf
);
5686 r
= MsiGetPropertyA(hpkg
, "Date", buf
, &size
);
5687 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5688 trace("Date = %s\n", buf
);
5692 r
= MsiGetPropertyA(hpkg
, "Time", buf
, &size
);
5693 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5694 trace("Time = %s\n", buf
);
5698 r
= MsiGetPropertyA(hpkg
, "PackageCode", buf
, &size
);
5699 ok( r
== ERROR_SUCCESS
, "failed to get property: %d\n", r
);
5700 trace("PackageCode = %s\n", buf
);
5704 r
= MsiGetPropertyA(hpkg
, "ComputerName", buf
, &size
);
5705 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
5706 trace("ComputerName = %s\n", buf
);
5708 langid
= GetUserDefaultLangID();
5709 sprintf(path
, "%d", langid
);
5713 r
= MsiGetPropertyA(hpkg
, "UserLanguageID", buf
, &size
);
5714 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
5715 ok( !lstrcmpA(buf
, path
), "Expected \"%s\", got \"%s\"\n", path
, buf
);
5717 res
= GetSystemMetrics(SM_CXSCREEN
);
5720 r
= MsiGetPropertyA(hpkg
, "ScreenX", buf
, &size
);
5721 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
5722 ok(atol(buf
) == res
, "Expected %d, got %s\n", res
, buf
);
5724 res
= GetSystemMetrics(SM_CYSCREEN
);
5727 r
= MsiGetPropertyA(hpkg
, "ScreenY", buf
, &size
);
5728 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
5729 ok(atol(buf
) == res
, "Expected %d, got %s\n", res
, buf
);
5733 r
= MsiGetPropertyA(hpkg
, "MsiNetAssemblySupport", buf
, &size
);
5734 if (r
== ERROR_SUCCESS
) trace( "MsiNetAssemblySupport \"%s\"\n", buf
);
5736 GetNativeSystemInfo(&si
);
5738 sprintf(buf
, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5739 check_prop(hpkg
, "VersionNT", buf
, 1);
5741 if (S(U(si
)).wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
)
5743 sprintf(buf
, "%d", si
.wProcessorLevel
);
5744 check_prop(hpkg
, "Intel", buf
, 1);
5745 check_prop(hpkg
, "MsiAMD64", buf
, 1);
5746 check_prop(hpkg
, "Msix64", buf
, 1);
5747 sprintf(buf
, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5748 check_prop(hpkg
, "VersionNT64", buf
, 1);
5750 GetSystemDirectoryA(path
, MAX_PATH
);
5752 check_prop(hpkg
, "System64Folder", path
, 0);
5754 GetSystemWow64DirectoryA(path
, MAX_PATH
);
5756 check_prop(hpkg
, "SystemFolder", path
, 0);
5759 r
= RegQueryValueExA(pathkey
, "ProgramFilesDir (x86)", 0, &type
, (BYTE
*)path
, &size
);
5761 check_prop(hpkg
, "ProgramFilesFolder", path
, 0);
5764 RegQueryValueExA(pathkey
, "ProgramFilesDir", 0, &type
, (BYTE
*)path
, &size
);
5766 check_prop(hpkg
, "ProgramFiles64Folder", path
, 0);
5769 RegQueryValueExA(pathkey
, "CommonFilesDir (x86)", 0, &type
, (BYTE
*)path
, &size
);
5771 check_prop(hpkg
, "CommonFilesFolder", path
, 0);
5774 RegQueryValueExA(pathkey
, "CommonFilesDir", 0, &type
, (BYTE
*)path
, &size
);
5776 check_prop(hpkg
, "CommonFiles64Folder", path
, 0);
5778 else if (S(U(si
)).wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_INTEL
)
5780 sprintf(buf
, "%d", si
.wProcessorLevel
);
5781 check_prop(hpkg
, "Intel", buf
, 1);
5783 GetSystemDirectoryA(path
, MAX_PATH
);
5785 check_prop(hpkg
, "SystemFolder", path
, 0);
5788 RegQueryValueExA(pathkey
, "ProgramFilesDir", 0, &type
, (BYTE
*)path
, &size
);
5790 check_prop(hpkg
, "ProgramFilesFolder", path
, 0);
5793 RegQueryValueExA(pathkey
, "CommonFilesDir", 0, &type
, (BYTE
*)path
, &size
);
5795 check_prop(hpkg
, "CommonFilesFolder", path
, 0);
5797 check_prop(hpkg
, "MsiAMD64", "", 1);
5798 check_prop(hpkg
, "Msix64", "", 1);
5799 check_prop(hpkg
, "VersionNT64", "", 1);
5800 check_prop(hpkg
, "System64Folder", "", 0);
5801 check_prop(hpkg
, "ProgramFiles64Dir", "", 0);
5802 check_prop(hpkg
, "CommonFiles64Dir", "", 0);
5807 RegCloseKey(pathkey
);
5808 MsiCloseHandle(hpkg
);
5809 DeleteFileA(msifile
);
5810 MsiSetInternalUI(uilevel
, NULL
);
5813 static void test_launchconditions(void)
5819 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5821 hdb
= create_package_db();
5822 ok( hdb
, "failed to create package database\n" );
5824 create_launchcondition_table( hdb
);
5826 add_launchcondition_entry( hdb
, "'X = \"1\"', 'one'" );
5828 /* invalid condition */
5829 add_launchcondition_entry( hdb
, "'X != \"1\"', 'one'" );
5831 r
= package_from_db( hdb
, &hpkg
);
5832 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5834 skip("Not enough rights to perform tests\n");
5835 DeleteFileA(msifile
);
5838 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
5840 MsiCloseHandle( hdb
);
5842 r
= MsiSetPropertyA( hpkg
, "X", "1" );
5843 ok( r
== ERROR_SUCCESS
, "failed to set property\n" );
5845 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5847 /* invalid conditions are ignored */
5848 r
= MsiDoActionA( hpkg
, "LaunchConditions" );
5849 ok( r
== ERROR_SUCCESS
, "cost init failed\n" );
5851 /* verify LaunchConditions still does some verification */
5852 r
= MsiSetPropertyA( hpkg
, "X", "2" );
5853 ok( r
== ERROR_SUCCESS
, "failed to set property\n" );
5855 r
= MsiDoActionA( hpkg
, "LaunchConditions" );
5856 ok( r
== ERROR_INSTALL_FAILURE
, "Expected ERROR_INSTALL_FAILURE, got %d\n", r
);
5858 MsiCloseHandle( hpkg
);
5859 DeleteFileA( msifile
);
5862 static void test_ccpsearch(void)
5864 MSIHANDLE hdb
, hpkg
;
5865 CHAR prop
[MAX_PATH
];
5866 DWORD size
= MAX_PATH
;
5869 hdb
= create_package_db();
5870 ok(hdb
, "failed to create package database\n");
5872 create_ccpsearch_table(hdb
);
5873 add_ccpsearch_entry(hdb
, "'CCP_random'");
5874 add_ccpsearch_entry(hdb
, "'RMCCP_random'");
5876 create_reglocator_table(hdb
);
5877 add_reglocator_entry(hdb
, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5879 create_drlocator_table(hdb
);
5880 add_drlocator_entry(hdb
, "'RMCCP_random', '', 'C:\\', '0'");
5882 create_signature_table(hdb
);
5884 r
= package_from_db(hdb
, &hpkg
);
5885 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5887 skip("Not enough rights to perform tests\n");
5888 DeleteFileA(msifile
);
5891 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
5893 MsiCloseHandle(hdb
);
5895 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
5897 r
= MsiDoActionA(hpkg
, "CCPSearch");
5898 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5900 r
= MsiGetPropertyA(hpkg
, "CCP_Success", prop
, &size
);
5901 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
5902 ok(!lstrcmpA(prop
, "1"), "Expected 1, got %s\n", prop
);
5904 MsiCloseHandle(hpkg
);
5905 DeleteFileA(msifile
);
5908 static void test_complocator(void)
5910 MSIHANDLE hdb
, hpkg
;
5912 CHAR prop
[MAX_PATH
];
5913 CHAR expected
[MAX_PATH
];
5914 DWORD size
= MAX_PATH
;
5916 hdb
= create_package_db();
5917 ok(hdb
, "failed to create package database\n");
5919 create_appsearch_table(hdb
);
5920 add_appsearch_entry(hdb
, "'ABELISAURUS', 'abelisaurus'");
5921 add_appsearch_entry(hdb
, "'BACTROSAURUS', 'bactrosaurus'");
5922 add_appsearch_entry(hdb
, "'CAMELOTIA', 'camelotia'");
5923 add_appsearch_entry(hdb
, "'DICLONIUS', 'diclonius'");
5924 add_appsearch_entry(hdb
, "'ECHINODON', 'echinodon'");
5925 add_appsearch_entry(hdb
, "'FALCARIUS', 'falcarius'");
5926 add_appsearch_entry(hdb
, "'GALLIMIMUS', 'gallimimus'");
5927 add_appsearch_entry(hdb
, "'HAGRYPHUS', 'hagryphus'");
5928 add_appsearch_entry(hdb
, "'IGUANODON', 'iguanodon'");
5929 add_appsearch_entry(hdb
, "'JOBARIA', 'jobaria'");
5930 add_appsearch_entry(hdb
, "'KAKURU', 'kakuru'");
5931 add_appsearch_entry(hdb
, "'LABOCANIA', 'labocania'");
5932 add_appsearch_entry(hdb
, "'MEGARAPTOR', 'megaraptor'");
5933 add_appsearch_entry(hdb
, "'NEOSODON', 'neosodon'");
5934 add_appsearch_entry(hdb
, "'OLOROTITAN', 'olorotitan'");
5935 add_appsearch_entry(hdb
, "'PANTYDRACO', 'pantydraco'");
5937 create_complocator_table(hdb
);
5938 add_complocator_entry(hdb
, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5939 add_complocator_entry(hdb
, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5940 add_complocator_entry(hdb
, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5941 add_complocator_entry(hdb
, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5942 add_complocator_entry(hdb
, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5943 add_complocator_entry(hdb
, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5944 add_complocator_entry(hdb
, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5945 add_complocator_entry(hdb
, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5946 add_complocator_entry(hdb
, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5947 add_complocator_entry(hdb
, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5948 add_complocator_entry(hdb
, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5949 add_complocator_entry(hdb
, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5950 add_complocator_entry(hdb
, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5951 add_complocator_entry(hdb
, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5952 add_complocator_entry(hdb
, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5953 add_complocator_entry(hdb
, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5955 create_signature_table(hdb
);
5956 add_signature_entry(hdb
, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5957 add_signature_entry(hdb
, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5958 add_signature_entry(hdb
, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5959 add_signature_entry(hdb
, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5960 add_signature_entry(hdb
, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5961 add_signature_entry(hdb
, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5962 add_signature_entry(hdb
, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5963 add_signature_entry(hdb
, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5965 r
= package_from_db(hdb
, &hpkg
);
5966 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
5968 skip("Not enough rights to perform tests\n");
5969 DeleteFileA(msifile
);
5972 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
5974 MsiCloseHandle(hdb
);
5976 create_test_file("abelisaurus");
5977 create_test_file("bactrosaurus");
5978 create_test_file("camelotia");
5979 create_test_file("diclonius");
5980 create_test_file("echinodon");
5981 create_test_file("falcarius");
5982 create_test_file("gallimimus");
5983 create_test_file("hagryphus");
5984 CreateDirectoryA("iguanodon", NULL
);
5985 CreateDirectoryA("jobaria", NULL
);
5986 CreateDirectoryA("kakuru", NULL
);
5987 CreateDirectoryA("labocania", NULL
);
5988 CreateDirectoryA("megaraptor", NULL
);
5989 CreateDirectoryA("neosodon", NULL
);
5990 CreateDirectoryA("olorotitan", NULL
);
5991 CreateDirectoryA("pantydraco", NULL
);
5993 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE
,
5994 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL
, FALSE
);
5995 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE
,
5996 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL
, FALSE
);
5997 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE
,
5998 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL
, FALSE
);
5999 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE
,
6000 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL
, FALSE
);
6001 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE
,
6002 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL
, FALSE
);
6003 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE
,
6004 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL
, FALSE
);
6005 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE
,
6006 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL
, FALSE
);
6007 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE
,
6008 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL
, FALSE
);
6010 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
6012 r
= MsiDoActionA(hpkg
, "AppSearch");
6013 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6016 r
= MsiGetPropertyA(hpkg
, "ABELISAURUS", prop
, &size
);
6017 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6019 lstrcpyA(expected
, CURR_DIR
);
6020 if (!is_root(CURR_DIR
)) lstrcatA(expected
, "\\");
6021 lstrcatA(expected
, "abelisaurus");
6022 ok(!lstrcmpA(prop
, expected
) || !lstrcmpA(prop
, ""),
6023 "Expected %s or empty string, got %s\n", expected
, prop
);
6026 r
= MsiGetPropertyA(hpkg
, "BACTROSAURUS", prop
, &size
);
6027 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6028 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6031 r
= MsiGetPropertyA(hpkg
, "CAMELOTIA", prop
, &size
);
6032 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6033 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6036 r
= MsiGetPropertyA(hpkg
, "DICLONIUS", prop
, &size
);
6037 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6038 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6041 r
= MsiGetPropertyA(hpkg
, "ECHINODON", prop
, &size
);
6042 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6044 lstrcpyA(expected
, CURR_DIR
);
6045 if (!is_root(CURR_DIR
)) lstrcatA(expected
, "\\");
6046 ok(!lstrcmpA(prop
, expected
) || !lstrcmpA(prop
, ""),
6047 "Expected %s or empty string, got %s\n", expected
, prop
);
6050 r
= MsiGetPropertyA(hpkg
, "FALCARIUS", prop
, &size
);
6051 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6052 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6055 r
= MsiGetPropertyA(hpkg
, "GALLIMIMUS", prop
, &size
);
6056 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6057 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6060 r
= MsiGetPropertyA(hpkg
, "HAGRYPHUS", prop
, &size
);
6061 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6062 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6065 r
= MsiGetPropertyA(hpkg
, "IGUANODON", prop
, &size
);
6066 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6067 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6070 r
= MsiGetPropertyA(hpkg
, "JOBARIA", prop
, &size
);
6071 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6072 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6075 r
= MsiGetPropertyA(hpkg
, "KAKURU", prop
, &size
);
6076 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6077 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6080 r
= MsiGetPropertyA(hpkg
, "LABOCANIA", prop
, &size
);
6081 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6082 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6085 r
= MsiGetPropertyA(hpkg
, "MEGARAPTOR", prop
, &size
);
6086 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6088 lstrcpyA(expected
, CURR_DIR
);
6089 if (!is_root(CURR_DIR
)) lstrcatA(expected
, "\\");
6090 ok(!lstrcmpA(prop
, expected
) || !lstrcmpA(prop
, ""),
6091 "Expected %s or empty string, got %s\n", expected
, prop
);
6094 r
= MsiGetPropertyA(hpkg
, "NEOSODON", prop
, &size
);
6095 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6097 lstrcpyA(expected
, CURR_DIR
);
6098 if (!is_root(CURR_DIR
)) lstrcatA(expected
, "\\");
6099 lstrcatA(expected
, "neosodon\\");
6100 ok(!lstrcmpA(prop
, expected
) || !lstrcmpA(prop
, ""),
6101 "Expected %s or empty string, got %s\n", expected
, prop
);
6104 r
= MsiGetPropertyA(hpkg
, "OLOROTITAN", prop
, &size
);
6105 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6106 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6109 r
= MsiGetPropertyA(hpkg
, "PANTYDRACO", prop
, &size
);
6110 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6111 ok(!lstrcmpA(prop
, ""), "Expected , got %s\n", prop
);
6113 MsiCloseHandle(hpkg
);
6114 DeleteFileA("abelisaurus");
6115 DeleteFileA("bactrosaurus");
6116 DeleteFileA("camelotia");
6117 DeleteFileA("diclonius");
6118 DeleteFileA("echinodon");
6119 DeleteFileA("falcarius");
6120 DeleteFileA("gallimimus");
6121 DeleteFileA("hagryphus");
6122 RemoveDirectoryA("iguanodon");
6123 RemoveDirectoryA("jobaria");
6124 RemoveDirectoryA("kakuru");
6125 RemoveDirectoryA("labocania");
6126 RemoveDirectoryA("megaraptor");
6127 RemoveDirectoryA("neosodon");
6128 RemoveDirectoryA("olorotitan");
6129 RemoveDirectoryA("pantydraco");
6130 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6131 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6132 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6133 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6134 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6135 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6136 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6137 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6138 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6139 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6140 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6141 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6142 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6143 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6144 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6145 MSIINSTALLCONTEXT_MACHINE
, NULL
);
6146 DeleteFileA(msifile
);
6149 static void set_suminfo_prop(MSIHANDLE db
, DWORD prop
, DWORD val
)
6154 r
= MsiGetSummaryInformationA(db
, NULL
, 1, &summary
);
6155 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6157 r
= MsiSummaryInfoSetPropertyA(summary
, prop
, VT_I4
, val
, NULL
, NULL
);
6158 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6160 r
= MsiSummaryInfoPersist(summary
);
6161 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
6163 MsiCloseHandle(summary
);
6166 static void test_MsiGetSourcePath(void)
6168 MSIHANDLE hdb
, hpkg
;
6169 CHAR path
[MAX_PATH
];
6171 CHAR subsrc
[MAX_PATH
];
6172 CHAR sub2
[MAX_PATH
];
6176 lstrcpyA(cwd
, CURR_DIR
);
6177 if (!is_root(CURR_DIR
)) lstrcatA(cwd
, "\\");
6179 lstrcpyA(subsrc
, cwd
);
6180 lstrcatA(subsrc
, "subsource");
6181 lstrcatA(subsrc
, "\\");
6183 lstrcpyA(sub2
, subsrc
);
6184 lstrcatA(sub2
, "sub2");
6185 lstrcatA(sub2
, "\\");
6187 /* uncompressed source */
6189 hdb
= create_package_db();
6190 ok( hdb
, "failed to create database\n");
6192 set_suminfo_prop(hdb
, PID_WORDCOUNT
, 0);
6194 add_directory_entry(hdb
, "'TARGETDIR', '', 'SourceDir'");
6195 add_directory_entry(hdb
, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6196 add_directory_entry(hdb
, "'SubDir2', 'SubDir', 'sub2'");
6198 r
= MsiDatabaseCommit(hdb
);
6199 ok(r
== ERROR_SUCCESS
, "Failed to commit database\n");
6201 r
= package_from_db(hdb
, &hpkg
);
6202 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
6204 skip("Not enough rights to perform tests\n");
6205 DeleteFileA(msifile
);
6208 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
6210 MsiCloseHandle(hdb
);
6212 /* invalid database handle */
6214 lstrcpyA(path
, "kiwi");
6215 r
= MsiGetSourcePathA(-1, "TARGETDIR", path
, &size
);
6216 ok(r
== ERROR_INVALID_HANDLE
,
6217 "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
6218 ok(!lstrcmpA(path
, "kiwi"),
6219 "Expected path to be unchanged, got \"%s\"\n", path
);
6220 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6224 lstrcpyA(path
, "kiwi");
6225 r
= MsiGetSourcePathA(hpkg
, NULL
, path
, &size
);
6226 ok(r
== ERROR_INVALID_PARAMETER
,
6227 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
6228 ok(!lstrcmpA(path
, "kiwi"),
6229 "Expected path to be unchanged, got \"%s\"\n", path
);
6230 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6232 /* empty szFolder */
6234 lstrcpyA(path
, "kiwi");
6235 r
= MsiGetSourcePathA(hpkg
, "", path
, &size
);
6236 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6237 ok(!lstrcmpA(path
, "kiwi"),
6238 "Expected path to be unchanged, got \"%s\"\n", path
);
6239 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6243 lstrcpyA(path
, "kiwi");
6244 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6245 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6246 ok(!lstrcmpA(path
, "kiwi"),
6247 "Expected path to be unchanged, got \"%s\"\n", path
);
6248 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6251 lstrcpyA(path
, "kiwi");
6252 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6253 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6254 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6255 ok(size
== 0, "Expected 0, got %d\n", size
);
6258 lstrcpyA(path
, "kiwi");
6259 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6260 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6261 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6262 ok(size
== 0, "Expected 0, got %d\n", size
);
6266 lstrcpyA(path
, "kiwi");
6267 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6268 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6269 ok(!lstrcmpA(path
, "kiwi"),
6270 "Expected path to be unchanged, got \"%s\"\n", path
);
6271 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6275 lstrcpyA(path
, "kiwi");
6276 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6277 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6278 ok(!lstrcmpA(path
, "kiwi"),
6279 "Expected path to be unchanged, got \"%s\"\n", path
);
6280 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6282 /* source path does not exist, but the property exists */
6284 lstrcpyA(path
, "kiwi");
6285 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6286 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6287 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6288 ok(size
== 0, "Expected 0, got %d\n", size
);
6291 lstrcpyA(path
, "kiwi");
6292 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6293 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6294 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6295 ok(size
== 0, "Expected 0, got %d\n", size
);
6299 lstrcpyA(path
, "kiwi");
6300 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6301 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6302 ok(!lstrcmpA(path
, "kiwi"),
6303 "Expected path to be unchanged, got \"%s\"\n", path
);
6304 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6308 lstrcpyA(path
, "kiwi");
6309 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6310 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6311 ok(!lstrcmpA(path
, "kiwi"),
6312 "Expected path to be unchanged, got \"%s\"\n", path
);
6313 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6315 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
6317 r
= MsiDoActionA(hpkg
, "CostInitialize");
6318 ok(r
== ERROR_SUCCESS
, "cost init failed\n");
6320 /* try TARGETDIR after CostInitialize */
6322 lstrcpyA(path
, "kiwi");
6323 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6324 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6325 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6326 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6328 /* try SourceDir after CostInitialize */
6330 lstrcpyA(path
, "kiwi");
6331 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6332 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6333 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6334 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6336 /* try SOURCEDIR after CostInitialize */
6338 lstrcpyA(path
, "kiwi");
6339 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6340 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6341 ok(!lstrcmpA(path
, "kiwi"),
6342 "Expected path to be unchanged, got \"%s\"\n", path
);
6343 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6345 /* source path does not exist, but the property exists */
6347 lstrcpyA(path
, "kiwi");
6348 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6349 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6350 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6351 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6354 lstrcpyA(path
, "kiwi");
6355 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6356 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6357 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6358 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6360 /* try SubDir after CostInitialize */
6362 lstrcpyA(path
, "kiwi");
6363 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6364 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6365 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
6366 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
6368 /* try SubDir2 after CostInitialize */
6370 lstrcpyA(path
, "kiwi");
6371 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6372 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6373 ok(!lstrcmpA(path
, sub2
), "Expected \"%s\", got \"%s\"\n", sub2
, path
);
6374 ok(size
== lstrlenA(sub2
), "Expected %d, got %d\n", lstrlenA(sub2
), size
);
6376 r
= MsiDoActionA(hpkg
, "ResolveSource");
6377 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
6379 /* try TARGETDIR after ResolveSource */
6381 lstrcpyA(path
, "kiwi");
6382 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6383 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6384 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6385 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6387 /* try SourceDir after ResolveSource */
6389 lstrcpyA(path
, "kiwi");
6390 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6391 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6392 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6393 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6395 /* try SOURCEDIR after ResolveSource */
6397 lstrcpyA(path
, "kiwi");
6398 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6399 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6400 ok(!lstrcmpA(path
, "kiwi"),
6401 "Expected path to be unchanged, got \"%s\"\n", path
);
6402 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6404 /* source path does not exist, but the property exists */
6406 lstrcpyA(path
, "kiwi");
6407 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6408 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6409 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6410 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6413 lstrcpyA(path
, "kiwi");
6414 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6415 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6416 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6417 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6419 /* try SubDir after ResolveSource */
6421 lstrcpyA(path
, "kiwi");
6422 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6423 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6424 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
6425 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
6427 /* try SubDir2 after ResolveSource */
6429 lstrcpyA(path
, "kiwi");
6430 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6431 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6432 ok(!lstrcmpA(path
, sub2
), "Expected \"%s\", got \"%s\"\n", sub2
, path
);
6433 ok(size
== lstrlenA(sub2
), "Expected %d, got %d\n", lstrlenA(sub2
), size
);
6435 r
= MsiDoActionA(hpkg
, "FileCost");
6436 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
6438 /* try TARGETDIR after FileCost */
6440 lstrcpyA(path
, "kiwi");
6441 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6442 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6443 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6444 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6446 /* try SourceDir after FileCost */
6448 lstrcpyA(path
, "kiwi");
6449 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6450 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6451 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6452 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6454 /* try SOURCEDIR after FileCost */
6456 lstrcpyA(path
, "kiwi");
6457 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6458 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6459 ok(!lstrcmpA(path
, "kiwi"),
6460 "Expected path to be unchanged, got \"%s\"\n", path
);
6461 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6463 /* source path does not exist, but the property exists */
6465 lstrcpyA(path
, "kiwi");
6466 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6467 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6468 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6469 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6472 lstrcpyA(path
, "kiwi");
6473 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6474 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6475 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6476 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6478 /* try SubDir after FileCost */
6480 lstrcpyA(path
, "kiwi");
6481 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6482 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6483 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
6484 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
6486 /* try SubDir2 after FileCost */
6488 lstrcpyA(path
, "kiwi");
6489 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6490 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6491 ok(!lstrcmpA(path
, sub2
), "Expected \"%s\", got \"%s\"\n", sub2
, path
);
6492 ok(size
== lstrlenA(sub2
), "Expected %d, got %d\n", lstrlenA(sub2
), size
);
6494 r
= MsiDoActionA(hpkg
, "CostFinalize");
6495 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
6497 /* try TARGETDIR after CostFinalize */
6499 lstrcpyA(path
, "kiwi");
6500 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6501 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6502 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6503 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6505 /* try SourceDir after CostFinalize */
6507 lstrcpyA(path
, "kiwi");
6508 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6509 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6510 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6511 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6513 /* try SOURCEDIR after CostFinalize */
6515 lstrcpyA(path
, "kiwi");
6516 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6517 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6518 ok(!lstrcmpA(path
, "kiwi"),
6519 "Expected path to be unchanged, got \"%s\"\n", path
);
6520 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6522 /* source path does not exist, but the property exists */
6524 lstrcpyA(path
, "kiwi");
6525 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6526 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6527 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6528 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6531 lstrcpyA(path
, "kiwi");
6532 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6533 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6534 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6535 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6537 /* try SubDir after CostFinalize */
6539 lstrcpyA(path
, "kiwi");
6540 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6541 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6542 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
6543 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
6545 /* try SubDir2 after CostFinalize */
6547 lstrcpyA(path
, "kiwi");
6548 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6549 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6550 ok(!lstrcmpA(path
, sub2
), "Expected \"%s\", got \"%s\"\n", sub2
, path
);
6551 ok(size
== lstrlenA(sub2
), "Expected %d, got %d\n", lstrlenA(sub2
), size
);
6553 /* nonexistent directory */
6555 lstrcpyA(path
, "kiwi");
6556 r
= MsiGetSourcePathA(hpkg
, "IDontExist", path
, &size
);
6557 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6558 ok(!lstrcmpA(path
, "kiwi"),
6559 "Expected path to be unchanged, got \"%s\"\n", path
);
6560 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6562 /* NULL szPathBuf */
6564 r
= MsiGetSourcePathA(hpkg
, "SourceDir", NULL
, &size
);
6565 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6566 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6568 /* NULL pcchPathBuf */
6569 lstrcpyA(path
, "kiwi");
6570 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, NULL
);
6571 ok(r
== ERROR_INVALID_PARAMETER
,
6572 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
6573 ok(!lstrcmpA(path
, "kiwi"),
6574 "Expected path to be unchanged, got \"%s\"\n", path
);
6576 /* pcchPathBuf is 0 */
6578 lstrcpyA(path
, "kiwi");
6579 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6580 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
6581 ok(!lstrcmpA(path
, "kiwi"),
6582 "Expected path to be unchanged, got \"%s\"\n", path
);
6583 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6585 /* pcchPathBuf does not have room for NULL terminator */
6586 size
= lstrlenA(cwd
);
6587 lstrcpyA(path
, "kiwi");
6588 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6589 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
6590 ok(!strncmp(path
, cwd
, lstrlenA(cwd
) - 1),
6591 "Expected path with no backslash, got \"%s\"\n", path
);
6592 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6594 /* pcchPathBuf has room for NULL terminator */
6595 size
= lstrlenA(cwd
) + 1;
6596 lstrcpyA(path
, "kiwi");
6597 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6598 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6599 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6600 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6602 /* remove property */
6603 r
= MsiSetPropertyA(hpkg
, "SourceDir", NULL
);
6604 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6606 /* try SourceDir again */
6608 lstrcpyA(path
, "kiwi");
6609 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6610 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6611 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6612 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6614 /* set property to a valid directory */
6615 r
= MsiSetPropertyA(hpkg
, "SOURCEDIR", cwd
);
6616 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6618 /* try SOURCEDIR again */
6620 lstrcpyA(path
, "kiwi");
6621 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6622 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6623 ok(!lstrcmpA(path
, "kiwi"),
6624 "Expected path to be unchanged, got \"%s\"\n", path
);
6625 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6627 MsiCloseHandle(hpkg
);
6629 /* compressed source */
6631 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_DIRECT
, &hdb
);
6632 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6634 set_suminfo_prop(hdb
, PID_WORDCOUNT
, msidbSumInfoSourceTypeCompressed
);
6636 r
= package_from_db(hdb
, &hpkg
);
6637 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
6641 lstrcpyA(path
, "kiwi");
6642 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6643 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6644 ok(!lstrcmpA(path
, "kiwi"),
6645 "Expected path to be unchanged, got \"%s\"\n", path
);
6646 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6650 lstrcpyA(path
, "kiwi");
6651 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6652 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6653 ok(!lstrcmpA(path
, "kiwi"),
6654 "Expected path to be unchanged, got \"%s\"\n", path
);
6655 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6659 lstrcpyA(path
, "kiwi");
6660 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6661 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6662 ok(!lstrcmpA(path
, "kiwi"),
6663 "Expected path to be unchanged, got \"%s\"\n", path
);
6664 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6666 /* source path nor the property exist */
6668 lstrcpyA(path
, "kiwi");
6669 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6670 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6671 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6672 ok(size
== 0, "Expected 0, got %d\n", size
);
6675 lstrcpyA(path
, "kiwi");
6676 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6677 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6678 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
6679 ok(size
== 0, "Expected 0, got %d\n", size
);
6683 lstrcpyA(path
, "kiwi");
6684 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6685 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6686 ok(!lstrcmpA(path
, "kiwi"),
6687 "Expected path to be unchanged, got \"%s\"\n", path
);
6688 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6692 lstrcpyA(path
, "kiwi");
6693 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6694 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
6695 ok(!lstrcmpA(path
, "kiwi"),
6696 "Expected path to be unchanged, got \"%s\"\n", path
);
6697 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
6699 r
= MsiDoActionA(hpkg
, "CostInitialize");
6700 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6702 /* try TARGETDIR after CostInitialize */
6704 lstrcpyA(path
, "kiwi");
6705 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6706 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6707 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6708 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6710 /* try SourceDir after CostInitialize */
6712 lstrcpyA(path
, "kiwi");
6713 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6714 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6715 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6716 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6718 /* try SOURCEDIR after CostInitialize */
6720 lstrcpyA(path
, "kiwi");
6721 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6724 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6725 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6726 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6729 /* source path does not exist, but the property exists */
6731 lstrcpyA(path
, "kiwi");
6732 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6733 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6734 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6735 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6738 lstrcpyA(path
, "kiwi");
6739 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6740 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6741 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6742 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6744 /* try SubDir after CostInitialize */
6746 lstrcpyA(path
, "kiwi");
6747 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6748 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6749 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6750 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6752 /* try SubDir2 after CostInitialize */
6754 lstrcpyA(path
, "kiwi");
6755 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6756 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6757 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6758 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6760 r
= MsiDoActionA(hpkg
, "ResolveSource");
6761 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
6763 /* try TARGETDIR after ResolveSource */
6765 lstrcpyA(path
, "kiwi");
6766 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6767 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6768 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6769 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6771 /* try SourceDir after ResolveSource */
6773 lstrcpyA(path
, "kiwi");
6774 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6775 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6776 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6777 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6779 /* try SOURCEDIR after ResolveSource */
6781 lstrcpyA(path
, "kiwi");
6782 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6785 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6786 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6787 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6790 /* source path and the property exist */
6792 lstrcpyA(path
, "kiwi");
6793 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6794 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6795 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6796 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6799 lstrcpyA(path
, "kiwi");
6800 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6801 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6802 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6803 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6805 /* try SubDir after ResolveSource */
6807 lstrcpyA(path
, "kiwi");
6808 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6809 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6810 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6811 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6813 /* try SubDir2 after ResolveSource */
6815 lstrcpyA(path
, "kiwi");
6816 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6817 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6818 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6819 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6821 r
= MsiDoActionA(hpkg
, "FileCost");
6822 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6824 /* try TARGETDIR after CostFinalize */
6826 lstrcpyA(path
, "kiwi");
6827 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6828 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6829 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6830 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6832 /* try SourceDir after CostFinalize */
6834 lstrcpyA(path
, "kiwi");
6835 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6836 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6837 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6838 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6840 /* try SOURCEDIR after CostFinalize */
6842 lstrcpyA(path
, "kiwi");
6843 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6846 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6847 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6848 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6851 /* source path and the property exist */
6853 lstrcpyA(path
, "kiwi");
6854 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6855 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6856 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6857 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6860 lstrcpyA(path
, "kiwi");
6861 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6862 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6863 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6864 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6866 /* try SubDir after CostFinalize */
6868 lstrcpyA(path
, "kiwi");
6869 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6870 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6871 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6872 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6874 /* try SubDir2 after CostFinalize */
6876 lstrcpyA(path
, "kiwi");
6877 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6878 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6879 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6880 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6882 r
= MsiDoActionA(hpkg
, "CostFinalize");
6883 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6885 /* try TARGETDIR after CostFinalize */
6887 lstrcpyA(path
, "kiwi");
6888 r
= MsiGetSourcePathA(hpkg
, "TARGETDIR", path
, &size
);
6889 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6890 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6891 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6893 /* try SourceDir after CostFinalize */
6895 lstrcpyA(path
, "kiwi");
6896 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
6897 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6898 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6899 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6901 /* try SOURCEDIR after CostFinalize */
6903 lstrcpyA(path
, "kiwi");
6904 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
6907 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6908 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6909 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6912 /* source path and the property exist */
6914 lstrcpyA(path
, "kiwi");
6915 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
6916 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6917 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6918 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6921 lstrcpyA(path
, "kiwi");
6922 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
6923 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6924 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6925 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6927 /* try SubDir after CostFinalize */
6929 lstrcpyA(path
, "kiwi");
6930 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
6931 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6932 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6933 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6935 /* try SubDir2 after CostFinalize */
6937 lstrcpyA(path
, "kiwi");
6938 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
6939 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
6940 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
6941 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
6943 MsiCloseHandle(hpkg
);
6944 DeleteFileA(msifile
);
6947 static void test_shortlongsource(void)
6949 MSIHANDLE hdb
, hpkg
;
6950 CHAR path
[MAX_PATH
];
6952 CHAR subsrc
[MAX_PATH
];
6956 lstrcpyA(cwd
, CURR_DIR
);
6957 if (!is_root(CURR_DIR
)) lstrcatA(cwd
, "\\");
6959 lstrcpyA(subsrc
, cwd
);
6960 lstrcatA(subsrc
, "long");
6961 lstrcatA(subsrc
, "\\");
6963 /* long file names */
6965 hdb
= create_package_db();
6966 ok( hdb
, "failed to create database\n");
6968 set_suminfo_prop(hdb
, PID_WORDCOUNT
, 0);
6970 add_directory_entry(hdb
, "'TARGETDIR', '', 'SourceDir'");
6971 add_directory_entry(hdb
, "'SubDir', 'TARGETDIR', 'short|long'");
6973 /* CostInitialize:short */
6974 add_directory_entry(hdb
, "'SubDir2', 'TARGETDIR', 'one|two'");
6976 /* CostInitialize:long */
6977 add_directory_entry(hdb
, "'SubDir3', 'TARGETDIR', 'three|four'");
6979 /* FileCost:short */
6980 add_directory_entry(hdb
, "'SubDir4', 'TARGETDIR', 'five|six'");
6983 add_directory_entry(hdb
, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6985 /* CostFinalize:short */
6986 add_directory_entry(hdb
, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6988 /* CostFinalize:long */
6989 add_directory_entry(hdb
, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6991 r
= MsiDatabaseCommit(hdb
);
6992 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
6994 r
= package_from_db(hdb
, &hpkg
);
6995 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
6997 skip("Not enough rights to perform tests\n");
6998 DeleteFileA(msifile
);
7001 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
7003 MsiCloseHandle(hdb
);
7005 CreateDirectoryA("one", NULL
);
7006 CreateDirectoryA("four", NULL
);
7008 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
7010 r
= MsiDoActionA(hpkg
, "CostInitialize");
7011 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7013 CreateDirectoryA("five", NULL
);
7014 CreateDirectoryA("eight", NULL
);
7016 r
= MsiDoActionA(hpkg
, "FileCost");
7017 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7019 CreateDirectoryA("nine", NULL
);
7020 CreateDirectoryA("twelve", NULL
);
7022 r
= MsiDoActionA(hpkg
, "CostFinalize");
7023 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7025 /* neither short nor long source directories exist */
7027 lstrcpyA(path
, "kiwi");
7028 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7029 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7030 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7031 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7033 CreateDirectoryA("short", NULL
);
7035 /* short source directory exists */
7037 lstrcpyA(path
, "kiwi");
7038 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7039 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7040 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7041 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7043 CreateDirectoryA("long", NULL
);
7045 /* both short and long source directories exist */
7047 lstrcpyA(path
, "kiwi");
7048 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7049 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7050 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7051 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7053 lstrcpyA(subsrc
, cwd
);
7054 lstrcatA(subsrc
, "two");
7055 lstrcatA(subsrc
, "\\");
7057 /* short dir exists before CostInitialize */
7059 lstrcpyA(path
, "kiwi");
7060 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
7061 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7062 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7063 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7065 lstrcpyA(subsrc
, cwd
);
7066 lstrcatA(subsrc
, "four");
7067 lstrcatA(subsrc
, "\\");
7069 /* long dir exists before CostInitialize */
7071 lstrcpyA(path
, "kiwi");
7072 r
= MsiGetSourcePathA(hpkg
, "SubDir3", path
, &size
);
7073 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7074 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7075 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7077 lstrcpyA(subsrc
, cwd
);
7078 lstrcatA(subsrc
, "six");
7079 lstrcatA(subsrc
, "\\");
7081 /* short dir exists before FileCost */
7083 lstrcpyA(path
, "kiwi");
7084 r
= MsiGetSourcePathA(hpkg
, "SubDir4", path
, &size
);
7085 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7086 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7087 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7089 lstrcpyA(subsrc
, cwd
);
7090 lstrcatA(subsrc
, "eight");
7091 lstrcatA(subsrc
, "\\");
7093 /* long dir exists before FileCost */
7095 lstrcpyA(path
, "kiwi");
7096 r
= MsiGetSourcePathA(hpkg
, "SubDir5", path
, &size
);
7097 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7098 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7099 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7101 lstrcpyA(subsrc
, cwd
);
7102 lstrcatA(subsrc
, "ten");
7103 lstrcatA(subsrc
, "\\");
7105 /* short dir exists before CostFinalize */
7107 lstrcpyA(path
, "kiwi");
7108 r
= MsiGetSourcePathA(hpkg
, "SubDir6", path
, &size
);
7109 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7110 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7111 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7113 lstrcpyA(subsrc
, cwd
);
7114 lstrcatA(subsrc
, "twelve");
7115 lstrcatA(subsrc
, "\\");
7117 /* long dir exists before CostFinalize */
7119 lstrcpyA(path
, "kiwi");
7120 r
= MsiGetSourcePathA(hpkg
, "SubDir7", path
, &size
);
7121 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7122 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7123 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7125 MsiCloseHandle(hpkg
);
7126 RemoveDirectoryA("short");
7127 RemoveDirectoryA("long");
7128 RemoveDirectoryA("one");
7129 RemoveDirectoryA("four");
7130 RemoveDirectoryA("five");
7131 RemoveDirectoryA("eight");
7132 RemoveDirectoryA("nine");
7133 RemoveDirectoryA("twelve");
7135 /* short file names */
7137 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_DIRECT
, &hdb
);
7138 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7140 set_suminfo_prop(hdb
, PID_WORDCOUNT
, msidbSumInfoSourceTypeSFN
);
7142 r
= package_from_db(hdb
, &hpkg
);
7143 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
7145 MsiCloseHandle(hdb
);
7147 CreateDirectoryA("one", NULL
);
7148 CreateDirectoryA("four", NULL
);
7150 r
= MsiDoActionA(hpkg
, "CostInitialize");
7151 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7153 CreateDirectoryA("five", NULL
);
7154 CreateDirectoryA("eight", NULL
);
7156 r
= MsiDoActionA(hpkg
, "FileCost");
7157 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7159 CreateDirectoryA("nine", NULL
);
7160 CreateDirectoryA("twelve", NULL
);
7162 r
= MsiDoActionA(hpkg
, "CostFinalize");
7163 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7165 lstrcpyA(subsrc
, cwd
);
7166 lstrcatA(subsrc
, "short");
7167 lstrcatA(subsrc
, "\\");
7169 /* neither short nor long source directories exist */
7171 lstrcpyA(path
, "kiwi");
7172 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7173 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7174 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7175 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7177 CreateDirectoryA("short", NULL
);
7179 /* short source directory exists */
7181 lstrcpyA(path
, "kiwi");
7182 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7183 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7184 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7185 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7187 CreateDirectoryA("long", NULL
);
7189 /* both short and long source directories exist */
7191 lstrcpyA(path
, "kiwi");
7192 r
= MsiGetSourcePathA(hpkg
, "SubDir", path
, &size
);
7193 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7194 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7195 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7197 lstrcpyA(subsrc
, cwd
);
7198 lstrcatA(subsrc
, "one");
7199 lstrcatA(subsrc
, "\\");
7201 /* short dir exists before CostInitialize */
7203 lstrcpyA(path
, "kiwi");
7204 r
= MsiGetSourcePathA(hpkg
, "SubDir2", path
, &size
);
7205 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7206 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7207 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7209 lstrcpyA(subsrc
, cwd
);
7210 lstrcatA(subsrc
, "three");
7211 lstrcatA(subsrc
, "\\");
7213 /* long dir exists before CostInitialize */
7215 lstrcpyA(path
, "kiwi");
7216 r
= MsiGetSourcePathA(hpkg
, "SubDir3", path
, &size
);
7217 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7218 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7219 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7221 lstrcpyA(subsrc
, cwd
);
7222 lstrcatA(subsrc
, "five");
7223 lstrcatA(subsrc
, "\\");
7225 /* short dir exists before FileCost */
7227 lstrcpyA(path
, "kiwi");
7228 r
= MsiGetSourcePathA(hpkg
, "SubDir4", path
, &size
);
7229 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7230 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7231 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7233 lstrcpyA(subsrc
, cwd
);
7234 lstrcatA(subsrc
, "seven");
7235 lstrcatA(subsrc
, "\\");
7237 /* long dir exists before FileCost */
7239 lstrcpyA(path
, "kiwi");
7240 r
= MsiGetSourcePathA(hpkg
, "SubDir5", path
, &size
);
7241 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7242 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7243 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7245 lstrcpyA(subsrc
, cwd
);
7246 lstrcatA(subsrc
, "nine");
7247 lstrcatA(subsrc
, "\\");
7249 /* short dir exists before CostFinalize */
7251 lstrcpyA(path
, "kiwi");
7252 r
= MsiGetSourcePathA(hpkg
, "SubDir6", path
, &size
);
7253 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7254 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7255 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7257 lstrcpyA(subsrc
, cwd
);
7258 lstrcatA(subsrc
, "eleven");
7259 lstrcatA(subsrc
, "\\");
7261 /* long dir exists before CostFinalize */
7263 lstrcpyA(path
, "kiwi");
7264 r
= MsiGetSourcePathA(hpkg
, "SubDir7", path
, &size
);
7265 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7266 ok(!lstrcmpA(path
, subsrc
), "Expected \"%s\", got \"%s\"\n", subsrc
, path
);
7267 ok(size
== lstrlenA(subsrc
), "Expected %d, got %d\n", lstrlenA(subsrc
), size
);
7269 MsiCloseHandle(hpkg
);
7270 RemoveDirectoryA("short");
7271 RemoveDirectoryA("long");
7272 RemoveDirectoryA("one");
7273 RemoveDirectoryA("four");
7274 RemoveDirectoryA("five");
7275 RemoveDirectoryA("eight");
7276 RemoveDirectoryA("nine");
7277 RemoveDirectoryA("twelve");
7278 DeleteFileA(msifile
);
7281 static void test_sourcedir(void)
7283 MSIHANDLE hdb
, hpkg
;
7285 CHAR path
[MAX_PATH
];
7287 CHAR subsrc
[MAX_PATH
];
7291 lstrcpyA(cwd
, CURR_DIR
);
7292 if (!is_root(CURR_DIR
)) lstrcatA(cwd
, "\\");
7294 lstrcpyA(subsrc
, cwd
);
7295 lstrcatA(subsrc
, "long");
7296 lstrcatA(subsrc
, "\\");
7298 hdb
= create_package_db();
7299 ok( hdb
, "failed to create database\n");
7301 add_directory_entry(hdb
, "'TARGETDIR', '', 'SourceDir'");
7303 sprintf(package
, "#%u", hdb
);
7304 r
= MsiOpenPackageA(package
, &hpkg
);
7305 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
7307 skip("Not enough rights to perform tests\n");
7310 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7312 /* properties only */
7314 /* SourceDir prop */
7316 lstrcpyA(path
, "kiwi");
7317 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7318 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7319 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7320 ok(size
== 0, "Expected 0, got %d\n", size
);
7322 /* SOURCEDIR prop */
7324 lstrcpyA(path
, "kiwi");
7325 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7326 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7327 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7328 ok(size
== 0, "Expected 0, got %d\n", size
);
7330 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
7332 r
= MsiDoActionA(hpkg
, "CostInitialize");
7333 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7335 /* SourceDir after CostInitialize */
7337 lstrcpyA(path
, "kiwi");
7338 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7339 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7340 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7341 ok(size
== 0, "Expected 0, got %d\n", size
);
7343 /* SOURCEDIR after CostInitialize */
7345 lstrcpyA(path
, "kiwi");
7346 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7347 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7348 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7349 ok(size
== 0, "Expected 0, got %d\n", size
);
7351 r
= MsiDoActionA(hpkg
, "FileCost");
7352 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7354 /* SourceDir after FileCost */
7356 lstrcpyA(path
, "kiwi");
7357 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7358 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7359 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7360 ok(size
== 0, "Expected 0, got %d\n", size
);
7362 /* SOURCEDIR after FileCost */
7364 lstrcpyA(path
, "kiwi");
7365 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7366 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7367 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7368 ok(size
== 0, "Expected 0, got %d\n", size
);
7370 r
= MsiDoActionA(hpkg
, "CostFinalize");
7371 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7373 /* SourceDir after CostFinalize */
7375 lstrcpyA(path
, "kiwi");
7376 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7377 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7378 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7379 ok(size
== 0, "Expected 0, got %d\n", size
);
7381 /* SOURCEDIR after CostFinalize */
7383 lstrcpyA(path
, "kiwi");
7384 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7385 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7386 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7387 ok(size
== 0, "Expected 0, got %d\n", size
);
7390 lstrcpyA(path
, "kiwi");
7391 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7392 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7393 ok(!lstrcmpA(path
, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path
);
7394 ok(size
== MAX_PATH
, "Expected %d, got %d\n", MAX_PATH
, size
);
7396 /* SOURCEDIR after calling MsiGetSourcePath */
7398 lstrcpyA(path
, "kiwi");
7399 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7400 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7402 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7403 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7406 r
= MsiDoActionA(hpkg
, "ResolveSource");
7407 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7409 /* SourceDir after ResolveSource */
7411 lstrcpyA(path
, "kiwi");
7412 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7413 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7414 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7415 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7417 /* SOURCEDIR after ResolveSource */
7419 lstrcpyA(path
, "kiwi");
7420 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7421 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7422 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7423 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7427 lstrcpyA(path
, "kiwi");
7428 r
= MsiGetPropertyA(hpkg
, "SoUrCeDiR", path
, &size
);
7429 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7430 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7431 ok(size
== 0, "Expected 0, got %d\n", size
);
7433 MsiCloseHandle(hpkg
);
7435 /* reset the package state */
7436 sprintf(package
, "#%i", hdb
);
7437 r
= MsiOpenPackageA(package
, &hpkg
);
7438 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7440 /* test how MsiGetSourcePath affects the properties */
7442 /* SourceDir prop */
7444 lstrcpyA(path
, "kiwi");
7445 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7446 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7449 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7450 ok(size
== 0, "Expected 0, got %d\n", size
);
7454 lstrcpyA(path
, "kiwi");
7455 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
7456 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7457 ok(!lstrcmpA(path
, "kiwi"),
7458 "Expected path to be unchanged, got \"%s\"\n", path
);
7459 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7461 /* SourceDir after MsiGetSourcePath */
7463 lstrcpyA(path
, "kiwi");
7464 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7465 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7468 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7469 ok(size
== 0, "Expected 0, got %d\n", size
);
7472 /* SOURCEDIR prop */
7474 lstrcpyA(path
, "kiwi");
7475 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7476 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7479 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7480 ok(size
== 0, "Expected 0, got %d\n", size
);
7484 lstrcpyA(path
, "kiwi");
7485 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7486 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7487 ok(!lstrcmpA(path
, "kiwi"),
7488 "Expected path to be unchanged, got \"%s\"\n", path
);
7489 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7491 /* SOURCEDIR prop after MsiGetSourcePath */
7493 lstrcpyA(path
, "kiwi");
7494 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7495 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7498 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7499 ok(size
== 0, "Expected 0, got %d\n", size
);
7502 r
= MsiDoActionA(hpkg
, "CostInitialize");
7503 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7505 /* SourceDir after CostInitialize */
7507 lstrcpyA(path
, "kiwi");
7508 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7509 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7512 ok(!lstrcmpA(path
, ""), "Expected \"\", got \"%s\"\n", path
);
7513 ok(size
== 0, "Expected 0, got %d\n", size
);
7517 lstrcpyA(path
, "kiwi");
7518 r
= MsiGetSourcePathA(hpkg
, "SourceDir", path
, &size
);
7519 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7520 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7521 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7523 /* SourceDir after MsiGetSourcePath */
7525 lstrcpyA(path
, "kiwi");
7526 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7527 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7528 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7529 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7531 /* SOURCEDIR after CostInitialize */
7533 lstrcpyA(path
, "kiwi");
7534 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7535 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7536 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7537 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7539 /* SOURCEDIR source path still does not exist */
7541 lstrcpyA(path
, "kiwi");
7542 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7543 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7544 ok(!lstrcmpA(path
, "kiwi"),
7545 "Expected path to be unchanged, got \"%s\"\n", path
);
7546 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7548 r
= MsiDoActionA(hpkg
, "FileCost");
7549 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7551 /* SourceDir after FileCost */
7553 lstrcpyA(path
, "kiwi");
7554 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7555 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7556 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7557 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7559 /* SOURCEDIR after FileCost */
7561 lstrcpyA(path
, "kiwi");
7562 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7563 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7564 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7565 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7567 /* SOURCEDIR source path still does not exist */
7569 lstrcpyA(path
, "kiwi");
7570 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7571 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7572 ok(!lstrcmpA(path
, "kiwi"),
7573 "Expected path to be unchanged, got \"%s\"\n", path
);
7574 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7576 r
= MsiDoActionA(hpkg
, "CostFinalize");
7577 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7579 /* SourceDir after CostFinalize */
7581 lstrcpyA(path
, "kiwi");
7582 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7583 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7584 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7585 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7587 /* SOURCEDIR after CostFinalize */
7589 lstrcpyA(path
, "kiwi");
7590 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7591 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7592 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7593 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7595 /* SOURCEDIR source path still does not exist */
7597 lstrcpyA(path
, "kiwi");
7598 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7599 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7600 ok(!lstrcmpA(path
, "kiwi"),
7601 "Expected path to be unchanged, got \"%s\"\n", path
);
7602 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7604 r
= MsiDoActionA(hpkg
, "ResolveSource");
7605 ok(r
== ERROR_SUCCESS
, "file cost failed\n");
7607 /* SourceDir after ResolveSource */
7609 lstrcpyA(path
, "kiwi");
7610 r
= MsiGetPropertyA(hpkg
, "SourceDir", path
, &size
);
7611 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7612 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7613 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7615 /* SOURCEDIR after ResolveSource */
7617 lstrcpyA(path
, "kiwi");
7618 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", path
, &size
);
7619 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7620 ok(!lstrcmpA(path
, cwd
), "Expected \"%s\", got \"%s\"\n", cwd
, path
);
7621 ok(size
== lstrlenA(cwd
), "Expected %d, got %d\n", lstrlenA(cwd
), size
);
7623 /* SOURCEDIR source path still does not exist */
7625 lstrcpyA(path
, "kiwi");
7626 r
= MsiGetSourcePathA(hpkg
, "SOURCEDIR", path
, &size
);
7627 ok(r
== ERROR_DIRECTORY
, "Expected ERROR_DIRECTORY, got %d\n", r
);
7628 ok(!lstrcmpA(path
, "kiwi"),
7629 "Expected path to be unchanged, got \"%s\"\n", path
);
7630 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
7632 MsiCloseHandle(hpkg
);
7635 MsiCloseHandle(hdb
);
7636 DeleteFileA(msifile
);
7646 static const struct access_res create
[16] =
7648 { TRUE
, ERROR_SUCCESS
, TRUE
},
7649 { TRUE
, ERROR_SUCCESS
, TRUE
},
7650 { TRUE
, ERROR_SUCCESS
, FALSE
},
7651 { TRUE
, ERROR_SUCCESS
, FALSE
},
7652 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7653 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7654 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7655 { TRUE
, ERROR_SUCCESS
, FALSE
},
7656 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7657 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7658 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7659 { TRUE
, ERROR_SUCCESS
, TRUE
},
7660 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7661 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7662 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7663 { TRUE
, ERROR_SUCCESS
, TRUE
}
7666 static const struct access_res create_commit
[16] =
7668 { TRUE
, ERROR_SUCCESS
, TRUE
},
7669 { TRUE
, ERROR_SUCCESS
, TRUE
},
7670 { TRUE
, ERROR_SUCCESS
, FALSE
},
7671 { TRUE
, ERROR_SUCCESS
, FALSE
},
7672 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7673 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7674 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7675 { TRUE
, ERROR_SUCCESS
, FALSE
},
7676 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7677 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7678 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7679 { TRUE
, ERROR_SUCCESS
, TRUE
},
7680 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7681 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7682 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
7683 { TRUE
, ERROR_SUCCESS
, TRUE
}
7686 static const struct access_res create_close
[16] =
7688 { TRUE
, ERROR_SUCCESS
, FALSE
},
7689 { TRUE
, ERROR_SUCCESS
, FALSE
},
7690 { TRUE
, ERROR_SUCCESS
, FALSE
},
7691 { TRUE
, ERROR_SUCCESS
, FALSE
},
7692 { TRUE
, ERROR_SUCCESS
, FALSE
},
7693 { TRUE
, ERROR_SUCCESS
, FALSE
},
7694 { TRUE
, ERROR_SUCCESS
, FALSE
},
7695 { TRUE
, ERROR_SUCCESS
, FALSE
},
7696 { TRUE
, ERROR_SUCCESS
, FALSE
},
7697 { TRUE
, ERROR_SUCCESS
, FALSE
},
7698 { TRUE
, ERROR_SUCCESS
, FALSE
},
7699 { TRUE
, ERROR_SUCCESS
, FALSE
},
7700 { TRUE
, ERROR_SUCCESS
, FALSE
},
7701 { TRUE
, ERROR_SUCCESS
, FALSE
},
7702 { TRUE
, ERROR_SUCCESS
, FALSE
},
7703 { TRUE
, ERROR_SUCCESS
}
7706 static void _test_file_access(LPCSTR file
, const struct access_res
*ares
, DWORD line
)
7708 DWORD access
= 0, share
= 0;
7713 for (i
= 0; i
< 4; i
++)
7715 if (i
== 0) access
= 0;
7716 if (i
== 1) access
= GENERIC_READ
;
7717 if (i
== 2) access
= GENERIC_WRITE
;
7718 if (i
== 3) access
= GENERIC_READ
| GENERIC_WRITE
;
7720 for (j
= 0; j
< 4; j
++)
7722 if (ares
[idx
].ignore
)
7725 if (j
== 0) share
= 0;
7726 if (j
== 1) share
= FILE_SHARE_READ
;
7727 if (j
== 2) share
= FILE_SHARE_WRITE
;
7728 if (j
== 3) share
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
7730 SetLastError(0xdeadbeef);
7731 hfile
= CreateFileA(file
, access
, share
, NULL
, OPEN_EXISTING
,
7732 FILE_ATTRIBUTE_NORMAL
, 0);
7733 lasterr
= GetLastError();
7735 ok((hfile
!= INVALID_HANDLE_VALUE
) == ares
[idx
].gothandle
,
7736 "(%d, handle, %d): Expected %d, got %d\n",
7737 line
, idx
, ares
[idx
].gothandle
,
7738 (hfile
!= INVALID_HANDLE_VALUE
));
7740 ok(lasterr
== ares
[idx
].lasterr
, "(%d, lasterr, %d): Expected %d, got %d\n",
7741 line
, idx
, ares
[idx
].lasterr
, lasterr
);
7749 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7751 static void test_access(void)
7756 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
7757 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7759 test_file_access(msifile
, create
);
7761 r
= MsiDatabaseCommit(hdb
);
7762 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7764 test_file_access(msifile
, create_commit
);
7765 MsiCloseHandle(hdb
);
7767 test_file_access(msifile
, create_close
);
7768 DeleteFileA(msifile
);
7770 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATEDIRECT
, &hdb
);
7771 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7773 test_file_access(msifile
, create
);
7775 r
= MsiDatabaseCommit(hdb
);
7776 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7778 test_file_access(msifile
, create_commit
);
7779 MsiCloseHandle(hdb
);
7781 test_file_access(msifile
, create_close
);
7782 DeleteFileA(msifile
);
7785 static void test_emptypackage(void)
7787 MSIHANDLE hpkg
= 0, hdb
= 0, hsuminfo
= 0;
7788 MSIHANDLE hview
= 0, hrec
= 0;
7789 MSICONDITION condition
;
7790 CHAR buffer
[MAX_PATH
];
7794 r
= MsiOpenPackageA("", &hpkg
);
7795 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
7797 skip("Not enough rights to perform tests\n");
7802 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7805 hdb
= MsiGetActiveDatabase(hpkg
);
7808 ok(hdb
!= 0, "Expected a valid database handle\n");
7811 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Tables`", &hview
);
7814 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7816 r
= MsiViewExecute(hview
, 0);
7819 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7822 r
= MsiViewFetch(hview
, &hrec
);
7825 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7830 r
= MsiRecordGetStringA(hrec
, 1, buffer
, &size
);
7833 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7834 ok(!lstrcmpA(buffer
, "_Property"),
7835 "Expected \"_Property\", got \"%s\"\n", buffer
);
7838 MsiCloseHandle(hrec
);
7840 r
= MsiViewFetch(hview
, &hrec
);
7843 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7847 r
= MsiRecordGetStringA(hrec
, 1, buffer
, &size
);
7850 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7851 ok(!lstrcmpA(buffer
, "#_FolderCache"),
7852 "Expected \"_Property\", got \"%s\"\n", buffer
);
7855 MsiCloseHandle(hrec
);
7856 MsiViewClose(hview
);
7857 MsiCloseHandle(hview
);
7859 condition
= MsiDatabaseIsTablePersistentA(hdb
, "_Property");
7862 ok(condition
== MSICONDITION_FALSE
,
7863 "Expected MSICONDITION_FALSE, got %d\n", condition
);
7866 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Property`", &hview
);
7869 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7871 r
= MsiViewExecute(hview
, 0);
7874 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7877 /* _Property table is not empty */
7878 r
= MsiViewFetch(hview
, &hrec
);
7881 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7884 MsiCloseHandle(hrec
);
7885 MsiViewClose(hview
);
7886 MsiCloseHandle(hview
);
7888 condition
= MsiDatabaseIsTablePersistentA(hdb
, "#_FolderCache");
7891 ok(condition
== MSICONDITION_FALSE
,
7892 "Expected MSICONDITION_FALSE, got %d\n", condition
);
7895 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `#_FolderCache`", &hview
);
7898 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7900 r
= MsiViewExecute(hview
, 0);
7903 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7906 /* #_FolderCache is not empty */
7907 r
= MsiViewFetch(hview
, &hrec
);
7910 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7913 MsiCloseHandle(hrec
);
7914 MsiViewClose(hview
);
7915 MsiCloseHandle(hview
);
7917 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Streams`", &hview
);
7920 ok(r
== ERROR_BAD_QUERY_SYNTAX
,
7921 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
7924 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Storages`", &hview
);
7927 ok(r
== ERROR_BAD_QUERY_SYNTAX
,
7928 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
7931 r
= MsiGetSummaryInformationA(hdb
, NULL
, 0, &hsuminfo
);
7934 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
7935 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
7938 MsiCloseHandle(hsuminfo
);
7940 r
= MsiDatabaseCommit(hdb
);
7943 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7946 MsiCloseHandle(hdb
);
7947 MsiCloseHandle(hpkg
);
7950 static void test_MsiGetProductProperty(void)
7952 WCHAR valW
[MAX_PATH
];
7953 MSIHANDLE hprod
, hdb
;
7955 CHAR path
[MAX_PATH
];
7956 CHAR query
[MAX_PATH
+ 17];
7957 CHAR keypath
[MAX_PATH
*2];
7958 CHAR prodcode
[MAX_PATH
];
7959 WCHAR prodcodeW
[MAX_PATH
];
7960 CHAR prod_squashed
[MAX_PATH
];
7961 WCHAR prod_squashedW
[MAX_PATH
];
7962 HKEY prodkey
, userkey
, props
;
7966 REGSAM access
= KEY_ALL_ACCESS
;
7968 GetCurrentDirectoryA(MAX_PATH
, path
);
7969 lstrcatA(path
, "\\");
7971 create_test_guid(prodcode
, prod_squashed
);
7972 MultiByteToWideChar(CP_ACP
, 0, prodcode
, -1, prodcodeW
, MAX_PATH
);
7973 squash_guid(prodcodeW
, prod_squashedW
);
7976 access
|= KEY_WOW64_64KEY
;
7978 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
7979 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7981 r
= MsiDatabaseCommit(hdb
);
7982 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7984 r
= set_summary_info(hdb
);
7985 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7988 "CREATE TABLE `Directory` ( "
7989 "`Directory` CHAR(255) NOT NULL, "
7990 "`Directory_Parent` CHAR(255), "
7991 "`DefaultDir` CHAR(255) NOT NULL "
7992 "PRIMARY KEY `Directory`)");
7993 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
7995 create_property_table(hdb
);
7997 sprintf(query
, "'ProductCode', '%s'", prodcode
);
7998 r
= add_property_entry(hdb
, query
);
8000 r
= MsiDatabaseCommit(hdb
);
8001 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8003 MsiCloseHandle(hdb
);
8005 lstrcpyA(keypath
, "Software\\Classes\\Installer\\Products\\");
8006 lstrcatA(keypath
, prod_squashed
);
8008 res
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
, keypath
, 0, NULL
, 0, access
, NULL
, &prodkey
, NULL
);
8009 if (res
== ERROR_ACCESS_DENIED
)
8011 skip("Not enough rights to perform tests\n");
8012 DeleteFileA(msifile
);
8015 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
8017 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8018 lstrcatA(keypath
, "Installer\\UserData\\S-1-5-18\\Products\\");
8019 lstrcatA(keypath
, prod_squashed
);
8021 res
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
, keypath
, 0, NULL
, 0, access
, NULL
, &userkey
, NULL
);
8022 if (res
== ERROR_ACCESS_DENIED
)
8024 skip("Not enough rights to perform tests\n");
8025 RegDeleteKeyA(prodkey
, "");
8026 RegCloseKey(prodkey
);
8029 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
8031 res
= RegCreateKeyExA(userkey
, "InstallProperties", 0, NULL
, 0, access
, NULL
, &props
, NULL
);
8032 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
8034 lstrcpyA(val
, path
);
8035 lstrcatA(val
, "\\");
8036 lstrcatA(val
, msifile
);
8037 res
= RegSetValueExA(props
, "LocalPackage", 0, REG_SZ
,
8038 (const BYTE
*)val
, lstrlenA(val
) + 1);
8039 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
8042 r
= MsiOpenProductA(prodcode
, &hprod
);
8043 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8044 ok(hprod
!= 0 && hprod
!= 0xdeadbeef, "Expected a valid product handle\n");
8046 /* hProduct is invalid */
8048 lstrcpyA(val
, "apple");
8049 r
= MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val
, &size
);
8050 ok(r
== ERROR_INVALID_HANDLE
,
8051 "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
8052 ok(!lstrcmpA(val
, "apple"),
8053 "Expected val to be unchanged, got \"%s\"\n", val
);
8054 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
8057 lstrcpyW(valW
, L
"apple");
8058 r
= MsiGetProductPropertyW(0xdeadbeef, L
"ProductCode", valW
, &size
);
8059 ok(r
== ERROR_INVALID_HANDLE
,
8060 "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
8061 ok(!lstrcmpW(valW
, L
"apple"),
8062 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW
));
8063 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
8065 /* szProperty is NULL */
8067 lstrcpyA(val
, "apple");
8068 r
= MsiGetProductPropertyA(hprod
, NULL
, val
, &size
);
8069 ok(r
== ERROR_INVALID_PARAMETER
,
8070 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8071 ok(!lstrcmpA(val
, "apple"),
8072 "Expected val to be unchanged, got \"%s\"\n", val
);
8073 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
8076 lstrcpyW(valW
, L
"apple");
8077 r
= MsiGetProductPropertyW(hprod
, NULL
, valW
, &size
);
8078 ok(r
== ERROR_INVALID_PARAMETER
,
8079 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8080 ok(!lstrcmpW(valW
, L
"apple"),
8081 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW
));
8082 ok(size
== MAX_PATH
, "Expected size to be unchanged, got %d\n", size
);
8084 /* szProperty is empty */
8086 lstrcpyA(val
, "apple");
8087 r
= MsiGetProductPropertyA(hprod
, "", val
, &size
);
8088 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8089 ok(!lstrcmpA(val
, ""), "Expected \"\", got \"%s\"\n", val
);
8090 ok(size
== 0, "Expected 0, got %d\n", size
);
8093 lstrcpyW(valW
, L
"apple");
8094 r
= MsiGetProductPropertyW(hprod
, L
"", valW
, &size
);
8095 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8096 ok(*valW
== 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW
));
8097 ok(size
== 0, "Expected 0, got %d\n", size
);
8099 /* get the property */
8101 lstrcpyA(val
, "apple");
8102 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, &size
);
8103 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8104 ok(!lstrcmpA(val
, prodcode
),
8105 "Expected \"%s\", got \"%s\"\n", prodcode
, val
);
8106 ok(size
== lstrlenA(prodcode
),
8107 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8110 lstrcpyW(valW
, L
"apple");
8111 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, &size
);
8112 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8113 ok(!lstrcmpW(valW
, prodcodeW
),
8114 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW
), wine_dbgstr_w(valW
));
8115 ok(size
== lstrlenW(prodcodeW
),
8116 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8118 /* lpValueBuf is NULL */
8120 r
= MsiGetProductPropertyA(hprod
, "ProductCode", NULL
, &size
);
8121 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8122 ok(size
== lstrlenA(prodcode
),
8123 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8126 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", NULL
, &size
);
8127 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8128 ok(size
== lstrlenW(prodcodeW
),
8129 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8131 /* pcchValueBuf is NULL */
8132 lstrcpyA(val
, "apple");
8133 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, NULL
);
8134 ok(r
== ERROR_INVALID_PARAMETER
,
8135 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8136 ok(!lstrcmpA(val
, "apple"),
8137 "Expected val to be unchanged, got \"%s\"\n", val
);
8138 ok(size
== lstrlenA(prodcode
),
8139 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8141 lstrcpyW(valW
, L
"apple");
8142 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, NULL
);
8143 ok(r
== ERROR_INVALID_PARAMETER
,
8144 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8145 ok(!lstrcmpW(valW
, L
"apple"),
8146 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW
));
8147 ok(size
== lstrlenW(prodcodeW
),
8148 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8150 /* pcchValueBuf is too small */
8152 lstrcpyA(val
, "apple");
8153 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, &size
);
8154 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
8155 ok(!strncmp(val
, prodcode
, 3),
8156 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode
, val
);
8157 ok(size
== lstrlenA(prodcode
),
8158 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8161 lstrcpyW(valW
, L
"apple");
8162 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, &size
);
8163 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
8164 ok(!memcmp(valW
, prodcodeW
, 3 * sizeof(WCHAR
)),
8165 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW
), wine_dbgstr_w(valW
));
8166 ok(size
== lstrlenW(prodcodeW
),
8167 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8169 /* pcchValueBuf does not leave room for NULL terminator */
8170 size
= lstrlenA(prodcode
);
8171 lstrcpyA(val
, "apple");
8172 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, &size
);
8173 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
8174 ok(!strncmp(val
, prodcode
, lstrlenA(prodcode
) - 1),
8175 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode
, val
);
8176 ok(size
== lstrlenA(prodcode
),
8177 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8179 size
= lstrlenW(prodcodeW
);
8180 lstrcpyW(valW
, L
"apple");
8181 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, &size
);
8182 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
8183 ok(!memcmp(valW
, prodcodeW
, lstrlenW(prodcodeW
) - 1),
8184 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW
), wine_dbgstr_w(valW
));
8185 ok(size
== lstrlenW(prodcodeW
),
8186 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8188 /* pcchValueBuf has enough room for NULL terminator */
8189 size
= lstrlenA(prodcode
) + 1;
8190 lstrcpyA(val
, "apple");
8191 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, &size
);
8192 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8193 ok(!lstrcmpA(val
, prodcode
),
8194 "Expected \"%s\", got \"%s\"\n", prodcode
, val
);
8195 ok(size
== lstrlenA(prodcode
),
8196 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8198 size
= lstrlenW(prodcodeW
) + 1;
8199 lstrcpyW(valW
, L
"apple");
8200 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, &size
);
8201 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8202 ok(!lstrcmpW(valW
, prodcodeW
),
8203 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW
), wine_dbgstr_w(valW
));
8204 ok(size
== lstrlenW(prodcodeW
),
8205 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8207 /* nonexistent property */
8209 lstrcpyA(val
, "apple");
8210 r
= MsiGetProductPropertyA(hprod
, "IDontExist", val
, &size
);
8211 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8212 ok(!lstrcmpA(val
, ""), "Expected \"\", got \"%s\"\n", val
);
8213 ok(size
== 0, "Expected 0, got %d\n", size
);
8216 lstrcpyW(valW
, L
"apple");
8217 r
= MsiGetProductPropertyW(hprod
, L
"IDontExist", valW
, &size
);
8218 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8219 ok(!lstrcmpW(valW
, L
""), "Expected \"\", got %s\n", wine_dbgstr_w(valW
));
8220 ok(size
== 0, "Expected 0, got %d\n", size
);
8222 r
= MsiSetPropertyA(hprod
, "NewProperty", "value");
8223 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8225 /* non-product property set */
8227 lstrcpyA(val
, "apple");
8228 r
= MsiGetProductPropertyA(hprod
, "NewProperty", val
, &size
);
8229 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8230 ok(!lstrcmpA(val
, ""), "Expected \"\", got \"%s\"\n", val
);
8231 ok(size
== 0, "Expected 0, got %d\n", size
);
8234 lstrcpyW(valW
, L
"apple");
8235 r
= MsiGetProductPropertyW(hprod
, L
"NewProperty", valW
, &size
);
8236 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8237 ok(!lstrcmpW(valW
, L
""), "Expected \"\", got %s\n", wine_dbgstr_w(valW
));
8238 ok(size
== 0, "Expected 0, got %d\n", size
);
8240 r
= MsiSetPropertyA(hprod
, "ProductCode", "value");
8241 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8243 /* non-product property that is also a product property set */
8245 lstrcpyA(val
, "apple");
8246 r
= MsiGetProductPropertyA(hprod
, "ProductCode", val
, &size
);
8247 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8248 ok(!lstrcmpA(val
, prodcode
),
8249 "Expected \"%s\", got \"%s\"\n", prodcode
, val
);
8250 ok(size
== lstrlenA(prodcode
),
8251 "Expected %d, got %d\n", lstrlenA(prodcode
), size
);
8254 lstrcpyW(valW
, L
"apple");
8255 r
= MsiGetProductPropertyW(hprod
, L
"ProductCode", valW
, &size
);
8256 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8257 ok(!lstrcmpW(valW
, prodcodeW
),
8258 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW
), wine_dbgstr_w(valW
));
8259 ok(size
== lstrlenW(prodcodeW
),
8260 "Expected %d, got %d\n", lstrlenW(prodcodeW
), size
);
8262 MsiCloseHandle(hprod
);
8264 RegDeleteValueA(props
, "LocalPackage");
8265 delete_key(props
, "", access
);
8267 delete_key(userkey
, "", access
);
8268 RegCloseKey(userkey
);
8269 delete_key(prodkey
, "", access
);
8270 RegCloseKey(prodkey
);
8271 DeleteFileA(msifile
);
8274 static void test_MsiSetProperty(void)
8276 MSIHANDLE hpkg
, hdb
, hrec
;
8282 r
= package_from_db(create_package_db(), &hpkg
);
8283 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
8285 skip("Not enough rights to perform tests\n");
8286 DeleteFileA(msifile
);
8289 ok(r
== ERROR_SUCCESS
, "Expected a valid package %u\n", r
);
8291 /* invalid hInstall */
8292 r
= MsiSetPropertyA(0, "Prop", "Val");
8293 ok(r
== ERROR_INVALID_HANDLE
,
8294 "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
8296 /* invalid hInstall */
8297 r
= MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8298 ok(r
== ERROR_INVALID_HANDLE
,
8299 "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
8301 /* szName is NULL */
8302 r
= MsiSetPropertyA(hpkg
, NULL
, "Val");
8303 ok(r
== ERROR_INVALID_PARAMETER
,
8304 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8306 /* both szName and szValue are NULL */
8307 r
= MsiSetPropertyA(hpkg
, NULL
, NULL
);
8308 ok(r
== ERROR_INVALID_PARAMETER
,
8309 "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
8311 /* szName is empty */
8312 r
= MsiSetPropertyA(hpkg
, "", "Val");
8313 ok(r
== ERROR_FUNCTION_FAILED
,
8314 "Expected ERROR_FUNCTION_FAILED, got %d\n", r
);
8316 /* szName is empty and szValue is NULL */
8317 r
= MsiSetPropertyA(hpkg
, "", NULL
);
8318 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8320 /* set a property */
8321 r
= MsiSetPropertyA(hpkg
, "Prop", "Val");
8322 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8324 /* get the property */
8326 r
= MsiGetPropertyA(hpkg
, "Prop", buf
, &size
);
8327 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8328 ok(!lstrcmpA(buf
, "Val"), "Expected \"Val\", got \"%s\"\n", buf
);
8329 ok(size
== 3, "Expected 3, got %d\n", size
);
8331 /* update the property */
8332 r
= MsiSetPropertyA(hpkg
, "Prop", "Nuvo");
8333 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8335 /* get the property */
8337 r
= MsiGetPropertyA(hpkg
, "Prop", buf
, &size
);
8338 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8339 ok(!lstrcmpA(buf
, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf
);
8340 ok(size
== 4, "Expected 4, got %d\n", size
);
8342 hdb
= MsiGetActiveDatabase(hpkg
);
8343 ok(hdb
!= 0, "Expected a valid database handle\n");
8345 /* set prop is not in the _Property table */
8346 query
= "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8347 r
= do_query(hdb
, query
, &hrec
);
8348 ok(r
== ERROR_BAD_QUERY_SYNTAX
,
8349 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
8351 /* set prop is not in the Property table */
8352 query
= "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8353 r
= do_query(hdb
, query
, &hrec
);
8354 ok(r
== ERROR_BAD_QUERY_SYNTAX
,
8355 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
8357 MsiCloseHandle(hdb
);
8359 /* szValue is an empty string */
8360 r
= MsiSetPropertyA(hpkg
, "Prop", "");
8361 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8363 /* try to get the property */
8365 r
= MsiGetPropertyA(hpkg
, "Prop", buf
, &size
);
8366 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8367 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
8368 ok(size
== 0, "Expected 0, got %d\n", size
);
8370 /* reset the property */
8371 r
= MsiSetPropertyA(hpkg
, "Prop", "BlueTap");
8372 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8374 /* delete the property */
8375 r
= MsiSetPropertyA(hpkg
, "Prop", NULL
);
8376 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8378 /* try to get the property */
8380 r
= MsiGetPropertyA(hpkg
, "Prop", buf
, &size
);
8381 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
8382 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
8383 ok(size
== 0, "Expected 0, got %d\n", size
);
8385 MsiCloseHandle(hpkg
);
8386 DeleteFileA(msifile
);
8389 static void test_MsiApplyMultiplePatches(void)
8391 UINT r
, type
= GetDriveTypeW(NULL
);
8393 r
= MsiApplyMultiplePatchesA(NULL
, NULL
, NULL
);
8394 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8396 r
= MsiApplyMultiplePatchesA("", NULL
, NULL
);
8397 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8399 r
= MsiApplyMultiplePatchesA(";", NULL
, NULL
);
8400 if (type
== DRIVE_FIXED
)
8401 todo_wine
ok(r
== ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r
);
8403 ok(r
== ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %u\n", r
);
8405 r
= MsiApplyMultiplePatchesA(" ;", NULL
, NULL
);
8406 if (type
== DRIVE_FIXED
)
8407 todo_wine
ok(r
== ERROR_PATCH_PACKAGE_OPEN_FAILED
, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r
);
8409 ok(r
== ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %u\n", r
);
8411 r
= MsiApplyMultiplePatchesA(";;", NULL
, NULL
);
8412 if (type
== DRIVE_FIXED
)
8413 todo_wine
ok(r
== ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r
);
8415 ok(r
== ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %u\n", r
);
8417 r
= MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL
, NULL
);
8418 todo_wine
ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r
);
8420 r
= MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL
, NULL
);
8421 if (type
== DRIVE_FIXED
)
8422 todo_wine
ok(r
== ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r
);
8424 ok(r
== ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %u\n", r
);
8426 r
= MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL
, NULL
);
8427 todo_wine
ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r
);
8429 r
= MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL
, NULL
);
8430 todo_wine
ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r
);
8433 static void test_MsiApplyPatch(void)
8437 r
= MsiApplyPatchA(NULL
, NULL
, INSTALLTYPE_DEFAULT
, NULL
);
8438 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8440 r
= MsiApplyPatchA("", NULL
, INSTALLTYPE_DEFAULT
, NULL
);
8441 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8444 static void test_costs(void)
8446 MSIHANDLE hdb
, hpkg
;
8447 char package
[12], drive
[3];
8452 hdb
= create_package_db();
8453 ok( hdb
, "failed to create database\n" );
8455 create_property_table( hdb
);
8456 add_property_entry( hdb
, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8457 add_property_entry( hdb
, "'MSIFASTINSTALL', '1'" );
8458 add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'" );
8460 create_media_table( hdb
);
8461 add_media_entry( hdb
, "'1', '2', 'cabinet', '', '', ''");
8463 create_file_table( hdb
);
8464 add_file_entry( hdb
, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8466 create_component_table( hdb
);
8467 add_component_entry( hdb
, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8468 add_component_entry( hdb
, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8470 create_feature_table( hdb
);
8471 add_feature_entry( hdb
, "'one', '', '', '', 0, 1, '', 0" );
8472 add_feature_entry( hdb
, "'two', '', '', '', 0, 1, '', 0" );
8474 create_feature_components_table( hdb
);
8475 add_feature_components_entry( hdb
, "'one', 'one'" );
8476 add_feature_components_entry( hdb
, "'two', 'two'" );
8478 create_install_execute_sequence_table( hdb
);
8479 add_install_execute_sequence_entry( hdb
, "'CostInitialize', '', '800'" );
8480 add_install_execute_sequence_entry( hdb
, "'FileCost', '', '900'" );
8481 add_install_execute_sequence_entry( hdb
, "'CostFinalize', '', '1000'" );
8482 add_install_execute_sequence_entry( hdb
, "'InstallValidate', '', '1100'" );
8484 r
= MsiDatabaseCommit( hdb
);
8485 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8487 sprintf( package
, "#%u", hdb
);
8488 r
= MsiOpenPackageA( package
, &hpkg
);
8489 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
8491 skip("Not enough rights to perform tests\n");
8494 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8496 r
= MsiEnumComponentCostsA( 0, NULL
, 0, INSTALLSTATE_UNKNOWN
, NULL
, NULL
, NULL
, NULL
);
8497 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8499 r
= MsiEnumComponentCostsA( hpkg
, NULL
, 0, INSTALLSTATE_UNKNOWN
, NULL
, NULL
, NULL
, NULL
);
8500 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8502 r
= MsiEnumComponentCostsA( hpkg
, NULL
, 0, INSTALLSTATE_UNKNOWN
, NULL
, NULL
, NULL
, NULL
);
8503 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8505 r
= MsiEnumComponentCostsA( hpkg
, "", 0, INSTALLSTATE_UNKNOWN
, NULL
, NULL
, NULL
, NULL
);
8506 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8508 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_UNKNOWN
, NULL
, NULL
, NULL
, NULL
);
8509 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8511 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, NULL
, NULL
, NULL
, NULL
);
8512 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8514 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, NULL
, NULL
, NULL
);
8515 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8517 len
= sizeof(drive
);
8518 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, NULL
, NULL
);
8519 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8521 len
= sizeof(drive
);
8522 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, NULL
);
8523 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8525 len
= sizeof(drive
);
8526 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8527 todo_wine
ok( r
== ERROR_INVALID_HANDLE_STATE
, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r
);
8529 len
= sizeof(drive
);
8530 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, NULL
, &len
, &cost
, &temp
);
8531 ok( r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u\n", r
);
8533 MsiSetInternalUI( INSTALLUILEVEL_NONE
, NULL
);
8535 r
= MsiDoActionA( hpkg
, "CostInitialize" );
8536 ok( r
== ERROR_SUCCESS
, "CostInitialize failed %u\n", r
);
8538 r
= MsiDoActionA( hpkg
, "FileCost" );
8539 ok( r
== ERROR_SUCCESS
, "FileCost failed %u\n", r
);
8541 len
= sizeof(drive
);
8542 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8543 ok( r
== ERROR_FUNCTION_NOT_CALLED
, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r
);
8545 r
= MsiDoActionA( hpkg
, "CostFinalize" );
8546 ok( r
== ERROR_SUCCESS
, "CostFinalize failed %u\n", r
);
8548 /* contrary to what msdn says InstallValidate must be called too */
8549 len
= sizeof(drive
);
8550 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8551 todo_wine
ok( r
== ERROR_FUNCTION_NOT_CALLED
, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r
);
8553 r
= MsiDoActionA( hpkg
, "InstallValidate" );
8554 ok( r
== ERROR_SUCCESS
, "InstallValidate failed %u\n", r
);
8557 r
= MsiEnumComponentCostsA( hpkg
, "three", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8558 ok( r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r
);
8561 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8562 ok( r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %u\n", r
);
8563 ok( len
== 2, "expected len == 2, got %u\n", len
);
8566 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8567 ok( r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %u\n", r
);
8568 ok( len
== 2, "expected len == 2, got %u\n", len
);
8571 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_UNKNOWN
, drive
, &len
, &cost
, &temp
);
8572 ok( r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %u\n", r
);
8573 ok( len
== 2, "expected len == 2, got %u\n", len
);
8575 /* install state doesn't seem to matter */
8576 len
= sizeof(drive
);
8577 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_UNKNOWN
, drive
, &len
, &cost
, &temp
);
8578 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8580 len
= sizeof(drive
);
8581 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_ABSENT
, drive
, &len
, &cost
, &temp
);
8582 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8584 len
= sizeof(drive
);
8585 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_SOURCE
, drive
, &len
, &cost
, &temp
);
8586 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8588 len
= sizeof(drive
);
8590 cost
= temp
= 0xdead;
8591 r
= MsiEnumComponentCostsA( hpkg
, "one", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8592 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8593 ok( len
== 2, "expected len == 2, got %u\n", len
);
8594 ok( drive
[0], "expected a drive\n" );
8595 ok( cost
&& cost
!= 0xdead, "expected cost > 0, got %d\n", cost
);
8596 ok( !temp
, "expected temp == 0, got %d\n", temp
);
8598 len
= sizeof(drive
);
8600 cost
= temp
= 0xdead;
8601 r
= MsiEnumComponentCostsA( hpkg
, "two", 0, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8602 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8603 ok( len
== 2, "expected len == 2, got %u\n", len
);
8604 ok( drive
[0], "expected a drive\n" );
8605 ok( !cost
, "expected cost == 0, got %d\n", cost
);
8606 ok( !temp
, "expected temp == 0, got %d\n", temp
);
8608 len
= sizeof(drive
);
8610 cost
= temp
= 0xdead;
8611 r
= MsiEnumComponentCostsA( hpkg
, "", 0, INSTALLSTATE_UNKNOWN
, drive
, &len
, &cost
, &temp
);
8612 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
8613 ok( len
== 2, "expected len == 2, got %u\n", len
);
8614 ok( drive
[0], "expected a drive\n" );
8615 ok( !cost
, "expected cost == 0, got %d\n", cost
);
8616 ok( temp
&& temp
!= 0xdead, "expected temp > 0, got %d\n", temp
);
8618 /* increased index */
8619 len
= sizeof(drive
);
8620 r
= MsiEnumComponentCostsA( hpkg
, "one", 1, INSTALLSTATE_LOCAL
, drive
, &len
, &cost
, &temp
);
8621 ok( r
== ERROR_NO_MORE_ITEMS
, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r
);
8623 len
= sizeof(drive
);
8624 r
= MsiEnumComponentCostsA( hpkg
, "", 1, INSTALLSTATE_UNKNOWN
, drive
, &len
, &cost
, &temp
);
8625 ok( r
== ERROR_NO_MORE_ITEMS
, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r
);
8627 /* test MsiGetFeatureCost */
8629 r
= MsiGetFeatureCostA( hpkg
, NULL
, MSICOSTTREE_SELFONLY
, INSTALLSTATE_LOCAL
, &cost
);
8630 ok( r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
8631 ok( cost
== 0xdead, "got %d\n", cost
);
8633 r
= MsiGetFeatureCostA( hpkg
, "one", MSICOSTTREE_SELFONLY
, INSTALLSTATE_LOCAL
, NULL
);
8634 ok( r
== ERROR_INVALID_PARAMETER
, "got %u\n", r
);
8637 r
= MsiGetFeatureCostA( hpkg
, "one", MSICOSTTREE_SELFONLY
, INSTALLSTATE_LOCAL
, &cost
);
8638 ok( !r
, "got %u\n", r
);
8639 ok( cost
== 8, "got %d\n", cost
);
8641 MsiCloseHandle( hpkg
);
8643 MsiCloseHandle( hdb
);
8644 DeleteFileA( msifile
);
8647 static void test_MsiDatabaseCommit(void)
8650 MSIHANDLE hdb
, hpkg
= 0;
8651 char buf
[32], package
[12];
8654 hdb
= create_package_db();
8655 ok( hdb
, "failed to create database\n" );
8657 create_property_table( hdb
);
8659 sprintf( package
, "#%u", hdb
);
8660 r
= MsiOpenPackageA( package
, &hpkg
);
8661 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
8663 skip("Not enough rights to perform tests\n");
8666 ok( r
== ERROR_SUCCESS
, "got %u\n", r
);
8668 r
= MsiSetPropertyA( hpkg
, "PROP", "value" );
8669 ok( r
== ERROR_SUCCESS
, "got %u\n", r
);
8673 r
= MsiGetPropertyA( hpkg
, "PROP", buf
, &sz
);
8674 ok( r
== ERROR_SUCCESS
, "MsiGetPropertyA returned %u\n", r
);
8675 ok( !lstrcmpA( buf
, "value" ), "got \"%s\"\n", buf
);
8677 r
= MsiDatabaseCommit( hdb
);
8678 ok( r
== ERROR_SUCCESS
, "MsiDatabaseCommit returned %u\n", r
);
8682 r
= MsiGetPropertyA( hpkg
, "PROP", buf
, &sz
);
8683 ok( r
== ERROR_SUCCESS
, "MsiGetPropertyA returned %u\n", r
);
8684 ok( !lstrcmpA( buf
, "value" ), "got \"%s\"\n", buf
);
8686 MsiCloseHandle( hpkg
);
8688 MsiCloseHandle( hdb
);
8689 DeleteFileA( msifile
);
8692 static int externalui_ran
;
8694 static INT CALLBACK
externalui_callback(void *context
, UINT message_type
, LPCSTR message
)
8697 ok(message_type
== INSTALLMESSAGE_USER
, "expected INSTALLMESSAGE_USER, got %08x\n", message_type
);
8701 static int externalui_record_ran
;
8703 static INT CALLBACK
externalui_record_callback(void *context
, UINT message_type
, MSIHANDLE hrecord
)
8705 INT retval
= context
? *((INT
*)context
) : 0;
8707 externalui_record_ran
= 1;
8708 ok(message_type
== INSTALLMESSAGE_USER
, "expected INSTALLMESSAGE_USER, got %08x\n", message_type
);
8709 r
= MsiRecordGetFieldCount(hrecord
);
8710 ok(r
== 1, "expected 1, got %u\n", r
);
8711 r
= MsiRecordGetInteger(hrecord
, 1);
8712 ok(r
== 12345, "expected 12345, got %u\n", r
);
8716 static void test_externalui(void)
8718 /* test that external UI handlers work correctly */
8720 INSTALLUI_HANDLERA prev
;
8721 INSTALLUI_HANDLER_RECORD prev_record
;
8722 MSIHANDLE hpkg
, hrecord
;
8726 prev
= MsiSetExternalUIA(externalui_callback
, INSTALLLOGMODE_USER
, NULL
);
8728 r
= package_from_db(create_package_db(), &hpkg
);
8729 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
8731 skip("Not enough rights to perform tests\n");
8732 DeleteFileA(msifile
);
8735 ok(r
== ERROR_SUCCESS
, "Expected a valid package %u\n", r
);
8737 hrecord
= MsiCreateRecord(1);
8738 ok(hrecord
, "Expected a valid record\n");
8739 r
= MsiRecordSetStringA(hrecord
, 0, "test message [1]");
8740 ok(r
== ERROR_SUCCESS
, "MsiSetString failed %u\n", r
);
8741 r
= MsiRecordSetInteger(hrecord
, 1, 12345);
8742 ok(r
== ERROR_SUCCESS
, "MsiSetInteger failed %u\n", r
);
8745 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
8746 ok(r
== 0, "expected 0, got %u\n", r
);
8747 ok(externalui_ran
== 1, "external UI callback did not run\n");
8749 prev
= MsiSetExternalUIA(prev
, 0, NULL
);
8750 ok(prev
== externalui_callback
, "wrong callback function %p\n", prev
);
8751 r
= MsiSetExternalUIRecord(externalui_record_callback
, INSTALLLOGMODE_USER
, &retval
, &prev_record
);
8752 ok(r
== ERROR_SUCCESS
, "MsiSetExternalUIRecord failed %u\n", r
);
8754 externalui_ran
= externalui_record_ran
= 0;
8755 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
8756 ok(r
== 0, "expected 0, got %u\n", r
);
8757 ok(externalui_ran
== 0, "external UI callback should not have run\n");
8758 ok(externalui_record_ran
== 1, "external UI record callback did not run\n");
8760 MsiSetExternalUIA(externalui_callback
, INSTALLLOGMODE_USER
, NULL
);
8762 externalui_ran
= externalui_record_ran
= 0;
8763 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
8764 ok(r
== 0, "expected 0, got %u\n", r
);
8765 ok(externalui_ran
== 1, "external UI callback did not run\n");
8766 ok(externalui_record_ran
== 1, "external UI record callback did not run\n");
8769 externalui_ran
= externalui_record_ran
= 0;
8770 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
8771 ok(r
== 1, "expected 1, got %u\n", r
);
8772 ok(externalui_ran
== 0, "external UI callback should not have run\n");
8773 ok(externalui_record_ran
== 1, "external UI record callback did not run\n");
8775 /* filter and context should be kept separately */
8776 r
= MsiSetExternalUIRecord(externalui_record_callback
, INSTALLLOGMODE_ERROR
, &retval
, &prev_record
);
8777 ok(r
== ERROR_SUCCESS
, "MsiSetExternalUIRecord failed %u\n", r
);
8779 externalui_ran
= externalui_record_ran
= 0;
8780 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
8781 ok(r
== 0, "expected 0, got %u\n", r
);
8782 ok(externalui_ran
== 1, "external UI callback did not run\n");
8783 ok(externalui_record_ran
== 0, "external UI record callback should not have run\n");
8785 MsiCloseHandle(hpkg
);
8786 DeleteFileA(msifile
);
8789 struct externalui_message
{
8793 int match
[4]; /* should we test for a match */
8797 static struct externalui_message
*sequence
;
8798 static int sequence_count
, sequence_size
;
8800 static void add_message(const struct externalui_message
*msg
)
8805 sequence
= HeapAlloc(GetProcessHeap(), 0, sequence_size
* sizeof(*sequence
));
8807 if (sequence_count
== sequence_size
)
8810 sequence
= HeapReAlloc(GetProcessHeap(), 0, sequence
, sequence_size
* sizeof(*sequence
));
8815 sequence
[sequence_count
++] = *msg
;
8818 static void flush_sequence(void)
8820 HeapFree(GetProcessHeap(), 0, sequence
);
8822 sequence_count
= sequence_size
= 0;
8825 static void ok_sequence_(const struct externalui_message
*expected
, const char *context
, BOOL todo
,
8826 const char *file
, int line
)
8828 static const struct externalui_message end_of_sequence
= {0};
8829 const struct externalui_message
*actual
;
8833 add_message(&end_of_sequence
);
8837 while (expected
->message
&& actual
->message
)
8839 if (expected
->message
== actual
->message
)
8841 if (expected
->field_count
< actual
->field_count
)
8844 ok_(file
, line
) (FALSE
, "%s: in msg 0x%08x expecting field count %d got %d\n",
8845 context
, expected
->message
, expected
->field_count
, actual
->field_count
);
8849 for (i
= 0; i
<= actual
->field_count
; i
++)
8851 if (expected
->match
[i
] && strcmp(expected
->field
[i
], actual
->field
[i
]))
8854 ok_(file
, line
) (FALSE
, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8855 context
, expected
->message
, i
, expected
->field
[i
], actual
->field
[i
]);
8863 else if (expected
->optional
)
8870 ok_(file
, line
) (FALSE
, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8871 context
, expected
->message
, actual
->message
);
8880 if (expected
->message
|| actual
->message
)
8883 ok_(file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8884 context
, expected
->message
, actual
->message
);
8888 if(todo
&& !failcount
) /* succeeded yet marked todo */
8891 ok_(file
, line
)(TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
8898 #define ok_sequence(exp, contx, todo) \
8899 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8901 /* don't use PROGRESS, which is timing-dependent,
8902 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8903 static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE
=
8904 INSTALLLOGMODE_FATALEXIT
|
8905 INSTALLLOGMODE_ERROR
|
8906 INSTALLLOGMODE_WARNING
|
8907 INSTALLLOGMODE_USER
|
8908 INSTALLLOGMODE_INFO
|
8909 INSTALLLOGMODE_FILESINUSE
|
8910 INSTALLLOGMODE_RESOLVESOURCE
|
8911 INSTALLLOGMODE_OUTOFDISKSPACE
|
8912 INSTALLLOGMODE_ACTIONSTART
|
8913 INSTALLLOGMODE_ACTIONDATA
|
8914 INSTALLLOGMODE_COMMONDATA
|
8915 INSTALLLOGMODE_INITIALIZE
|
8916 INSTALLLOGMODE_TERMINATE
|
8917 INSTALLLOGMODE_RMFILESINUSE
|
8918 INSTALLLOGMODE_INSTALLSTART
|
8919 INSTALLLOGMODE_INSTALLEND
;
8921 static const struct externalui_message empty_sequence
[] = {
8925 static const struct externalui_message openpackage_nonexistent_sequence
[] = {
8926 {INSTALLMESSAGE_INITIALIZE
, -1},
8927 {INSTALLMESSAGE_TERMINATE
, -1},
8931 static const struct externalui_message openpackage_sequence
[] = {
8932 {INSTALLMESSAGE_INITIALIZE
, -1},
8933 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8934 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
8935 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8936 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8940 static const struct externalui_message processmessage_info_sequence
[] = {
8941 {INSTALLMESSAGE_INFO
, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8945 static const struct externalui_message processmessage_actionstart_sequence
[] = {
8946 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8950 static const struct externalui_message processmessage_actiondata_sequence
[] = {
8951 {INSTALLMESSAGE_ACTIONDATA
, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8955 static const struct externalui_message processmessage_error_sequence
[] = {
8956 {INSTALLMESSAGE_USER
, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8960 static const struct externalui_message processmessage_internal_error_sequence
[] = {
8961 {INSTALLMESSAGE_INFO
, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8962 {INSTALLMESSAGE_USER
, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8966 static const struct externalui_message processmessage_error_format_sequence
[] = {
8967 {INSTALLMESSAGE_USER
, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8971 static const struct externalui_message doaction_costinitialize_sequence
[] = {
8972 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8973 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8974 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8978 static const struct externalui_message doaction_custom_sequence
[] = {
8979 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8980 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "1"}, {0, 1, 1}},
8981 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "0"}, {0, 1, 1}},
8985 static const struct externalui_message doaction_custom_fullui_sequence
[] = {
8986 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8987 {INSTALLMESSAGE_INFO
, 2, {"", "custom", ""}, {0, 1, 1}},
8988 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"custom"}, {1}},
8989 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "1"}, {0, 1, 1}},
8993 static const struct externalui_message doaction_custom_cancel_sequence
[] = {
8994 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8998 static const struct externalui_message doaction_dialog_nonexistent_sequence
[] = {
8999 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9000 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "1"}, {0, 1, 1}},
9001 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"custom"}, {1}},
9002 {INSTALLMESSAGE_INFO
, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
9003 {INSTALLMESSAGE_INFO
, 2, {"", "2726", "custom"}, {0, 1, 1}},
9004 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "0"}, {0, 1, 1}},
9008 static const struct externalui_message doaction_dialog_sequence
[] = {
9009 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9010 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "0"}, {0, 1, 1}},
9011 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"dialog"}, {1}},
9012 {INSTALLMESSAGE_ACTIONSTART
, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
9013 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "1"}, {0, 1, 1}},
9017 static const struct externalui_message doaction_dialog_error_sequence
[] = {
9018 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
9019 {INSTALLMESSAGE_INFO
, 2, {"", "error", "1"}, {0, 1, 1}},
9020 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"error"}, {1}},
9024 static const struct externalui_message doaction_dialog_3_sequence
[] = {
9025 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9026 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "0"}, {0, 1, 1}},
9027 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"dialog"}, {1}},
9028 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "3"}, {0, 1, 1}},
9032 static const struct externalui_message doaction_dialog_12345_sequence
[] = {
9033 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9034 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "3"}, {0, 1, 1}},
9035 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"dialog"}, {1}},
9036 {INSTALLMESSAGE_INFO
, 2, {"", "dialog", "12345"}, {0, 1, 1}},
9040 static const struct externalui_message closehandle_sequence
[] = {
9041 {INSTALLMESSAGE_TERMINATE
, -1},
9045 static INT CALLBACK
externalui_message_string_callback(void *context
, UINT message
, LPCSTR string
)
9047 INT retval
= context
? *((INT
*)context
) : 0;
9048 struct externalui_message msg
;
9050 msg
.message
= message
;
9051 msg
.field_count
= 0;
9052 strcpy(msg
.field
[0], string
);
9058 static INT CALLBACK
externalui_message_callback(void *context
, UINT message
, MSIHANDLE hrecord
)
9060 INT retval
= context
? *((INT
*)context
) : 0;
9061 struct externalui_message msg
;
9067 msg
.message
= message
;
9068 if (message
== INSTALLMESSAGE_TERMINATE
)
9070 /* trying to access the record seems to hang on some versions of Windows */
9071 msg
.field_count
= -1;
9075 msg
.field_count
= MsiRecordGetFieldCount(hrecord
);
9076 for (i
= 0; i
<= msg
.field_count
; i
++)
9078 length
= sizeof(buffer
);
9079 r
= MsiRecordGetStringA(hrecord
, i
, buffer
, &length
);
9080 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
9081 memcpy(msg
.field
[i
], buffer
, min(100, length
+1));
9084 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
9085 if (message
== (INSTALLMESSAGE_INFO
|MB_ICONHAND
) && msg
.field_count
> 0 && !strncmp(msg
.field
[0], "Property", 8))
9093 static void test_externalui_message(void)
9095 /* test that events trigger the correct sequence of messages */
9097 INSTALLUI_HANDLER_RECORD prev
;
9098 MSIHANDLE hdb
, hpkg
, hrecord
;
9102 MsiSetInternalUI(INSTALLUILEVEL_FULL
, NULL
);
9104 MsiSetExternalUIA(externalui_message_string_callback
, INSTALLLOGMODE_SHOWDIALOG
, &retval
);
9105 r
= MsiSetExternalUIRecord(externalui_message_callback
, MSITEST_INSTALLLOGMODE
, &retval
, &prev
);
9111 hdb
= create_package_db();
9112 ok(hdb
, "failed to create database\n");
9114 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9115 r
= MsiDatabaseImportA(hdb
, CURR_DIR
, "forcecodepage.idt");
9116 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9118 r
= run_query(hdb
, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9119 ok(r
== ERROR_SUCCESS
, "Failed to create Error table: %u\n", r
);
9120 r
= run_query(hdb
, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9121 ok(r
== ERROR_SUCCESS
, "Failed to insert into Error table: %u\n", r
);
9123 create_actiontext_table(hdb
);
9124 add_actiontext_entry(hdb
, "'custom', 'description', 'template'");
9125 add_actiontext_entry(hdb
, "'CostInitialize', 'cost description', 'cost template'");
9127 r
= MsiOpenPackageA(NULL
, &hpkg
);
9128 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
9129 ok_sequence(empty_sequence
, "MsiOpenPackage with NULL db", FALSE
);
9131 r
= MsiOpenPackageA("nonexistent", &hpkg
);
9132 ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r
);
9133 ok_sequence(openpackage_nonexistent_sequence
, "MsiOpenPackage with nonexistent db", FALSE
);
9135 r
= package_from_db(hdb
, &hpkg
);
9136 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
9138 skip("Not enough rights to perform tests\n");
9139 DeleteFileA(msifile
);
9142 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
9143 ok_sequence(openpackage_sequence
, "MsiOpenPackage with valid db", FALSE
);
9145 /* Test MsiProcessMessage */
9146 hrecord
= MsiCreateRecord(3);
9147 ok(hrecord
, "failed to create record\n");
9149 MsiRecordSetStringA(hrecord
, 0, "zero");
9150 MsiRecordSetStringA(hrecord
, 1, "one");
9151 MsiRecordSetStringA(hrecord
, 2, "two");
9152 MsiRecordSetStringA(hrecord
, 3, "three");
9153 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_INFO
, hrecord
);
9154 ok(r
== 1, "Expected 1, got %d\n", r
);
9155 ok_sequence(processmessage_info_sequence
, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE
);
9157 MsiRecordSetStringA(hrecord
, 1, "name");
9158 MsiRecordSetStringA(hrecord
, 2, "description");
9159 MsiRecordSetStringA(hrecord
, 3, "template");
9160 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_ACTIONSTART
, hrecord
);
9161 ok(r
== 1, "Expected 1, got %d\n", r
);
9162 ok_sequence(processmessage_actionstart_sequence
, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE
);
9164 MsiRecordSetStringA(hrecord
, 0, "apple");
9165 MsiRecordSetStringA(hrecord
, 1, "cherry");
9166 MsiRecordSetStringA(hrecord
, 2, "banana");
9167 MsiRecordSetStringA(hrecord
, 3, "guava");
9168 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_ACTIONDATA
, hrecord
);
9169 ok(r
== 1, "Expected 1, got %d\n", r
);
9170 ok_sequence(processmessage_actiondata_sequence
, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE
);
9172 /* non-internal error */
9173 MsiRecordSetStringA(hrecord
, 0, NULL
);
9174 MsiRecordSetInteger(hrecord
, 1, 1311);
9175 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
9176 ok(r
== 1, "Expected 1, got %d\n", r
);
9177 ok_sequence(processmessage_error_sequence
, "MsiProcessMessage non-internal error", FALSE
);
9179 /* internal error */
9180 MsiRecordSetStringA(hrecord
, 0, NULL
);
9181 MsiRecordSetInteger(hrecord
, 1, 2726);
9182 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
9183 ok(r
== 0, "Expected 0, got %d\n", r
);
9184 ok_sequence(processmessage_internal_error_sequence
, "MsiProcessMessage internal error", FALSE
);
9186 /* with format field */
9187 MsiRecordSetStringA(hrecord
, 0, "starfruit");
9188 r
= MsiProcessMessage(hpkg
, INSTALLMESSAGE_USER
, hrecord
);
9189 ok(r
== 1, "Expected 1, got %d\n", r
);
9190 ok_sequence(processmessage_error_format_sequence
, "MsiProcessMessage error", FALSE
);
9192 /* Test a standard action */
9193 r
= MsiDoActionA(hpkg
, "CostInitialize");
9194 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9195 ok_sequence(doaction_costinitialize_sequence
, "MsiDoAction(\"CostInitialize\")", FALSE
);
9197 /* Test a custom action */
9198 r
= MsiDoActionA(hpkg
, "custom");
9199 ok(r
== ERROR_FUNCTION_NOT_CALLED
, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r
);
9200 ok_sequence(doaction_custom_sequence
, "MsiDoAction(\"custom\")", FALSE
);
9202 /* close the package */
9203 MsiCloseHandle(hpkg
);
9204 ok_sequence(closehandle_sequence
, "MsiCloseHandle()", FALSE
);
9207 hdb
= create_package_db();
9208 ok(hdb
, "failed to create database\n");
9210 r
= MsiDatabaseImportA(hdb
, CURR_DIR
, "forcecodepage.idt");
9211 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9213 create_dialog_table(hdb
);
9214 add_dialog_entry(hdb
, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9216 create_control_table(hdb
);
9217 add_control_entry(hdb
, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9219 r
= package_from_db(hdb
, &hpkg
);
9220 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
9221 ok_sequence(openpackage_sequence
, "MsiOpenPackage with valid db", FALSE
);
9223 /* Test a custom action */
9224 r
= MsiDoActionA(hpkg
, "custom");
9225 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9226 ok_sequence(doaction_custom_fullui_sequence
, "MsiDoAction(\"custom\")", FALSE
);
9229 r
= MsiDoActionA(hpkg
, "custom");
9230 ok(r
== ERROR_INSTALL_USEREXIT
, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r
);
9231 ok_sequence(doaction_custom_cancel_sequence
, "MsiDoAction(\"custom\")", FALSE
);
9234 r
= MsiDoActionA(hpkg
, "custom");
9235 ok(r
== ERROR_FUNCTION_NOT_CALLED
, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r
);
9236 ok_sequence(doaction_dialog_nonexistent_sequence
, "MsiDoAction(\"custom\")", FALSE
);
9238 r
= MsiDoActionA(hpkg
, "dialog");
9239 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9240 ok_sequence(doaction_dialog_sequence
, "MsiDoAction(\"dialog\")", FALSE
);
9243 r
= MsiDoActionA(hpkg
, "error");
9244 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9245 ok_sequence(doaction_dialog_error_sequence
, "MsiDoAction(\"error\")", FALSE
);
9247 r
= MsiDoActionA(hpkg
, "error");
9248 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9249 ok_sequence(doaction_dialog_error_sequence
, "MsiDoAction(\"error\")", FALSE
);
9252 r
= MsiDoActionA(hpkg
, "custom");
9253 ok(r
== ERROR_FUNCTION_NOT_CALLED
, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r
);
9254 ok_sequence(doaction_dialog_nonexistent_sequence
, "MsiDoAction(\"custom\")", FALSE
);
9257 r
= MsiDoActionA(hpkg
, "dialog");
9258 ok(r
== ERROR_INSTALL_FAILURE
, "Expected ERROR_INSTALL_FAILURE, got %d\n", r
);
9259 ok_sequence(doaction_dialog_3_sequence
, "MsiDoAction(\"dialog\")", FALSE
);
9262 r
= MsiDoActionA(hpkg
, "dialog");
9263 ok(r
== ERROR_FUNCTION_FAILED
, "Expected ERROR_INSTALL_FAILURE, got %d\n", r
);
9264 ok_sequence(doaction_dialog_12345_sequence
, "MsiDoAction(\"dialog\")", FALSE
);
9266 MsiCloseHandle(hpkg
);
9267 ok_sequence(closehandle_sequence
, "MsiCloseHandle()", FALSE
);
9269 MsiCloseHandle(hrecord
);
9271 DeleteFileA(msifile
);
9272 DeleteFileA("forcecodepage.idt");
9275 static const struct externalui_message controlevent_spawn_sequence
[] = {
9276 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9277 {INSTALLMESSAGE_INFO
, 2, {"", "spawn", ""}, {0, 1, 1}},
9278 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"spawn"}, {1}},
9279 {INSTALLMESSAGE_ACTIONSTART
, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9281 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9282 {INSTALLMESSAGE_INFO
, 2, {"", "custom", ""}, {0, 1, 1}},
9283 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "1"}, {0, 1, 1}},
9285 {INSTALLMESSAGE_ACTIONSTART
, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9287 {INSTALLMESSAGE_INFO
, 2, {"", "spawn", "2"}, {0, 1, 1}},
9291 static const struct externalui_message controlevent_spawn2_sequence
[] = {
9292 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9293 {INSTALLMESSAGE_INFO
, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9294 {INSTALLMESSAGE_SHOWDIALOG
, 0, {"spawn2"}, {1}},
9295 {INSTALLMESSAGE_ACTIONSTART
, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9297 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9298 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "2"}, {0, 1, 1}},
9299 {INSTALLMESSAGE_INFO
, 2, {"", "custom", "1"}, {0, 1, 1}},
9301 {INSTALLMESSAGE_ACTIONSTART
, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9303 {INSTALLMESSAGE_INFO
, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9307 static void test_controlevent(void)
9309 INSTALLUI_HANDLER_RECORD prev
;
9310 MSIHANDLE hdb
, hpkg
;
9313 if (!winetest_interactive
)
9315 skip("interactive ControlEvent tests\n");
9319 MsiSetInternalUI(INSTALLUILEVEL_FULL
, NULL
);
9321 MsiSetExternalUIA(externalui_message_string_callback
, INSTALLLOGMODE_SHOWDIALOG
, NULL
);
9322 r
= MsiSetExternalUIRecord(externalui_message_callback
, MSITEST_INSTALLLOGMODE
, NULL
, &prev
);
9328 hdb
= create_package_db();
9329 ok(hdb
, "failed to create database\n");
9331 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9332 r
= MsiDatabaseImportA(hdb
, CURR_DIR
, "forcecodepage.idt");
9333 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9335 create_dialog_table(hdb
);
9336 add_dialog_entry(hdb
, "'spawn', 50, 50, 100, 100, 3, 'button'");
9337 add_dialog_entry(hdb
, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9338 add_dialog_entry(hdb
, "'child1', 50, 50, 80, 40, 3, 'exit'");
9339 add_dialog_entry(hdb
, "'child2', 50, 50, 80, 40, 3, 'exit'");
9341 create_control_table(hdb
);
9342 add_control_entry(hdb
, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9343 add_control_entry(hdb
, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9344 add_control_entry(hdb
, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9345 add_control_entry(hdb
, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9347 create_controlevent_table(hdb
);
9348 add_controlevent_entry(hdb
, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9349 add_controlevent_entry(hdb
, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9351 create_custom_action_table(hdb
);
9352 add_custom_action_entry(hdb
, "'custom', 51, 'dummy', 'dummy value'");
9354 /* SpawnDialog and EndDialog should trigger after all other events */
9355 add_controlevent_entry(hdb
, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9356 add_controlevent_entry(hdb
, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9358 /* Multiple dialog events cause only the last one to be triggered */
9359 add_controlevent_entry(hdb
, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9360 add_controlevent_entry(hdb
, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9361 add_controlevent_entry(hdb
, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9363 r
= package_from_db(hdb
, &hpkg
);
9364 ok(r
== ERROR_SUCCESS
, "failed to create package: %u\n", r
);
9365 ok_sequence(openpackage_sequence
, "MsiOpenPackage()", FALSE
);
9367 r
= MsiDoActionA(hpkg
, "spawn");
9368 ok(r
== ERROR_INSTALL_USEREXIT
, "expected ERROR_INSTALL_USEREXIT, got %u\n", r
);
9369 ok_sequence(controlevent_spawn_sequence
, "control event: spawn", FALSE
);
9371 r
= MsiDoActionA(hpkg
, "spawn2");
9372 ok(r
== ERROR_INSTALL_USEREXIT
, "expected ERROR_INSTALL_USEREXIT, got %u\n", r
);
9373 ok_sequence(controlevent_spawn2_sequence
, "control event: spawn2", FALSE
);
9375 MsiCloseHandle(hpkg
);
9376 ok_sequence(closehandle_sequence
, "MsiCloseHandle()", FALSE
);
9379 DeleteFileA(msifile
);
9380 DeleteFileA("forcecodepage.idt");
9383 static const struct externalui_message toplevel_install_sequence
[] = {
9384 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9385 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9387 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9388 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9389 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
9390 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9391 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9393 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9394 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9395 {INSTALLMESSAGE_INSTALLSTART
, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9397 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9398 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9399 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9401 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9402 {INSTALLMESSAGE_INFO
, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9403 {INSTALLMESSAGE_INFO
, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9405 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9406 {INSTALLMESSAGE_INFO
, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9407 {INSTALLMESSAGE_INFO
, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9409 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9410 {INSTALLMESSAGE_INSTALLEND
, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9414 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9415 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9416 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9420 static const struct externalui_message toplevel_install_ui_sequence
[] = {
9421 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9422 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9424 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9425 {INSTALLMESSAGE_INFO
, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9426 {INSTALLMESSAGE_INFO
, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9428 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9432 static const struct externalui_message toplevel_executeaction_install_sequence
[] = {
9433 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9434 {INSTALLMESSAGE_INFO
, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9436 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9437 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9438 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9439 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9441 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9442 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9443 {INSTALLMESSAGE_INSTALLSTART
, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9445 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9446 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize"}, {0, 1}},
9447 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9449 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9450 {INSTALLMESSAGE_INFO
, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9451 {INSTALLMESSAGE_INFO
, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9453 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9454 {INSTALLMESSAGE_INFO
, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9455 {INSTALLMESSAGE_INFO
, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9457 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9458 {INSTALLMESSAGE_INSTALLEND
, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9462 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9463 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9464 {INSTALLMESSAGE_INFO
, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9468 static const struct externalui_message toplevel_executeaction_costinitialize_sequence
[] = {
9469 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9470 {INSTALLMESSAGE_INFO
, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9472 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9473 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9474 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9475 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9477 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9478 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", ""}, {0, 1}},
9479 {INSTALLMESSAGE_INFO
, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9483 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9484 {INSTALLMESSAGE_COMMONDATA
, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9485 {INSTALLMESSAGE_INFO
, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9489 static const struct externalui_message toplevel_msiinstallproduct_sequence
[] = {
9490 {INSTALLMESSAGE_INITIALIZE
, -1},
9492 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9493 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9494 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
9495 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9496 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9498 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9499 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9501 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9502 {INSTALLMESSAGE_INFO
, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9503 {INSTALLMESSAGE_INFO
, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9505 {INSTALLMESSAGE_INFO
, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9509 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
9510 {INSTALLMESSAGE_TERMINATE
, -1},
9514 static const struct externalui_message toplevel_msiinstallproduct_custom_sequence
[] = {
9515 {INSTALLMESSAGE_INITIALIZE
, -1},
9517 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9518 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9519 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
9520 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9521 {INSTALLMESSAGE_COMMONDATA
, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9523 {INSTALLMESSAGE_ACTIONSTART
, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9524 {INSTALLMESSAGE_INFO
, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9525 {INSTALLMESSAGE_INFO
, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9529 {INSTALLMESSAGE_INFO
|MB_ICONHAND
, 0, {""}, {0}},
9530 {INSTALLMESSAGE_TERMINATE
, -1},
9534 /* tests involving top-level actions: INSTALL, ExecuteAction */
9535 static void test_top_level_action(void)
9537 INSTALLUI_HANDLER_RECORD prev
;
9538 MSIHANDLE hdb
, hpkg
;
9540 char msifile_absolute
[MAX_PATH
];
9542 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
9544 MsiSetExternalUIA(externalui_message_string_callback
, INSTALLLOGMODE_SHOWDIALOG
, NULL
);
9545 r
= MsiSetExternalUIRecord(externalui_message_callback
, MSITEST_INSTALLLOGMODE
, NULL
, &prev
);
9551 hdb
= create_package_db();
9552 ok(hdb
, "failed to create database\n");
9554 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9555 r
= MsiDatabaseImportA(hdb
, CURR_DIR
, "forcecodepage.idt");
9556 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
9558 create_property_table(hdb
);
9559 add_property_entry(hdb
, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9561 create_install_execute_sequence_table(hdb
);
9562 add_install_execute_sequence_entry(hdb
, "'CostInitialize', '', 1");
9563 add_install_execute_sequence_entry(hdb
, "'FileCost', '', 2");
9564 add_install_execute_sequence_entry(hdb
, "'CostFinalize', '', 3");
9566 create_install_ui_sequence_table(hdb
);
9567 add_install_ui_sequence_entry(hdb
, "'AppSearch', '', 1");
9569 MsiDatabaseCommit(hdb
);
9571 /* for some reason we have to open the package from file using an absolute path */
9572 MsiCloseHandle(hdb
);
9573 GetFullPathNameA(msifile
, MAX_PATH
, msifile_absolute
, NULL
);
9574 r
= MsiOpenPackageA(msifile_absolute
, &hpkg
);
9575 ok(r
== ERROR_SUCCESS
, "failed to create package: %u\n", r
);
9576 ok_sequence(openpackage_sequence
, "MsiOpenPackage()", FALSE
);
9579 r
= MsiDoActionA(hpkg
, "INSTALL");
9580 ok(r
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", r
);
9581 ok_sequence(toplevel_install_sequence
, "INSTALL (no UI)", FALSE
);
9583 /* test INSTALL with reduced+ UI */
9584 /* for some reason we need to re-open the package to change the internal UI */
9585 MsiCloseHandle(hpkg
);
9586 ok_sequence(closehandle_sequence
, "MsiCloseHandle()", FALSE
);
9587 MsiSetInternalUI(INSTALLUILEVEL_REDUCED
, NULL
);
9588 r
= MsiOpenPackageA(msifile_absolute
, &hpkg
);
9589 ok(r
== ERROR_SUCCESS
, "failed to create package: %u\n", r
);
9590 ok_sequence(openpackage_sequence
, "MsiOpenPackage()", FALSE
);
9592 r
= MsiDoActionA(hpkg
, "INSTALL");
9593 ok(r
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", r
);
9594 ok_sequence(toplevel_install_ui_sequence
, "INSTALL (reduced+ UI)", TRUE
);
9596 /* test ExecuteAction with EXECUTEACTION property unset */
9597 MsiSetPropertyA(hpkg
, "EXECUTEACTION", NULL
);
9598 r
= MsiDoActionA(hpkg
, "ExecuteAction");
9599 ok(r
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", r
);
9600 ok_sequence(toplevel_executeaction_install_sequence
, "ExecuteAction: INSTALL", FALSE
);
9602 /* test ExecuteAction with EXECUTEACTION property set */
9603 MsiSetPropertyA(hpkg
, "EXECUTEACTION", "CostInitialize");
9604 r
= MsiDoActionA(hpkg
, "ExecuteAction");
9605 ok(r
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", r
);
9606 ok_sequence(toplevel_executeaction_costinitialize_sequence
, "ExecuteAction: CostInitialize", FALSE
);
9608 MsiCloseHandle(hpkg
);
9609 ok_sequence(closehandle_sequence
, "MsiCloseHandle()", FALSE
);
9611 /* test MsiInstallProduct() */
9612 r
= MsiInstallProductA(msifile_absolute
, NULL
);
9613 ok(r
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", r
);
9614 ok_sequence(toplevel_msiinstallproduct_sequence
, "MsiInstallProduct()", TRUE
);
9616 r
= MsiInstallProductA(msifile_absolute
, "ACTION=custom");
9618 ok(r
== ERROR_INSTALL_FAILURE
, "expected ERROR_INSTALL_FAILURE, got %u\n", r
);
9619 ok_sequence(toplevel_msiinstallproduct_custom_sequence
, "MsiInstallProduct(ACTION=custom)", TRUE
);
9622 DeleteFileA(msifile
);
9623 DeleteFileA("forcecodepage.idt");
9628 char temp_path
[MAX_PATH
], prev_path
[MAX_PATH
];
9629 STATEMGRSTATUS status
;
9633 init_functionpointers();
9635 if (pIsWow64Process
)
9636 pIsWow64Process(GetCurrentProcess(), &is_wow64
);
9638 GetCurrentDirectoryA(MAX_PATH
, prev_path
);
9639 GetTempPathA(MAX_PATH
, temp_path
);
9640 SetCurrentDirectoryA(temp_path
);
9642 lstrcpyA(CURR_DIR
, temp_path
);
9643 len
= lstrlenA(CURR_DIR
);
9645 if (len
&& (CURR_DIR
[len
- 1] == '\\'))
9646 CURR_DIR
[len
- 1] = 0;
9648 /* Create a restore point ourselves so we circumvent the multitude of restore points
9649 * that would have been created by all the installation and removal tests.
9651 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
9652 * creation of restore points.
9654 if (pSRSetRestorePointA
&& !pMsiGetComponentPathExA
)
9656 memset(&status
, 0, sizeof(status
));
9657 ret
= notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE
, &status
);
9660 test_createpackage();
9662 test_gettargetpath_bad();
9663 test_settargetpath();
9665 test_property_table();
9668 test_formatrecord2();
9669 test_formatrecord_tables();
9673 test_appsearch_complocator();
9674 test_appsearch_reglocator();
9675 test_appsearch_inilocator();
9676 test_appsearch_drlocator();
9677 test_featureparents();
9678 test_installprops();
9679 test_launchconditions();
9682 test_MsiGetSourcePath();
9683 test_shortlongsource();
9686 test_emptypackage();
9687 test_MsiGetProductProperty();
9688 test_MsiSetProperty();
9689 test_MsiApplyMultiplePatches();
9690 test_MsiApplyPatch();
9692 test_MsiDatabaseCommit();
9694 test_externalui_message();
9695 test_controlevent();
9696 test_top_level_action();
9698 if (pSRSetRestorePointA
&& !pMsiGetComponentPathExA
&& ret
)
9700 ret
= notify_system_change(END_NESTED_SYSTEM_CHANGE
, &status
);
9702 remove_restore_point(status
.llSequenceNumber
);
9705 SetCurrentDirectoryA(prev_path
);