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
29 #include <srrestoreptapi.h>
32 #include "wine/test.h"
35 static const char msifile
[] = "winetest-package.msi";
36 static const WCHAR msifileW
[] =
37 {'w','i','n','e','t','e','s','t','-','p','a','c','k','a','g','e','.','m','s','i',0};
38 static char CURR_DIR
[MAX_PATH
];
40 static UINT (WINAPI
*pMsiApplyMultiplePatchesA
)(LPCSTR
, LPCSTR
, LPCSTR
);
41 static INSTALLSTATE (WINAPI
*pMsiGetComponentPathExA
)(LPCSTR
, LPCSTR
, LPCSTR
, MSIINSTALLCONTEXT
, LPSTR
, LPDWORD
);
42 static HRESULT (WINAPI
*pSHGetFolderPathA
)(HWND
, int, HANDLE
, DWORD
, LPSTR
);
44 static BOOL (WINAPI
*pCheckTokenMembership
)(HANDLE
,PSID
,PBOOL
);
45 static BOOL (WINAPI
*pConvertSidToStringSidA
)(PSID
, LPSTR
*);
46 static BOOL (WINAPI
*pOpenProcessToken
)( HANDLE
, DWORD
, PHANDLE
);
47 static LONG (WINAPI
*pRegDeleteKeyExA
)(HKEY
, LPCSTR
, REGSAM
, DWORD
);
48 static LONG (WINAPI
*pRegDeleteKeyExW
)(HKEY
, LPCWSTR
, REGSAM
, DWORD
);
49 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
50 static void (WINAPI
*pGetSystemInfo
)(LPSYSTEM_INFO
);
51 static void (WINAPI
*pGetNativeSystemInfo
)(LPSYSTEM_INFO
);
52 static UINT (WINAPI
*pGetSystemWow64DirectoryA
)(LPSTR
, UINT
);
54 static BOOL (WINAPI
*pSRRemoveRestorePoint
)(DWORD
);
55 static BOOL (WINAPI
*pSRSetRestorePointA
)(RESTOREPOINTINFOA
*, STATEMGRSTATUS
*);
57 static void init_functionpointers(void)
59 HMODULE hmsi
= GetModuleHandleA("msi.dll");
60 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
61 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
62 HMODULE hshell32
= GetModuleHandleA("shell32.dll");
65 #define GET_PROC(mod, func) \
66 p ## func = (void*)GetProcAddress(mod, #func);
68 GET_PROC(hmsi
, MsiApplyMultiplePatchesA
);
69 GET_PROC(hmsi
, MsiGetComponentPathExA
);
70 GET_PROC(hshell32
, SHGetFolderPathA
);
72 GET_PROC(hadvapi32
, CheckTokenMembership
);
73 GET_PROC(hadvapi32
, ConvertSidToStringSidA
);
74 GET_PROC(hadvapi32
, OpenProcessToken
);
75 GET_PROC(hadvapi32
, RegDeleteKeyExA
)
76 GET_PROC(hadvapi32
, RegDeleteKeyExW
)
77 GET_PROC(hkernel32
, IsWow64Process
)
78 GET_PROC(hkernel32
, GetNativeSystemInfo
)
79 GET_PROC(hkernel32
, GetSystemInfo
)
80 GET_PROC(hkernel32
, GetSystemWow64DirectoryA
)
82 hsrclient
= LoadLibraryA("srclient.dll");
83 GET_PROC(hsrclient
, SRRemoveRestorePoint
);
84 GET_PROC(hsrclient
, SRSetRestorePointA
);
88 static BOOL
is_process_limited(void)
90 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
95 if (!pCheckTokenMembership
|| !pOpenProcessToken
) return FALSE
;
97 if (!AllocateAndInitializeSid(&NtAuthority
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
98 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &Group
) ||
99 !pCheckTokenMembership(NULL
, Group
, &IsInGroup
))
101 trace("Could not check if the current user is an administrator\n");
109 if (!AllocateAndInitializeSid(&NtAuthority
, 2,
110 SECURITY_BUILTIN_DOMAIN_RID
,
111 DOMAIN_ALIAS_RID_POWER_USERS
,
112 0, 0, 0, 0, 0, 0, &Group
) ||
113 !pCheckTokenMembership(NULL
, Group
, &IsInGroup
))
115 trace("Could not check if the current user is a power user\n");
120 /* Only administrators and power users can be powerful */
125 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
))
128 TOKEN_ELEVATION_TYPE type
= TokenElevationTypeDefault
;
131 ret
= GetTokenInformation(token
, TokenElevationType
, &type
, sizeof(type
), &size
);
133 return (ret
&& type
== TokenElevationTypeLimited
);
138 static LONG
delete_key( HKEY key
, LPCSTR subkey
, REGSAM access
)
140 if (pRegDeleteKeyExA
)
141 return pRegDeleteKeyExA( key
, subkey
, access
, 0 );
142 return RegDeleteKeyA( key
, subkey
);
145 static char *get_user_sid(void)
150 char *usersid
= NULL
;
152 if (!pConvertSidToStringSidA
)
154 win_skip("ConvertSidToStringSidA is not available\n");
157 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
);
158 GetTokenInformation(token
, TokenUser
, NULL
, size
, &size
);
160 user
= HeapAlloc(GetProcessHeap(), 0, size
);
161 GetTokenInformation(token
, TokenUser
, user
, size
, &size
);
162 pConvertSidToStringSidA(user
->User
.Sid
, &usersid
);
163 HeapFree(GetProcessHeap(), 0, user
);
169 /* RegDeleteTreeW from dlls/advapi32/registry.c */
170 static LSTATUS
package_RegDeleteTreeW(HKEY hKey
, LPCWSTR lpszSubKey
, REGSAM access
)
173 DWORD dwMaxSubkeyLen
, dwMaxValueLen
;
174 DWORD dwMaxLen
, dwSize
;
175 WCHAR szNameBuf
[MAX_PATH
], *lpszName
= szNameBuf
;
180 ret
= RegOpenKeyExW(hKey
, lpszSubKey
, 0, access
, &hSubKey
);
184 ret
= RegQueryInfoKeyW(hSubKey
, NULL
, NULL
, NULL
, NULL
,
185 &dwMaxSubkeyLen
, NULL
, NULL
, &dwMaxValueLen
, NULL
, NULL
, NULL
);
186 if (ret
) goto cleanup
;
190 dwMaxLen
= max(dwMaxSubkeyLen
, dwMaxValueLen
);
191 if (dwMaxLen
> sizeof(szNameBuf
)/sizeof(WCHAR
))
193 /* Name too big: alloc a buffer for it */
194 if (!(lpszName
= HeapAlloc( GetProcessHeap(), 0, dwMaxLen
*sizeof(WCHAR
))))
196 ret
= ERROR_NOT_ENOUGH_MEMORY
;
201 /* Recursively delete all the subkeys */
205 if (RegEnumKeyExW(hSubKey
, 0, lpszName
, &dwSize
, NULL
,
206 NULL
, NULL
, NULL
)) break;
208 ret
= package_RegDeleteTreeW(hSubKey
, lpszName
, access
);
209 if (ret
) goto cleanup
;
214 if (pRegDeleteKeyExW
)
215 ret
= pRegDeleteKeyExW(hKey
, lpszSubKey
, access
, 0);
217 ret
= RegDeleteKeyW(hKey
, lpszSubKey
);
223 if (RegEnumValueW(hKey
, 0, lpszName
, &dwSize
,
224 NULL
, NULL
, NULL
, NULL
)) break;
226 ret
= RegDeleteValueW(hKey
, lpszName
);
227 if (ret
) goto cleanup
;
231 if (lpszName
!= szNameBuf
)
232 HeapFree(GetProcessHeap(), 0, lpszName
);
234 RegCloseKey(hSubKey
);
238 static BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
243 if (FAILED(CLSIDFromString((LPCOLESTR
)in
, &guid
)))
257 out
[17+i
*2] = in
[n
++];
258 out
[16+i
*2] = in
[n
++];
263 out
[17+i
*2] = in
[n
++];
264 out
[16+i
*2] = in
[n
++];
270 static void create_test_guid(LPSTR prodcode
, LPSTR squashed
)
272 WCHAR guidW
[MAX_PATH
];
273 WCHAR squashedW
[MAX_PATH
];
278 hr
= CoCreateGuid(&guid
);
279 ok(hr
== S_OK
, "Expected S_OK, got %d\n", hr
);
281 size
= StringFromGUID2(&guid
, guidW
, MAX_PATH
);
282 ok(size
== 39, "Expected 39, got %d\n", hr
);
284 WideCharToMultiByte(CP_ACP
, 0, guidW
, size
, prodcode
, MAX_PATH
, NULL
, NULL
);
285 squash_guid(guidW
, squashedW
);
286 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
289 static void set_component_path(LPCSTR filename
, MSIINSTALLCONTEXT context
,
290 LPCSTR guid
, LPSTR usersid
, BOOL dir
)
292 WCHAR guidW
[MAX_PATH
];
293 WCHAR squashedW
[MAX_PATH
];
294 CHAR squashed
[MAX_PATH
];
295 CHAR comppath
[MAX_PATH
];
296 CHAR prodpath
[MAX_PATH
];
300 REGSAM access
= KEY_ALL_ACCESS
;
303 access
|= KEY_WOW64_64KEY
;
305 MultiByteToWideChar(CP_ACP
, 0, guid
, -1, guidW
, MAX_PATH
);
306 squash_guid(guidW
, squashedW
);
307 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
309 if (context
== MSIINSTALLCONTEXT_MACHINE
)
311 prod
= "3D0DAE300FACA1300AD792060BCDAA92";
313 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
314 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed
);
316 "SOFTWARE\\Classes\\Installer\\"
317 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
319 else if (context
== MSIINSTALLCONTEXT_USERUNMANAGED
)
321 prod
= "7D2F387510109040002000060BECB6AB";
323 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
324 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
326 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
327 "Installer\\%s\\Installer\\Products\\"
328 "7D2F387510109040002000060BECB6AB", usersid
);
330 else if (context
== MSIINSTALLCONTEXT_USERMANAGED
)
332 prod
= "7D2F387510109040002000060BECB6AB";
334 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
335 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
337 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
338 "Installer\\Managed\\%s\\Installer\\Products\\"
339 "7D2F387510109040002000060BECB6AB", usersid
);
342 RegCreateKeyExA(HKEY_LOCAL_MACHINE
, comppath
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
);
344 lstrcpyA(path
, CURR_DIR
);
345 lstrcatA(path
, "\\");
346 if (!dir
) lstrcatA(path
, filename
);
348 RegSetValueExA(hkey
, prod
, 0, REG_SZ
, (LPBYTE
)path
, lstrlenA(path
));
351 RegCreateKeyExA(HKEY_LOCAL_MACHINE
, prodpath
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
);
355 static void delete_component_path(LPCSTR guid
, MSIINSTALLCONTEXT context
, LPSTR usersid
)
357 WCHAR guidW
[MAX_PATH
];
358 WCHAR squashedW
[MAX_PATH
];
359 WCHAR substrW
[MAX_PATH
];
360 CHAR squashed
[MAX_PATH
];
361 CHAR comppath
[MAX_PATH
];
362 CHAR prodpath
[MAX_PATH
];
363 REGSAM access
= KEY_ALL_ACCESS
;
366 access
|= KEY_WOW64_64KEY
;
368 MultiByteToWideChar(CP_ACP
, 0, guid
, -1, guidW
, MAX_PATH
);
369 squash_guid(guidW
, squashedW
);
370 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
372 if (context
== MSIINSTALLCONTEXT_MACHINE
)
375 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
376 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed
);
378 "SOFTWARE\\Classes\\Installer\\"
379 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
381 else if (context
== MSIINSTALLCONTEXT_USERUNMANAGED
)
384 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
385 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
387 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
388 "Installer\\%s\\Installer\\Products\\"
389 "7D2F387510109040002000060BECB6AB", usersid
);
391 else if (context
== MSIINSTALLCONTEXT_USERMANAGED
)
394 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
395 "Installer\\UserData\\%s\\Components\\%s", usersid
, squashed
);
397 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
398 "Installer\\Managed\\%s\\Installer\\Products\\"
399 "7D2F387510109040002000060BECB6AB", usersid
);
402 MultiByteToWideChar(CP_ACP
, 0, comppath
, -1, substrW
, MAX_PATH
);
403 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE
, substrW
, access
);
405 MultiByteToWideChar(CP_ACP
, 0, prodpath
, -1, substrW
, MAX_PATH
);
406 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE
, substrW
, access
);
409 static UINT
do_query(MSIHANDLE hdb
, const char *query
, MSIHANDLE
*phrec
)
414 /* open a select query */
415 r
= MsiDatabaseOpenViewA(hdb
, query
, &hview
);
416 if (r
!= ERROR_SUCCESS
)
418 r
= MsiViewExecute(hview
, 0);
419 if (r
!= ERROR_SUCCESS
)
421 ret
= MsiViewFetch(hview
, phrec
);
422 r
= MsiViewClose(hview
);
423 if (r
!= ERROR_SUCCESS
)
425 r
= MsiCloseHandle(hview
);
426 if (r
!= ERROR_SUCCESS
)
431 static UINT
run_query( MSIHANDLE hdb
, const char *query
)
436 r
= MsiDatabaseOpenViewA(hdb
, query
, &hview
);
437 if( r
!= ERROR_SUCCESS
)
440 r
= MsiViewExecute(hview
, 0);
441 if( r
== ERROR_SUCCESS
)
442 r
= MsiViewClose(hview
);
443 MsiCloseHandle(hview
);
447 static UINT
create_component_table( MSIHANDLE hdb
)
449 return run_query( hdb
,
450 "CREATE TABLE `Component` ( "
451 "`Component` CHAR(72) NOT NULL, "
452 "`ComponentId` CHAR(38), "
453 "`Directory_` CHAR(72) NOT NULL, "
454 "`Attributes` SHORT NOT NULL, "
455 "`Condition` CHAR(255), "
456 "`KeyPath` CHAR(72) "
457 "PRIMARY KEY `Component`)" );
460 static UINT
create_feature_table( MSIHANDLE hdb
)
462 return run_query( hdb
,
463 "CREATE TABLE `Feature` ( "
464 "`Feature` CHAR(38) NOT NULL, "
465 "`Feature_Parent` CHAR(38), "
467 "`Description` CHAR(255), "
468 "`Display` SHORT NOT NULL, "
469 "`Level` SHORT NOT NULL, "
470 "`Directory_` CHAR(72), "
471 "`Attributes` SHORT NOT NULL "
472 "PRIMARY KEY `Feature`)" );
475 static UINT
create_feature_components_table( MSIHANDLE hdb
)
477 return run_query( hdb
,
478 "CREATE TABLE `FeatureComponents` ( "
479 "`Feature_` CHAR(38) NOT NULL, "
480 "`Component_` CHAR(72) NOT NULL "
481 "PRIMARY KEY `Feature_`, `Component_` )" );
484 static UINT
create_file_table( MSIHANDLE hdb
)
486 return run_query( hdb
,
487 "CREATE TABLE `File` ("
488 "`File` CHAR(72) NOT NULL, "
489 "`Component_` CHAR(72) NOT NULL, "
490 "`FileName` CHAR(255) NOT NULL, "
491 "`FileSize` LONG NOT NULL, "
492 "`Version` CHAR(72), "
493 "`Language` CHAR(20), "
494 "`Attributes` SHORT, "
495 "`Sequence` SHORT NOT NULL "
496 "PRIMARY KEY `File`)" );
499 static UINT
create_remove_file_table( MSIHANDLE hdb
)
501 return run_query( hdb
,
502 "CREATE TABLE `RemoveFile` ("
503 "`FileKey` CHAR(72) NOT NULL, "
504 "`Component_` CHAR(72) NOT NULL, "
505 "`FileName` CHAR(255) LOCALIZABLE, "
506 "`DirProperty` CHAR(72) NOT NULL, "
507 "`InstallMode` SHORT NOT NULL "
508 "PRIMARY KEY `FileKey`)" );
511 static UINT
create_appsearch_table( MSIHANDLE hdb
)
513 return run_query( hdb
,
514 "CREATE TABLE `AppSearch` ("
515 "`Property` CHAR(72) NOT NULL, "
516 "`Signature_` CHAR(72) NOT NULL "
517 "PRIMARY KEY `Property`, `Signature_`)" );
520 static UINT
create_reglocator_table( MSIHANDLE hdb
)
522 return run_query( hdb
,
523 "CREATE TABLE `RegLocator` ("
524 "`Signature_` CHAR(72) NOT NULL, "
525 "`Root` SHORT NOT NULL, "
526 "`Key` CHAR(255) NOT NULL, "
529 "PRIMARY KEY `Signature_`)" );
532 static UINT
create_signature_table( MSIHANDLE hdb
)
534 return run_query( hdb
,
535 "CREATE TABLE `Signature` ("
536 "`Signature` CHAR(72) NOT NULL, "
537 "`FileName` CHAR(255) NOT NULL, "
538 "`MinVersion` CHAR(20), "
539 "`MaxVersion` CHAR(20), "
544 "`Languages` CHAR(255) "
545 "PRIMARY KEY `Signature`)" );
548 static UINT
create_launchcondition_table( MSIHANDLE hdb
)
550 return run_query( hdb
,
551 "CREATE TABLE `LaunchCondition` ("
552 "`Condition` CHAR(255) NOT NULL, "
553 "`Description` CHAR(255) NOT NULL "
554 "PRIMARY KEY `Condition`)" );
557 static UINT
create_property_table( MSIHANDLE hdb
)
559 return run_query( hdb
,
560 "CREATE TABLE `Property` ("
561 "`Property` CHAR(72) NOT NULL, "
563 "PRIMARY KEY `Property`)" );
566 static UINT
create_install_execute_sequence_table( MSIHANDLE hdb
)
568 return run_query( hdb
,
569 "CREATE TABLE `InstallExecuteSequence` ("
570 "`Action` CHAR(72) NOT NULL, "
571 "`Condition` CHAR(255), "
573 "PRIMARY KEY `Action`)" );
576 static UINT
create_media_table( MSIHANDLE hdb
)
578 return run_query( hdb
,
579 "CREATE TABLE `Media` ("
580 "`DiskId` SHORT NOT NULL, "
581 "`LastSequence` SHORT NOT NULL, "
582 "`DiskPrompt` CHAR(64), "
583 "`Cabinet` CHAR(255), "
584 "`VolumeLabel` CHAR(32), "
586 "PRIMARY KEY `DiskId`)" );
589 static UINT
create_ccpsearch_table( MSIHANDLE hdb
)
591 return run_query( hdb
,
592 "CREATE TABLE `CCPSearch` ("
593 "`Signature_` CHAR(72) NOT NULL "
594 "PRIMARY KEY `Signature_`)" );
597 static UINT
create_drlocator_table( MSIHANDLE hdb
)
599 return run_query( hdb
,
600 "CREATE TABLE `DrLocator` ("
601 "`Signature_` CHAR(72) NOT NULL, "
602 "`Parent` CHAR(72), "
605 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
608 static UINT
create_complocator_table( MSIHANDLE hdb
)
610 return run_query( hdb
,
611 "CREATE TABLE `CompLocator` ("
612 "`Signature_` CHAR(72) NOT NULL, "
613 "`ComponentId` CHAR(38) NOT NULL, "
615 "PRIMARY KEY `Signature_`)" );
618 static UINT
create_inilocator_table( MSIHANDLE hdb
)
620 return run_query( hdb
,
621 "CREATE TABLE `IniLocator` ("
622 "`Signature_` CHAR(72) NOT NULL, "
623 "`FileName` CHAR(255) NOT NULL, "
624 "`Section` CHAR(96)NOT NULL, "
625 "`Key` CHAR(128)NOT NULL, "
628 "PRIMARY KEY `Signature_`)" );
631 static UINT
create_custom_action_table( MSIHANDLE hdb
)
633 return run_query( hdb
,
634 "CREATE TABLE `CustomAction` ("
635 "`Action` CHAR(72) NOT NULL, "
636 "`Type` SHORT NOT NULL, "
637 "`Source` CHAR(75), "
638 "`Target` CHAR(255) "
639 "PRIMARY KEY `Action`)" );
642 #define make_add_entry(type, qtext) \
643 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
645 char insert[] = qtext; \
648 sz = strlen(values) + sizeof insert; \
649 query = HeapAlloc(GetProcessHeap(),0,sz); \
650 sprintf(query,insert,values); \
651 r = run_query( hdb, query ); \
652 HeapFree(GetProcessHeap(), 0, query); \
656 make_add_entry(component
,
657 "INSERT INTO `Component` "
658 "(`Component`, `ComponentId`, `Directory_`, "
659 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
661 make_add_entry(directory
,
662 "INSERT INTO `Directory` "
663 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
665 make_add_entry(feature
,
666 "INSERT INTO `Feature` "
667 "(`Feature`, `Feature_Parent`, `Title`, `Description`, "
668 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
670 make_add_entry(feature_components
,
671 "INSERT INTO `FeatureComponents` "
672 "(`Feature_`, `Component_`) VALUES( %s )")
675 "INSERT INTO `File` "
676 "(`File`, `Component_`, `FileName`, `FileSize`, "
677 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
679 make_add_entry(appsearch
,
680 "INSERT INTO `AppSearch` "
681 "(`Property`, `Signature_`) VALUES( %s )")
683 make_add_entry(signature
,
684 "INSERT INTO `Signature` "
685 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
686 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) "
689 make_add_entry(launchcondition
,
690 "INSERT INTO `LaunchCondition` "
691 "(`Condition`, `Description`) VALUES( %s )")
693 make_add_entry(property
,
694 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
696 make_add_entry(install_execute_sequence
,
697 "INSERT INTO `InstallExecuteSequence` "
698 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
700 make_add_entry(media
,
701 "INSERT INTO `Media` "
702 "(`DiskId`, `LastSequence`, `DiskPrompt`, "
703 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
705 make_add_entry(ccpsearch
,
706 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
708 make_add_entry(drlocator
,
709 "INSERT INTO `DrLocator` "
710 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
712 make_add_entry(complocator
,
713 "INSERT INTO `CompLocator` "
714 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
716 make_add_entry(inilocator
,
717 "INSERT INTO `IniLocator` "
718 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
721 make_add_entry(custom_action
,
722 "INSERT INTO `CustomAction` "
723 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
725 static UINT
add_reglocator_entry( MSIHANDLE hdb
, const char *sig
, UINT root
, const char *path
,
726 const char *name
, UINT type
)
728 const char insert
[] =
729 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
730 "VALUES( '%s', %u, '%s', '%s', %u )";
734 sz
= strlen( sig
) + 10 + strlen( path
) + strlen( name
) + 10 + sizeof( insert
);
735 query
= HeapAlloc( GetProcessHeap(), 0, sz
);
736 sprintf( query
, insert
, sig
, root
, path
, name
, type
);
737 r
= run_query( hdb
, query
);
738 HeapFree( GetProcessHeap(), 0, query
);
742 static UINT
set_summary_info(MSIHANDLE hdb
)
747 /* build summary info */
748 res
= MsiGetSummaryInformationA(hdb
, NULL
, 7, &suminfo
);
749 ok( res
== ERROR_SUCCESS
, "Failed to open summaryinfo\n" );
751 res
= MsiSummaryInfoSetPropertyA(suminfo
,2, VT_LPSTR
, 0,NULL
,
752 "Installation Database");
753 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
755 res
= MsiSummaryInfoSetPropertyA(suminfo
,3, VT_LPSTR
, 0,NULL
,
756 "Installation Database");
757 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
759 res
= MsiSummaryInfoSetPropertyA(suminfo
,4, VT_LPSTR
, 0,NULL
,
761 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
763 res
= MsiSummaryInfoSetPropertyA(suminfo
,7, VT_LPSTR
, 0,NULL
,
765 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
767 res
= MsiSummaryInfoSetPropertyA(suminfo
,9, VT_LPSTR
, 0,NULL
,
768 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
769 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
771 res
= MsiSummaryInfoSetPropertyA(suminfo
, 14, VT_I4
, 100, NULL
, NULL
);
772 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
774 res
= MsiSummaryInfoSetPropertyA(suminfo
, 15, VT_I4
, 0, NULL
, NULL
);
775 ok( res
== ERROR_SUCCESS
, "Failed to set summary info\n" );
777 res
= MsiSummaryInfoPersist(suminfo
);
778 ok( res
== ERROR_SUCCESS
, "Failed to make summary info persist\n" );
780 res
= MsiCloseHandle( suminfo
);
781 ok( res
== ERROR_SUCCESS
, "Failed to close suminfo\n" );
787 static MSIHANDLE
create_package_db(void)
792 DeleteFileA(msifile
);
794 /* create an empty database */
795 res
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
796 ok( res
== ERROR_SUCCESS
, "Failed to create database %u\n", res
);
797 if( res
!= ERROR_SUCCESS
)
800 res
= MsiDatabaseCommit( hdb
);
801 ok( res
== ERROR_SUCCESS
, "Failed to commit database\n" );
803 res
= set_summary_info(hdb
);
804 ok( res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", res
);
806 res
= run_query( hdb
,
807 "CREATE TABLE `Directory` ( "
808 "`Directory` CHAR(255) NOT NULL, "
809 "`Directory_Parent` CHAR(255), "
810 "`DefaultDir` CHAR(255) NOT NULL "
811 "PRIMARY KEY `Directory`)" );
812 ok( res
== ERROR_SUCCESS
, "Failed to create directory table\n" );
817 static UINT
package_from_db(MSIHANDLE hdb
, MSIHANDLE
*handle
)
823 sprintf(szPackage
, "#%u", hdb
);
824 res
= MsiOpenPackageA(szPackage
, &hPackage
);
825 if (res
!= ERROR_SUCCESS
)
831 res
= MsiCloseHandle(hdb
);
832 if (res
!= ERROR_SUCCESS
)
834 MsiCloseHandle(hPackage
);
839 return ERROR_SUCCESS
;
842 static void create_test_file(const CHAR
*name
)
847 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
848 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file %s\n", name
);
849 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
850 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
854 typedef struct _tagVS_VERSIONINFO
861 VS_FIXEDFILEINFO Value
;
866 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
867 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
869 static BOOL
create_file_with_version(const CHAR
*name
, LONG ms
, LONG ls
)
871 VS_VERSIONINFO
*pVerInfo
;
872 VS_FIXEDFILEINFO
*pFixedInfo
;
879 GetSystemDirectoryA(path
, MAX_PATH
);
880 /* Some dlls can't be updated on Vista/W2K8 */
881 lstrcatA(path
, "\\version.dll");
883 CopyFileA(path
, name
, FALSE
);
885 size
= GetFileVersionInfoSizeA(path
, &handle
);
886 buffer
= HeapAlloc(GetProcessHeap(), 0, size
);
888 GetFileVersionInfoA(path
, 0, size
, buffer
);
890 pVerInfo
= (VS_VERSIONINFO
*)buffer
;
891 ofs
= (BYTE
*)&pVerInfo
->szKey
[lstrlenW(pVerInfo
->szKey
) + 1];
892 pFixedInfo
= (VS_FIXEDFILEINFO
*)roundpos(pVerInfo
, ofs
, 4);
894 pFixedInfo
->dwFileVersionMS
= ms
;
895 pFixedInfo
->dwFileVersionLS
= ls
;
896 pFixedInfo
->dwProductVersionMS
= ms
;
897 pFixedInfo
->dwProductVersionLS
= ls
;
899 resource
= BeginUpdateResourceA(name
, FALSE
);
903 if (!UpdateResourceA(resource
, (LPCSTR
)RT_VERSION
, (LPCSTR
)MAKEINTRESOURCE(VS_VERSION_INFO
),
904 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), buffer
, size
))
907 if (!EndUpdateResourceA(resource
, FALSE
))
913 HeapFree(GetProcessHeap(), 0, buffer
);
917 static BOOL
notify_system_change(DWORD event_type
, STATEMGRSTATUS
*status
)
919 RESTOREPOINTINFOA spec
;
921 spec
.dwEventType
= event_type
;
922 spec
.dwRestorePtType
= APPLICATION_INSTALL
;
923 spec
.llSequenceNumber
= status
->llSequenceNumber
;
924 lstrcpyA(spec
.szDescription
, "msitest restore point");
926 return pSRSetRestorePointA(&spec
, status
);
929 static void remove_restore_point(DWORD seq_number
)
933 res
= pSRRemoveRestorePoint(seq_number
);
934 if (res
!= ERROR_SUCCESS
)
935 trace("Failed to remove the restore point : %08x\n", res
);
938 static BOOL
is_root(const char *path
)
940 return (isalpha(path
[0]) && path
[1] == ':' && path
[2] == '\\' && !path
[3]);
943 static void test_createpackage(void)
945 MSIHANDLE hPackage
= 0;
948 res
= package_from_db(create_package_db(), &hPackage
);
949 if (res
== ERROR_INSTALL_PACKAGE_REJECTED
)
951 skip("Not enough rights to perform tests\n");
952 DeleteFileA(msifile
);
955 ok( res
== ERROR_SUCCESS
, " Failed to create package %u\n", res
);
957 res
= MsiCloseHandle( hPackage
);
958 ok( res
== ERROR_SUCCESS
, "Failed to close package\n" );
959 DeleteFileA(msifile
);
962 static void test_doaction( void )
967 r
= MsiDoActionA( -1, NULL
);
968 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
970 r
= package_from_db(create_package_db(), &hpkg
);
971 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
973 skip("Not enough rights to perform tests\n");
974 DeleteFileA(msifile
);
977 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
979 r
= MsiDoActionA(hpkg
, NULL
);
980 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
982 r
= MsiDoActionA(0, "boo");
983 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
985 r
= MsiDoActionA(hpkg
, "boo");
986 ok( r
== ERROR_FUNCTION_NOT_CALLED
, "wrong return val\n");
988 MsiCloseHandle( hpkg
);
989 DeleteFileA(msifile
);
992 static void test_gettargetpath_bad(void)
994 static const WCHAR boo
[] = {'b','o','o',0};
995 static const WCHAR empty
[] = {0};
1002 r
= package_from_db(create_package_db(), &hpkg
);
1003 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1005 skip("Not enough rights to perform tests\n");
1006 DeleteFileA(msifile
);
1009 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1011 r
= MsiGetTargetPathA( 0, NULL
, NULL
, NULL
);
1012 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1014 r
= MsiGetTargetPathA( 0, NULL
, NULL
, &sz
);
1015 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1017 r
= MsiGetTargetPathA( 0, "boo", NULL
, NULL
);
1018 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1020 r
= MsiGetTargetPathA( 0, "boo", NULL
, NULL
);
1021 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1023 r
= MsiGetTargetPathA( hpkg
, "boo", NULL
, NULL
);
1024 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1026 r
= MsiGetTargetPathA( hpkg
, "boo", buffer
, NULL
);
1027 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1030 r
= MsiGetTargetPathA( hpkg
, "", buffer
, &sz
);
1031 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1033 r
= MsiGetTargetPathW( 0, NULL
, NULL
, NULL
);
1034 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1036 r
= MsiGetTargetPathW( 0, NULL
, NULL
, &sz
);
1037 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1039 r
= MsiGetTargetPathW( 0, boo
, NULL
, NULL
);
1040 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1042 r
= MsiGetTargetPathW( 0, boo
, NULL
, NULL
);
1043 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1045 r
= MsiGetTargetPathW( hpkg
, boo
, NULL
, NULL
);
1046 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1048 r
= MsiGetTargetPathW( hpkg
, boo
, bufferW
, NULL
);
1049 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1052 r
= MsiGetTargetPathW( hpkg
, empty
, bufferW
, &sz
);
1053 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1055 MsiCloseHandle( hpkg
);
1056 DeleteFileA(msifile
);
1059 static void query_file_path(MSIHANDLE hpkg
, LPCSTR file
, LPSTR buff
)
1065 rec
= MsiCreateRecord( 1 );
1066 ok(rec
, "MsiCreate record failed\n");
1068 r
= MsiRecordSetStringA( rec
, 0, file
);
1069 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
1072 r
= MsiFormatRecordA( hpkg
, rec
, buff
, &size
);
1073 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
1075 MsiCloseHandle( rec
);
1078 static void test_settargetpath(void)
1080 char tempdir
[MAX_PATH
+8], buffer
[MAX_PATH
], file
[MAX_PATH
];
1086 hdb
= create_package_db();
1087 ok ( hdb
, "failed to create package database\n" );
1089 r
= add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'" );
1090 ok( r
== S_OK
, "failed to add directory entry: %d\n" , r
);
1092 r
= create_component_table( hdb
);
1093 ok( r
== S_OK
, "cannot create Component table: %d\n", r
);
1095 r
= add_component_entry( hdb
, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1096 ok( r
== S_OK
, "cannot add dummy component: %d\n", r
);
1098 r
= add_component_entry( hdb
, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1099 ok( r
== S_OK
, "cannot add test component: %d\n", r
);
1101 r
= create_feature_table( hdb
);
1102 ok( r
== S_OK
, "cannot create Feature table: %d\n", r
);
1104 r
= add_feature_entry( hdb
, "'TestFeature', '', '', '', 0, 1, '', 0" );
1105 ok( r
== ERROR_SUCCESS
, "cannot add TestFeature to Feature table: %d\n", r
);
1107 r
= create_feature_components_table( hdb
);
1108 ok( r
== S_OK
, "cannot create FeatureComponents table: %d\n", r
);
1110 r
= add_feature_components_entry( hdb
, "'TestFeature', 'RootComp'" );
1111 ok( r
== S_OK
, "cannot insert component into FeatureComponents table: %d\n", r
);
1113 r
= add_feature_components_entry( hdb
, "'TestFeature', 'TestComp'" );
1114 ok( r
== S_OK
, "cannot insert component into FeatureComponents table: %d\n", r
);
1116 add_directory_entry( hdb
, "'TestParent', 'TARGETDIR', 'TestParent'" );
1117 add_directory_entry( hdb
, "'TestDir', 'TestParent', 'TestDir'" );
1119 r
= create_file_table( hdb
);
1120 ok( r
== S_OK
, "cannot create File table: %d\n", r
);
1122 r
= add_file_entry( hdb
, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1123 ok( r
== S_OK
, "cannot add file to the File table: %d\n", r
);
1125 r
= add_file_entry( hdb
, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1126 ok( r
== S_OK
, "cannot add file to the File table: %d\n", r
);
1128 r
= package_from_db( hdb
, &hpkg
);
1129 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1131 skip("Not enough rights to perform tests\n");
1132 DeleteFileA(msifile
);
1135 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1137 MsiSetInternalUI(INSTALLUILEVEL_NONE
, NULL
);
1139 r
= MsiDoActionA( hpkg
, "CostInitialize");
1140 ok( r
== ERROR_SUCCESS
, "cost init failed\n");
1142 r
= MsiDoActionA( hpkg
, "FileCost");
1143 ok( r
== ERROR_SUCCESS
, "file cost failed\n");
1145 r
= MsiDoActionA( hpkg
, "CostFinalize");
1146 ok( r
== ERROR_SUCCESS
, "cost finalize failed\n");
1149 sz
= sizeof(buffer
);
1150 r
= MsiGetPropertyA( hpkg
, "OutOfNoRbDiskSpace", buffer
, &sz
);
1151 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1152 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer
);
1154 r
= MsiSetTargetPathA( 0, NULL
, NULL
);
1155 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1157 r
= MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1158 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
1160 r
= MsiSetTargetPathA( hpkg
, "boo", NULL
);
1161 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
1163 r
= MsiSetTargetPathA( hpkg
, "boo", "c:\\bogusx" );
1164 ok( r
== ERROR_DIRECTORY
, "wrong return val\n");
1166 sz
= sizeof tempdir
- 1;
1167 r
= MsiGetTargetPathA( hpkg
, "TARGETDIR", tempdir
, &sz
);
1168 sprintf( file
, "%srootfile.txt", tempdir
);
1170 query_file_path( hpkg
, "[#RootFile]", buffer
);
1171 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1172 ok( !lstrcmpA(buffer
, file
), "Expected %s, got %s\n", file
, buffer
);
1174 GetTempFileNameA( tempdir
, "_wt", 0, buffer
);
1175 sprintf( tempdir
, "%s\\subdir", buffer
);
1177 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", buffer
);
1178 ok( r
== ERROR_SUCCESS
|| r
== ERROR_DIRECTORY
,
1179 "MsiSetTargetPath on file returned %d\n", r
);
1181 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", tempdir
);
1182 ok( r
== ERROR_SUCCESS
|| r
== ERROR_DIRECTORY
,
1183 "MsiSetTargetPath on 'subdir' of file returned %d\n", r
);
1185 DeleteFileA( buffer
);
1187 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", buffer
);
1188 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1190 r
= GetFileAttributesA( buffer
);
1191 ok ( r
== INVALID_FILE_ATTRIBUTES
, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r
);
1193 r
= MsiSetTargetPathA( hpkg
, "TARGETDIR", tempdir
);
1194 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath on subsubdir returned %d\n", r
);
1197 sz
= sizeof buffer
- 1;
1198 lstrcatA( tempdir
, "\\" );
1199 r
= MsiGetTargetPathA( hpkg
, "TARGETDIR", buffer
, &sz
);
1200 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1201 ok( !lstrcmpA(buffer
, tempdir
), "Expected %s, got %s\n", tempdir
, buffer
);
1203 sprintf( file
, "%srootfile.txt", tempdir
);
1204 query_file_path( hpkg
, "[#RootFile]", buffer
);
1205 ok( !lstrcmpA(buffer
, file
), "Expected %s, got %s\n", file
, buffer
);
1208 sz
= sizeof(buffer
);
1209 r
= MsiGetPropertyA( hpkg
, "TestParent", buffer
, &sz
);
1210 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1211 lstrcatA( tempdir
, "TestParent\\" );
1212 ok( !lstrcmpiA(buffer
, tempdir
), "Expected \"%s\", got \"%s\"\n", tempdir
, buffer
);
1214 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\one\\two" );
1215 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1218 sz
= sizeof(buffer
);
1219 r
= MsiGetPropertyA( hpkg
, "TestParent", buffer
, &sz
);
1220 ok( r
== ERROR_SUCCESS
, "MsiGetProperty returned %u\n", r
);
1221 ok( lstrcmpiA(buffer
, "C:\\one\\two\\TestDir\\"),
1222 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer
);
1225 query_file_path( hpkg
, "[#TestFile]", buffer
);
1226 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\TestDir\\testfile.txt"),
1227 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer
);
1230 sz
= sizeof buffer
- 1;
1231 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1232 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1233 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer
);
1235 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\one\\two\\three" );
1236 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1239 sz
= sizeof buffer
- 1;
1240 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1241 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1242 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer
);
1244 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\\\one\\\\two " );
1245 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1248 sz
= sizeof buffer
- 1;
1249 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1250 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1251 ok( !lstrcmpiA(buffer
, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer
);
1253 r
= MsiSetTargetPathA( hpkg
, "TestParent", "C:\\\\ Program Files \\\\ " );
1254 ok( r
== ERROR_SUCCESS
, "MsiSetTargetPath returned %d\n", r
);
1257 sz
= sizeof buffer
- 1;
1258 r
= MsiGetTargetPathA( hpkg
, "TestParent", buffer
, &sz
);
1259 ok( r
== ERROR_SUCCESS
, "failed to get target path: %d\n", r
);
1260 ok( !lstrcmpiA(buffer
, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer
);
1262 MsiCloseHandle( hpkg
);
1265 static void test_condition(void)
1267 static const WCHAR cond1
[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0};
1268 static const WCHAR cond2
[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0};
1269 static const WCHAR cond3
[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0};
1270 static const WCHAR cond4
[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0};
1274 r
= package_from_db(create_package_db(), &hpkg
);
1275 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
1277 skip("Not enough rights to perform tests\n");
1278 DeleteFileA(msifile
);
1281 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
1283 r
= MsiEvaluateConditionA(0, NULL
);
1284 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1286 r
= MsiEvaluateConditionA(hpkg
, NULL
);
1287 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1289 r
= MsiEvaluateConditionA(hpkg
, "");
1290 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1292 r
= MsiEvaluateConditionA(hpkg
, "1");
1293 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1295 r
= MsiEvaluateConditionA(hpkg
, "0");
1296 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1298 r
= MsiEvaluateConditionA(hpkg
, "-1");
1299 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1301 r
= MsiEvaluateConditionA(hpkg
, "0 = 0");
1302 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1304 r
= MsiEvaluateConditionA(hpkg
, "0 <> 0");
1305 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1307 r
= MsiEvaluateConditionA(hpkg
, "0 = 1");
1308 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1310 r
= MsiEvaluateConditionA(hpkg
, "0 > 1");
1311 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1313 r
= MsiEvaluateConditionA(hpkg
, "0 ~> 1");
1314 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1316 r
= MsiEvaluateConditionA(hpkg
, "1 > 1");
1317 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1319 r
= MsiEvaluateConditionA(hpkg
, "1 ~> 1");
1320 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1322 r
= MsiEvaluateConditionA(hpkg
, "0 >= 1");
1323 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1325 r
= MsiEvaluateConditionA(hpkg
, "0 ~>= 1");
1326 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1328 r
= MsiEvaluateConditionA(hpkg
, "1 >= 1");
1329 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1331 r
= MsiEvaluateConditionA(hpkg
, "1 ~>= 1");
1332 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1334 r
= MsiEvaluateConditionA(hpkg
, "0 < 1");
1335 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1337 r
= MsiEvaluateConditionA(hpkg
, "0 ~< 1");
1338 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1340 r
= MsiEvaluateConditionA(hpkg
, "1 < 1");
1341 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1343 r
= MsiEvaluateConditionA(hpkg
, "1 ~< 1");
1344 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1346 r
= MsiEvaluateConditionA(hpkg
, "0 <= 1");
1347 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1349 r
= MsiEvaluateConditionA(hpkg
, "0 ~<= 1");
1350 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1352 r
= MsiEvaluateConditionA(hpkg
, "1 <= 1");
1353 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1355 r
= MsiEvaluateConditionA(hpkg
, "1 ~<= 1");
1356 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1358 r
= MsiEvaluateConditionA(hpkg
, "0 >=");
1359 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1361 r
= MsiEvaluateConditionA(hpkg
, " ");
1362 ok( r
== MSICONDITION_NONE
, "wrong return val\n");
1364 r
= MsiEvaluateConditionA(hpkg
, "LicView <> \"1\"");
1365 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1367 r
= MsiEvaluateConditionA(hpkg
, "LicView <> \"0\"");
1368 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1370 r
= MsiEvaluateConditionA(hpkg
, "LicView <> LicView");
1371 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1373 r
= MsiEvaluateConditionA(hpkg
, "not 0");
1374 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1376 r
= MsiEvaluateConditionA(hpkg
, "not LicView");
1377 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1379 r
= MsiEvaluateConditionA(hpkg
, "\"Testing\" ~<< \"Testing\"");
1380 ok (r
== MSICONDITION_TRUE
, "wrong return val\n");
1382 r
= MsiEvaluateConditionA(hpkg
, "LicView ~<< \"Testing\"");
1383 ok (r
== MSICONDITION_FALSE
, "wrong return val\n");
1385 r
= MsiEvaluateConditionA(hpkg
, "Not LicView ~<< \"Testing\"");
1386 ok (r
== MSICONDITION_TRUE
, "wrong return val\n");
1388 r
= MsiEvaluateConditionA(hpkg
, "not \"A\"");
1389 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1391 r
= MsiEvaluateConditionA(hpkg
, "~not \"A\"");
1392 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1394 r
= MsiEvaluateConditionA(hpkg
, "\"0\"");
1395 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1397 r
= MsiEvaluateConditionA(hpkg
, "1 and 2");
1398 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1400 r
= MsiEvaluateConditionA(hpkg
, "not 0 and 3");
1401 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1403 r
= MsiEvaluateConditionA(hpkg
, "not 0 and 0");
1404 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1406 r
= MsiEvaluateConditionA(hpkg
, "not 0 or 1");
1407 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1409 r
= MsiEvaluateConditionA(hpkg
, "(0)");
1410 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1412 r
= MsiEvaluateConditionA(hpkg
, "(((((1))))))");
1413 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1415 r
= MsiEvaluateConditionA(hpkg
, "(((((1)))))");
1416 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1418 r
= MsiEvaluateConditionA(hpkg
, " \"A\" < \"B\" ");
1419 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1421 r
= MsiEvaluateConditionA(hpkg
, " \"A\" > \"B\" ");
1422 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1424 r
= MsiEvaluateConditionA(hpkg
, " \"1\" > \"12\" ");
1425 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1427 r
= MsiEvaluateConditionA(hpkg
, " \"100\" < \"21\" ");
1428 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1430 r
= MsiEvaluateConditionA(hpkg
, "0 < > 0");
1431 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1433 r
= MsiEvaluateConditionA(hpkg
, "(1<<1) == 2");
1434 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1436 r
= MsiEvaluateConditionA(hpkg
, " \"A\" = \"a\" ");
1437 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1439 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~ = \"a\" ");
1440 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1442 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~= \"a\" ");
1443 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1445 r
= MsiEvaluateConditionA(hpkg
, " \"A\" ~= 1 ");
1446 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1448 r
= MsiEvaluateConditionA(hpkg
, " \"A\" = 1 ");
1449 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1451 r
= MsiEvaluateConditionA(hpkg
, " 1 ~= 1 ");
1452 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1454 r
= MsiEvaluateConditionA(hpkg
, " 1 ~= \"1\" ");
1455 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1457 r
= MsiEvaluateConditionA(hpkg
, " 1 = \"1\" ");
1458 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1460 r
= MsiEvaluateConditionA(hpkg
, " 0 = \"1\" ");
1461 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1463 r
= MsiEvaluateConditionA(hpkg
, " 0 < \"100\" ");
1464 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1466 r
= MsiEvaluateConditionA(hpkg
, " 100 > \"0\" ");
1467 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1469 r
= MsiEvaluateConditionA(hpkg
, "1 XOR 1");
1470 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1472 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 1");
1473 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1475 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 0");
1476 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1478 r
= MsiEvaluateConditionA(hpkg
, "0 IMP 0");
1479 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1481 r
= MsiEvaluateConditionA(hpkg
, "0 EQV 0");
1482 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1484 r
= MsiEvaluateConditionA(hpkg
, "0 EQV 1");
1485 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1487 r
= MsiEvaluateConditionA(hpkg
, "1 IMP 1 OR 0");
1488 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1490 r
= MsiEvaluateConditionA(hpkg
, "1 IMPL 1");
1491 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1493 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" >< \"S\" ");
1494 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1496 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"s\" ");
1497 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1499 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"\" ");
1500 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1502 r
= MsiEvaluateConditionA(hpkg
, "\"ASFD\" ~>< \"sss\" ");
1503 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1505 MsiSetPropertyA(hpkg
, "mm", "5" );
1507 r
= MsiEvaluateConditionA(hpkg
, "mm = 5");
1508 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1510 r
= MsiEvaluateConditionA(hpkg
, "mm < 6");
1511 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1513 r
= MsiEvaluateConditionA(hpkg
, "mm <= 5");
1514 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1516 r
= MsiEvaluateConditionA(hpkg
, "mm > 4");
1517 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1519 r
= MsiEvaluateConditionA(hpkg
, "mm < 12");
1520 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1522 r
= MsiEvaluateConditionA(hpkg
, "mm = \"5\"");
1523 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1525 r
= MsiEvaluateConditionA(hpkg
, "0 = \"\"");
1526 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1528 r
= MsiEvaluateConditionA(hpkg
, "0 AND \"\"");
1529 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1531 r
= MsiEvaluateConditionA(hpkg
, "1 AND \"\"");
1532 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1534 r
= MsiEvaluateConditionA(hpkg
, "1 AND \"1\"");
1535 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1537 r
= MsiEvaluateConditionA(hpkg
, "3 >< 1");
1538 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1540 r
= MsiEvaluateConditionA(hpkg
, "3 >< 4");
1541 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1543 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 0");
1544 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1546 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 1");
1547 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1549 r
= MsiEvaluateConditionA(hpkg
, "NOT 1 OR 0");
1550 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1552 r
= MsiEvaluateConditionA(hpkg
, "0 AND 1 OR 1");
1553 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1555 r
= MsiEvaluateConditionA(hpkg
, "0 AND 0 OR 1");
1556 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1558 r
= MsiEvaluateConditionA(hpkg
, "NOT 0 AND 1 OR 0");
1559 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1561 r
= MsiEvaluateConditionA(hpkg
, "_1 = _1");
1562 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1564 r
= MsiEvaluateConditionA(hpkg
, "( 1 AND 1 ) = 2");
1565 ok( r
== MSICONDITION_ERROR
, "wrong return val\n");
1567 r
= MsiEvaluateConditionA(hpkg
, "NOT ( 1 AND 1 )");
1568 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1570 r
= MsiEvaluateConditionA(hpkg
, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1571 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1573 r
= MsiEvaluateConditionA(hpkg
, "Installed<>\"\"");
1574 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1576 r
= MsiEvaluateConditionA(hpkg
, "NOT 1 AND 0");
1577 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1579 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1580 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1582 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<>0");
1583 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1585 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<0");
1586 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1588 r
= MsiEvaluateConditionA(hpkg
, "bandalmael>0");
1589 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1591 r
= MsiEvaluateConditionA(hpkg
, "bandalmael>=0");
1592 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1594 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<=0");
1595 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1597 r
= MsiEvaluateConditionA(hpkg
, "bandalmael~<>0");
1598 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1600 MsiSetPropertyA(hpkg
, "bandalmael", "0" );
1601 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1602 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1604 MsiSetPropertyA(hpkg
, "bandalmael", "" );
1605 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1606 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1608 MsiSetPropertyA(hpkg
, "bandalmael", "asdf" );
1609 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1610 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1612 MsiSetPropertyA(hpkg
, "bandalmael", "0asdf" );
1613 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1614 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1616 MsiSetPropertyA(hpkg
, "bandalmael", "0 " );
1617 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1618 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1620 MsiSetPropertyA(hpkg
, "bandalmael", "-0" );
1621 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1622 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1624 MsiSetPropertyA(hpkg
, "bandalmael", "0000000000000" );
1625 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1626 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1628 MsiSetPropertyA(hpkg
, "bandalmael", "--0" );
1629 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1630 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1632 MsiSetPropertyA(hpkg
, "bandalmael", "0x00" );
1633 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1634 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1636 MsiSetPropertyA(hpkg
, "bandalmael", "-" );
1637 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1638 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1640 MsiSetPropertyA(hpkg
, "bandalmael", "+0" );
1641 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1642 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1644 MsiSetPropertyA(hpkg
, "bandalmael", "0.0" );
1645 r
= MsiEvaluateConditionA(hpkg
, "bandalmael=0");
1646 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1647 r
= MsiEvaluateConditionA(hpkg
, "bandalmael<>0");
1648 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1650 MsiSetPropertyA(hpkg
, "one", "hi");
1651 MsiSetPropertyA(hpkg
, "two", "hithere");
1652 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1653 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1655 MsiSetPropertyA(hpkg
, "one", "hithere");
1656 MsiSetPropertyA(hpkg
, "two", "hi");
1657 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1658 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1660 MsiSetPropertyA(hpkg
, "one", "hello");
1661 MsiSetPropertyA(hpkg
, "two", "hi");
1662 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1663 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1665 MsiSetPropertyA(hpkg
, "one", "hellohithere");
1666 MsiSetPropertyA(hpkg
, "two", "hi");
1667 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1668 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1670 MsiSetPropertyA(hpkg
, "one", "");
1671 MsiSetPropertyA(hpkg
, "two", "hi");
1672 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1673 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1675 MsiSetPropertyA(hpkg
, "one", "hi");
1676 MsiSetPropertyA(hpkg
, "two", "");
1677 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1678 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1680 MsiSetPropertyA(hpkg
, "one", "");
1681 MsiSetPropertyA(hpkg
, "two", "");
1682 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1683 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1685 MsiSetPropertyA(hpkg
, "one", "1234");
1686 MsiSetPropertyA(hpkg
, "two", "1");
1687 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1688 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1690 MsiSetPropertyA(hpkg
, "one", "one 1234");
1691 MsiSetPropertyA(hpkg
, "two", "1");
1692 r
= MsiEvaluateConditionA(hpkg
, "one >< two");
1693 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1695 MsiSetPropertyA(hpkg
, "one", "hithere");
1696 MsiSetPropertyA(hpkg
, "two", "hi");
1697 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1698 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1700 MsiSetPropertyA(hpkg
, "one", "hi");
1701 MsiSetPropertyA(hpkg
, "two", "hithere");
1702 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1703 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1705 MsiSetPropertyA(hpkg
, "one", "hi");
1706 MsiSetPropertyA(hpkg
, "two", "hi");
1707 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1708 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1710 MsiSetPropertyA(hpkg
, "one", "abcdhithere");
1711 MsiSetPropertyA(hpkg
, "two", "hi");
1712 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1713 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1715 MsiSetPropertyA(hpkg
, "one", "");
1716 MsiSetPropertyA(hpkg
, "two", "hi");
1717 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1718 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1720 MsiSetPropertyA(hpkg
, "one", "hithere");
1721 MsiSetPropertyA(hpkg
, "two", "");
1722 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1723 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1725 MsiSetPropertyA(hpkg
, "one", "");
1726 MsiSetPropertyA(hpkg
, "two", "");
1727 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1728 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1730 MsiSetPropertyA(hpkg
, "one", "1234");
1731 MsiSetPropertyA(hpkg
, "two", "1");
1732 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1733 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1735 MsiSetPropertyA(hpkg
, "one", "1234 one");
1736 MsiSetPropertyA(hpkg
, "two", "1");
1737 r
= MsiEvaluateConditionA(hpkg
, "one << two");
1738 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1740 MsiSetPropertyA(hpkg
, "one", "hithere");
1741 MsiSetPropertyA(hpkg
, "two", "there");
1742 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1743 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1745 MsiSetPropertyA(hpkg
, "one", "hithere");
1746 MsiSetPropertyA(hpkg
, "two", "hi");
1747 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1748 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1750 MsiSetPropertyA(hpkg
, "one", "there");
1751 MsiSetPropertyA(hpkg
, "two", "hithere");
1752 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1753 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1755 MsiSetPropertyA(hpkg
, "one", "there");
1756 MsiSetPropertyA(hpkg
, "two", "there");
1757 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1758 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1760 MsiSetPropertyA(hpkg
, "one", "abcdhithere");
1761 MsiSetPropertyA(hpkg
, "two", "hi");
1762 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1763 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1765 MsiSetPropertyA(hpkg
, "one", "");
1766 MsiSetPropertyA(hpkg
, "two", "there");
1767 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1768 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1770 MsiSetPropertyA(hpkg
, "one", "there");
1771 MsiSetPropertyA(hpkg
, "two", "");
1772 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1773 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1775 MsiSetPropertyA(hpkg
, "one", "");
1776 MsiSetPropertyA(hpkg
, "two", "");
1777 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1778 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1780 MsiSetPropertyA(hpkg
, "one", "1234");
1781 MsiSetPropertyA(hpkg
, "two", "4");
1782 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1783 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1785 MsiSetPropertyA(hpkg
, "one", "one 1234");
1786 MsiSetPropertyA(hpkg
, "two", "4");
1787 r
= MsiEvaluateConditionA(hpkg
, "one >> two");
1788 ok( r
== MSICONDITION_TRUE
, "wrong return val\n");
1790 MsiSetPropertyA(hpkg
, "MsiNetAssemblySupport", NULL
); /* make sure it's empty */
1792 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322\"");
1793 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1795 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport > \"1.1.4322\"");
1796 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1798 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport >= \"1.1.4322\"");
1799 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1801 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport <= \"1.1.4322\"");
1802 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1804 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport <> \"1.1.4322\"");
1805 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1807 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1808 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1810 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"abcd\"");
1811 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1813 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a1.1.4322\"");
1814 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1816 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322a\"");
1817 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1819 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1820 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1822 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1823 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1825 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1826 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1828 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"1.1");
1829 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
1831 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"1.1\"");
1832 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1834 r
= MsiEvaluateConditionA(hpkg
, "\"2\" < \"12.1\"");
1835 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1837 r
= MsiEvaluateConditionA(hpkg
, "\"02.1\" < \"2.11\"");
1838 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1840 r
= MsiEvaluateConditionA(hpkg
, "\"02.1.1\" < \"2.1\"");
1841 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1843 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1\"");
1844 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1846 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1\"");
1847 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1849 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"0\"");
1850 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1852 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"-1\"");
1853 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1855 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a\"");
1856 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1858 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"!\"");
1859 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1861 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"!\"");
1862 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1864 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"/\"");
1865 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1867 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \" \"");
1868 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1870 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"azAZ_\"");
1871 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1873 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a[a]\"");
1874 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1876 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a[a]a\"");
1877 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1879 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a]\"");
1880 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1882 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a]a\"");
1883 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1885 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"{a}\"");
1886 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1888 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"{a\"");
1889 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1891 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"[a\"");
1892 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1894 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a{\"");
1895 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1897 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"a]\"");
1898 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1900 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"A\"");
1901 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1903 MsiSetPropertyA(hpkg
, "MsiNetAssemblySupport", "1.1.4322");
1904 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.4322\"");
1905 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1907 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.14322\"");
1908 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1910 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1.5\"");
1911 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1913 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1.1\"");
1914 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1916 r
= MsiEvaluateConditionA(hpkg
, "MsiNetAssemblySupport < \"1\"");
1917 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1919 MsiSetPropertyA(hpkg
, "one", "1");
1920 r
= MsiEvaluateConditionA(hpkg
, "one < \"1\"");
1921 ok( r
== MSICONDITION_FALSE
, "wrong return val\n");
1923 MsiSetPropertyA(hpkg
, "X", "5.0");
1925 r
= MsiEvaluateConditionA(hpkg
, "X != \"\"");
1926 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
1928 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.0\"");
1929 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1931 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.1\"");
1932 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1934 r
= MsiEvaluateConditionA(hpkg
, "X =\"6.0\"");
1935 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1937 r
= MsiEvaluateConditionA(hpkg
, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
1938 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1940 r
= MsiEvaluateConditionA(hpkg
, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1941 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1943 r
= MsiEvaluateConditionA(hpkg
, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1944 ok( r
== MSICONDITION_ERROR
, "wrong return val (%d)\n", r
);
1946 /* feature doesn't exist */
1947 r
= MsiEvaluateConditionA(hpkg
, "&nofeature");
1948 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1950 MsiSetPropertyA(hpkg
, "A", "2");
1951 MsiSetPropertyA(hpkg
, "X", "50");
1953 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
1954 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1956 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
1957 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1959 r
= MsiEvaluateConditionA(hpkg
, "A <= 50");
1960 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1962 MsiSetPropertyA(hpkg
, "X", "50val");
1964 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
1965 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1967 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
1968 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1970 MsiSetPropertyA(hpkg
, "A", "7");
1971 MsiSetPropertyA(hpkg
, "X", "50");
1973 r
= MsiEvaluateConditionA(hpkg
, "7 <= X");
1974 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1976 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
1977 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1979 r
= MsiEvaluateConditionA(hpkg
, "A <= 50");
1980 ok( r
== MSICONDITION_TRUE
, "wrong return val (%d)\n", r
);
1982 MsiSetPropertyA(hpkg
, "X", "50val");
1984 r
= MsiEvaluateConditionA(hpkg
, "2 <= X");
1985 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1987 r
= MsiEvaluateConditionA(hpkg
, "A <= X");
1988 ok( r
== MSICONDITION_FALSE
, "wrong return val (%d)\n", r
);
1990 r
= MsiEvaluateConditionW(hpkg
, cond1
);
1991 ok( r
== MSICONDITION_TRUE
|| broken(r
== MSICONDITION_FALSE
),
1992 "wrong return val (%d)\n", r
);
1994 r
= MsiEvaluateConditionW(hpkg
, cond2
);
1995 ok( r
== MSICONDITION_FALSE
|| broken(r
== MSICONDITION_TRUE
),
1996 "wrong return val (%d)\n", r
);
1998 r
= MsiEvaluateConditionW(hpkg
, cond3
);
1999 ok( r
== MSICONDITION_TRUE
|| broken(r
== MSICONDITION_FALSE
),
2000 "wrong return val (%d)\n", r
);
2002 r
= MsiEvaluateConditionW(hpkg
, cond4
);
2003 ok( r
== MSICONDITION_FALSE
|| broken(r
== MSICONDITION_TRUE
),
2004 "wrong return val (%d)\n", r
);
2006 MsiCloseHandle( hpkg
);
2007 DeleteFileA(msifile
);
2010 static BOOL
check_prop_empty( MSIHANDLE hpkg
, const char * prop
)
2018 r
= MsiGetPropertyA( hpkg
, prop
, buffer
, &sz
);
2019 return r
== ERROR_SUCCESS
&& buffer
[0] == 0 && sz
== 0;
2022 static void test_props(void)
2024 MSIHANDLE hpkg
, hdb
;
2029 hdb
= create_package_db();
2031 "CREATE TABLE `Property` ( "
2032 "`Property` CHAR(255) NOT NULL, "
2033 "`Value` CHAR(255) "
2034 "PRIMARY KEY `Property`)" );
2035 ok( r
== ERROR_SUCCESS
, "Failed\n" );
2038 "INSERT INTO `Property` "
2039 "(`Property`, `Value`) "
2040 "VALUES( 'MetadataCompName', 'Photoshop.dll' )");
2041 ok( r
== ERROR_SUCCESS
, "Failed\n" );
2043 r
= package_from_db( hdb
, &hpkg
);
2044 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2046 skip("Not enough rights to perform tests\n");
2047 DeleteFileA(msifile
);
2050 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2052 /* test invalid values */
2053 r
= MsiGetPropertyA( 0, NULL
, NULL
, NULL
);
2054 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
2056 r
= MsiGetPropertyA( hpkg
, NULL
, NULL
, NULL
);
2057 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
2059 r
= MsiGetPropertyA( hpkg
, "boo", NULL
, NULL
);
2060 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2062 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, NULL
);
2063 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
2065 /* test retrieving an empty/nonexistent property */
2067 r
= MsiGetPropertyA( hpkg
, "boo", NULL
, &sz
);
2068 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2069 ok( sz
== 0, "wrong size returned\n");
2071 check_prop_empty( hpkg
, "boo");
2074 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2075 ok( r
== ERROR_MORE_DATA
, "wrong return val\n");
2076 ok( !strcmp(buffer
,"x"), "buffer was changed\n");
2077 ok( sz
== 0, "wrong size returned\n");
2081 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2082 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2083 ok( buffer
[0] == 0, "buffer was not changed\n");
2084 ok( sz
== 0, "wrong size returned\n");
2086 /* set the property to something */
2087 r
= MsiSetPropertyA( 0, NULL
, NULL
);
2088 ok( r
== ERROR_INVALID_HANDLE
, "wrong return val\n");
2090 r
= MsiSetPropertyA( hpkg
, NULL
, NULL
);
2091 ok( r
== ERROR_INVALID_PARAMETER
, "wrong return val\n");
2093 r
= MsiSetPropertyA( hpkg
, "", NULL
);
2094 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2096 /* try set and get some illegal property identifiers */
2097 r
= MsiSetPropertyA( hpkg
, "", "asdf" );
2098 ok( r
== ERROR_FUNCTION_FAILED
, "wrong return val\n");
2100 r
= MsiSetPropertyA( hpkg
, "=", "asdf" );
2101 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2103 r
= MsiSetPropertyA( hpkg
, " ", "asdf" );
2104 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2106 r
= MsiSetPropertyA( hpkg
, "'", "asdf" );
2107 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2111 r
= MsiGetPropertyA( hpkg
, "'", buffer
, &sz
);
2112 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2113 ok( !strcmp(buffer
,"asdf"), "buffer was not changed\n");
2115 /* set empty values */
2116 r
= MsiSetPropertyA( hpkg
, "boo", NULL
);
2117 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2118 ok( check_prop_empty( hpkg
, "boo"), "prop wasn't empty\n");
2120 r
= MsiSetPropertyA( hpkg
, "boo", "" );
2121 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2122 ok( check_prop_empty( hpkg
, "boo"), "prop wasn't empty\n");
2124 /* set a non-empty value */
2125 r
= MsiSetPropertyA( hpkg
, "boo", "xyz" );
2126 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2130 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2131 ok( r
== ERROR_MORE_DATA
, "wrong return val\n");
2132 ok( buffer
[0] == 0, "buffer was not changed\n");
2133 ok( sz
== 3, "wrong size returned\n");
2137 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2138 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2139 ok( !strcmp(buffer
,"xyz"), "buffer was not changed\n");
2140 ok( sz
== 3, "wrong size returned\n");
2144 r
= MsiGetPropertyA( hpkg
, "boo", buffer
, &sz
);
2145 ok( r
== ERROR_MORE_DATA
, "wrong return val\n");
2146 ok( !strcmp(buffer
,"xy"), "buffer was not changed\n");
2147 ok( sz
== 3, "wrong size returned\n");
2149 r
= MsiSetPropertyA(hpkg
, "SourceDir", "foo");
2150 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2153 r
= MsiGetPropertyA(hpkg
, "SOURCEDIR", buffer
, &sz
);
2154 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2155 ok( !strcmp(buffer
,""), "buffer wrong\n");
2156 ok( sz
== 0, "wrong size returned\n");
2159 r
= MsiGetPropertyA(hpkg
, "SOMERANDOMNAME", buffer
, &sz
);
2160 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2161 ok( !strcmp(buffer
,""), "buffer wrong\n");
2162 ok( sz
== 0, "wrong size returned\n");
2165 r
= MsiGetPropertyA(hpkg
, "SourceDir", buffer
, &sz
);
2166 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2167 ok( !strcmp(buffer
,"foo"), "buffer wrong\n");
2168 ok( sz
== 3, "wrong size returned\n");
2170 r
= MsiSetPropertyA(hpkg
, "MetadataCompName", "Photoshop.dll");
2171 ok( r
== ERROR_SUCCESS
, "wrong return val\n");
2174 r
= MsiGetPropertyA(hpkg
, "MetadataCompName", NULL
, &sz
);
2175 ok( r
== ERROR_SUCCESS
, "return wrong\n");
2176 ok( sz
== 13, "size wrong (%d)\n", sz
);
2179 r
= MsiGetPropertyA(hpkg
, "MetadataCompName", buffer
, &sz
);
2180 ok( r
== ERROR_MORE_DATA
, "return wrong\n");
2181 ok( !strcmp(buffer
,"Photoshop.dl"), "buffer wrong\n");
2183 r
= MsiSetPropertyA(hpkg
, "property", "value");
2184 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2187 r
= MsiGetPropertyA(hpkg
, "property", buffer
, &sz
);
2188 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2189 ok( !strcmp(buffer
, "value"), "Expected value, got %s\n", buffer
);
2191 r
= MsiSetPropertyA(hpkg
, "property", NULL
);
2192 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2195 r
= MsiGetPropertyA(hpkg
, "property", buffer
, &sz
);
2196 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2197 ok(!buffer
[0], "Expected empty string, got %s\n", buffer
);
2199 MsiCloseHandle( hpkg
);
2200 DeleteFileA(msifile
);
2203 static BOOL
find_prop_in_property(MSIHANDLE hdb
, LPCSTR prop
, LPCSTR val
, int len
)
2205 MSIHANDLE hview
, hrec
;
2207 CHAR buffer
[MAX_PATH
];
2211 r
= MsiDatabaseOpenViewA(hdb
, "SELECT * FROM `_Property`", &hview
);
2212 ok(r
== ERROR_SUCCESS
, "MsiDatabaseOpenView failed\n");
2213 r
= MsiViewExecute(hview
, 0);
2214 ok(r
== ERROR_SUCCESS
, "MsiViewExecute failed\n");
2216 if (len
< 0) len
= lstrlenA(val
);
2218 while (r
== ERROR_SUCCESS
&& !found
)
2220 r
= MsiViewFetch(hview
, &hrec
);
2221 if (r
!= ERROR_SUCCESS
) break;
2224 r
= MsiRecordGetStringA(hrec
, 1, buffer
, &sz
);
2225 if (r
== ERROR_SUCCESS
&& !lstrcmpA(buffer
, prop
))
2228 r
= MsiRecordGetStringA(hrec
, 2, buffer
, &sz
);
2229 if (r
== ERROR_SUCCESS
&& !memcmp(buffer
, val
, len
) && !buffer
[len
])
2231 ok(sz
== len
, "wrong size %u\n", sz
);
2236 MsiCloseHandle(hrec
);
2238 MsiViewClose(hview
);
2239 MsiCloseHandle(hview
);
2243 static void test_property_table(void)
2247 MSIHANDLE hpkg
, hdb
, hrec
;
2248 char buffer
[MAX_PATH
], package
[10];
2252 hdb
= create_package_db();
2253 ok( hdb
, "failed to create package\n");
2255 r
= package_from_db(hdb
, &hpkg
);
2256 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2258 skip("Not enough rights to perform tests\n");
2259 DeleteFileA(msifile
);
2262 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2264 MsiCloseHandle(hdb
);
2266 hdb
= MsiGetActiveDatabase(hpkg
);
2268 query
= "CREATE TABLE `_Property` ( "
2269 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2270 r
= run_query(hdb
, query
);
2271 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
2273 MsiCloseHandle(hdb
);
2274 MsiCloseHandle(hpkg
);
2275 DeleteFileA(msifile
);
2277 hdb
= create_package_db();
2278 ok( hdb
, "failed to create package\n");
2280 query
= "CREATE TABLE `_Property` ( "
2281 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2282 r
= run_query(hdb
, query
);
2283 ok(r
== ERROR_SUCCESS
, "failed to create table\n");
2285 query
= "ALTER `_Property` ADD `foo` INTEGER";
2286 r
= run_query(hdb
, query
);
2287 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "failed to add column\n");
2289 query
= "ALTER TABLE `_Property` ADD `foo` INTEGER";
2290 r
= run_query(hdb
, query
);
2291 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "failed to add column\n");
2293 query
= "ALTER TABLE `_Property` ADD `extra` INTEGER";
2294 r
= run_query(hdb
, query
);
2295 ok(r
== ERROR_SUCCESS
, "failed to add column\n");
2297 sprintf(package
, "#%i", hdb
);
2298 r
= MsiOpenPackageA(package
, &hpkg
);
2299 ok(r
!= ERROR_SUCCESS
, "MsiOpenPackage succeeded\n");
2300 if (r
== ERROR_SUCCESS
)
2301 MsiCloseHandle(hpkg
);
2303 r
= MsiCloseHandle(hdb
);
2304 ok(r
== ERROR_SUCCESS
, "MsiCloseHandle failed %u\n", r
);
2306 hdb
= create_package_db();
2307 ok (hdb
, "failed to create package database\n");
2309 r
= create_property_table(hdb
);
2310 ok(r
== ERROR_SUCCESS
, "cannot create Property table: %d\n", r
);
2312 r
= add_property_entry(hdb
, "'prop', 'val'");
2313 ok(r
== ERROR_SUCCESS
, "cannot add property: %d\n", r
);
2315 r
= create_custom_action_table(hdb
);
2316 ok(r
== ERROR_SUCCESS
, "cannot create CustomAction table: %d\n", r
);
2318 r
= add_custom_action_entry( hdb
, "'EmbedNull', 51, 'prop2', '[~]np'" );
2319 ok( r
== ERROR_SUCCESS
, "cannot add custom action: %d\n", r
);
2321 r
= package_from_db(hdb
, &hpkg
);
2322 ok(r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2324 MsiCloseHandle(hdb
);
2327 r
= MsiGetPropertyA(hpkg
, "prop", buffer
, &sz
);
2328 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2329 ok(!lstrcmpA(buffer
, "val"), "Expected val, got %s\n", buffer
);
2331 hdb
= MsiGetActiveDatabase(hpkg
);
2333 found
= find_prop_in_property(hdb
, "prop", "val", -1);
2334 ok(found
, "prop should be in the _Property table\n");
2336 r
= add_property_entry(hdb
, "'dantes', 'mercedes'");
2337 ok(r
== ERROR_SUCCESS
, "cannot add property: %d\n", r
);
2339 query
= "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2340 r
= do_query(hdb
, query
, &hrec
);
2341 ok(r
== ERROR_BAD_QUERY_SYNTAX
, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r
);
2343 found
= find_prop_in_property(hdb
, "dantes", "mercedes", -1);
2344 ok(found
== FALSE
, "dantes should not be in the _Property table\n");
2347 lstrcpyA(buffer
, "aaa");
2348 r
= MsiGetPropertyA(hpkg
, "dantes", buffer
, &sz
);
2349 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2350 ok(!buffer
[0], "Expected empty string, got %s\n", buffer
);
2352 r
= MsiSetPropertyA(hpkg
, "dantes", "mercedes");
2353 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2355 found
= find_prop_in_property(hdb
, "dantes", "mercedes", -1);
2356 ok(found
== TRUE
, "dantes should be in the _Property table\n");
2358 r
= MsiDoActionA( hpkg
, "EmbedNull" );
2359 ok( r
== ERROR_SUCCESS
, "EmbedNull failed: %d\n", r
);
2362 memset( buffer
, 'a', sizeof(buffer
) );
2363 r
= MsiGetPropertyA( hpkg
, "prop2", buffer
, &sz
);
2364 ok( r
== ERROR_SUCCESS
, "get property failed: %d\n", r
);
2365 ok( !memcmp( buffer
, "\0np", sizeof("\0np") ), "wrong value\n");
2366 ok( sz
== sizeof("\0np") - 1, "got %u\n", sz
);
2368 found
= find_prop_in_property(hdb
, "prop2", "\0np", 3);
2369 ok(found
== TRUE
, "prop2 should be in the _Property table\n");
2371 MsiCloseHandle(hdb
);
2372 MsiCloseHandle(hpkg
);
2373 DeleteFileA(msifile
);
2376 static UINT
try_query_param( MSIHANDLE hdb
, LPCSTR szQuery
, MSIHANDLE hrec
)
2381 res
= MsiDatabaseOpenViewA( hdb
, szQuery
, &htab
);
2382 if( res
== ERROR_SUCCESS
)
2386 r
= MsiViewExecute( htab
, hrec
);
2387 if( r
!= ERROR_SUCCESS
)
2390 fprintf(stderr
,"MsiViewExecute failed %08x\n", res
);
2393 r
= MsiViewClose( htab
);
2394 if( r
!= ERROR_SUCCESS
)
2397 r
= MsiCloseHandle( htab
);
2398 if( r
!= ERROR_SUCCESS
)
2404 static UINT
try_query( MSIHANDLE hdb
, LPCSTR szQuery
)
2406 return try_query_param( hdb
, szQuery
, 0 );
2409 static void set_summary_str(MSIHANDLE hdb
, DWORD pid
, LPCSTR value
)
2414 r
= MsiGetSummaryInformationA(hdb
, NULL
, 1, &summary
);
2415 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2417 r
= MsiSummaryInfoSetPropertyA(summary
, pid
, VT_LPSTR
, 0, NULL
, value
);
2418 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2420 r
= MsiSummaryInfoPersist(summary
);
2421 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2423 MsiCloseHandle(summary
);
2426 static void set_summary_dword(MSIHANDLE hdb
, DWORD pid
, DWORD value
)
2431 r
= MsiGetSummaryInformationA(hdb
, NULL
, 1, &summary
);
2432 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2434 r
= MsiSummaryInfoSetPropertyA(summary
, pid
, VT_I4
, value
, NULL
, NULL
);
2435 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2437 r
= MsiSummaryInfoPersist(summary
);
2438 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %u\n", r
);
2440 MsiCloseHandle(summary
);
2443 static void test_msipackage(void)
2445 MSIHANDLE hdb
= 0, hpack
= 100;
2450 /* NULL szPackagePath */
2451 r
= MsiOpenPackageA(NULL
, &hpack
);
2452 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
2454 /* empty szPackagePath */
2455 r
= MsiOpenPackageA("", &hpack
);
2456 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2458 skip("Not enough rights to perform tests\n");
2463 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2466 if (r
== ERROR_SUCCESS
)
2467 MsiCloseHandle(hpack
);
2469 /* nonexistent szPackagePath */
2470 r
= MsiOpenPackageA("nonexistent", &hpack
);
2471 ok(r
== ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r
);
2474 r
= MsiOpenPackageA(msifile
, NULL
);
2475 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
2479 r
= MsiOpenPackageA(name
, &hpack
);
2480 ok(r
== ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", r
);
2482 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
2483 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2485 /* database exists, but is emtpy */
2486 sprintf(name
, "#%d", hdb
);
2487 r
= MsiOpenPackageA(name
, &hpack
);
2488 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2489 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2491 query
= "CREATE TABLE `Property` ( "
2492 "`Property` CHAR(72), `Value` CHAR(0) "
2493 "PRIMARY KEY `Property`)";
2494 r
= try_query(hdb
, query
);
2495 ok(r
== ERROR_SUCCESS
, "failed to create Properties table\n");
2497 query
= "CREATE TABLE `InstallExecuteSequence` ("
2498 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2499 "PRIMARY KEY `Action`)";
2500 r
= try_query(hdb
, query
);
2501 ok(r
== ERROR_SUCCESS
, "failed to create InstallExecuteSequence table\n");
2503 /* a few key tables exist */
2504 sprintf(name
, "#%d", hdb
);
2505 r
= MsiOpenPackageA(name
, &hpack
);
2506 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2507 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2509 MsiCloseHandle(hdb
);
2510 DeleteFileA(msifile
);
2512 /* start with a clean database to show what constitutes a valid package */
2513 r
= MsiOpenDatabaseW(msifileW
, MSIDBOPEN_CREATE
, &hdb
);
2514 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
2516 sprintf(name
, "#%d", hdb
);
2518 /* The following summary information props must exist:
2523 set_summary_dword(hdb
, PID_PAGECOUNT
, 100);
2524 r
= MsiOpenPackageA(name
, &hpack
);
2525 ok(r
== ERROR_INSTALL_PACKAGE_INVALID
,
2526 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r
);
2528 set_summary_str(hdb
, PID_REVNUMBER
, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2529 r
= MsiOpenPackageA(name
, &hpack
);
2530 ok(r
== ERROR_SUCCESS
,
2531 "Expected ERROR_SUCCESS, got %d\n", r
);
2533 MsiCloseHandle(hpack
);
2534 MsiCloseHandle(hdb
);
2535 DeleteFileA(msifile
);
2538 static void test_formatrecord2(void)
2540 MSIHANDLE hpkg
, hrec
;
2545 r
= package_from_db(create_package_db(), &hpkg
);
2546 if (r
== ERROR_INSTALL_PACKAGE_REJECTED
)
2548 skip("Not enough rights to perform tests\n");
2549 DeleteFileA(msifile
);
2552 ok( r
== ERROR_SUCCESS
, "failed to create package %u\n", r
);
2554 r
= MsiSetPropertyA(hpkg
, "Manufacturer", " " );
2555 ok( r
== ERROR_SUCCESS
, "set property failed\n");
2557 hrec
= MsiCreateRecord(2);
2558 ok(hrec
, "create record failed\n");
2560 r
= MsiRecordSetStringA( hrec
, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2561 ok( r
== ERROR_SUCCESS
, "format record failed\n");
2565 r
= MsiFormatRecordA( hpkg
, hrec
, buffer
, &sz
);
2566 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2568 r
= MsiRecordSetStringA(hrec
, 0, "[foo][1]");
2569 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2570 r
= MsiRecordSetStringA(hrec
, 1, "hoo");
2571 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2573 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2574 ok( sz
== 3, "size wrong\n");
2575 ok( 0 == strcmp(buffer
,"hoo"), "wrong output %s\n",buffer
);
2576 ok( r
== ERROR_SUCCESS
, "format failed\n");
2578 r
= MsiRecordSetStringA(hrec
, 0, "x[~]x");
2579 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2581 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2582 ok( sz
== 3, "size wrong\n");
2583 ok( 0 == strcmp(buffer
,"x"), "wrong output %s\n",buffer
);
2584 ok( r
== ERROR_SUCCESS
, "format failed\n");
2586 r
= MsiRecordSetStringA(hrec
, 0, "[foo.$%}][1]");
2587 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2588 r
= MsiRecordSetStringA(hrec
, 1, "hoo");
2589 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2591 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2592 ok( sz
== 3, "size wrong\n");
2593 ok( 0 == strcmp(buffer
,"hoo"), "wrong output %s\n",buffer
);
2594 ok( r
== ERROR_SUCCESS
, "format failed\n");
2596 r
= MsiRecordSetStringA(hrec
, 0, "[\\[]");
2597 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2599 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2600 ok( sz
== 1, "size wrong\n");
2601 ok( 0 == strcmp(buffer
,"["), "wrong output %s\n",buffer
);
2602 ok( r
== ERROR_SUCCESS
, "format failed\n");
2604 SetEnvironmentVariableA("FOO", "BAR");
2605 r
= MsiRecordSetStringA(hrec
, 0, "[%FOO]");
2606 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2608 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2609 ok( sz
== 3, "size wrong\n");
2610 ok( 0 == strcmp(buffer
,"BAR"), "wrong output %s\n",buffer
);
2611 ok( r
== ERROR_SUCCESS
, "format failed\n");
2613 r
= MsiRecordSetStringA(hrec
, 0, "[[1]]");
2614 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2615 r
= MsiRecordSetStringA(hrec
, 1, "%FOO");
2616 ok( r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %d\n", r
);
2618 r
= MsiFormatRecordA(hpkg
, hrec
, buffer
, &sz
);
2619 ok( sz
== 3, "size wrong\n");
2620 ok( 0 == strcmp(buffer
,"BAR"), "wrong output %s\n",buffer
);
2621 ok( r
== ERROR_SUCCESS
, "format failed\n");
2623 MsiCloseHandle( hrec
);
2624 MsiCloseHandle( hpkg
);
2625 DeleteFileA(msifile
);
2628 static void test_feature_states( UINT line
, MSIHANDLE package
, const char *feature
, UINT error
,
2629 INSTALLSTATE expected_state
, INSTALLSTATE expected_action
, BOOL todo
)
2632 INSTALLSTATE state
= 0xdeadbee;
2633 INSTALLSTATE action
= 0xdeadbee;
2635 r
= MsiGetFeatureStateA( package
, feature
, &state
, &action
);
2636 ok( r
== error
, "%u: expected %d got %d\n", line
, error
, r
);
2637 if (r
== ERROR_SUCCESS
)
2639 ok( state
== expected_state
, "%u: expected state %d got %d\n",
2640 line
, expected_state
, state
);
2642 ok( action
== expected_action
, "%u: expected action %d got %d\n",
2643 line
, expected_action
, action
);
2645 ok( action
== expected_action
, "%u: expected action %d got %d\n",
2646 line
, expected_action
, action
);
2650 ok( state
== 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line
, state
);
2652 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line
, action
);
2654 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line
, action
);
2659 static void test_component_states( UINT line
, MSIHANDLE package
, const char *component
, UINT error
,
2660 INSTALLSTATE expected_state
, INSTALLSTATE expected_action
, BOOL todo
)
2663 INSTALLSTATE state
= 0xdeadbee;
2664 INSTALLSTATE action
= 0xdeadbee;
2666 r
= MsiGetComponentStateA( package
, component
, &state
, &action
);
2667 ok( r
== error
, "%u: expected %d got %d\n", line
, error
, r
);
2668 if (r
== ERROR_SUCCESS
)
2670 ok( state
== expected_state
, "%u: expected state %d got %d\n",
2671 line
, expected_state
, state
);
2673 ok( action
== expected_action
, "%u: expected action %d got %d\n",
2674 line
, expected_action
, action
);
2676 ok( action
== expected_action
, "%u: expected action %d got %d\n",
2677 line
, expected_action
, action
);
2681 ok( state
== 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2684 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2687 ok( action
== 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2692 static void test_states(void)
2694 static const char msifile2
[] = "winetest2-package.msi";
2695 static const char msifile3
[] = "winetest3-package.msi";
2696 static const char msifile4
[] = "winetest4-package.msi";
2697 static const WCHAR msifile2W
[] =
2698 {'w','i','n','e','t','e','s','t','2','-','p','a','c','k','a','g','e','.','m','s','i',0};
2699 static const WCHAR msifile3W
[] =
2700 {'w','i','n','e','t','e','s','t','3','-','p','a','c','k','a','g','e','.','m','s','i',0};
2701 static const WCHAR msifile4W
[] =
2702 {'w','i','n','e','t','e','s','t','4','-','p','a','c','k','a','g','e','.','m','s','i',0};
2708 if (is_process_limited())
2710 skip("process is limited\n");
2714 hdb
= create_package_db();
2715 ok ( hdb
, "failed to create package database\n" );
2717 r
= add_directory_entry( hdb
, "'TARGETDIR', '', 'SourceDir'");
2718 ok( r
== ERROR_SUCCESS
, "cannot add directory: %d\n", r
);
2720 r
= create_property_table( hdb
);
2721 ok( r
== ERROR_SUCCESS
, "cannot create Property table: %d\n", r
);
2723 r
= add_property_entry( hdb
, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2724 ok( r
== ERROR_SUCCESS
, "cannot add property entry: %d\n", r
);
2726 r
= add_property_entry( hdb
, "'ProductLanguage', '1033'" );
2727 ok( r
== ERROR_SUCCESS
, "cannot add property entry: %d\n", r
);
2729 r
= add_property_entry( hdb
, "'ProductName', 'MSITEST'" );
2730 ok( r
== ERROR_SUCCESS
, "cannot add property entry: %d\n", r
);
2732 r
= add_property_entry( hdb
, "'ProductVersion', '1.1.1'" );
2733 ok( r
== ERROR_SUCCESS
, "cannot add property entry: %d\n", r
);
2735 r
= add_property_entry( hdb
, "'MSIFASTINSTALL', '1'" );
2736 ok( r
== ERROR_SUCCESS
, "cannot add property entry: %d\n", r
);
2738 r
= create_install_execute_sequence_table( hdb
);
2739 ok( r
== ERROR_SUCCESS
, "cannot create InstallExecuteSequence table: %d\n", r
);
2741 r
= add_install_execute_sequence_entry( hdb
, "'CostInitialize', '', '800'" );
2742 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2744 r
= add_install_execute_sequence_entry( hdb
, "'FileCost', '', '900'" );
2745 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2747 r
= add_install_execute_sequence_entry( hdb
, "'CostFinalize', '', '1000'" );
2748 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2750 r
= add_install_execute_sequence_entry( hdb
, "'InstallValidate', '', '1400'" );
2751 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2753 r
= add_install_execute_sequence_entry( hdb
, "'InstallInitialize', '', '1500'" );
2754 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2756 r
= add_install_execute_sequence_entry( hdb
, "'ProcessComponents', '', '1600'" );
2757 ok( r
== ERROR_SUCCESS
, "cannot add install execute sequence entry: %d\n", r
);
2759 r
= add_install_execute_sequence_entry( hdb
, "'UnpublishFeatures', '', '1800'" );