msi: Pass string length to msi_set_property in ACTION_CustomAction.
[wine] / dlls / msi / tests / package.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2005 Aric Stewart for CodeWeavers
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #define COBJMACROS
23
24 #include <stdio.h>
25 #include <windows.h>
26 #include <msidefs.h>
27 #include <msi.h>
28 #include <msiquery.h>
29 #include <srrestoreptapi.h>
30 #include <shlobj.h>
31
32 #include "wine/test.h"
33
34 static BOOL is_wow64;
35 static const char msifile[] = "winetest-package.msi";
36 static char CURR_DIR[MAX_PATH];
37
38 static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR);
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
40 static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
41
42 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
43 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
44 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
45 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
46 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
47 static void (WINAPI *pGetSystemInfo)(LPSYSTEM_INFO);
48 static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
49 static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR, UINT);
50
51 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
52 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
53
54 static void init_functionpointers(void)
55 {
56     HMODULE hmsi = GetModuleHandleA("msi.dll");
57     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
58     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
59     HMODULE hshell32 = GetModuleHandleA("shell32.dll");
60     HMODULE hsrclient;
61
62 #define GET_PROC(mod, func) \
63     p ## func = (void*)GetProcAddress(mod, #func);
64
65     GET_PROC(hmsi, MsiApplyMultiplePatchesA);
66     GET_PROC(hmsi, MsiGetComponentPathExA);
67     GET_PROC(hshell32, SHGetFolderPathA);
68
69     GET_PROC(hadvapi32, ConvertSidToStringSidA);
70     GET_PROC(hadvapi32, OpenProcessToken);
71     GET_PROC(hadvapi32, RegDeleteKeyExA)
72     GET_PROC(hadvapi32, RegDeleteKeyExW)
73     GET_PROC(hkernel32, IsWow64Process)
74     GET_PROC(hkernel32, GetNativeSystemInfo)
75     GET_PROC(hkernel32, GetSystemInfo)
76     GET_PROC(hkernel32, GetSystemWow64DirectoryA)
77
78     hsrclient = LoadLibraryA("srclient.dll");
79     GET_PROC(hsrclient, SRRemoveRestorePoint);
80     GET_PROC(hsrclient, SRSetRestorePointA);
81 #undef GET_PROC
82 }
83
84 static BOOL is_process_limited(void)
85 {
86     HANDLE token;
87
88     if (!pOpenProcessToken) return FALSE;
89
90     if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
91     {
92         BOOL ret;
93         TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
94         DWORD size;
95
96         ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
97         CloseHandle(token);
98         return (ret && type == TokenElevationTypeLimited);
99     }
100     return FALSE;
101 }
102
103 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
104 {
105     if (pRegDeleteKeyExA)
106         return pRegDeleteKeyExA( key, subkey, access, 0 );
107     return RegDeleteKeyA( key, subkey );
108 }
109
110 static char *get_user_sid(void)
111 {
112     HANDLE token;
113     DWORD size = 0;
114     TOKEN_USER *user;
115     char *usersid = NULL;
116
117     if (!pConvertSidToStringSidA)
118     {
119         win_skip("ConvertSidToStringSidA is not available\n");
120         return NULL;
121     }
122     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
123     GetTokenInformation(token, TokenUser, NULL, size, &size);
124
125     user = HeapAlloc(GetProcessHeap(), 0, size);
126     GetTokenInformation(token, TokenUser, user, size, &size);
127     pConvertSidToStringSidA(user->User.Sid, &usersid);
128     HeapFree(GetProcessHeap(), 0, user);
129
130     CloseHandle(token);
131     return usersid;
132 }
133
134 /* RegDeleteTreeW from dlls/advapi32/registry.c */
135 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
136 {
137     LONG ret;
138     DWORD dwMaxSubkeyLen, dwMaxValueLen;
139     DWORD dwMaxLen, dwSize;
140     WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
141     HKEY hSubKey = hKey;
142
143     if(lpszSubKey)
144     {
145         ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
146         if (ret) return ret;
147     }
148
149     ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
150             &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
151     if (ret) goto cleanup;
152
153     dwMaxSubkeyLen++;
154     dwMaxValueLen++;
155     dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
156     if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
157     {
158         /* Name too big: alloc a buffer for it */
159         if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
160         {
161             ret = ERROR_NOT_ENOUGH_MEMORY;
162             goto cleanup;
163         }
164     }
165
166     /* Recursively delete all the subkeys */
167     while (TRUE)
168     {
169         dwSize = dwMaxLen;
170         if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
171                           NULL, NULL, NULL)) break;
172
173         ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
174         if (ret) goto cleanup;
175     }
176
177     if (lpszSubKey)
178     {
179         if (pRegDeleteKeyExW)
180             ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
181         else
182             ret = RegDeleteKeyW(hKey, lpszSubKey);
183     }
184     else
185         while (TRUE)
186         {
187             dwSize = dwMaxLen;
188             if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
189                   NULL, NULL, NULL, NULL)) break;
190
191             ret = RegDeleteValueW(hKey, lpszName);
192             if (ret) goto cleanup;
193         }
194
195 cleanup:
196     if (lpszName != szNameBuf)
197         HeapFree(GetProcessHeap(), 0, lpszName);
198     if(lpszSubKey)
199         RegCloseKey(hSubKey);
200     return ret;
201 }
202
203 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
204 {
205     DWORD i,n=1;
206     GUID guid;
207
208     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
209         return FALSE;
210
211     for(i=0; i<8; i++)
212         out[7-i] = in[n++];
213     n++;
214     for(i=0; i<4; i++)
215         out[11-i] = in[n++];
216     n++;
217     for(i=0; i<4; i++)
218         out[15-i] = in[n++];
219     n++;
220     for(i=0; i<2; i++)
221     {
222         out[17+i*2] = in[n++];
223         out[16+i*2] = in[n++];
224     }
225     n++;
226     for( ; i<8; i++)
227     {
228         out[17+i*2] = in[n++];
229         out[16+i*2] = in[n++];
230     }
231     out[32]=0;
232     return TRUE;
233 }
234
235 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
236 {
237     WCHAR guidW[MAX_PATH];
238     WCHAR squashedW[MAX_PATH];
239     GUID guid;
240     HRESULT hr;
241     int size;
242
243     hr = CoCreateGuid(&guid);
244     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
245
246     size = StringFromGUID2(&guid, guidW, MAX_PATH);
247     ok(size == 39, "Expected 39, got %d\n", hr);
248
249     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
250     squash_guid(guidW, squashedW);
251     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
252 }
253
254 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
255                                LPCSTR guid, LPSTR usersid, BOOL dir)
256 {
257     WCHAR guidW[MAX_PATH];
258     WCHAR squashedW[MAX_PATH];
259     CHAR squashed[MAX_PATH];
260     CHAR comppath[MAX_PATH];
261     CHAR prodpath[MAX_PATH];
262     CHAR path[MAX_PATH];
263     LPCSTR prod = NULL;
264     HKEY hkey;
265     REGSAM access = KEY_ALL_ACCESS;
266
267     if (is_wow64)
268         access |= KEY_WOW64_64KEY;
269
270     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
271     squash_guid(guidW, squashedW);
272     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
273
274     if (context == MSIINSTALLCONTEXT_MACHINE)
275     {
276         prod = "3D0DAE300FACA1300AD792060BCDAA92";
277         sprintf(comppath,
278                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
279                 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
280         lstrcpyA(prodpath,
281                  "SOFTWARE\\Classes\\Installer\\"
282                  "Products\\3D0DAE300FACA1300AD792060BCDAA92");
283     }
284     else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
285     {
286         prod = "7D2F387510109040002000060BECB6AB";
287         sprintf(comppath,
288                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
289                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
290         sprintf(prodpath,
291                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
292                 "Installer\\%s\\Installer\\Products\\"
293                 "7D2F387510109040002000060BECB6AB", usersid);
294     }
295     else if (context == MSIINSTALLCONTEXT_USERMANAGED)
296     {
297         prod = "7D2F387510109040002000060BECB6AB";
298         sprintf(comppath,
299                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
300                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
301         sprintf(prodpath,
302                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
303                 "Installer\\Managed\\%s\\Installer\\Products\\"
304                 "7D2F387510109040002000060BECB6AB", usersid);
305     }
306
307     RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
308
309     lstrcpyA(path, CURR_DIR);
310     lstrcatA(path, "\\");
311     if (!dir) lstrcatA(path, filename);
312
313     RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
314     RegCloseKey(hkey);
315
316     RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
317     RegCloseKey(hkey);
318 }
319
320 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
321 {
322     WCHAR guidW[MAX_PATH];
323     WCHAR squashedW[MAX_PATH];
324     WCHAR substrW[MAX_PATH];
325     CHAR squashed[MAX_PATH];
326     CHAR comppath[MAX_PATH];
327     CHAR prodpath[MAX_PATH];
328     REGSAM access = KEY_ALL_ACCESS;
329
330     if (is_wow64)
331         access |= KEY_WOW64_64KEY;
332
333     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
334     squash_guid(guidW, squashedW);
335     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
336
337     if (context == MSIINSTALLCONTEXT_MACHINE)
338     {
339         sprintf(comppath,
340                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
341                 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
342         lstrcpyA(prodpath,
343                  "SOFTWARE\\Classes\\Installer\\"
344                  "Products\\3D0DAE300FACA1300AD792060BCDAA92");
345     }
346     else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
347     {
348         sprintf(comppath,
349                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
350                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
351         sprintf(prodpath,
352                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
353                 "Installer\\%s\\Installer\\Products\\"
354                 "7D2F387510109040002000060BECB6AB", usersid);
355     }
356     else if (context == MSIINSTALLCONTEXT_USERMANAGED)
357     {
358         sprintf(comppath,
359                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
360                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
361         sprintf(prodpath,
362                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
363                 "Installer\\Managed\\%s\\Installer\\Products\\"
364                 "7D2F387510109040002000060BECB6AB", usersid);
365     }
366
367     MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
368     package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
369
370     MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
371     package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
372 }
373
374 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
375 {
376     MSIHANDLE hview = 0;
377     UINT r, ret;
378
379     /* open a select query */
380     r = MsiDatabaseOpenView(hdb, query, &hview);
381     if (r != ERROR_SUCCESS)
382         return r;
383     r = MsiViewExecute(hview, 0);
384     if (r != ERROR_SUCCESS)
385         return r;
386     ret = MsiViewFetch(hview, phrec);
387     r = MsiViewClose(hview);
388     if (r != ERROR_SUCCESS)
389         return r;
390     r = MsiCloseHandle(hview);
391     if (r != ERROR_SUCCESS)
392         return r;
393     return ret;
394 }
395
396 static UINT run_query( MSIHANDLE hdb, const char *query )
397 {
398     MSIHANDLE hview = 0;
399     UINT r;
400
401     r = MsiDatabaseOpenView(hdb, query, &hview);
402     if( r != ERROR_SUCCESS )
403         return r;
404
405     r = MsiViewExecute(hview, 0);
406     if( r == ERROR_SUCCESS )
407         r = MsiViewClose(hview);
408     MsiCloseHandle(hview);
409     return r;
410 }
411
412 static UINT create_component_table( MSIHANDLE hdb )
413 {
414     return run_query( hdb,
415             "CREATE TABLE `Component` ( "
416             "`Component` CHAR(72) NOT NULL, "
417             "`ComponentId` CHAR(38), "
418             "`Directory_` CHAR(72) NOT NULL, "
419             "`Attributes` SHORT NOT NULL, "
420             "`Condition` CHAR(255), "
421             "`KeyPath` CHAR(72) "
422             "PRIMARY KEY `Component`)" );
423 }
424
425 static UINT create_feature_table( MSIHANDLE hdb )
426 {
427     return run_query( hdb,
428             "CREATE TABLE `Feature` ( "
429             "`Feature` CHAR(38) NOT NULL, "
430             "`Feature_Parent` CHAR(38), "
431             "`Title` CHAR(64), "
432             "`Description` CHAR(255), "
433             "`Display` SHORT NOT NULL, "
434             "`Level` SHORT NOT NULL, "
435             "`Directory_` CHAR(72), "
436             "`Attributes` SHORT NOT NULL "
437             "PRIMARY KEY `Feature`)" );
438 }
439
440 static UINT create_feature_components_table( MSIHANDLE hdb )
441 {
442     return run_query( hdb,
443             "CREATE TABLE `FeatureComponents` ( "
444             "`Feature_` CHAR(38) NOT NULL, "
445             "`Component_` CHAR(72) NOT NULL "
446             "PRIMARY KEY `Feature_`, `Component_` )" );
447 }
448
449 static UINT create_file_table( MSIHANDLE hdb )
450 {
451     return run_query( hdb,
452             "CREATE TABLE `File` ("
453             "`File` CHAR(72) NOT NULL, "
454             "`Component_` CHAR(72) NOT NULL, "
455             "`FileName` CHAR(255) NOT NULL, "
456             "`FileSize` LONG NOT NULL, "
457             "`Version` CHAR(72), "
458             "`Language` CHAR(20), "
459             "`Attributes` SHORT, "
460             "`Sequence` SHORT NOT NULL "
461             "PRIMARY KEY `File`)" );
462 }
463
464 static UINT create_remove_file_table( MSIHANDLE hdb )
465 {
466     return run_query( hdb,
467             "CREATE TABLE `RemoveFile` ("
468             "`FileKey` CHAR(72) NOT NULL, "
469             "`Component_` CHAR(72) NOT NULL, "
470             "`FileName` CHAR(255) LOCALIZABLE, "
471             "`DirProperty` CHAR(72) NOT NULL, "
472             "`InstallMode` SHORT NOT NULL "
473             "PRIMARY KEY `FileKey`)" );
474 }
475
476 static UINT create_appsearch_table( MSIHANDLE hdb )
477 {
478     return run_query( hdb,
479             "CREATE TABLE `AppSearch` ("
480             "`Property` CHAR(72) NOT NULL, "
481             "`Signature_` CHAR(72) NOT NULL "
482             "PRIMARY KEY `Property`, `Signature_`)" );
483 }
484
485 static UINT create_reglocator_table( MSIHANDLE hdb )
486 {
487     return run_query( hdb,
488             "CREATE TABLE `RegLocator` ("
489             "`Signature_` CHAR(72) NOT NULL, "
490             "`Root` SHORT NOT NULL, "
491             "`Key` CHAR(255) NOT NULL, "
492             "`Name` CHAR(255), "
493             "`Type` SHORT "
494             "PRIMARY KEY `Signature_`)" );
495 }
496
497 static UINT create_signature_table( MSIHANDLE hdb )
498 {
499     return run_query( hdb,
500             "CREATE TABLE `Signature` ("
501             "`Signature` CHAR(72) NOT NULL, "
502             "`FileName` CHAR(255) NOT NULL, "
503             "`MinVersion` CHAR(20), "
504             "`MaxVersion` CHAR(20), "
505             "`MinSize` LONG, "
506             "`MaxSize` LONG, "
507             "`MinDate` LONG, "
508             "`MaxDate` LONG, "
509             "`Languages` CHAR(255) "
510             "PRIMARY KEY `Signature`)" );
511 }
512
513 static UINT create_launchcondition_table( MSIHANDLE hdb )
514 {
515     return run_query( hdb,
516             "CREATE TABLE `LaunchCondition` ("
517             "`Condition` CHAR(255) NOT NULL, "
518             "`Description` CHAR(255) NOT NULL "
519             "PRIMARY KEY `Condition`)" );
520 }
521
522 static UINT create_property_table( MSIHANDLE hdb )
523 {
524     return run_query( hdb,
525             "CREATE TABLE `Property` ("
526             "`Property` CHAR(72) NOT NULL, "
527             "`Value` CHAR(0) "
528             "PRIMARY KEY `Property`)" );
529 }
530
531 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
532 {
533     return run_query( hdb,
534             "CREATE TABLE `InstallExecuteSequence` ("
535             "`Action` CHAR(72) NOT NULL, "
536             "`Condition` CHAR(255), "
537             "`Sequence` SHORT "
538             "PRIMARY KEY `Action`)" );
539 }
540
541 static UINT create_media_table( MSIHANDLE hdb )
542 {
543     return run_query( hdb,
544             "CREATE TABLE `Media` ("
545             "`DiskId` SHORT NOT NULL, "
546             "`LastSequence` SHORT NOT NULL, "
547             "`DiskPrompt` CHAR(64), "
548             "`Cabinet` CHAR(255), "
549             "`VolumeLabel` CHAR(32), "
550             "`Source` CHAR(72) "
551             "PRIMARY KEY `DiskId`)" );
552 }
553
554 static UINT create_ccpsearch_table( MSIHANDLE hdb )
555 {
556     return run_query( hdb,
557             "CREATE TABLE `CCPSearch` ("
558             "`Signature_` CHAR(72) NOT NULL "
559             "PRIMARY KEY `Signature_`)" );
560 }
561
562 static UINT create_drlocator_table( MSIHANDLE hdb )
563 {
564     return run_query( hdb,
565             "CREATE TABLE `DrLocator` ("
566             "`Signature_` CHAR(72) NOT NULL, "
567             "`Parent` CHAR(72), "
568             "`Path` CHAR(255), "
569             "`Depth` SHORT "
570             "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
571 }
572
573 static UINT create_complocator_table( MSIHANDLE hdb )
574 {
575     return run_query( hdb,
576             "CREATE TABLE `CompLocator` ("
577             "`Signature_` CHAR(72) NOT NULL, "
578             "`ComponentId` CHAR(38) NOT NULL, "
579             "`Type` SHORT "
580             "PRIMARY KEY `Signature_`)" );
581 }
582
583 static UINT create_inilocator_table( MSIHANDLE hdb )
584 {
585     return run_query( hdb,
586             "CREATE TABLE `IniLocator` ("
587             "`Signature_` CHAR(72) NOT NULL, "
588             "`FileName` CHAR(255) NOT NULL, "
589             "`Section` CHAR(96)NOT NULL, "
590             "`Key` CHAR(128)NOT NULL, "
591             "`Field` SHORT, "
592             "`Type` SHORT "
593             "PRIMARY KEY `Signature_`)" );
594 }
595
596 static UINT create_custom_action_table( MSIHANDLE hdb )
597 {
598     return run_query( hdb,
599             "CREATE TABLE `CustomAction` ("
600             "`Action` CHAR(72) NOT NULL, "
601             "`Type` SHORT NOT NULL, "
602             "`Source` CHAR(75), "
603             "`Target` CHAR(255) "
604             "PRIMARY KEY `Action`)" );
605 }
606
607 #define make_add_entry(type, qtext) \
608     static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
609     { \
610         char insert[] = qtext; \
611         char *query; \
612         UINT sz, r; \
613         sz = strlen(values) + sizeof insert; \
614         query = HeapAlloc(GetProcessHeap(),0,sz); \
615         sprintf(query,insert,values); \
616         r = run_query( hdb, query ); \
617         HeapFree(GetProcessHeap(), 0, query); \
618         return r; \
619     }
620
621 make_add_entry(component,
622                "INSERT INTO `Component`  "
623                "(`Component`, `ComponentId`, `Directory_`, "
624                "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
625
626 make_add_entry(directory,
627                "INSERT INTO `Directory` "
628                "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
629
630 make_add_entry(feature,
631                "INSERT INTO `Feature` "
632                "(`Feature`, `Feature_Parent`, `Title`, `Description`, "
633                "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
634
635 make_add_entry(feature_components,
636                "INSERT INTO `FeatureComponents` "
637                "(`Feature_`, `Component_`) VALUES( %s )")
638
639 make_add_entry(file,
640                "INSERT INTO `File` "
641                "(`File`, `Component_`, `FileName`, `FileSize`, "
642                "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
643
644 make_add_entry(appsearch,
645                "INSERT INTO `AppSearch` "
646                "(`Property`, `Signature_`) VALUES( %s )")
647
648 make_add_entry(signature,
649                "INSERT INTO `Signature` "
650                "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
651                " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) "
652                "VALUES( %s )")
653
654 make_add_entry(launchcondition,
655                "INSERT INTO `LaunchCondition` "
656                "(`Condition`, `Description`) VALUES( %s )")
657
658 make_add_entry(property,
659                "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
660
661 make_add_entry(install_execute_sequence,
662                "INSERT INTO `InstallExecuteSequence` "
663                "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
664
665 make_add_entry(media,
666                "INSERT INTO `Media` "
667                "(`DiskId`, `LastSequence`, `DiskPrompt`, "
668                "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
669
670 make_add_entry(ccpsearch,
671                "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
672
673 make_add_entry(drlocator,
674                "INSERT INTO `DrLocator` "
675                "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
676
677 make_add_entry(complocator,
678                "INSERT INTO `CompLocator` "
679                "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
680
681 make_add_entry(inilocator,
682                "INSERT INTO `IniLocator` "
683                "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
684                "VALUES( %s )")
685
686 make_add_entry(custom_action,
687                "INSERT INTO `CustomAction`  "
688                "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
689
690 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
691                                   const char *name, UINT type )
692 {
693     const char insert[] =
694         "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
695         "VALUES( '%s', %u, '%s', '%s', %u )";
696     char *query;
697     UINT sz, r;
698
699     sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
700     query = HeapAlloc( GetProcessHeap(), 0, sz );
701     sprintf( query, insert, sig, root, path, name, type );
702     r = run_query( hdb, query );
703     HeapFree( GetProcessHeap(), 0, query );
704     return r;
705 }
706
707 static UINT set_summary_info(MSIHANDLE hdb)
708 {
709     UINT res;
710     MSIHANDLE suminfo;
711
712     /* build summary info */
713     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
714     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
715
716     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
717                         "Installation Database");
718     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
719
720     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
721                         "Installation Database");
722     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
723
724     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
725                         "Wine Hackers");
726     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
727
728     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
729                     ";1033");
730     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
731
732     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
733                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
734     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
735
736     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
737     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
738
739     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
740     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
741
742     res = MsiSummaryInfoPersist(suminfo);
743     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
744
745     res = MsiCloseHandle( suminfo);
746     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
747
748     return res;
749 }
750
751
752 static MSIHANDLE create_package_db(void)
753 {
754     MSIHANDLE hdb = 0;
755     UINT res;
756
757     DeleteFile(msifile);
758
759     /* create an empty database */
760     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
761     ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
762     if( res != ERROR_SUCCESS )
763         return hdb;
764
765     res = MsiDatabaseCommit( hdb );
766     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
767
768     res = set_summary_info(hdb);
769     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
770
771     res = run_query( hdb,
772             "CREATE TABLE `Directory` ( "
773             "`Directory` CHAR(255) NOT NULL, "
774             "`Directory_Parent` CHAR(255), "
775             "`DefaultDir` CHAR(255) NOT NULL "
776             "PRIMARY KEY `Directory`)" );
777     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
778
779     return hdb;
780 }
781
782 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
783 {
784     UINT res;
785     CHAR szPackage[12];
786     MSIHANDLE hPackage;
787
788     sprintf(szPackage, "#%u", hdb);
789     res = MsiOpenPackage(szPackage, &hPackage);
790     if (res != ERROR_SUCCESS)
791     {
792         MsiCloseHandle(hdb);
793         return res;
794     }
795
796     res = MsiCloseHandle(hdb);
797     if (res != ERROR_SUCCESS)
798     {
799         MsiCloseHandle(hPackage);
800         return res;
801     }
802
803     *handle = hPackage;
804     return ERROR_SUCCESS;
805 }
806
807 static void create_test_file(const CHAR *name)
808 {
809     HANDLE file;
810     DWORD written;
811
812     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
813     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
814     WriteFile(file, name, strlen(name), &written, NULL);
815     WriteFile(file, "\n", strlen("\n"), &written, NULL);
816     CloseHandle(file);
817 }
818
819 typedef struct _tagVS_VERSIONINFO
820 {
821     WORD wLength;
822     WORD wValueLength;
823     WORD wType;
824     WCHAR szKey[1];
825     WORD wPadding1[1];
826     VS_FIXEDFILEINFO Value;
827     WORD wPadding2[1];
828     WORD wChildren[1];
829 } VS_VERSIONINFO;
830
831 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
832 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
833
834 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
835 {
836     VS_VERSIONINFO *pVerInfo;
837     VS_FIXEDFILEINFO *pFixedInfo;
838     LPBYTE buffer, ofs;
839     CHAR path[MAX_PATH];
840     DWORD handle, size;
841     HANDLE resource;
842     BOOL ret = FALSE;
843
844     GetSystemDirectory(path, MAX_PATH);
845     /* Some dlls can't be updated on Vista/W2K8 */
846     lstrcatA(path, "\\version.dll");
847
848     CopyFileA(path, name, FALSE);
849
850     size = GetFileVersionInfoSize(path, &handle);
851     buffer = HeapAlloc(GetProcessHeap(), 0, size);
852
853     GetFileVersionInfoA(path, 0, size, buffer);
854
855     pVerInfo = (VS_VERSIONINFO *)buffer;
856     ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
857     pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
858
859     pFixedInfo->dwFileVersionMS = ms;
860     pFixedInfo->dwFileVersionLS = ls;
861     pFixedInfo->dwProductVersionMS = ms;
862     pFixedInfo->dwProductVersionLS = ls;
863
864     resource = BeginUpdateResource(name, FALSE);
865     if (!resource)
866         goto done;
867
868     if (!UpdateResource(resource, RT_VERSION, MAKEINTRESOURCE(VS_VERSION_INFO),
869                    MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
870         goto done;
871
872     if (!EndUpdateResource(resource, FALSE))
873         goto done;
874
875     ret = TRUE;
876
877 done:
878     HeapFree(GetProcessHeap(), 0, buffer);
879     return ret;
880 }
881
882 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
883 {
884     RESTOREPOINTINFOA spec;
885
886     spec.dwEventType = event_type;
887     spec.dwRestorePtType = APPLICATION_INSTALL;
888     spec.llSequenceNumber = status->llSequenceNumber;
889     lstrcpyA(spec.szDescription, "msitest restore point");
890
891     return pSRSetRestorePointA(&spec, status);
892 }
893
894 static void remove_restore_point(DWORD seq_number)
895 {
896     DWORD res;
897
898     res = pSRRemoveRestorePoint(seq_number);
899     if (res != ERROR_SUCCESS)
900         trace("Failed to remove the restore point : %08x\n", res);
901 }
902
903 static void test_createpackage(void)
904 {
905     MSIHANDLE hPackage = 0;
906     UINT res;
907
908     res = package_from_db(create_package_db(), &hPackage);
909     if (res == ERROR_INSTALL_PACKAGE_REJECTED)
910     {
911         skip("Not enough rights to perform tests\n");
912         DeleteFile(msifile);
913         return;
914     }
915     ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
916
917     res = MsiCloseHandle( hPackage);
918     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
919     DeleteFile(msifile);
920 }
921
922 static void test_doaction( void )
923 {
924     MSIHANDLE hpkg;
925     UINT r;
926
927     r = MsiDoAction( -1, NULL );
928     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
929
930     r = package_from_db(create_package_db(), &hpkg);
931     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
932     {
933         skip("Not enough rights to perform tests\n");
934         DeleteFile(msifile);
935         return;
936     }
937     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
938
939     r = MsiDoAction(hpkg, NULL);
940     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
941
942     r = MsiDoAction(0, "boo");
943     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
944
945     r = MsiDoAction(hpkg, "boo");
946     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
947
948     MsiCloseHandle( hpkg );
949     DeleteFile(msifile);
950 }
951
952 static void test_gettargetpath_bad(void)
953 {
954     static const WCHAR boo[] = {'b','o','o',0};
955     static const WCHAR empty[] = {0};
956     char buffer[0x80];
957     WCHAR bufferW[0x80];
958     MSIHANDLE hpkg;
959     DWORD sz;
960     UINT r;
961
962     r = package_from_db(create_package_db(), &hpkg);
963     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
964     {
965         skip("Not enough rights to perform tests\n");
966         DeleteFile(msifile);
967         return;
968     }
969     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
970
971     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
972     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
973
974     r = MsiGetTargetPath( 0, NULL, NULL, &sz );
975     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
976
977     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
978     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
979
980     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
981     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
982
983     r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
984     ok( r == ERROR_DIRECTORY, "wrong return val\n");
985
986     r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
987     ok( r == ERROR_DIRECTORY, "wrong return val\n");
988
989     sz = 0;
990     r = MsiGetTargetPath( hpkg, "", buffer, &sz );
991     ok( r == ERROR_DIRECTORY, "wrong return val\n");
992
993     r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
994     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
995
996     r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
997     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
998
999     r = MsiGetTargetPathW( 0, boo, NULL, NULL );
1000     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1001
1002     r = MsiGetTargetPathW( 0, boo, NULL, NULL );
1003     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1004
1005     r = MsiGetTargetPathW( hpkg, boo, NULL, NULL );
1006     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1007
1008     r = MsiGetTargetPathW( hpkg, boo, bufferW, NULL );
1009     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1010
1011     sz = 0;
1012     r = MsiGetTargetPathW( hpkg, empty, bufferW, &sz );
1013     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1014
1015     MsiCloseHandle( hpkg );
1016     DeleteFile(msifile);
1017 }
1018
1019 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1020 {
1021     UINT r;
1022     DWORD size;
1023     MSIHANDLE rec;
1024
1025     rec = MsiCreateRecord( 1 );
1026     ok(rec, "MsiCreate record failed\n");
1027
1028     r = MsiRecordSetString( rec, 0, file );
1029     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1030
1031     size = MAX_PATH;
1032     r = MsiFormatRecord( hpkg, rec, buff, &size );
1033     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1034
1035     MsiCloseHandle( rec );
1036 }
1037
1038 static void test_settargetpath(void)
1039 {
1040     char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH];
1041     DWORD sz;
1042     MSIHANDLE hpkg;
1043     UINT r;
1044     MSIHANDLE hdb;
1045
1046     hdb = create_package_db();
1047     ok ( hdb, "failed to create package database\n" );
1048
1049     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1050     ok( r == S_OK, "failed to add directory entry: %d\n" , r );
1051
1052     r = create_component_table( hdb );
1053     ok( r == S_OK, "cannot create Component table: %d\n", r );
1054
1055     r = add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1056     ok( r == S_OK, "cannot add dummy component: %d\n", r );
1057
1058     r = add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1059     ok( r == S_OK, "cannot add test component: %d\n", r );
1060
1061     r = create_feature_table( hdb );
1062     ok( r == S_OK, "cannot create Feature table: %d\n", r );
1063
1064     r = add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1065     ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r );
1066
1067     r = create_feature_components_table( hdb );
1068     ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
1069
1070     r = add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1071     ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1072
1073     r = add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1074     ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1075
1076     add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1077     add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1078
1079     r = create_file_table( hdb );
1080     ok( r == S_OK, "cannot create File table: %d\n", r );
1081
1082     r = add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1083     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1084
1085     r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1086     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1087
1088     r = package_from_db( hdb, &hpkg );
1089     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1090     {
1091         skip("Not enough rights to perform tests\n");
1092         DeleteFile(msifile);
1093         return;
1094     }
1095     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1096
1097     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1098
1099     r = MsiDoAction( hpkg, "CostInitialize");
1100     ok( r == ERROR_SUCCESS, "cost init failed\n");
1101
1102     r = MsiDoAction( hpkg, "FileCost");
1103     ok( r == ERROR_SUCCESS, "file cost failed\n");
1104
1105     r = MsiDoAction( hpkg, "CostFinalize");
1106     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1107
1108     r = MsiSetTargetPath( 0, NULL, NULL );
1109     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1110
1111     r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
1112     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1113
1114     r = MsiSetTargetPath( hpkg, "boo", NULL );
1115     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1116
1117     r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
1118     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1119
1120     sz = sizeof tempdir - 1;
1121     r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
1122     sprintf( file, "%srootfile.txt", tempdir );
1123     buffer[0] = 0;
1124     query_file_path( hpkg, "[#RootFile]", buffer );
1125     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1126     ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer );
1127
1128     GetTempFileName( tempdir, "_wt", 0, buffer );
1129     sprintf( tempdir, "%s\\subdir", buffer );
1130
1131     r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
1132     ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1133         "MsiSetTargetPath on file returned %d\n", r );
1134
1135     r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
1136     ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1137         "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1138
1139     DeleteFile( buffer );
1140
1141     r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
1142     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1143
1144     r = GetFileAttributes( buffer );
1145     ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1146
1147     r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
1148     ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1149
1150     buffer[0] = 0;
1151     sz = sizeof buffer - 1;
1152     lstrcat( tempdir, "\\" );
1153     r = MsiGetTargetPath( hpkg, "TARGETDIR", buffer, &sz );
1154     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1155     ok( !lstrcmp(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1156
1157     sprintf( file, "%srootfile.txt", tempdir );
1158     query_file_path( hpkg, "[#RootFile]", buffer );
1159     ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer);
1160
1161     buffer[0] = 0;
1162     sz = sizeof(buffer);
1163     r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1164     ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1165     lstrcatA( tempdir, "TestParent\\" );
1166     ok( !lstrcmpi(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1167
1168     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );
1169     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1170
1171     buffer[0] = 0;
1172     sz = sizeof(buffer);
1173     r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1174     ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1175     ok( lstrcmpi(buffer, "C:\\one\\two\\TestDir\\"),
1176         "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1177
1178     buffer[0] = 0;
1179     query_file_path( hpkg, "[#TestFile]", buffer );
1180     ok( !lstrcmpi(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1181         "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1182
1183     buffer[0] = 0;
1184     sz = sizeof buffer - 1;
1185     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1186     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1187     ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1188
1189     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two\\three" );
1190     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1191
1192     buffer[0] = 0;
1193     sz = sizeof buffer - 1;
1194     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1195     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1196     ok( !lstrcmpi(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1197
1198     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\one\\\\two  " );
1199     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1200
1201     buffer[0] = 0;
1202     sz = sizeof buffer - 1;
1203     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1204     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1205     ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1206
1207     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1208     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1209
1210     buffer[0] = 0;
1211     sz = sizeof buffer - 1;
1212     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1213     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1214     ok( !lstrcmpi(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1215
1216     MsiCloseHandle( hpkg );
1217 }
1218
1219 static void test_condition(void)
1220 {
1221     static const WCHAR cond1[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0};
1222     static const WCHAR cond2[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0};
1223     static const WCHAR cond3[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0};
1224     static const WCHAR cond4[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0};
1225     MSICONDITION r;
1226     MSIHANDLE hpkg;
1227
1228     r = package_from_db(create_package_db(), &hpkg);
1229     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1230     {
1231         skip("Not enough rights to perform tests\n");
1232         DeleteFile(msifile);
1233         return;
1234     }
1235     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1236
1237     r = MsiEvaluateCondition(0, NULL);
1238     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1239
1240     r = MsiEvaluateCondition(hpkg, NULL);
1241     ok( r == MSICONDITION_NONE, "wrong return val\n");
1242
1243     r = MsiEvaluateCondition(hpkg, "");
1244     ok( r == MSICONDITION_NONE, "wrong return val\n");
1245
1246     r = MsiEvaluateCondition(hpkg, "1");
1247     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1248
1249     r = MsiEvaluateCondition(hpkg, "0");
1250     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1251
1252     r = MsiEvaluateCondition(hpkg, "-1");
1253     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1254
1255     r = MsiEvaluateCondition(hpkg, "0 = 0");
1256     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1257
1258     r = MsiEvaluateCondition(hpkg, "0 <> 0");
1259     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1260
1261     r = MsiEvaluateCondition(hpkg, "0 = 1");
1262     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1263
1264     r = MsiEvaluateCondition(hpkg, "0 > 1");
1265     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1266
1267     r = MsiEvaluateCondition(hpkg, "0 ~> 1");
1268     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1269
1270     r = MsiEvaluateCondition(hpkg, "1 > 1");
1271     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1272
1273     r = MsiEvaluateCondition(hpkg, "1 ~> 1");
1274     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1275
1276     r = MsiEvaluateCondition(hpkg, "0 >= 1");
1277     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1278
1279     r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
1280     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1281
1282     r = MsiEvaluateCondition(hpkg, "1 >= 1");
1283     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1284
1285     r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
1286     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1287
1288     r = MsiEvaluateCondition(hpkg, "0 < 1");
1289     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1290
1291     r = MsiEvaluateCondition(hpkg, "0 ~< 1");
1292     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1293
1294     r = MsiEvaluateCondition(hpkg, "1 < 1");
1295     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1296
1297     r = MsiEvaluateCondition(hpkg, "1 ~< 1");
1298     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1299
1300     r = MsiEvaluateCondition(hpkg, "0 <= 1");
1301     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1302
1303     r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
1304     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1305
1306     r = MsiEvaluateCondition(hpkg, "1 <= 1");
1307     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1308
1309     r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
1310     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1311
1312     r = MsiEvaluateCondition(hpkg, "0 >=");
1313     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1314
1315     r = MsiEvaluateCondition(hpkg, " ");
1316     ok( r == MSICONDITION_NONE, "wrong return val\n");
1317
1318     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
1319     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1320
1321     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
1322     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1323
1324     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
1325     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1326
1327     r = MsiEvaluateCondition(hpkg, "not 0");
1328     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1329
1330     r = MsiEvaluateCondition(hpkg, "not LicView");
1331     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1332
1333     r = MsiEvaluateCondition(hpkg, "\"Testing\" ~<< \"Testing\"");
1334     ok (r == MSICONDITION_TRUE, "wrong return val\n");
1335
1336     r = MsiEvaluateCondition(hpkg, "LicView ~<< \"Testing\"");
1337     ok (r == MSICONDITION_FALSE, "wrong return val\n");
1338
1339     r = MsiEvaluateCondition(hpkg, "Not LicView ~<< \"Testing\"");
1340     ok (r == MSICONDITION_TRUE, "wrong return val\n");
1341
1342     r = MsiEvaluateCondition(hpkg, "not \"A\"");
1343     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1344
1345     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
1346     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1347
1348     r = MsiEvaluateCondition(hpkg, "\"0\"");
1349     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1350
1351     r = MsiEvaluateCondition(hpkg, "1 and 2");
1352     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1353
1354     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
1355     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1356
1357     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
1358     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1359
1360     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
1361     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1362
1363     r = MsiEvaluateCondition(hpkg, "(0)");
1364     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1365
1366     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
1367     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1368
1369     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
1370     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1371
1372     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
1373     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1374
1375     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
1376     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1377
1378     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
1379     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1380
1381     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
1382     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1383
1384     r = MsiEvaluateCondition(hpkg, "0 < > 0");
1385     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1386
1387     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
1388     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1389
1390     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
1391     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1392
1393     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
1394     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1395
1396     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
1397     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1398
1399     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
1400     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1401
1402     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
1403     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1404
1405     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
1406     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1407
1408     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
1409     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1410
1411     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
1412     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1413
1414     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
1415     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1416
1417     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
1418     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1419
1420     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
1421     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1422
1423     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
1424     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1425
1426     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
1427     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1428
1429     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
1430     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1431
1432     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
1433     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1434
1435     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
1436     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1437
1438     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
1439     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1440
1441     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
1442     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1443
1444     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
1445     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1446
1447     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
1448     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1449
1450     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
1451     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1452
1453     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
1454     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1455
1456     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
1457     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1458
1459     MsiSetProperty(hpkg, "mm", "5" );
1460
1461     r = MsiEvaluateCondition(hpkg, "mm = 5");
1462     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1463
1464     r = MsiEvaluateCondition(hpkg, "mm < 6");
1465     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1466
1467     r = MsiEvaluateCondition(hpkg, "mm <= 5");
1468     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1469
1470     r = MsiEvaluateCondition(hpkg, "mm > 4");
1471     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1472
1473     r = MsiEvaluateCondition(hpkg, "mm < 12");
1474     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1475
1476     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
1477     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1478
1479     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
1480     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1481
1482     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
1483     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1484
1485     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
1486     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1487
1488     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
1489     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1490
1491     r = MsiEvaluateCondition(hpkg, "3 >< 1");
1492     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1493
1494     r = MsiEvaluateCondition(hpkg, "3 >< 4");
1495     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1496
1497     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
1498     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1499
1500     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
1501     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1502
1503     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
1504     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1505
1506     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
1507     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1508
1509     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
1510     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1511
1512     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
1513     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1514
1515     r = MsiEvaluateCondition(hpkg, "_1 = _1");
1516     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1517
1518     r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
1519     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1520
1521     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
1522     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1523
1524     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1525     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1526
1527     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
1528     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1529
1530     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
1531     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1532
1533     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1534     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1535
1536     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1537     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1538
1539     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
1540     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1541
1542     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
1543     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1544
1545     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
1546     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1547
1548     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
1549     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1550
1551     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
1552     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1553
1554     MsiSetProperty(hpkg, "bandalmael", "0" );
1555     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1556     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1557
1558     MsiSetProperty(hpkg, "bandalmael", "" );
1559     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1560     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1561
1562     MsiSetProperty(hpkg, "bandalmael", "asdf" );
1563     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1564     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1565
1566     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
1567     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1568     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1569
1570     MsiSetProperty(hpkg, "bandalmael", "0 " );
1571     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1572     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1573
1574     MsiSetProperty(hpkg, "bandalmael", "-0" );
1575     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1576     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1577
1578     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
1579     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1580     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1581
1582     MsiSetProperty(hpkg, "bandalmael", "--0" );
1583     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1584     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1585
1586     MsiSetProperty(hpkg, "bandalmael", "0x00" );
1587     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1588     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1589
1590     MsiSetProperty(hpkg, "bandalmael", "-" );
1591     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1592     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1593
1594     MsiSetProperty(hpkg, "bandalmael", "+0" );
1595     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1596     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1597
1598     MsiSetProperty(hpkg, "bandalmael", "0.0" );
1599     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1600     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1601     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1602     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1603
1604     MsiSetProperty(hpkg, "one", "hi");
1605     MsiSetProperty(hpkg, "two", "hithere");
1606     r = MsiEvaluateCondition(hpkg, "one >< two");
1607     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1608
1609     MsiSetProperty(hpkg, "one", "hithere");
1610     MsiSetProperty(hpkg, "two", "hi");
1611     r = MsiEvaluateCondition(hpkg, "one >< two");
1612     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1613
1614     MsiSetProperty(hpkg, "one", "hello");
1615     MsiSetProperty(hpkg, "two", "hi");
1616     r = MsiEvaluateCondition(hpkg, "one >< two");
1617     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1618
1619     MsiSetProperty(hpkg, "one", "hellohithere");
1620     MsiSetProperty(hpkg, "two", "hi");
1621     r = MsiEvaluateCondition(hpkg, "one >< two");
1622     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1623
1624     MsiSetProperty(hpkg, "one", "");
1625     MsiSetProperty(hpkg, "two", "hi");
1626     r = MsiEvaluateCondition(hpkg, "one >< two");
1627     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1628
1629     MsiSetProperty(hpkg, "one", "hi");
1630     MsiSetProperty(hpkg, "two", "");
1631     r = MsiEvaluateCondition(hpkg, "one >< two");
1632     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1633
1634     MsiSetProperty(hpkg, "one", "");
1635     MsiSetProperty(hpkg, "two", "");
1636     r = MsiEvaluateCondition(hpkg, "one >< two");
1637     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1638
1639     MsiSetProperty(hpkg, "one", "1234");
1640     MsiSetProperty(hpkg, "two", "1");
1641     r = MsiEvaluateCondition(hpkg, "one >< two");
1642     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1643
1644     MsiSetProperty(hpkg, "one", "one 1234");
1645     MsiSetProperty(hpkg, "two", "1");
1646     r = MsiEvaluateCondition(hpkg, "one >< two");
1647     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1648
1649     MsiSetProperty(hpkg, "one", "hithere");
1650     MsiSetProperty(hpkg, "two", "hi");
1651     r = MsiEvaluateCondition(hpkg, "one << two");
1652     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1653
1654     MsiSetProperty(hpkg, "one", "hi");
1655     MsiSetProperty(hpkg, "two", "hithere");
1656     r = MsiEvaluateCondition(hpkg, "one << two");
1657     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1658
1659     MsiSetProperty(hpkg, "one", "hi");
1660     MsiSetProperty(hpkg, "two", "hi");
1661     r = MsiEvaluateCondition(hpkg, "one << two");
1662     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1663
1664     MsiSetProperty(hpkg, "one", "abcdhithere");
1665     MsiSetProperty(hpkg, "two", "hi");
1666     r = MsiEvaluateCondition(hpkg, "one << two");
1667     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1668
1669     MsiSetProperty(hpkg, "one", "");
1670     MsiSetProperty(hpkg, "two", "hi");
1671     r = MsiEvaluateCondition(hpkg, "one << two");
1672     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1673
1674     MsiSetProperty(hpkg, "one", "hithere");
1675     MsiSetProperty(hpkg, "two", "");
1676     r = MsiEvaluateCondition(hpkg, "one << two");
1677     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1678
1679     MsiSetProperty(hpkg, "one", "");
1680     MsiSetProperty(hpkg, "two", "");
1681     r = MsiEvaluateCondition(hpkg, "one << two");
1682     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1683
1684     MsiSetProperty(hpkg, "one", "1234");
1685     MsiSetProperty(hpkg, "two", "1");
1686     r = MsiEvaluateCondition(hpkg, "one << two");
1687     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1688
1689     MsiSetProperty(hpkg, "one", "1234 one");
1690     MsiSetProperty(hpkg, "two", "1");
1691     r = MsiEvaluateCondition(hpkg, "one << two");
1692     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1693
1694     MsiSetProperty(hpkg, "one", "hithere");
1695     MsiSetProperty(hpkg, "two", "there");
1696     r = MsiEvaluateCondition(hpkg, "one >> two");
1697     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1698
1699     MsiSetProperty(hpkg, "one", "hithere");
1700     MsiSetProperty(hpkg, "two", "hi");
1701     r = MsiEvaluateCondition(hpkg, "one >> two");
1702     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1703
1704     MsiSetProperty(hpkg, "one", "there");
1705     MsiSetProperty(hpkg, "two", "hithere");
1706     r = MsiEvaluateCondition(hpkg, "one >> two");
1707     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1708
1709     MsiSetProperty(hpkg, "one", "there");
1710     MsiSetProperty(hpkg, "two", "there");
1711     r = MsiEvaluateCondition(hpkg, "one >> two");
1712     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1713
1714     MsiSetProperty(hpkg, "one", "abcdhithere");
1715     MsiSetProperty(hpkg, "two", "hi");
1716     r = MsiEvaluateCondition(hpkg, "one >> two");
1717     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1718
1719     MsiSetProperty(hpkg, "one", "");
1720     MsiSetProperty(hpkg, "two", "there");
1721     r = MsiEvaluateCondition(hpkg, "one >> two");
1722     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1723
1724     MsiSetProperty(hpkg, "one", "there");
1725     MsiSetProperty(hpkg, "two", "");
1726     r = MsiEvaluateCondition(hpkg, "one >> two");
1727     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1728
1729     MsiSetProperty(hpkg, "one", "");
1730     MsiSetProperty(hpkg, "two", "");
1731     r = MsiEvaluateCondition(hpkg, "one >> two");
1732     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1733
1734     MsiSetProperty(hpkg, "one", "1234");
1735     MsiSetProperty(hpkg, "two", "4");
1736     r = MsiEvaluateCondition(hpkg, "one >> two");
1737     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1738
1739     MsiSetProperty(hpkg, "one", "one 1234");
1740     MsiSetProperty(hpkg, "two", "4");
1741     r = MsiEvaluateCondition(hpkg, "one >> two");
1742     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1743
1744     MsiSetProperty(hpkg, "MsiNetAssemblySupport", NULL);  /* make sure it's empty */
1745
1746     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1747     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1748
1749     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1750     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1751
1752     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1753     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1754
1755     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1756     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1757
1758     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1759     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1760
1761     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1762     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1763
1764     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1765     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1766
1767     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1768     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1769
1770     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1771     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1772
1773     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1774     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1775
1776     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1777     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1778
1779     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1780     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1781
1782     r = MsiEvaluateCondition(hpkg, "\"2\" < \"1.1");
1783     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1784
1785     r = MsiEvaluateCondition(hpkg, "\"2\" < \"1.1\"");
1786     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1787
1788     r = MsiEvaluateCondition(hpkg, "\"2\" < \"12.1\"");
1789     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1790
1791     r = MsiEvaluateCondition(hpkg, "\"02.1\" < \"2.11\"");
1792     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1793
1794     r = MsiEvaluateCondition(hpkg, "\"02.1.1\" < \"2.1\"");
1795     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1796
1797     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1798     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1799
1800     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1\"");
1801     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1802
1803     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"0\"");
1804     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1805
1806     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"-1\"");
1807     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1808
1809     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a\"");
1810     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1811
1812     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"!\"");
1813     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1814
1815     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"!\"");
1816     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1817
1818     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"/\"");
1819     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1820
1821     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \" \"");
1822     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1823
1824     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1825     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1826
1827     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1828     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1829
1830     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1831     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1832
1833     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1834     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1835
1836     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
1837     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1838
1839     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"{a}\"");
1840     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1841
1842     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"{a\"");
1843     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1844
1845     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a\"");
1846     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1847
1848     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a{\"");
1849     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1850
1851     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a]\"");
1852     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1853
1854     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"A\"");
1855     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1856
1857     MsiSetProperty(hpkg, "MsiNetAssemblySupport", "1.1.4322");
1858     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1859     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1860
1861     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
1862     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1863
1864     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
1865     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1866
1867     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1868     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1869
1870     r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1\"");
1871     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1872
1873     MsiSetProperty(hpkg, "one", "1");
1874     r = MsiEvaluateCondition(hpkg, "one < \"1\"");
1875     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1876
1877     MsiSetProperty(hpkg, "X", "5.0");
1878
1879     r = MsiEvaluateCondition(hpkg, "X != \"\"");
1880     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1881
1882     r = MsiEvaluateCondition(hpkg, "X =\"5.0\"");
1883     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1884
1885     r = MsiEvaluateCondition(hpkg, "X =\"5.1\"");
1886     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1887
1888     r = MsiEvaluateCondition(hpkg, "X =\"6.0\"");
1889     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1890
1891     r = MsiEvaluateCondition(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
1892     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1893
1894     r = MsiEvaluateCondition(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1895     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1896
1897     r = MsiEvaluateCondition(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1898     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1899
1900     /* feature doesn't exist */
1901     r = MsiEvaluateCondition(hpkg, "&nofeature");
1902     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1903
1904     MsiSetProperty(hpkg, "A", "2");
1905     MsiSetProperty(hpkg, "X", "50");
1906
1907     r = MsiEvaluateCondition(hpkg, "2 <= X");
1908     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1909
1910     r = MsiEvaluateCondition(hpkg, "A <= X");
1911     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1912
1913     r = MsiEvaluateCondition(hpkg, "A <= 50");
1914     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1915
1916     MsiSetProperty(hpkg, "X", "50val");
1917
1918     r = MsiEvaluateCondition(hpkg, "2 <= X");
1919     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1920
1921     r = MsiEvaluateCondition(hpkg, "A <= X");
1922     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1923
1924     MsiSetProperty(hpkg, "A", "7");
1925     MsiSetProperty(hpkg, "X", "50");
1926
1927     r = MsiEvaluateCondition(hpkg, "7 <= X");
1928     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1929
1930     r = MsiEvaluateCondition(hpkg, "A <= X");
1931     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1932
1933     r = MsiEvaluateCondition(hpkg, "A <= 50");
1934     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1935
1936     MsiSetProperty(hpkg, "X", "50val");
1937
1938     r = MsiEvaluateCondition(hpkg, "2 <= X");
1939     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1940
1941     r = MsiEvaluateCondition(hpkg, "A <= X");
1942     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1943
1944     r = MsiEvaluateConditionW(hpkg, cond1);
1945     ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
1946         "wrong return val (%d)\n", r);
1947
1948     r = MsiEvaluateConditionW(hpkg, cond2);
1949     ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
1950         "wrong return val (%d)\n", r);
1951
1952     r = MsiEvaluateConditionW(hpkg, cond3);
1953     ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
1954         "wrong return val (%d)\n", r);
1955
1956     r = MsiEvaluateConditionW(hpkg, cond4);
1957     ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
1958         "wrong return val (%d)\n", r);
1959
1960     MsiCloseHandle( hpkg );
1961     DeleteFile(msifile);
1962 }
1963
1964 static BOOL check_prop_empty( MSIHANDLE hpkg, const char * prop)
1965 {
1966     UINT r;
1967     DWORD sz;
1968     char buffer[2];
1969
1970     sz = sizeof buffer;
1971     strcpy(buffer,"x");
1972     r = MsiGetProperty( hpkg, prop, buffer, &sz );
1973     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
1974 }
1975
1976 static void test_props(void)
1977 {
1978     MSIHANDLE hpkg, hdb;
1979     UINT r;
1980     DWORD sz;
1981     char buffer[0x100];
1982
1983     hdb = create_package_db();
1984     r = run_query( hdb,
1985             "CREATE TABLE `Property` ( "
1986             "`Property` CHAR(255) NOT NULL, "
1987             "`Value` CHAR(255) "
1988             "PRIMARY KEY `Property`)" );
1989     ok( r == ERROR_SUCCESS , "Failed\n" );
1990
1991     r = run_query(hdb,
1992             "INSERT INTO `Property` "
1993             "(`Property`, `Value`) "
1994             "VALUES( 'MetadataCompName', 'Photoshop.dll' )");
1995     ok( r == ERROR_SUCCESS , "Failed\n" );
1996
1997     r = package_from_db( hdb, &hpkg );
1998     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1999     {
2000         skip("Not enough rights to perform tests\n");
2001         DeleteFile(msifile);
2002         return;
2003     }
2004     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2005
2006     /* test invalid values */
2007     r = MsiGetProperty( 0, NULL, NULL, NULL );
2008     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2009
2010     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
2011     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2012
2013     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
2014     ok( r == ERROR_SUCCESS, "wrong return val\n");
2015
2016     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
2017     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2018
2019     /* test retrieving an empty/nonexistent property */
2020     sz = sizeof buffer;
2021     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
2022     ok( r == ERROR_SUCCESS, "wrong return val\n");
2023     ok( sz == 0, "wrong size returned\n");
2024
2025     check_prop_empty( hpkg, "boo");
2026     sz = 0;
2027     strcpy(buffer,"x");
2028     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2029     ok( r == ERROR_MORE_DATA, "wrong return val\n");
2030     ok( !strcmp(buffer,"x"), "buffer was changed\n");
2031     ok( sz == 0, "wrong size returned\n");
2032
2033     sz = 1;
2034     strcpy(buffer,"x");
2035     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2036     ok( r == ERROR_SUCCESS, "wrong return val\n");
2037     ok( buffer[0] == 0, "buffer was not changed\n");
2038     ok( sz == 0, "wrong size returned\n");
2039
2040     /* set the property to something */
2041     r = MsiSetProperty( 0, NULL, NULL );
2042     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
2043
2044     r = MsiSetProperty( hpkg, NULL, NULL );
2045     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2046
2047     r = MsiSetProperty( hpkg, "", NULL );
2048     ok( r == ERROR_SUCCESS, "wrong return val\n");
2049
2050     /* try set and get some illegal property identifiers */
2051     r = MsiSetProperty( hpkg, "", "asdf" );
2052     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
2053
2054     r = MsiSetProperty( hpkg, "=", "asdf" );
2055     ok( r == ERROR_SUCCESS, "wrong return val\n");
2056
2057     r = MsiSetProperty( hpkg, " ", "asdf" );
2058     ok( r == ERROR_SUCCESS, "wrong return val\n");
2059
2060     r = MsiSetProperty( hpkg, "'", "asdf" );
2061     ok( r == ERROR_SUCCESS, "wrong return val\n");
2062
2063     sz = sizeof buffer;
2064     buffer[0]=0;
2065     r = MsiGetProperty( hpkg, "'", buffer, &sz );
2066     ok( r == ERROR_SUCCESS, "wrong return val\n");
2067     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
2068
2069     /* set empty values */
2070     r = MsiSetProperty( hpkg, "boo", NULL );
2071     ok( r == ERROR_SUCCESS, "wrong return val\n");
2072     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2073
2074     r = MsiSetProperty( hpkg, "boo", "" );
2075     ok( r == ERROR_SUCCESS, "wrong return val\n");
2076     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2077
2078     /* set a non-empty value */
2079     r = MsiSetProperty( hpkg, "boo", "xyz" );
2080     ok( r == ERROR_SUCCESS, "wrong return val\n");
2081
2082     sz = 1;
2083     strcpy(buffer,"x");
2084     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2085     ok( r == ERROR_MORE_DATA, "wrong return val\n");
2086     ok( buffer[0] == 0, "buffer was not changed\n");
2087     ok( sz == 3, "wrong size returned\n");
2088
2089     sz = 4;
2090     strcpy(buffer,"x");
2091     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2092     ok( r == ERROR_SUCCESS, "wrong return val\n");
2093     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
2094     ok( sz == 3, "wrong size returned\n");
2095
2096     sz = 3;
2097     strcpy(buffer,"x");
2098     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2099     ok( r == ERROR_MORE_DATA, "wrong return val\n");
2100     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
2101     ok( sz == 3, "wrong size returned\n");
2102
2103     r = MsiSetProperty(hpkg, "SourceDir", "foo");
2104     ok( r == ERROR_SUCCESS, "wrong return val\n");
2105
2106     sz = 4;
2107     r = MsiGetProperty(hpkg, "SOURCEDIR", buffer, &sz);
2108     ok( r == ERROR_SUCCESS, "wrong return val\n");
2109     ok( !strcmp(buffer,""), "buffer wrong\n");
2110     ok( sz == 0, "wrong size returned\n");
2111
2112     sz = 4;
2113     r = MsiGetProperty(hpkg, "SOMERANDOMNAME", buffer, &sz);
2114     ok( r == ERROR_SUCCESS, "wrong return val\n");
2115     ok( !strcmp(buffer,""), "buffer wrong\n");
2116     ok( sz == 0, "wrong size returned\n");
2117
2118     sz = 4;
2119     r = MsiGetProperty(hpkg, "SourceDir", buffer, &sz);
2120     ok( r == ERROR_SUCCESS, "wrong return val\n");
2121     ok( !strcmp(buffer,"foo"), "buffer wrong\n");
2122     ok( sz == 3, "wrong size returned\n");
2123
2124     r = MsiSetProperty(hpkg, "MetadataCompName", "Photoshop.dll");
2125     ok( r == ERROR_SUCCESS, "wrong return val\n");
2126
2127     sz = 0;
2128     r = MsiGetProperty(hpkg, "MetadataCompName", NULL, &sz );
2129     ok( r == ERROR_SUCCESS, "return wrong\n");
2130     ok( sz == 13, "size wrong (%d)\n", sz);
2131
2132     sz = 13;
2133     r = MsiGetProperty(hpkg, "MetadataCompName", buffer, &sz );
2134     ok( r == ERROR_MORE_DATA, "return wrong\n");
2135     ok( !strcmp(buffer,"Photoshop.dl"), "buffer wrong\n");
2136
2137     r = MsiSetProperty(hpkg, "property", "value");
2138     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2139
2140     sz = 6;
2141     r = MsiGetProperty(hpkg, "property", buffer, &sz);
2142     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2143     ok( !strcmp(buffer, "value"), "Expected value, got %s\n", buffer);
2144
2145     r = MsiSetProperty(hpkg, "property", NULL);
2146     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2147
2148     sz = 6;
2149     r = MsiGetProperty(hpkg, "property", buffer, &sz);
2150     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2151     ok( !strlen(buffer), "Expected empty string, got %s\n", buffer);
2152
2153     MsiCloseHandle( hpkg );
2154     DeleteFile(msifile);
2155 }
2156
2157 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2158 {
2159     MSIHANDLE hview, hrec;
2160     BOOL found = FALSE;
2161     CHAR buffer[MAX_PATH];
2162     DWORD sz;
2163     UINT r;
2164
2165     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Property`", &hview);
2166     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2167     r = MsiViewExecute(hview, 0);
2168     ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2169
2170     if (len < 0) len = lstrlenA(val);
2171
2172     while (r == ERROR_SUCCESS && !found)
2173     {
2174         r = MsiViewFetch(hview, &hrec);
2175         if (r != ERROR_SUCCESS) break;
2176
2177         sz = MAX_PATH;
2178         r = MsiRecordGetString(hrec, 1, buffer, &sz);
2179         if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2180         {
2181             sz = MAX_PATH;
2182             r = MsiRecordGetString(hrec, 2, buffer, &sz);
2183             if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2184             {
2185                 ok(sz == len, "wrong size %u\n", sz);
2186                 found = TRUE;
2187             }
2188         }
2189
2190         MsiCloseHandle(hrec);
2191     }
2192     MsiViewClose(hview);
2193     MsiCloseHandle(hview);
2194     return found;
2195 }
2196
2197 static void test_property_table(void)
2198 {
2199     const char *query;
2200     UINT r;
2201     MSIHANDLE hpkg, hdb, hrec;
2202     char buffer[MAX_PATH], package[10];
2203     DWORD sz;
2204     BOOL found;
2205
2206     hdb = create_package_db();
2207     ok( hdb, "failed to create package\n");
2208
2209     r = package_from_db(hdb, &hpkg);
2210     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2211     {
2212         skip("Not enough rights to perform tests\n");
2213         DeleteFile(msifile);
2214         return;
2215     }
2216     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2217
2218     MsiCloseHandle(hdb);
2219
2220     hdb = MsiGetActiveDatabase(hpkg);
2221
2222     query = "CREATE TABLE `_Property` ( "
2223         "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2224     r = run_query(hdb, query);
2225     ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2226
2227     MsiCloseHandle(hdb);
2228     MsiCloseHandle(hpkg);
2229     DeleteFile(msifile);
2230
2231     hdb = create_package_db();
2232     ok( hdb, "failed to create package\n");
2233
2234     query = "CREATE TABLE `_Property` ( "
2235         "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2236     r = run_query(hdb, query);
2237     ok(r == ERROR_SUCCESS, "failed to create table\n");
2238
2239     query = "ALTER `_Property` ADD `foo` INTEGER";
2240     r = run_query(hdb, query);
2241     ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2242
2243     query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2244     r = run_query(hdb, query);
2245     ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2246
2247     query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2248     r = run_query(hdb, query);
2249     ok(r == ERROR_SUCCESS, "failed to add column\n");
2250
2251     sprintf(package, "#%i", hdb);
2252     r = MsiOpenPackage(package, &hpkg);
2253     todo_wine ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2254     if (r == ERROR_SUCCESS)
2255         MsiCloseHandle(hpkg);
2256
2257     r = MsiCloseHandle(hdb);
2258     ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2259
2260     hdb = create_package_db();
2261     ok (hdb, "failed to create package database\n");
2262
2263     r = create_property_table(hdb);
2264     ok(r == ERROR_SUCCESS, "cannot create Property table: %d\n", r);
2265
2266     r = add_property_entry(hdb, "'prop', 'val'");
2267     ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2268
2269     r = create_custom_action_table(hdb);
2270     ok(r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
2271
2272     r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2273     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2274
2275     r = package_from_db(hdb, &hpkg);
2276     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2277
2278     MsiCloseHandle(hdb);
2279
2280     sz = MAX_PATH;
2281     r = MsiGetProperty(hpkg, "prop", buffer, &sz);
2282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2283     ok(!lstrcmp(buffer, "val"), "Expected val, got %s\n", buffer);
2284
2285     hdb = MsiGetActiveDatabase(hpkg);
2286
2287     found = find_prop_in_property(hdb, "prop", "val", -1);
2288     ok(found, "prop should be in the _Property table\n");
2289
2290     r = add_property_entry(hdb, "'dantes', 'mercedes'");
2291     ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2292
2293     query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2294     r = do_query(hdb, query, &hrec);
2295     ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2296
2297     found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2298     ok(found == FALSE, "dantes should not be in the _Property table\n");
2299
2300     sz = MAX_PATH;
2301     lstrcpy(buffer, "aaa");
2302     r = MsiGetProperty(hpkg, "dantes", buffer, &sz);
2303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2304     ok(lstrlenA(buffer) == 0, "Expected empty string, got %s\n", buffer);
2305
2306     r = MsiSetProperty(hpkg, "dantes", "mercedes");
2307     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2308
2309     found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2310     ok(found == TRUE, "dantes should be in the _Property table\n");
2311
2312     r = MsiDoAction( hpkg, "EmbedNull" );
2313     ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2314
2315     sz = MAX_PATH;
2316     memset( buffer, 'a', sizeof(buffer) );
2317     r = MsiGetProperty( hpkg, "prop2", buffer, &sz );
2318     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2319     ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2320     ok( sz == sizeof("\0np") - 1, "got %u\n", sz );
2321
2322     found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2323     ok(found == TRUE, "prop2 should be in the _Property table\n");
2324
2325     MsiCloseHandle(hdb);
2326     MsiCloseHandle(hpkg);
2327     DeleteFile(msifile);
2328 }
2329
2330 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2331 {
2332     MSIHANDLE htab = 0;
2333     UINT res;
2334
2335     res = MsiDatabaseOpenView( hdb, szQuery, &htab );
2336     if( res == ERROR_SUCCESS )
2337     {
2338         UINT r;
2339
2340         r = MsiViewExecute( htab, hrec );
2341         if( r != ERROR_SUCCESS )
2342         {
2343             res = r;
2344             fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2345         }
2346
2347         r = MsiViewClose( htab );
2348         if( r != ERROR_SUCCESS )
2349             res = r;
2350
2351         r = MsiCloseHandle( htab );
2352         if( r != ERROR_SUCCESS )
2353             res = r;
2354     }
2355     return res;
2356 }
2357
2358 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2359 {
2360     return try_query_param( hdb, szQuery, 0 );
2361 }
2362
2363 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2364 {
2365     MSIHANDLE summary;
2366     UINT r;
2367
2368     r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2369     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2370
2371     r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2373
2374     r = MsiSummaryInfoPersist(summary);
2375     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2376
2377     MsiCloseHandle(summary);
2378 }
2379
2380 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2381 {
2382     MSIHANDLE summary;
2383     UINT r;
2384
2385     r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2387
2388     r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2390
2391     r = MsiSummaryInfoPersist(summary);
2392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2393
2394     MsiCloseHandle(summary);
2395 }
2396
2397 static void test_msipackage(void)
2398 {
2399     MSIHANDLE hdb = 0, hpack = 100;
2400     UINT r;
2401     const char *query;
2402     char name[10];
2403
2404     /* NULL szPackagePath */
2405     r = MsiOpenPackage(NULL, &hpack);
2406     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2407
2408     /* empty szPackagePath */
2409     r = MsiOpenPackage("", &hpack);
2410     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2411     {
2412         skip("Not enough rights to perform tests\n");
2413         return;
2414     }
2415     todo_wine
2416     {
2417         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2418     }
2419
2420     if (r == ERROR_SUCCESS)
2421         MsiCloseHandle(hpack);
2422
2423     /* nonexistent szPackagePath */
2424     r = MsiOpenPackage("nonexistent", &hpack);
2425     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2426
2427     /* NULL hProduct */
2428     r = MsiOpenPackage(msifile, NULL);
2429     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2430
2431     name[0]='#';
2432     name[1]=0;
2433     r = MsiOpenPackage(name, &hpack);
2434     ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2435
2436     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2438
2439     /* database exists, but is emtpy */
2440     sprintf(name, "#%d", hdb);
2441     r = MsiOpenPackage(name, &hpack);
2442     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2443        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2444
2445     query = "CREATE TABLE `Property` ( "
2446             "`Property` CHAR(72), `Value` CHAR(0) "
2447             "PRIMARY KEY `Property`)";
2448     r = try_query(hdb, query);
2449     ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2450
2451     query = "CREATE TABLE `InstallExecuteSequence` ("
2452             "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2453             "PRIMARY KEY `Action`)";
2454     r = try_query(hdb, query);
2455     ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2456
2457     /* a few key tables exist */
2458     sprintf(name, "#%d", hdb);
2459     r = MsiOpenPackage(name, &hpack);
2460     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2461        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2462
2463     MsiCloseHandle(hdb);
2464     DeleteFile(msifile);
2465
2466     /* start with a clean database to show what constitutes a valid package */
2467     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2469
2470     sprintf(name, "#%d", hdb);
2471
2472     /* The following summary information props must exist:
2473      *  - PID_REVNUMBER
2474      *  - PID_PAGECOUNT
2475      */
2476
2477     set_summary_dword(hdb, PID_PAGECOUNT, 100);
2478     r = MsiOpenPackage(name, &hpack);
2479     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2480        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2481
2482     set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2483     r = MsiOpenPackage(name, &hpack);
2484     ok(r == ERROR_SUCCESS,
2485        "Expected ERROR_SUCCESS, got %d\n", r);
2486
2487     MsiCloseHandle(hpack);
2488     MsiCloseHandle(hdb);
2489     DeleteFile(msifile);
2490 }
2491
2492 static void test_formatrecord2(void)
2493 {
2494     MSIHANDLE hpkg, hrec ;
2495     char buffer[0x100];
2496     DWORD sz;
2497     UINT r;
2498
2499     r = package_from_db(create_package_db(), &hpkg);
2500     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2501     {
2502         skip("Not enough rights to perform tests\n");
2503         DeleteFile(msifile);
2504         return;
2505     }
2506     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2507
2508     r = MsiSetProperty(hpkg, "Manufacturer", " " );
2509     ok( r == ERROR_SUCCESS, "set property failed\n");
2510
2511     hrec = MsiCreateRecord(2);
2512     ok(hrec, "create record failed\n");
2513
2514     r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2515     ok( r == ERROR_SUCCESS, "format record failed\n");
2516
2517     buffer[0] = 0;
2518     sz = sizeof buffer;
2519     r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
2520     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2521
2522     r = MsiRecordSetString(hrec, 0, "[foo][1]");
2523     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2524     r = MsiRecordSetString(hrec, 1, "hoo");
2525     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2526     sz = sizeof buffer;
2527     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2528     ok( sz == 3, "size wrong\n");
2529     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2530     ok( r == ERROR_SUCCESS, "format failed\n");
2531
2532     r = MsiRecordSetString(hrec, 0, "x[~]x");
2533     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2534     sz = sizeof buffer;
2535     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2536     ok( sz == 3, "size wrong\n");
2537     ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2538     ok( r == ERROR_SUCCESS, "format failed\n");
2539
2540     r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
2541     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2542     r = MsiRecordSetString(hrec, 1, "hoo");
2543     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2544     sz = sizeof buffer;
2545     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2546     ok( sz == 3, "size wrong\n");
2547     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2548     ok( r == ERROR_SUCCESS, "format failed\n");
2549
2550     r = MsiRecordSetString(hrec, 0, "[\\[]");
2551     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2552     sz = sizeof buffer;
2553     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2554     ok( sz == 1, "size wrong\n");
2555     ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2556     ok( r == ERROR_SUCCESS, "format failed\n");
2557
2558     SetEnvironmentVariable("FOO", "BAR");
2559     r = MsiRecordSetString(hrec, 0, "[%FOO]");
2560     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2561     sz = sizeof buffer;
2562     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2563     ok( sz == 3, "size wrong\n");
2564     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2565     ok( r == ERROR_SUCCESS, "format failed\n");
2566
2567     r = MsiRecordSetString(hrec, 0, "[[1]]");
2568     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2569     r = MsiRecordSetString(hrec, 1, "%FOO");
2570     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2571     sz = sizeof buffer;
2572     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2573     ok( sz == 3, "size wrong\n");
2574     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2575     ok( r == ERROR_SUCCESS, "format failed\n");
2576
2577     MsiCloseHandle( hrec );
2578     MsiCloseHandle( hpkg );
2579     DeleteFile(msifile);
2580 }
2581
2582 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
2583                                  INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
2584 {
2585     UINT r;
2586     INSTALLSTATE state = 0xdeadbee;
2587     INSTALLSTATE action = 0xdeadbee;
2588
2589     r = MsiGetFeatureState( package, feature, &state, &action );
2590     ok( r == error, "%u: expected %d got %d\n", line, error, r );
2591     if (r == ERROR_SUCCESS)
2592     {
2593         ok( state == expected_state, "%u: expected state %d got %d\n",
2594             line, expected_state, state );
2595         if (todo) todo_wine
2596             ok( action == expected_action, "%u: expected action %d got %d\n",
2597                 line, expected_action, action );
2598         else
2599             ok( action == expected_action, "%u: expected action %d got %d\n",
2600                 line, expected_action, action );
2601     }
2602     else
2603     {
2604         ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
2605         if (todo) todo_wine
2606             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2607         else
2608             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2609
2610     }
2611 }
2612
2613 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
2614                                    INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
2615 {
2616     UINT r;
2617     INSTALLSTATE state = 0xdeadbee;
2618     INSTALLSTATE action = 0xdeadbee;
2619
2620     r = MsiGetComponentState( package, component, &state, &action );
2621     ok( r == error, "%u: expected %d got %d\n", line, error, r );
2622     if (r == ERROR_SUCCESS)
2623     {
2624         ok( state == expected_state, "%u: expected state %d got %d\n",
2625             line, expected_state, state );
2626         if (todo) todo_wine
2627             ok( action == expected_action, "%u: expected action %d got %d\n",
2628                 line, expected_action, action );
2629         else
2630             ok( action == expected_action, "%u: expected action %d got %d\n",
2631                 line, expected_action, action );
2632     }
2633     else
2634     {
2635         ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2636             line, state );
2637         if (todo) todo_wine
2638             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2639                 line, action );
2640         else
2641             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2642                 line, action );
2643     }
2644 }
2645
2646 static void test_states(void)
2647 {
2648     static char msifile2[] = "winetest2-package.msi";
2649     static char msifile3[] = "winetest3-package.msi";
2650     static char msifile4[] = "winetest4-package.msi";
2651     MSIHANDLE hpkg;
2652     UINT r;
2653     MSIHANDLE hdb;
2654
2655     if (is_process_limited())
2656     {
2657         skip("process is limited\n");
2658         return;
2659     }
2660
2661     hdb = create_package_db();
2662     ok ( hdb, "failed to create package database\n" );
2663
2664     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2665     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
2666
2667     r = create_property_table( hdb );
2668     ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r );
2669
2670     r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2671     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2672
2673     r = add_property_entry( hdb, "'ProductLanguage', '1033'" );
2674     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2675
2676     r = add_property_entry( hdb, "'ProductName', 'MSITEST'" );
2677     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2678
2679     r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
2680     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2681
2682     r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
2683     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2684
2685     r = create_install_execute_sequence_table( hdb );
2686     ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r );
2687
2688     r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
2689     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2690
2691     r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
2692     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2693
2694     r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
2695     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2696
2697     r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
2698     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2699
2700     r = add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
2701     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2702
2703     r = add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
2704     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2705
2706     r = add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
2707     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2708
2709     r = add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
2710     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2711
2712     r = add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
2713     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2714
2715     r = add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
2716     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2717
2718     r = add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
2719     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2720
2721     r = create_media_table( hdb );
2722     ok( r == ERROR_SUCCESS, "cannot create media table: %d\n", r );
2723
2724     r = add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
2725     ok( r == ERROR_SUCCESS, "cannot add media entry: %d\n", r );
2726
2727     r = create_feature_table( hdb );
2728     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
2729
2730     r = create_component_table( hdb );
2731     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
2732
2733     /* msidbFeatureAttributesFavorLocal */
2734     r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2735     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2736
2737     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2738     r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
2739     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2740
2741     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2742     r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
2743     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2744
2745     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2746     r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
2747     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2748
2749     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
2750     r = add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
2751     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2752
2753     /* msidbFeatureAttributesFavorSource */
2754     r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
2755     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2756
2757     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2758     r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
2759     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2760
2761     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2762     r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
2763     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2764
2765     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2766     r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
2767     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2768
2769     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
2770     r = add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
2771     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2772
2773     /* msidbFeatureAttributesFavorSource */
2774     r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
2775     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2776
2777     /* msidbFeatureAttributesFavorLocal */
2778     r = add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
2779     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2780
2781     /* disabled */
2782     r = add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
2783     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2784
2785     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2786     r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
2787     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2788
2789     /* no feature parent:msidbComponentAttributesLocalOnly */
2790     r = add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
2791     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2792
2793     /* msidbFeatureAttributesFavorLocal:removed */
2794     r = add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
2795     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2796
2797     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
2798     r = add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
2799     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2800
2801     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
2802     r = add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
2803     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2804
2805     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
2806     r = add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
2807     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2808
2809     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
2810     r = add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
2811     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2812
2813     /* msidbFeatureAttributesFavorSource:removed */
2814     r = add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
2815     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2816
2817     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
2818     r = add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
2819     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2820
2821     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
2822     r = add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
2823     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2824
2825     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
2826     r = add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
2827     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2828
2829     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
2830     r = add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
2831     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2832
2833     /* msidbFeatureAttributesFavorLocal */
2834     r = add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
2835     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2836
2837     r = add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
2838     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2839
2840     /* msidbFeatureAttributesFavorSource */
2841     r = add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
2842     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2843
2844     r = add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
2845     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2846
2847     /* msidbFeatureAttributesFavorAdvertise */
2848     r = add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
2849     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2850
2851     r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
2852     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2853
2854     /* msidbFeatureAttributesUIDisallowAbsent */
2855     r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
2856     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2857
2858     r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
2859     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2860
2861     r = create_feature_components_table( hdb );
2862     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
2863
2864     r = add_feature_components_entry( hdb, "'one', 'alpha'" );
2865     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2866
2867     r = add_feature_components_entry( hdb, "'one', 'beta'" );
2868     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2869
2870     r = add_feature_components_entry( hdb, "'one', 'gamma'" );
2871     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2872
2873     r = add_feature_components_entry( hdb, "'one', 'theta'" );
2874     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2875
2876     r = add_feature_components_entry( hdb, "'two', 'delta'" );
2877     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2878
2879     r = add_feature_components_entry( hdb, "'two', 'epsilon'" );
2880     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2881
2882     r = add_feature_components_entry( hdb, "'two', 'zeta'" );
2883     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2884
2885     r = add_feature_components_entry( hdb, "'two', 'iota'" );
2886     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2887
2888     r = add_feature_components_entry( hdb, "'three', 'eta'" );
2889     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2890
2891     r = add_feature_components_entry( hdb, "'four', 'eta'" );
2892     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2893
2894     r = add_feature_components_entry( hdb, "'five', 'eta'" );
2895     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2896
2897     r = add_feature_components_entry( hdb, "'six', 'lambda'" );
2898     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2899
2900     r = add_feature_components_entry( hdb, "'six', 'mu'" );
2901     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2902
2903     r = add_feature_components_entry( hdb, "'six', 'nu'" );
2904     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2905
2906     r = add_feature_components_entry( hdb, "'six', 'xi'" );
2907     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2908
2909     r = add_feature_components_entry( hdb, "'seven', 'omicron'" );
2910     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2911
2912     r = add_feature_components_entry( hdb, "'seven', 'pi'" );
2913     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2914
2915     r = add_feature_components_entry( hdb, "'seven', 'rho'" );
2916     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2917
2918     r = add_feature_components_entry( hdb, "'seven', 'sigma'" );
2919     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2920
2921     r = add_feature_components_entry( hdb, "'eight', 'tau'" );
2922     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2923
2924     r = add_feature_components_entry( hdb, "'nine', 'phi'" );
2925     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2926
2927     r = add_feature_components_entry( hdb, "'ten', 'chi'" );
2928     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2929
2930     r = add_feature_components_entry( hdb, "'eleven', 'psi'" );
2931     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2932
2933     r = create_file_table( hdb );
2934     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
2935
2936     r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
2937     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2938
2939     r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
2940     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2941
2942     r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
2943     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2944
2945     r = add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
2946     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2947
2948     r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
2949     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2950
2951     r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
2952     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2953
2954     r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
2955     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2956
2957     r = add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
2958     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2959
2960     /* compressed file */
2961     r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
2962     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2963
2964     r = add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
2965     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2966
2967     r = add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
2968     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2969
2970     r = add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
2971     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2972
2973     r = add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
2974     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2975
2976     r = add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
2977     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2978
2979     r = add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
2980     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2981
2982     r = add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
2983     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2984
2985     r = add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
2986     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2987
2988     r = add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
2989     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2990
2991     r = add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
2992     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2993
2994     r = add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
2995     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2996
2997     r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
2998     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2999
3000     r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3001     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3002
3003     MsiDatabaseCommit(hdb);
3004
3005     /* these properties must not be in the saved msi file */
3006     r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3007     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3008
3009     r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3010     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3011
3012     r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
3013     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3014
3015     r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3016     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3017
3018     r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3019     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3020
3021     r = package_from_db( hdb, &hpkg );
3022     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3023     {
3024         skip("Not enough rights to perform tests\n");
3025         DeleteFile(msifile);
3026         return;
3027     }
3028     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3029
3030     MsiCloseHandle(hdb);
3031
3032     CopyFileA(msifile, msifile2, FALSE);
3033     CopyFileA(msifile, msifile3, FALSE);
3034     CopyFileA(msifile, msifile4, FALSE);
3035
3036     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3037     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3038
3039     r = MsiDoAction( hpkg, "CostInitialize");
3040     ok( r == ERROR_SUCCESS, "cost init failed\n");
3041
3042     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3043     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3044
3045     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3046
3047     r = MsiDoAction( hpkg, "FileCost");
3048     ok( r == ERROR_SUCCESS, "file cost failed\n");
3049
3050     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3051     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3052
3053     r = MsiDoAction( hpkg, "CostFinalize");
3054     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3055
3056     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3057     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3058     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3059     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3060     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3061     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3062     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3063     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3064     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3065     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3066     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3067
3068     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3069     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3070     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3071     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3072     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3073     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3074     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3075     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3076     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3077     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3078     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3079     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3080     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3081     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3082     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3083     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3084     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3085     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3086     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3087     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3088     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3089     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3090
3091     MsiCloseHandle( hpkg );
3092
3093     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3094
3095     /* publish the features and components */
3096     r = MsiInstallProduct(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3097     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3098
3099     r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
3100     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3101
3102     /* these properties must not be in the saved msi file */
3103     r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3104     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3105
3106     r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3107     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3108
3109     r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
3110     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3111
3112     r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3113     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3114
3115     r = package_from_db( hdb, &hpkg );
3116     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3117
3118     MsiCloseHandle(hdb);
3119
3120     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3121     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3122
3123     r = MsiDoAction( hpkg, "CostInitialize");
3124     ok( r == ERROR_SUCCESS, "cost init failed\n");
3125
3126     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3127     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3128
3129     r = MsiDoAction( hpkg, "FileCost");
3130     ok( r == ERROR_SUCCESS, "file cost failed\n");
3131
3132     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3133     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3134
3135     r = MsiDoAction( hpkg, "CostFinalize");
3136     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3137
3138     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
3139     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3140     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3141     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3142     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3143     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3144     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3145     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3146     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3147     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3148     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3149
3150     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3151     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3152     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3153     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3154     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3155     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3156     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3157     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3158     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3159     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3160     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3161     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3162     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3163     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3164     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3165     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3166     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3167     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3168     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3169     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3170     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3171     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3172
3173     MsiCloseHandle(hpkg);
3174
3175     /* uninstall the product */
3176     r = MsiInstallProduct(msifile, "REMOVE=ALL");
3177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3178
3179     /* all features installed locally */
3180     r = MsiInstallProduct(msifile2, "ADDLOCAL=ALL");
3181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3182
3183     r = MsiOpenDatabase(msifile2, MSIDBOPEN_DIRECT, &hdb);
3184     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3185
3186     /* these properties must not be in the saved msi file */
3187     r = add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3188     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3189
3190     r = package_from_db( hdb, &hpkg );
3191     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3192
3193     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3194     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3195
3196     r = MsiDoAction( hpkg, "CostInitialize");
3197     ok( r == ERROR_SUCCESS, "cost init failed\n");
3198
3199     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3200     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3201
3202     r = MsiDoAction( hpkg, "CostFinalize");
3203     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3204
3205     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
3206     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
3207     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3208     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3209     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3210     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
3211     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
3212     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
3213     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
3214     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
3215     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3216
3217     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3218     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3219     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3220     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3221     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3222     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3223     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3224     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3225     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3226     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3227     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3228     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3229     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3230     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3231     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3232     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3233     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3234     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3235     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3236     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3237     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3238     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3239
3240     MsiCloseHandle(hpkg);
3241
3242     /* uninstall the product */
3243     r = MsiInstallProduct(msifile2, "REMOVE=ALL");
3244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3245
3246     /* all features installed from source */
3247     r = MsiInstallProduct(msifile3, "ADDSOURCE=ALL");
3248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3249
3250     r = MsiOpenDatabase(msifile3, MSIDBOPEN_DIRECT, &hdb);
3251     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3252
3253     /* this property must not be in the saved msi file */
3254     r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3255     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3256
3257     r = package_from_db( hdb, &hpkg );
3258     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3259
3260     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3261     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3262
3263     r = MsiDoAction( hpkg, "CostInitialize");
3264     ok( r == ERROR_SUCCESS, "cost init failed\n");
3265
3266     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3267     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3268
3269     r = MsiDoAction( hpkg, "FileCost");
3270     ok( r == ERROR_SUCCESS, "file cost failed\n");
3271
3272     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3273     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3274
3275     r = MsiDoAction( hpkg, "CostFinalize");
3276     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3277
3278     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3279     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3280     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3281     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3282     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3283     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3284     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3285     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3286     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3287     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3288     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3289
3290     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3291     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3292     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3293     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3294     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3295     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3296     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3297     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3298     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3299     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3300     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3301     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3302     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3303     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3304     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3305     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3306     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3307     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3308     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3309     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3310     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3311     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3312
3313     MsiCloseHandle(hpkg);
3314
3315     /* reinstall the product */
3316     r = MsiInstallProduct(msifile3, "REINSTALL=ALL");
3317     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3318
3319     r = MsiOpenDatabase(msifile4, MSIDBOPEN_DIRECT, &hdb);
3320     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3321
3322     /* this property must not be in the saved msi file */
3323     r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3324     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3325
3326     r = package_from_db( hdb, &hpkg );
3327     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3328
3329     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3330     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3331
3332     r = MsiDoAction( hpkg, "CostInitialize");
3333     ok( r == ERROR_SUCCESS, "cost init failed\n");
3334
3335     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3336     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3337
3338     r = MsiDoAction( hpkg, "FileCost");
3339     ok( r == ERROR_SUCCESS, "file cost failed\n");
3340
3341     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3342     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3343
3344     r = MsiDoAction( hpkg, "CostFinalize");
3345     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3346
3347     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3348     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3349     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3350     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3351     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3352     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3353     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3354     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3355     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3356     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
3357     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
3358
3359     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3360     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3361     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3362     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3363     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3364     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3365     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3366     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3367     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3368     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3369     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3370     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3371     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3372     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3373     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3374     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3375     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3376     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
3377     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3378     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3379     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3380     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
3381
3382     MsiCloseHandle(hpkg);
3383
3384     /* uninstall the product */
3385     r = MsiInstallProduct(msifile4, "REMOVE=ALL");
3386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3387
3388     DeleteFileA(msifile);
3389     DeleteFileA(msifile2);
3390     DeleteFileA(msifile3);
3391     DeleteFileA(msifile4);
3392 }
3393
3394 static void test_getproperty(void)
3395 {
3396     MSIHANDLE hPackage = 0;
3397     char prop[100];
3398     static CHAR empty[] = "";
3399     DWORD size;
3400     UINT r;
3401
3402     r = package_from_db(create_package_db(), &hPackage);
3403     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3404     {
3405         skip("Not enough rights to perform tests\n");
3406         DeleteFile(msifile);
3407         return;
3408     }
3409     ok( r == ERROR_SUCCESS, "Failed to create package %u\n", r );
3410
3411     /* set the property */
3412     r = MsiSetProperty(hPackage, "Name", "Value");
3413     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3414
3415     /* retrieve the size, NULL pointer */
3416     size = 0;
3417     r = MsiGetProperty(hPackage, "Name", NULL, &size);
3418     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3419     ok( size == 5, "Expected 5, got %d\n", size);
3420
3421     /* retrieve the size, empty string */
3422     size = 0;
3423     r = MsiGetProperty(hPackage, "Name", empty, &size);
3424     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3425     ok( size == 5, "Expected 5, got %d\n", size);
3426
3427     /* don't change size */
3428     r = MsiGetProperty(hPackage, "Name", prop, &size);
3429     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3430     ok( size == 5, "Expected 5, got %d\n", size);
3431     ok( !lstrcmp(prop, "Valu"), "Expected Valu, got %s\n", prop);
3432
3433     /* increase the size by 1 */
3434     size++;
3435     r = MsiGetProperty(hPackage, "Name", prop, &size);
3436     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3437     ok( size == 5, "Expected 5, got %d\n", size);
3438     ok( !lstrcmp(prop, "Value"), "Expected Value, got %s\n", prop);
3439
3440     r = MsiCloseHandle( hPackage);
3441     ok( r == ERROR_SUCCESS , "Failed to close package\n" );
3442     DeleteFile(msifile);
3443 }
3444
3445 static void test_removefiles(void)
3446 {
3447     MSIHANDLE hpkg;
3448     UINT r;
3449     MSIHANDLE hdb;
3450     INSTALLSTATE installed, action;
3451
3452     hdb = create_package_db();
3453     ok ( hdb, "failed to create package database\n" );
3454
3455     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3456     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
3457
3458     r = create_feature_table( hdb );
3459     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
3460
3461     r = create_component_table( hdb );
3462     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
3463
3464     r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3465     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
3466
3467     r = add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3468     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3469
3470     r = add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3471     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3472
3473     r = add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3474     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3475
3476     r = add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3477     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3478
3479     r = add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3480     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3481
3482     r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3483     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3484
3485     r = add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3486     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3487
3488     r = create_feature_components_table( hdb );
3489     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
3490
3491     r = add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3492     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3493
3494     r = add_feature_components_entry( hdb, "'one', 'helium'" );
3495     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3496
3497     r = add_feature_components_entry( hdb, "'one', 'lithium'" );
3498     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3499
3500     r = add_feature_components_entry( hdb, "'one', 'beryllium'" );
3501     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3502
3503     r = add_feature_components_entry( hdb, "'one', 'boron'" );
3504     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3505
3506     r = add_feature_components_entry( hdb, "'one', 'carbon'" );
3507     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3508
3509     r = add_feature_components_entry( hdb, "'one', 'oxygen'" );
3510     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3511
3512     r = create_file_table( hdb );
3513     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
3514
3515     r = add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3516     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3517
3518     r = add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3519     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3520
3521     r = add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3522     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3523
3524     r = add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3525     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3526
3527     r = add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3528     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3529
3530     r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3531     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3532
3533     r = add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3534     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3535
3536     r = create_remove_file_table( hdb );
3537     ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r);
3538
3539     r = package_from_db( hdb, &hpkg );
3540     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3541     {
3542         skip("Not enough rights to perform tests\n");
3543         DeleteFile(msifile);
3544         return;
3545     }
3546     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3547
3548     MsiCloseHandle( hdb );
3549
3550     create_test_file( "hydrogen.txt" );
3551     create_test_file( "helium.txt" );
3552     create_test_file( "lithium.txt" );
3553     create_test_file( "beryllium.txt" );
3554     create_test_file( "boron.txt" );
3555     create_test_file( "carbon.txt" );
3556     create_test_file( "oxygen.txt" );
3557
3558     r = MsiSetProperty( hpkg, "TARGETDIR", CURR_DIR );
3559     ok( r == ERROR_SUCCESS, "set property failed\n");
3560
3561     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3562
3563     r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
3564     ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3565
3566     r = MsiDoAction( hpkg, "CostInitialize");
3567     ok( r == ERROR_SUCCESS, "cost init failed\n");
3568
3569     r = MsiDoAction( hpkg, "FileCost");
3570     ok( r == ERROR_SUCCESS, "file cost failed\n");
3571
3572     installed = action = 0xdeadbeef;
3573     r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
3574     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3575     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3576     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3577
3578     r = MsiDoAction( hpkg, "CostFinalize");
3579     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3580
3581     r = MsiDoAction( hpkg, "InstallValidate");
3582     ok( r == ERROR_SUCCESS, "install validate failed\n");
3583
3584     r = MsiSetComponentState( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3585     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3586
3587     installed = action = 0xdeadbeef;
3588     r = MsiGetComponentState( hpkg, "hydrogen", &installed, &action );
3589     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3590     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3591     todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3592
3593     r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL );
3594     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3595
3596     r = MsiSetComponentState( hpkg, "lithium", INSTALLSTATE_SOURCE );
3597     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3598
3599     r = MsiSetComponentState( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3600     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3601
3602     r = MsiSetComponentState( hpkg, "boron", INSTALLSTATE_LOCAL );
3603     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3604
3605     r = MsiSetComponentState( hpkg, "carbon", INSTALLSTATE_SOURCE );
3606     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3607
3608     installed = action = 0xdeadbeef;
3609     r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
3610     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3611     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3612     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3613
3614     r = MsiSetComponentState( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3615     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3616
3617     installed = action = 0xdeadbeef;
3618     r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
3619     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3620     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3621     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3622
3623     r = MsiDoAction( hpkg, "RemoveFiles");
3624     ok( r == ERROR_SUCCESS, "remove files failed\n");
3625
3626     installed = action = 0xdeadbeef;
3627     r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
3628     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3629     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3630     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3631
3632     ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3633     ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");    
3634     ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
3635     ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
3636     ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
3637     ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
3638     ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
3639
3640     MsiCloseHandle( hpkg );
3641     DeleteFileA(msifile);
3642 }
3643
3644 static void test_appsearch(void)
3645 {
3646     MSIHANDLE hpkg;
3647     UINT r;
3648     MSIHANDLE hdb;
3649     CHAR prop[MAX_PATH];
3650     DWORD size;
3651
3652     hdb = create_package_db();
3653     ok ( hdb, "failed to create package database\n" );
3654
3655     r = create_appsearch_table( hdb );
3656     ok( r == ERROR_SUCCESS, "cannot create AppSearch table: %d\n", r );
3657
3658     r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
3659     ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
3660
3661     r = add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
3662     ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
3663
3664     r = create_reglocator_table( hdb );
3665     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3666
3667     r = add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
3668     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3669
3670     r = create_drlocator_table( hdb );
3671     ok( r == ERROR_SUCCESS, "cannot create DrLocator table: %d\n", r );
3672
3673     r = add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
3674     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3675
3676     r = create_signature_table( hdb );
3677     ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
3678
3679     r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
3680     ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
3681
3682     r = add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3683     ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
3684
3685     r = package_from_db( hdb, &hpkg );
3686     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3687     {
3688         skip("Not enough rights to perform tests\n");
3689         DeleteFile(msifile);
3690         return;
3691     }
3692     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3693     MsiCloseHandle( hdb );
3694     if (r != ERROR_SUCCESS)
3695         goto done;
3696
3697     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3698
3699     r = MsiDoAction( hpkg, "AppSearch" );
3700     ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
3701
3702     size = sizeof(prop);
3703     r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
3704     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3705     ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3706
3707     size = sizeof(prop);
3708     r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
3709     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3710
3711 done:
3712     MsiCloseHandle( hpkg );
3713     DeleteFileA(msifile);
3714 }
3715
3716 static void test_appsearch_complocator(void)
3717 {
3718     MSIHANDLE hpkg, hdb;
3719     CHAR path[MAX_PATH];
3720     CHAR prop[MAX_PATH];
3721     LPSTR usersid;
3722     DWORD size;
3723     UINT r;
3724
3725     if (!(usersid = get_user_sid()))
3726         return;
3727
3728     if (is_process_limited())
3729     {
3730         skip("process is limited\n");
3731         return;
3732     }
3733
3734     create_test_file("FileName1");
3735     create_test_file("FileName4");
3736     set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
3737                        "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
3738
3739     create_test_file("FileName2");
3740     set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
3741                        "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
3742
3743     create_test_file("FileName3");
3744     set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
3745                        "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
3746
3747     create_test_file("FileName5");
3748     set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
3749                        "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
3750
3751     create_test_file("FileName6");
3752     set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
3753                        "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
3754
3755     create_test_file("FileName7");
3756     set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
3757                        "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
3758
3759     /* dir is FALSE, but we're pretending it's a directory */
3760     set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
3761                        "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
3762
3763     create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
3764     set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
3765                        "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
3766
3767     create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
3768     set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
3769                        "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
3770
3771     create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
3772     set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
3773                        "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
3774
3775     hdb = create_package_db();
3776     ok(hdb, "Expected a valid database handle\n");
3777
3778     r = create_appsearch_table(hdb);
3779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3780
3781     r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
3782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3783
3784     r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786
3787     r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
3788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3789
3790     r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
3791     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3792
3793     r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
3794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3795
3796     r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
3797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3798
3799     r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
3800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3801
3802     r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
3803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3804
3805     r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
3806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3807
3808     r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
3809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3810
3811     r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
3812     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3813
3814     r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
3815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3816
3817     r = create_complocator_table(hdb);
3818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3819
3820     /* published component, machine, file, signature, misdbLocatorTypeFile */
3821     r = add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
3822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3823
3824     /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
3825     r = add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
3826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3827
3828     /* published component, user-managed, file, signature, misdbLocatorTypeFile */
3829     r = add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
3830     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3831
3832     /* published component, machine, file, signature, misdbLocatorTypeDirectory */
3833     r = add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
3834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3835
3836     /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
3837     r = add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
3838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3839
3840     /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
3841     r = add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
3842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3843
3844     /* published component, machine, file, no signature, misdbLocatorTypeFile */
3845     r = add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
3846     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3847
3848     /* unpublished component, no signature, misdbLocatorTypeDir */
3849     r = add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
3850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3851
3852     /* published component, no signature, dir does not exist misdbLocatorTypeDir */
3853     r = add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
3854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3855
3856     /* published component, signature w/ ver, misdbLocatorTypeFile */
3857     r = add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
3858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3859
3860     /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
3861     r = add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
3862     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3863
3864     /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
3865     r = add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
3866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3867
3868     r = create_signature_table(hdb);
3869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3870
3871     r = add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
3872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3873
3874     r = add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
3875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3876
3877     r = add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
3878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3879
3880     r = add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
3881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3882
3883     r = add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
3884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3885
3886     r = add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
3887     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3888
3889     r = add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
3890     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3891
3892     r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
3893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3894
3895     r = package_from_db(hdb, &hpkg);
3896     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3897     {
3898         skip("Not enough rights to perform tests\n");
3899         goto error;
3900     }
3901     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
3902
3903     r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
3904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3905
3906     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3907
3908     r = MsiDoAction(hpkg, "AppSearch");
3909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3910
3911     size = MAX_PATH;
3912     sprintf(path, "%s\\FileName1", CURR_DIR);
3913     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
3914     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3915     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3916
3917     size = MAX_PATH;
3918     sprintf(path, "%s\\FileName2", CURR_DIR);
3919     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
3920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3921     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3922
3923     size = MAX_PATH;
3924     sprintf(path, "%s\\FileName3", CURR_DIR);
3925     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
3926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3927     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3928
3929     size = MAX_PATH;
3930     sprintf(path, "%s\\FileName4", CURR_DIR);
3931     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
3932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3933     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
3934
3935     size = MAX_PATH;
3936     sprintf(path, "%s\\FileName5", CURR_DIR);
3937     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
3938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3939     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3940
3941     size = MAX_PATH;
3942     sprintf(path, "%s\\", CURR_DIR);
3943     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
3944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3945     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3946
3947     size = MAX_PATH;
3948     sprintf(path, "%s\\", CURR_DIR);
3949     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
3950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3951     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3952
3953     size = MAX_PATH;
3954     r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
3955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3956     ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
3957
3958     size = MAX_PATH;
3959     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
3960     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3961     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
3962
3963     size = MAX_PATH;
3964     sprintf(path, "%s\\FileName8.dll", CURR_DIR);
3965     r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
3966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3967     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3968
3969     size = MAX_PATH;
3970     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
3971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3972     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
3973
3974     size = MAX_PATH;
3975     sprintf(path, "%s\\FileName10.dll", CURR_DIR);
3976     r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
3977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3978     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
3979
3980     delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
3981                           MSIINSTALLCONTEXT_MACHINE, NULL);
3982     delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
3983                           MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
3984     delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
3985                           MSIINSTALLCONTEXT_USERMANAGED, usersid);
3986     delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
3987                           MSIINSTALLCONTEXT_MACHINE, NULL);
3988     delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
3989                           MSIINSTALLCONTEXT_MACHINE, NULL);
3990     delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
3991                           MSIINSTALLCONTEXT_MACHINE, NULL);
3992     delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
3993                           MSIINSTALLCONTEXT_MACHINE, NULL);
3994     delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
3995                           MSIINSTALLCONTEXT_MACHINE, NULL);
3996     delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
3997                           MSIINSTALLCONTEXT_MACHINE, NULL);
3998     delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
3999                           MSIINSTALLCONTEXT_MACHINE, NULL);
4000
4001     MsiCloseHandle(hpkg);
4002
4003 error:
4004     DeleteFileA("FileName1");
4005     DeleteFileA("FileName2");
4006     DeleteFileA("FileName3");
4007     DeleteFileA("FileName4");
4008     DeleteFileA("FileName5");
4009     DeleteFileA("FileName6");
4010     DeleteFileA("FileName7");
4011     DeleteFileA("FileName8.dll");
4012     DeleteFileA("FileName9.dll");
4013     DeleteFileA("FileName10.dll");
4014     DeleteFileA(msifile);
4015     LocalFree(usersid);
4016 }
4017
4018 static void test_appsearch_reglocator(void)
4019 {
4020     MSIHANDLE hpkg, hdb;
4021     CHAR path[MAX_PATH], prop[MAX_PATH];
4022     DWORD binary[2], size, val;
4023     BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4024     HKEY hklm, classes, hkcu, users;
4025     LPSTR pathdata, pathvar, ptr;
4026     LPCSTR str;
4027     LONG res;
4028     UINT r, type = 0;
4029     SYSTEM_INFO si;
4030
4031     version = TRUE;
4032     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4033         version = FALSE;
4034
4035     DeleteFileA("test.dll");
4036
4037     res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4038     if (res == ERROR_ACCESS_DENIED)
4039     {
4040         skip("Not enough rights to perform tests\n");
4041         return;
4042     }
4043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4044
4045     res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4046                          (const BYTE *)"regszdata", 10);
4047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4048
4049     res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4051
4052     res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4053                          (const BYTE *)"regszdata", 10);
4054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4055
4056     users = 0;
4057     res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4058     ok(res == ERROR_SUCCESS ||
4059        broken(res == ERROR_INVALID_PARAMETER),
4060        "Expected ERROR_SUCCESS, got %d\n", res);
4061
4062     if (res == ERROR_SUCCESS)
4063     {
4064         res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4065                              (const BYTE *)"regszdata", 10);
4066         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4067     }
4068
4069     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4071
4072     res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4074
4075     res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4076                          (const BYTE *)"regszdata", 10);
4077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4078
4079     val = 42;
4080     res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4081                          (const BYTE *)&val, sizeof(DWORD));
4082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4083
4084     val = -42;
4085     res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4086                          (const BYTE *)&val, sizeof(DWORD));
4087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4088
4089     res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4090                          (const BYTE *)"%PATH%", 7);
4091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4092
4093     res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4094                          (const BYTE *)"my%NOVAR%", 10);
4095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4096
4097     res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4098                          (const BYTE *)"one\0two\0", 9);
4099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4100
4101     binary[0] = 0x1234abcd;
4102     binary[1] = 0x567890ef;
4103     res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4104                          (const BYTE *)binary, sizeof(binary));
4105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4106
4107     res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4108                          (const BYTE *)"#regszdata", 11);
4109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4110
4111     create_test_file("FileName1");
4112     sprintf(path, "%s\\FileName1", CURR_DIR);
4113     res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4114                          (const BYTE *)path, lstrlenA(path) + 1);
4115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4116
4117     sprintf(path, "%s\\FileName2", CURR_DIR);
4118     res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4119                          (const BYTE *)path, lstrlenA(path) + 1);
4120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4121
4122     lstrcpyA(path, CURR_DIR);
4123     res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4124                          (const BYTE *)path, lstrlenA(path) + 1);
4125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4126
4127     res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4128                          (const BYTE *)"", 1);
4129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4130
4131     create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4132     sprintf(path, "%s\\FileName3.dll", CURR_DIR);
4133     res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4134                          (const BYTE *)path, lstrlenA(path) + 1);
4135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4136
4137     create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4138     sprintf(path, "%s\\FileName4.dll", CURR_DIR);
4139     res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4140                          (const BYTE *)path, lstrlenA(path) + 1);
4141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4142
4143     create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4144     sprintf(path, "%s\\FileName5.dll", CURR_DIR);
4145     res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4146                          (const BYTE *)path, lstrlenA(path) + 1);
4147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4148
4149     sprintf(path, "\"%s\\FileName1\" -option", CURR_DIR);
4150     res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4151                          (const BYTE *)path, lstrlenA(path) + 1);
4152     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4153
4154     space = strchr(CURR_DIR, ' ') != NULL;
4155     sprintf(path, "%s\\FileName1 -option", CURR_DIR);
4156     res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4157                          (const BYTE *)path, lstrlenA(path) + 1);
4158     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4159
4160     hdb = create_package_db();
4161     ok(hdb, "Expected a valid database handle\n");
4162
4163     r = create_appsearch_table(hdb);
4164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4165
4166     r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4168
4169     r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4170     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4171
4172     r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4174
4175     r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4177
4178     r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180
4181     r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4183
4184     r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4186
4187     r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4189
4190     r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4192
4193     r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4195
4196     r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4197     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4198
4199     r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4201
4202     r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4204
4205     r = add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4207
4208     r = add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4209     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4210
4211     r = add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213
4214     r = add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4216
4217     r = add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4219
4220     r = add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4222
4223     r = add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4225
4226     r = add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4228
4229     r = add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4231
4232     r = add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4234
4235     r = add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4237
4238     r = add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4240
4241     r = add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4242     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243
4244     r = add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4246
4247     r = add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4249
4250     r = add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252
4253     r = add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4255
4256     r = create_reglocator_table(hdb);
4257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4258
4259     type = msidbLocatorTypeRawValue;
4260     if (is_64bit)
4261         type |= msidbLocatorType64bit;
4262
4263     /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4264     r = add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4266
4267     /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4268     r = add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4270
4271     /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4272     r = add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4274
4275     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4276     r = add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4278
4279     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4280     r = add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4282
4283     /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4284     r = add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4286
4287     /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4288     r = add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4290
4291     /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4292     r = add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4294
4295     type = msidbLocatorTypeFileName;
4296     if (is_64bit)
4297         type |= msidbLocatorType64bit;
4298
4299     /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4300     r = add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4302
4303     /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4304     r = add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4306
4307     /* HKLM, msidbLocatorTypeFileName, no signature */
4308     r = add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4310
4311     type = msidbLocatorTypeDirectory;
4312     if (is_64bit)
4313         type |= msidbLocatorType64bit;
4314
4315     /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4316     r = add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4317     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4318
4319     /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4320     r = add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4322
4323     /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4324     r = add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4326
4327     type = msidbLocatorTypeRawValue;
4328     if (is_64bit)
4329         type |= msidbLocatorType64bit;
4330
4331     /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4332     r = add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4334
4335     /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4336     r = add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4338
4339     /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4340     r = add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4341     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4342
4343     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4344     r = add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4346
4347     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4348     r = add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4350
4351     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4352     r = add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4354
4355     type = msidbLocatorTypeFileName;
4356     if (is_64bit)
4357         type |= msidbLocatorType64bit;
4358
4359     /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4360     r = add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4361     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4362
4363     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4364     r = add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4366
4367     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4368     r = add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4369     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4370
4371     /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4372     r = add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4374
4375     /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4376     r = add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4378
4379     type = msidbLocatorTypeDirectory;
4380     if (is_64bit)
4381         type |= msidbLocatorType64bit;
4382
4383     /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4384     r = add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4385     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4386
4387     /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4388     r = add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4390
4391     /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4392     r = add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4394
4395     type = msidbLocatorTypeFileName;
4396     if (is_64bit)
4397         type |= msidbLocatorType64bit;
4398
4399     /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4400     r = add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4402
4403     /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4404     r = add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4406
4407     r = create_signature_table(hdb);
4408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4409
4410     str = "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''";
4411     r = add_signature_entry(hdb, str);
4412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4413
4414     str = "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''";
4415     r = add_signature_entry(hdb, str);
4416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4417
4418     str = "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''";
4419     r = add_signature_entry(hdb, str);
4420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4421
4422     str = "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4423     r = add_signature_entry(hdb, str);
4424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4425
4426     str = "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4427     r = add_signature_entry(hdb, str);
4428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4429
4430     str = "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4431     r = add_signature_entry(hdb, str);
4432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4433
4434     ptr = strrchr(CURR_DIR, '\\') + 1;
4435     sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4436     r = add_signature_entry(hdb, path);
4437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4438
4439     str = "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''";
4440     r = add_signature_entry(hdb, str);
4441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4442
4443     str = "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''";
4444     r = add_signature_entry(hdb, str);
4445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4446
4447     str = "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''";
4448     r = add_signature_entry(hdb, str);
4449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4450
4451     r = package_from_db(hdb, &hpkg);
4452     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4453
4454     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4455
4456     r = MsiDoAction(hpkg, "AppSearch");
4457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4458
4459     size = MAX_PATH;
4460     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4461     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4462     ok(!lstrcmpA(prop, "regszdata"),
4463        "Expected \"regszdata\", got \"%s\"\n", prop);
4464
4465     size = MAX_PATH;
4466     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4468     ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4469
4470     size = MAX_PATH;
4471     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4473     ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4474
4475     memset(&si, 0, sizeof(si));
4476     if (pGetNativeSystemInfo) pGetNativeSystemInfo(&si);
4477
4478     if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4479     {
4480         size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4481         pathvar = HeapAlloc(GetProcessHeap(), 0, size);
4482         ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4483
4484         size = 0;
4485         r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4486         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4487
4488         pathdata = HeapAlloc(GetProcessHeap(), 0, ++size);
4489         r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4490         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4491         ok(!lstrcmpA(pathdata, pathvar),
4492             "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4493
4494         HeapFree(GetProcessHeap(), 0, pathvar);
4495         HeapFree(GetProcessHeap(), 0, pathdata);
4496     }
4497
4498     size = MAX_PATH;
4499     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4501     ok(!lstrcmpA(prop,
4502        "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4503
4504     size = MAX_PATH;
4505     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4506     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4507     todo_wine
4508     {
4509         ok(!memcmp(prop, "\0one\0two\0\0", 10),
4510            "Expected \"\\0one\\0two\\0\\0\"\n");
4511     }
4512
4513     size = MAX_PATH;
4514     lstrcpyA(path, "#xCDAB3412EF907856");
4515     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4517     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4518
4519     size = MAX_PATH;
4520     r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4522     ok(!lstrcmpA(prop, "##regszdata"),
4523        "Expected \"##regszdata\", got \"%s\"\n", prop);
4524
4525     size = MAX_PATH;
4526     sprintf(path, "%s\\FileName1", CURR_DIR);
4527     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4529     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4530
4531     size = MAX_PATH;
4532     r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4533     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4534     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4535
4536     size = MAX_PATH;
4537     sprintf(path, "%s\\", CURR_DIR);
4538     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4540     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4541
4542     size = MAX_PATH;
4543     r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4545     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4546
4547     size = MAX_PATH;
4548     sprintf(path, "%s\\", CURR_DIR);
4549     r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4551     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4552
4553     size = MAX_PATH;
4554     r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4556     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4557
4558     size = MAX_PATH;
4559     r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4561     ok(!lstrcmpA(prop, "regszdata"),
4562        "Expected \"regszdata\", got \"%s\"\n", prop);
4563
4564     size = MAX_PATH;
4565     r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4567     ok(!lstrcmpA(prop, "regszdata"),
4568        "Expected \"regszdata\", got \"%s\"\n", prop);
4569
4570     if (users)
4571     {
4572         size = MAX_PATH;
4573         r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4574         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4575         ok(!lstrcmpA(prop, "regszdata"),
4576            "Expected \"regszdata\", got \"%s\"\n", prop);
4577     }
4578
4579     size = MAX_PATH;
4580     r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4582     ok(!lstrcmpA(prop, "defvalue"),
4583        "Expected \"defvalue\", got \"%s\"\n", prop);
4584
4585     size = MAX_PATH;
4586     r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4588     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4589
4590     size = MAX_PATH;
4591     r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4592     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4593     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4594
4595     if (version)
4596     {
4597         size = MAX_PATH;
4598         sprintf(path, "%s\\FileName3.dll", CURR_DIR);
4599         r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4600         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4601         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4602
4603         size = MAX_PATH;
4604         r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4605         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4606         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4607
4608         size = MAX_PATH;
4609         sprintf(path, "%s\\FileName5.dll", CURR_DIR);
4610         r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4611         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4612         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4613     }
4614
4615     size = MAX_PATH;
4616     lstrcpyA(path, CURR_DIR);
4617     ptr = strrchr(path, '\\') + 1;
4618     *ptr = '\0';
4619     r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4621     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4622
4623     size = MAX_PATH;
4624     sprintf(path, "%s\\", CURR_DIR);
4625     r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4626     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4627     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4628
4629     size = MAX_PATH;
4630     r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4632     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4633
4634     size = MAX_PATH;
4635     r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4637     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4638
4639     size = MAX_PATH;
4640     r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4642     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4643
4644     size = MAX_PATH;
4645     sprintf(path, "%s\\FileName1", CURR_DIR);
4646     r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4648     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4649
4650     size = MAX_PATH;
4651     sprintf(path, "%s\\FileName1", CURR_DIR);
4652     r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4654     if (space)
4655         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4656     else
4657         todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4658
4659     RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4660     RegDeleteValueA(hklm, "Value1");
4661     RegDeleteValueA(hklm, "Value2");
4662     RegDeleteValueA(hklm, "Value3");
4663     RegDeleteValueA(hklm, "Value4");
4664     RegDeleteValueA(hklm, "Value5");
4665     RegDeleteValueA(hklm, "Value6");
4666     RegDeleteValueA(hklm, "Value7");
4667     RegDeleteValueA(hklm, "Value8");
4668     RegDeleteValueA(hklm, "Value9");
4669     RegDeleteValueA(hklm, "Value10");
4670     RegDeleteValueA(hklm, "Value11");
4671     RegDeleteValueA(hklm, "Value12");
4672     RegDeleteValueA(hklm, "Value13");
4673     RegDeleteValueA(hklm, "Value14");
4674     RegDeleteValueA(hklm, "Value15");
4675     RegDeleteValueA(hklm, "Value16");
4676     RegDeleteValueA(hklm, "Value17");
4677     RegDeleteKey(hklm, "");
4678     RegCloseKey(hklm);
4679
4680     RegDeleteValueA(classes, "Value1");
4681     RegDeleteKeyA(classes, "");
4682     RegCloseKey(classes);
4683
4684     RegDeleteValueA(hkcu, "Value1");
4685     RegDeleteKeyA(hkcu, "");
4686     RegCloseKey(hkcu);
4687
4688     RegDeleteValueA(users, "Value1");
4689     RegDeleteKeyA(users, "");
4690     RegCloseKey(users);
4691
4692     DeleteFileA("FileName1");
4693     DeleteFileA("FileName3.dll");
4694     DeleteFileA("FileName4.dll");
4695     DeleteFileA("FileName5.dll");
4696     MsiCloseHandle(hpkg);
4697     DeleteFileA(msifile);
4698 }
4699
4700 static void delete_win_ini(LPCSTR file)
4701 {
4702     CHAR path[MAX_PATH];
4703
4704     GetWindowsDirectoryA(path, MAX_PATH);
4705     lstrcatA(path, "\\");
4706     lstrcatA(path, file);
4707
4708     DeleteFileA(path);
4709 }
4710
4711 static void test_appsearch_inilocator(void)
4712 {
4713     MSIHANDLE hpkg, hdb;
4714     CHAR path[MAX_PATH];
4715     CHAR prop[MAX_PATH];
4716     BOOL version;
4717     LPCSTR str;
4718     LPSTR ptr;
4719     DWORD size;
4720     UINT r;
4721
4722     version = TRUE;
4723     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4724         version = FALSE;
4725
4726     DeleteFileA("test.dll");
4727
4728     WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4729
4730     create_test_file("FileName1");
4731     sprintf(path, "%s\\FileName1", CURR_DIR);
4732     WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4733
4734     WritePrivateProfileStringA("Section", "Key3", CURR_DIR, "IniFile.ini");
4735
4736     sprintf(path, "%s\\IDontExist", CURR_DIR);
4737     WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4738
4739     create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4740     sprintf(path, "%s\\FileName2.dll", CURR_DIR);
4741     WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4742
4743     create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4744     sprintf(path, "%s\\FileName3.dll", CURR_DIR);
4745     WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4746
4747     create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4748     sprintf(path, "%s\\FileName4.dll", CURR_DIR);
4749     WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4750
4751     hdb = create_package_db();
4752     ok(hdb, "Expected a valid database handle\n");
4753
4754     r = create_appsearch_table(hdb);
4755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4756
4757     r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4759
4760     r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4762
4763     r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4765
4766     r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4767     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4768
4769     r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4771
4772     r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4774
4775     r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4777
4778     r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4780
4781     r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4783
4784     r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4786
4787     r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4789
4790     r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4791     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4792
4793     r = create_inilocator_table(hdb);
4794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4795
4796     /* msidbLocatorTypeRawValue, field 1 */
4797     str = "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2";
4798     r = add_inilocator_entry(hdb, str);
4799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800
4801     /* msidbLocatorTypeRawValue, field 2 */
4802     str = "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2";
4803     r = add_inilocator_entry(hdb, str);
4804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805
4806     /* msidbLocatorTypeRawValue, entire field */
4807     str = "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2";
4808     r = add_inilocator_entry(hdb, str);
4809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4810
4811     /* msidbLocatorTypeFile */
4812     str = "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1";
4813     r = add_inilocator_entry(hdb, str);
4814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4815
4816     /* msidbLocatorTypeDirectory, file */
4817     str = "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0";
4818     r = add_inilocator_entry(hdb, str);
4819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4820
4821     /* msidbLocatorTypeDirectory, directory */
4822     str = "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0";
4823     r = add_inilocator_entry(hdb, str);
4824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4825
4826     /* msidbLocatorTypeFile, file, no signature */
4827     str = "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1";
4828     r = add_inilocator_entry(hdb, str);
4829     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4830
4831     /* msidbLocatorTypeFile, dir, no signature */
4832     str = "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1";
4833     r = add_inilocator_entry(hdb, str);
4834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4835
4836     /* msidbLocatorTypeFile, file does not exist */
4837     str = "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1";
4838     r = add_inilocator_entry(hdb, str);
4839     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4840
4841     /* msidbLocatorTypeFile, signature with version */
4842     str = "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1";
4843     r = add_inilocator_entry(hdb, str);
4844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4845
4846     /* msidbLocatorTypeFile, signature with version, ver > max */
4847     str = "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1";
4848     r = add_inilocator_entry(hdb, str);
4849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4850
4851     /* msidbLocatorTypeFile, signature with version, sig->name ignored */
4852     str = "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1";
4853     r = add_inilocator_entry(hdb, str);
4854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4855
4856     r = create_signature_table(hdb);
4857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4858
4859     r = add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
4860     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4861
4862     r = add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
4863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4864
4865     r = add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4867
4868     r = add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4870
4871     r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4873
4874     r = package_from_db(hdb, &hpkg);
4875     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4876     {
4877         skip("Not enough rights to perform tests\n");
4878         goto error;
4879     }
4880     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4881
4882     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4883
4884     r = MsiDoAction(hpkg, "AppSearch");
4885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4886
4887     size = MAX_PATH;
4888     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4890     ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
4891
4892     size = MAX_PATH;
4893     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895     ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
4896
4897     size = MAX_PATH;
4898     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4900     ok(!lstrcmpA(prop, "keydata,field2"),
4901        "Expected \"keydata,field2\", got \"%s\"\n", prop);
4902
4903     size = MAX_PATH;
4904     sprintf(path, "%s\\FileName1", CURR_DIR);
4905     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4907     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4908
4909     size = MAX_PATH;
4910     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4912     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4913
4914     size = MAX_PATH;
4915     sprintf(path, "%s\\", CURR_DIR);
4916     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4918     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4919
4920     size = MAX_PATH;
4921     sprintf(path, "%s\\", CURR_DIR);
4922     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4924     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4925
4926     size = MAX_PATH;
4927     lstrcpyA(path, CURR_DIR);
4928     ptr = strrchr(path, '\\');
4929     *(ptr + 1) = '\0';
4930     r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4932     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4933
4934     size = MAX_PATH;
4935     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4937     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4938
4939     if (version)
4940     {
4941         size = MAX_PATH;
4942         sprintf(path, "%s\\FileName2.dll", CURR_DIR);
4943         r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4944         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4945         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4946
4947         size = MAX_PATH;
4948         r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4949         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4950         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4951
4952         size = MAX_PATH;
4953         sprintf(path, "%s\\FileName4.dll", CURR_DIR);
4954         r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4955         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4956         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4957     }
4958
4959     MsiCloseHandle(hpkg);
4960
4961 error:
4962     delete_win_ini("IniFile.ini");
4963     DeleteFileA("FileName1");
4964     DeleteFileA("FileName2.dll");
4965     DeleteFileA("FileName3.dll");
4966     DeleteFileA("FileName4.dll");
4967     DeleteFileA(msifile);
4968 }
4969
4970 /*
4971  * MSI AppSearch action on DrLocator table always returns absolute paths.
4972  * If a relative path was set, it returns the first absolute path that
4973  * matches or an empty string if it didn't find anything.
4974  * This helper function replicates this behaviour.
4975  */
4976 static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
4977 {
4978     int i, size;
4979     DWORD attr, drives;
4980
4981     size = lstrlenA(relative);
4982     drives = GetLogicalDrives();
4983     lstrcpyA(absolute, "A:\\");
4984     for (i = 0; i < 26; absolute[0] = '\0', i++)
4985     {
4986         if (!(drives & (1 << i)))
4987             continue;
4988
4989         absolute[0] = 'A' + i;
4990         if (GetDriveType(absolute) != DRIVE_FIXED)
4991             continue;
4992
4993         lstrcpynA(absolute + 3, relative, size + 1);
4994         attr = GetFileAttributesA(absolute);
4995         if (attr != INVALID_FILE_ATTRIBUTES &&
4996             (attr & FILE_ATTRIBUTE_DIRECTORY))
4997         {
4998             if (absolute[3 + size - 1] != '\\')
4999                 lstrcatA(absolute, "\\");
5000             break;
5001         }
5002         absolute[3] = '\0';
5003     }
5004 }
5005
5006 static void test_appsearch_drlocator(void)
5007 {
5008     MSIHANDLE hpkg, hdb;
5009     CHAR path[MAX_PATH];
5010     CHAR prop[MAX_PATH];
5011     BOOL version;
5012     LPCSTR str;
5013     DWORD size;
5014     UINT r;
5015
5016     version = TRUE;
5017     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5018         version = FALSE;
5019
5020     DeleteFileA("test.dll");
5021
5022     create_test_file("FileName1");
5023     CreateDirectoryA("one", NULL);
5024     CreateDirectoryA("one\\two", NULL);
5025     CreateDirectoryA("one\\two\\three", NULL);
5026     create_test_file("one\\two\\three\\FileName2");
5027     CreateDirectoryA("another", NULL);
5028     create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5029     create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5030     create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5031
5032     hdb = create_package_db();
5033     ok(hdb, "Expected a valid database handle\n");
5034
5035     r = create_appsearch_table(hdb);
5036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5037
5038     r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5040
5041     r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5043
5044     r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5046
5047     r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5049
5050     r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5052
5053     r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5055
5056     r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5058
5059     r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5061
5062     r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5064
5065     r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5067
5068     r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5070
5071     r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5073
5074     r = create_drlocator_table(hdb);
5075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5076
5077     /* no parent, full path, depth 0, signature */
5078     sprintf(path, "'NewSignature1', '', '%s', 0", CURR_DIR);
5079     r = add_drlocator_entry(hdb, path);
5080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5081
5082     /* no parent, full path, depth 0, no signature */
5083     sprintf(path, "'NewSignature2', '', '%s', 0", CURR_DIR);
5084     r = add_drlocator_entry(hdb, path);
5085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086
5087     /* no parent, relative path, depth 0, no signature */
5088     sprintf(path, "'NewSignature3', '', '%s', 0", CURR_DIR + 3);
5089     r = add_drlocator_entry(hdb, path);
5090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5091
5092     /* no parent, full path, depth 2, signature */
5093     sprintf(path, "'NewSignature4', '', '%s', 2", CURR_DIR);
5094     r = add_drlocator_entry(hdb, path);
5095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5096
5097     /* no parent, full path, depth 3, signature */
5098     sprintf(path, "'NewSignature5', '', '%s', 3", CURR_DIR);
5099     r = add_drlocator_entry(hdb, path);
5100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5101
5102     /* no parent, full path, depth 1, signature is dir */
5103     sprintf(path, "'NewSignature6', '', '%s', 1", CURR_DIR);
5104     r = add_drlocator_entry(hdb, path);
5105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5106
5107     /* parent is in DrLocator, relative path, depth 0, signature */
5108     sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5109     r = add_drlocator_entry(hdb, path);
5110     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5111
5112     /* no parent, full path, depth 0, signature w/ version */
5113     sprintf(path, "'NewSignature8', '', '%s', 0", CURR_DIR);
5114     r = add_drlocator_entry(hdb, path);
5115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5116
5117     /* no parent, full path, depth 0, signature w/ version, ver > max */
5118     sprintf(path, "'NewSignature9', '', '%s', 0", CURR_DIR);
5119     r = add_drlocator_entry(hdb, path);
5120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5121
5122     /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5123     sprintf(path, "'NewSignature10', '', '%s', 0", CURR_DIR);
5124     r = add_drlocator_entry(hdb, path);
5125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5126
5127     /* no parent, relative empty path, depth 0, no signature */
5128     sprintf(path, "'NewSignature11', '', '', 0");
5129     r = add_drlocator_entry(hdb, path);
5130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5131
5132     r = create_reglocator_table(hdb);
5133     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5134
5135     /* parent */
5136     r = add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5138
5139     /* parent is in RegLocator, no path, depth 0, no signature */
5140     sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5141     r = add_drlocator_entry(hdb, path);
5142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5143
5144     r = create_signature_table(hdb);
5145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5146
5147     str = "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''";
5148     r = add_signature_entry(hdb, str);
5149     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5150
5151     str = "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''";
5152     r = add_signature_entry(hdb, str);
5153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5154
5155     str = "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''";
5156     r = add_signature_entry(hdb, str);
5157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5158
5159     str = "'NewSignature6', 'another', '', '', '', '', '', '', ''";
5160     r = add_signature_entry(hdb, str);
5161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5162
5163     str = "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''";
5164     r = add_signature_entry(hdb, str);
5165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5166
5167     str = "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5168     r = add_signature_entry(hdb, str);
5169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5170
5171     str = "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5172     r = add_signature_entry(hdb, str);
5173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5174
5175     str = "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5176     r = add_signature_entry(hdb, str);
5177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5178
5179     r = package_from_db(hdb, &hpkg);
5180     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5181     {
5182         skip("Not enough rights to perform tests\n");
5183         goto error;
5184     }
5185     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5186
5187     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5188
5189     r = MsiDoAction(hpkg, "AppSearch");
5190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5191
5192     size = MAX_PATH;
5193     sprintf(path, "%s\\FileName1", CURR_DIR);
5194     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5196     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5197
5198     size = MAX_PATH;
5199     sprintf(path, "%s\\", CURR_DIR);
5200     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5201     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5202     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5203
5204     size = MAX_PATH;
5205     search_absolute_directory(path, CURR_DIR + 3);
5206     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5208     ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5209
5210     size = MAX_PATH;
5211     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5213     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5214
5215     size = MAX_PATH;
5216     sprintf(path, "%s\\one\\two\\three\\FileName2", CURR_DIR);
5217     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5219     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5220
5221     size = MAX_PATH;
5222     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5224     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5225
5226     size = MAX_PATH;
5227     sprintf(path, "%s\\one\\two\\three\\FileName2", CURR_DIR);
5228     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5230     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5231
5232     if (version)
5233     {
5234         size = MAX_PATH;
5235         sprintf(path, "%s\\FileName3.dll", CURR_DIR);
5236         r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5237         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5238         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5239
5240         size = MAX_PATH;
5241         r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5242         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5243         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5244
5245         size = MAX_PATH;
5246         r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5247         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5249     }
5250
5251     size = MAX_PATH;
5252     search_absolute_directory(path, "");
5253     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5255     ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5256
5257     size = MAX_PATH;
5258     strcpy(path, "c:\\");
5259     r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5261     ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5262
5263     MsiCloseHandle(hpkg);
5264
5265 error:
5266     DeleteFileA("FileName1");
5267     DeleteFileA("FileName3.dll");
5268     DeleteFileA("FileName4.dll");
5269     DeleteFileA("FileName5.dll");
5270     DeleteFileA("one\\two\\three\\FileName2");
5271     RemoveDirectoryA("one\\two\\three");
5272     RemoveDirectoryA("one\\two");
5273     RemoveDirectoryA("one");
5274     RemoveDirectoryA("another");
5275     DeleteFileA(msifile);
5276 }
5277
5278 static void test_featureparents(void)
5279 {
5280     MSIHANDLE hpkg;
5281     UINT r;
5282     MSIHANDLE hdb;
5283
5284     hdb = create_package_db();
5285     ok ( hdb, "failed to create package database\n" );
5286
5287     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
5288     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
5289
5290     r = create_feature_table( hdb );
5291     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
5292
5293     r = create_component_table( hdb );
5294     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
5295
5296     r = create_feature_components_table( hdb );
5297     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
5298
5299     r = create_file_table( hdb );
5300     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
5301
5302     /* msidbFeatureAttributesFavorLocal */
5303     r = add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5304     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5305
5306     /* msidbFeatureAttributesFavorSource */
5307     r = add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5308     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5309
5310     /* msidbFeatureAttributesFavorLocal */
5311     r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5312     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5313
5314     /* msidbFeatureAttributesUIDisallowAbsent */
5315     r = add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5316     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5317
5318     /* disabled because of install level */
5319     r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5320     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5321
5322     /* child feature of disabled feature */
5323     r = add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5324     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5325
5326     /* component of disabled feature (install level) */
5327     r = add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5328     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5329
5330     /* component of disabled child feature (install level) */
5331     r = add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5332     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5333
5334     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5335     r = add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5336     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5337
5338     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5339     r = add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5340     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5341
5342     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5343     r = add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5344     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5345
5346     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5347     r = add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5348     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5349
5350     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5351     r = add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5352     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5353
5354     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5355     r = add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5356     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5357
5358     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5359     r = add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5360     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5361
5362     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5363     r = add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5364     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5365
5366     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5367     r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5368     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5369
5370     r = add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5371     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5372
5373     r = add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5374     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5375
5376     r = add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5377     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5378
5379     r = add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5380     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5381
5382     r = add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5383     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5384
5385     r = add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5386     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5387
5388     r = add_feature_components_entry( hdb, "'orion', 'leo'" );
5389     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5390
5391     r = add_feature_components_entry( hdb, "'orion', 'virgo'" );
5392     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5393
5394     r = add_feature_components_entry( hdb, "'orion', 'libra'" );
5395     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5396
5397     r = add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5398     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5399
5400     r = add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5401     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5402
5403     r = add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5404     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5405
5406     r = add_feature_components_entry( hdb, "'orion', 'canis'" );
5407     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5408
5409     r = add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5410     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5411
5412     r = add_feature_components_entry( hdb, "'orion', 'lepus'" );
5413     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5414
5415     r = add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5416     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5417
5418     r = add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5419     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5420
5421     r = add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5422     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5423
5424     r = add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5425     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5426
5427     r = add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5428     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5429
5430     r = add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5431     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5432
5433     r = add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5434     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5435
5436     r = add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5437     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5438
5439     r = add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5440     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5441
5442     r = add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5443     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5444
5445     r = add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5446     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5447
5448     r = add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5449     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5450
5451     r = add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5452     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5453
5454     r = package_from_db( hdb, &hpkg );
5455     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5456     {
5457         skip("Not enough rights to perform tests\n");
5458         DeleteFile(msifile);
5459         return;
5460     }
5461     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5462
5463     MsiCloseHandle( hdb );
5464
5465     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5466
5467     r = MsiDoAction( hpkg, "CostInitialize");
5468     ok( r == ERROR_SUCCESS, "cost init failed\n");
5469
5470     r = MsiDoAction( hpkg, "FileCost");
5471     ok( r == ERROR_SUCCESS, "file cost failed\n");
5472
5473     r = MsiDoAction( hpkg, "CostFinalize");
5474     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5475
5476     test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
5477     test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
5478     test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
5479     test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
5480     test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
5481     test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
5482
5483     test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5484     test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5485     test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5486     test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5487     test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5488     test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5489     test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5490     test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5491     test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5492     test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5493     test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5494
5495     r = MsiSetFeatureState(hpkg, "orion", INSTALLSTATE_ABSENT);
5496     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5497
5498     r = MsiSetFeatureState(hpkg, "lyra", INSTALLSTATE_ABSENT);
5499     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5500
5501     r = MsiSetFeatureState(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5502     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5503
5504     test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
5505     test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
5506     test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, 0 );
5507     test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, 0 );
5508     test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
5509     test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
5510
5511     test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5512     test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5513     test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5514     test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
5515     test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5516     test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
5517     test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5518     test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5519     test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5520     test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5521     test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
5522
5523     MsiCloseHandle(hpkg);
5524     DeleteFileA(msifile);
5525 }
5526
5527 static void test_installprops(void)
5528 {
5529     MSIHANDLE hpkg, hdb;
5530     CHAR path[MAX_PATH], buf[MAX_PATH];
5531     DWORD size, type;
5532     LANGID langid;
5533     HKEY hkey1, hkey2;
5534     int res;
5535     UINT r;
5536     REGSAM access = KEY_ALL_ACCESS;
5537     SYSTEM_INFO si;
5538     INSTALLUILEVEL uilevel;
5539
5540     if (is_wow64)
5541         access |= KEY_WOW64_64KEY;
5542
5543     GetCurrentDirectory(MAX_PATH, path);
5544     lstrcat(path, "\\");
5545     lstrcat(path, msifile);
5546
5547     uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5548
5549     hdb = create_package_db();
5550     ok( hdb, "failed to create database\n");
5551
5552     r = package_from_db(hdb, &hpkg);
5553     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5554     {
5555         skip("Not enough rights to perform tests\n");
5556         MsiSetInternalUI(uilevel, NULL);
5557         DeleteFile(msifile);
5558         return;
5559     }
5560     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5561
5562     MsiCloseHandle(hdb);
5563
5564     buf[0] = 0;
5565     size = MAX_PATH;
5566     r = MsiGetProperty(hpkg, "UILevel", buf, &size);
5567     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5568     ok( !lstrcmp(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5569
5570     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5571
5572     buf[0] = 0;
5573     size = MAX_PATH;
5574     r = MsiGetProperty(hpkg, "UILevel", buf, &size);
5575     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5576     ok( !lstrcmp(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5577
5578     buf[0] = 0;
5579     size = MAX_PATH;
5580     r = MsiGetProperty(hpkg, "DATABASE", buf, &size);
5581     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5582     ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
5583
5584     RegOpenKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5585     RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5586
5587     size = MAX_PATH;
5588     type = REG_SZ;
5589     *path = '\0';
5590     if (RegQueryValueEx(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5591     {
5592         size = MAX_PATH;
5593         type = REG_SZ;
5594         RegQueryValueEx(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5595     }
5596
5597     buf[0] = 0;
5598     size = MAX_PATH;
5599     r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
5600     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5601     ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
5602
5603     size = MAX_PATH;
5604     type = REG_SZ;
5605     *path = '\0';
5606     if (RegQueryValueEx(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5607     {
5608         size = MAX_PATH;
5609         type = REG_SZ;
5610         RegQueryValueEx(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5611     }
5612
5613     if (*path)
5614     {
5615         buf[0] = 0;
5616         size = MAX_PATH;
5617         r = MsiGetProperty(hpkg, "COMPANYNAME", buf, &size);
5618         ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5619         ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
5620     }
5621
5622     buf[0] = 0;
5623     size = MAX_PATH;
5624     r = MsiGetProperty(hpkg, "VersionDatabase", buf, &size);
5625     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5626     trace("VersionDatabase = %s\n", buf);
5627
5628     buf[0] = 0;
5629     size = MAX_PATH;
5630     r = MsiGetProperty(hpkg, "VersionMsi", buf, &size);
5631     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5632     trace("VersionMsi = %s\n", buf);
5633
5634     buf[0] = 0;
5635     size = MAX_PATH;
5636     r = MsiGetProperty(hpkg, "Date", buf, &size);
5637     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5638     trace("Date = %s\n", buf);
5639
5640     buf[0] = 0;
5641     size = MAX_PATH;
5642     r = MsiGetProperty(hpkg, "Time", buf, &size);
5643     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5644     trace("Time = %s\n", buf);
5645
5646     buf[0] = 0;
5647     size = MAX_PATH;
5648     r = MsiGetProperty(hpkg, "PackageCode", buf, &size);
5649     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5650     trace("PackageCode = %s\n", buf);
5651
5652     buf[0] = 0;
5653     size = MAX_PATH;
5654     r = MsiGetProperty(hpkg, "ComputerName", buf, &size);
5655     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5656     trace("ComputerName = %s\n", buf);
5657
5658     langid = GetUserDefaultLangID();
5659     sprintf(path, "%d", langid);
5660
5661     buf[0] = 0;
5662     size = MAX_PATH;
5663     r = MsiGetProperty(hpkg, "UserLanguageID", buf, &size);
5664     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5665     ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5666
5667     res = GetSystemMetrics(SM_CXSCREEN);
5668     buf[0] = 0;
5669     size = MAX_PATH;
5670     r = MsiGetProperty(hpkg, "ScreenX", buf, &size);
5671     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5672     ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
5673
5674     res = GetSystemMetrics(SM_CYSCREEN);
5675     buf[0] = 0;
5676     size = MAX_PATH;
5677     r = MsiGetProperty(hpkg, "ScreenY", buf, &size);
5678     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5679     ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
5680
5681     if (pGetSystemInfo && pSHGetFolderPathA)
5682     {
5683         pGetSystemInfo(&si);
5684         if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5685         {
5686             buf[0] = 0;
5687             size = MAX_PATH;
5688             r = MsiGetProperty(hpkg, "Intel", buf, &size);
5689             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5690             ok(buf[0], "property not set\n");
5691
5692             buf[0] = 0;
5693             size = MAX_PATH;
5694             r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
5695             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5696             ok(buf[0], "property not set\n");
5697
5698             buf[0] = 0;
5699             size = MAX_PATH;
5700             r = MsiGetProperty(hpkg, "Msix64", buf, &size);
5701             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5702             ok(buf[0], "property not set\n");
5703
5704             buf[0] = 0;
5705             size = MAX_PATH;
5706             r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
5707             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5708             GetSystemDirectoryA(path, MAX_PATH);
5709             if (size) buf[size - 1] = 0;
5710             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5711
5712             buf[0] = 0;
5713             size = MAX_PATH;
5714             r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
5715             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5716             pGetSystemWow64DirectoryA(path, MAX_PATH);
5717             if (size) buf[size - 1] = 0;
5718             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5719
5720             buf[0] = 0;
5721             size = MAX_PATH;
5722             r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size);
5723             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5724             pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
5725             if (size) buf[size - 1] = 0;
5726             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5727
5728             buf[0] = 0;
5729             size = MAX_PATH;
5730             r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
5731             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5732             pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
5733             if (size) buf[size - 1] = 0;
5734             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5735
5736             buf[0] = 0;
5737             size = MAX_PATH;
5738             r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size);
5739             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5740             pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
5741             if (size) buf[size - 1] = 0;
5742             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5743
5744             buf[0] = 0;
5745             size = MAX_PATH;
5746             r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
5747             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5748             pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
5749             if (size) buf[size - 1] = 0;
5750             ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5751
5752             buf[0] = 0;
5753             size = MAX_PATH;
5754             r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
5755             ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5756             ok(buf[0], "property not set\n");
5757         }
5758         else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5759         {
5760             if (!is_wow64)
5761             {
5762                 buf[0] = 0;
5763                 size = MAX_PATH;
5764                 r = MsiGetProperty(hpkg, "Intel", buf, &size);
5765                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5766                 ok(buf[0], "property not set\n");
5767
5768                 buf[0] = 0;
5769                 size = MAX_PATH;
5770                 r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
5771                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5772                 ok(!buf[0], "property set\n");
5773
5774                 buf[0] = 0;
5775                 size = MAX_PATH;
5776                 r = MsiGetProperty(hpkg, "Msix64", buf, &size);
5777                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5778                 ok(!buf[0], "property set\n");
5779
5780                 buf[0] = 0;
5781                 size = MAX_PATH;
5782                 r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
5783                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5784                 ok(!buf[0], "property set\n");
5785
5786                 buf[0] = 0;
5787                 size = MAX_PATH;
5788                 r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
5789                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5790                 GetSystemDirectoryA(path, MAX_PATH);
5791                 if (size) buf[size - 1] = 0;
5792                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5793
5794                 buf[0] = 0;
5795                 size = MAX_PATH;
5796                 r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size);
5797                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5798                 ok(!buf[0], "property set\n");
5799
5800                 buf[0] = 0;
5801                 size = MAX_PATH;
5802                 r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
5803                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5804                 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
5805                 if (size) buf[size - 1] = 0;
5806                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5807
5808                 buf[0] = 0;
5809                 size = MAX_PATH;
5810                 r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size);
5811                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5812                 ok(!buf[0], "property set\n");
5813
5814                 buf[0] = 0;
5815                 size = MAX_PATH;
5816                 r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
5817                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5818                 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
5819                 if (size) buf[size - 1] = 0;
5820                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5821
5822                 buf[0] = 0;
5823                 size = MAX_PATH;
5824                 r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
5825                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5826                 ok(!buf[0], "property set\n");
5827             }
5828             else
5829             {
5830                 buf[0] = 0;
5831                 size = MAX_PATH;
5832                 r = MsiGetProperty(hpkg, "Intel", buf, &size);
5833                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5834                 ok(buf[0], "property not set\n");
5835
5836                 buf[0] = 0;
5837                 size = MAX_PATH;
5838                 r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
5839                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5840                 ok(buf[0], "property not set\n");
5841
5842                 buf[0] = 0;
5843                 size = MAX_PATH;
5844                 r = MsiGetProperty(hpkg, "Msix64", buf, &size);
5845                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5846                 ok(buf[0], "property not set\n");
5847
5848                 buf[0] = 0;
5849                 size = MAX_PATH;
5850                 r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
5851                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5852                 GetSystemDirectoryA(path, MAX_PATH);
5853                 if (size) buf[size - 1] = 0;
5854                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5855
5856                 buf[0] = 0;
5857                 size = MAX_PATH;
5858                 r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
5859                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5860                 pGetSystemWow64DirectoryA(path, MAX_PATH);
5861                 if (size) buf[size - 1] = 0;
5862                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5863
5864                 buf[0] = 0;
5865                 size = MAX_PATH;
5866                 r = MsiGetProperty(hpkg, "ProgramFilesFolder64", buf, &size);
5867                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5868                 ok(!buf[0], "property set\n");
5869
5870                 buf[0] = 0;
5871                 size = MAX_PATH;
5872                 r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
5873                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5874                 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
5875                 if (size) buf[size - 1] = 0;
5876                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5877
5878                 buf[0] = 0;
5879                 size = MAX_PATH;
5880                 r = MsiGetProperty(hpkg, "CommonFilesFolder64", buf, &size);
5881                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5882                 ok(!buf[0], "property set\n");
5883
5884                 buf[0] = 0;
5885                 size = MAX_PATH;
5886                 r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
5887                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5888                 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
5889                 if (size) buf[size - 1] = 0;
5890                 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5891
5892                 buf[0] = 0;
5893                 size = MAX_PATH;
5894                 r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
5895                 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5896                 ok(buf[0], "property not set\n");
5897             }
5898         }
5899     }
5900
5901     CloseHandle(hkey1);
5902     CloseHandle(hkey2);
5903     MsiCloseHandle(hpkg);
5904     DeleteFile(msifile);
5905     MsiSetInternalUI(uilevel, NULL);
5906 }
5907
5908 static void test_launchconditions(void)
5909 {
5910     MSIHANDLE hpkg;
5911     MSIHANDLE hdb;
5912     UINT r;
5913
5914     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5915
5916     hdb = create_package_db();
5917     ok( hdb, "failed to create package database\n" );
5918
5919     r = create_launchcondition_table( hdb );
5920     ok( r == ERROR_SUCCESS, "cannot create LaunchCondition table: %d\n", r );
5921
5922     r = add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5923     ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r );
5924
5925     /* invalid condition */
5926     r = add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5927     ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r );
5928
5929     r = package_from_db( hdb, &hpkg );
5930     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5931     {
5932         skip("Not enough rights to perform tests\n");
5933         DeleteFile(msifile);
5934         return;
5935     }
5936     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5937
5938     MsiCloseHandle( hdb );
5939
5940     r = MsiSetProperty( hpkg, "X", "1" );
5941     ok( r == ERROR_SUCCESS, "failed to set property\n" );
5942
5943     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5944
5945     /* invalid conditions are ignored */
5946     r = MsiDoAction( hpkg, "LaunchConditions" );
5947     ok( r == ERROR_SUCCESS, "cost init failed\n" );
5948
5949     /* verify LaunchConditions still does some verification */
5950     r = MsiSetProperty( hpkg, "X", "2" );
5951     ok( r == ERROR_SUCCESS, "failed to set property\n" );
5952
5953     r = MsiDoAction( hpkg, "LaunchConditions" );
5954     ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5955
5956     MsiCloseHandle( hpkg );
5957     DeleteFile( msifile );
5958 }
5959
5960 static void test_ccpsearch(void)
5961 {
5962     MSIHANDLE hdb, hpkg;
5963     CHAR prop[MAX_PATH];
5964     DWORD size = MAX_PATH;
5965     UINT r;
5966
5967     hdb = create_package_db();
5968     ok(hdb, "failed to create package database\n");
5969
5970     r = create_ccpsearch_table(hdb);
5971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5972
5973     r = add_ccpsearch_entry(hdb, "'CCP_random'");
5974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5975
5976     r = add_ccpsearch_entry(hdb, "'RMCCP_random'");
5977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5978
5979     r = create_reglocator_table(hdb);
5980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5981
5982     r = add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5984
5985     r = create_drlocator_table(hdb);
5986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5987
5988     r = add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5989     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5990
5991     r = create_signature_table(hdb);
5992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5993
5994     r = package_from_db(hdb, &hpkg);
5995     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5996     {
5997         skip("Not enough rights to perform tests\n");
5998         DeleteFile(msifile);
5999         return;
6000     }
6001     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6002
6003     MsiCloseHandle(hdb);
6004
6005     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6006
6007     r = MsiDoAction(hpkg, "CCPSearch");
6008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6009
6010     r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
6011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6012     ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
6013
6014     MsiCloseHandle(hpkg);
6015     DeleteFileA(msifile);
6016 }
6017
6018 static void test_complocator(void)
6019 {
6020     MSIHANDLE hdb, hpkg;
6021     UINT r;
6022     CHAR prop[MAX_PATH];
6023     CHAR expected[MAX_PATH];
6024     DWORD size = MAX_PATH;
6025
6026     hdb = create_package_db();
6027     ok(hdb, "failed to create package database\n");
6028
6029     r = create_appsearch_table(hdb);
6030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6031
6032     r = add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
6033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6034
6035     r = add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
6036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6037
6038     r = add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
6039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6040
6041     r = add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
6042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6043
6044     r = add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
6045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6046
6047     r = add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
6048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6049
6050     r = add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
6051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6052
6053     r = add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
6054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6055
6056     r = add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
6057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6058
6059     r = add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
6060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6061
6062     r = add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
6063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6064
6065     r = add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
6066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6067
6068     r = add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
6069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6070
6071     r = add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
6072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6073
6074     r = add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
6075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6076
6077     r = add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
6078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6079
6080     r = create_complocator_table(hdb);
6081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6082
6083     r = add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
6084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6085
6086     r = add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
6087     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6088
6089     r = add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
6090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6091
6092     r = add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
6093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6094
6095     r = add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
6096     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6097
6098     r = add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
6099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6100
6101     r = add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
6102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6103
6104     r = add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
6105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6106
6107     r = add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
6108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6109
6110     r = add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
6111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6112
6113     r = add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
6114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6115
6116     r = add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
6117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6118
6119     r = add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
6120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6121
6122     r = add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
6123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6124
6125     r = add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
6126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6127
6128     r = add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
6129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6130
6131     r = create_signature_table(hdb);
6132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6133
6134     r = add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
6135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6136
6137     r = add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
6138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6139
6140     r = add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
6141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6142
6143     r = add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
6144     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6145
6146     r = add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
6147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6148
6149     r = add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
6150     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6151
6152     r = add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
6153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6154
6155     r = add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
6156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6157
6158     r = package_from_db(hdb, &hpkg);
6159     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6160     {
6161         skip("Not enough rights to perform tests\n");
6162         DeleteFile(msifile);
6163         return;
6164     }
6165     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6166
6167     MsiCloseHandle(hdb);
6168
6169     create_test_file("abelisaurus");
6170     create_test_file("bactrosaurus");
6171     create_test_file("camelotia");
6172     create_test_file("diclonius");
6173     create_test_file("echinodon");
6174     create_test_file("falcarius");
6175     create_test_file("gallimimus");
6176     create_test_file("hagryphus");
6177     CreateDirectoryA("iguanodon", NULL);
6178     CreateDirectoryA("jobaria", NULL);
6179     CreateDirectoryA("kakuru", NULL);
6180     CreateDirectoryA("labocania", NULL);
6181     CreateDirectoryA("megaraptor", NULL);
6182     CreateDirectoryA("neosodon", NULL);
6183     CreateDirectoryA("olorotitan", NULL);
6184     CreateDirectoryA("pantydraco", NULL);
6185
6186     set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
6187                        "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
6188     set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
6189                        "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
6190     set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
6191                        "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
6192     set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
6193                        "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
6194     set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
6195                        "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
6196     set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
6197                        "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
6198     set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
6199                        "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
6200     set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
6201                        "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
6202
6203     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6204
6205     r = MsiDoAction(hpkg, "AppSearch");
6206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6207
6208     size = MAX_PATH;
6209     r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
6210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6211
6212     lstrcpyA(expected, CURR_DIR);
6213     lstrcatA(expected, "\\abelisaurus");
6214     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6215        "Expected %s or empty string, got %s\n", expected, prop);
6216
6217     size = MAX_PATH;
6218     r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
6219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6220     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6221
6222     size = MAX_PATH;
6223     r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
6224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6225     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6226
6227     size = MAX_PATH;
6228     r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
6229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6230     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6231
6232     size = MAX_PATH;
6233     r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
6234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6235
6236     lstrcpyA(expected, CURR_DIR);
6237     lstrcatA(expected, "\\");
6238     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6239        "Expected %s or empty string, got %s\n", expected, prop);
6240
6241     size = MAX_PATH;
6242     r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
6243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6244     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6245
6246     size = MAX_PATH;
6247     r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
6248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6249     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6250
6251     size = MAX_PATH;
6252     r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
6253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6254     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6255
6256     size = MAX_PATH;
6257     r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
6258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6259     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6260
6261     size = MAX_PATH;
6262     r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
6263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6264     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6265
6266     size = MAX_PATH;
6267     r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
6268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6269     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6270
6271     size = MAX_PATH;
6272     r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
6273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6274     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6275
6276     size = MAX_PATH;
6277     r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
6278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6279
6280     lstrcpyA(expected, CURR_DIR);
6281     lstrcatA(expected, "\\");
6282     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6283        "Expected %s or empty string, got %s\n", expected, prop);
6284
6285     size = MAX_PATH;
6286     r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
6287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6288
6289     lstrcpyA(expected, CURR_DIR);
6290     lstrcatA(expected, "\\neosodon\\");
6291     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6292        "Expected %s or empty string, got %s\n", expected, prop);
6293
6294     size = MAX_PATH;
6295     r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6297     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6298
6299     size = MAX_PATH;
6300     r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6302     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6303
6304     MsiCloseHandle(hpkg);
6305     DeleteFileA("abelisaurus");
6306     DeleteFileA("bactrosaurus");
6307     DeleteFileA("camelotia");
6308     DeleteFileA("diclonius");
6309     DeleteFileA("echinodon");
6310     DeleteFileA("falcarius");
6311     DeleteFileA("gallimimus");
6312     DeleteFileA("hagryphus");
6313     RemoveDirectoryA("iguanodon");
6314     RemoveDirectoryA("jobaria");
6315     RemoveDirectoryA("kakuru");
6316     RemoveDirectoryA("labocania");
6317     RemoveDirectoryA("megaraptor");
6318     RemoveDirectoryA("neosodon");
6319     RemoveDirectoryA("olorotitan");
6320     RemoveDirectoryA("pantydraco");
6321     delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6322                           MSIINSTALLCONTEXT_MACHINE, NULL);
6323     delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6324                           MSIINSTALLCONTEXT_MACHINE, NULL);
6325     delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6326                           MSIINSTALLCONTEXT_MACHINE, NULL);
6327     delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6328                           MSIINSTALLCONTEXT_MACHINE, NULL);
6329     delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6330                           MSIINSTALLCONTEXT_MACHINE, NULL);
6331     delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6332                           MSIINSTALLCONTEXT_MACHINE, NULL);
6333     delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6334                           MSIINSTALLCONTEXT_MACHINE, NULL);
6335     delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6336                           MSIINSTALLCONTEXT_MACHINE, NULL);
6337     DeleteFileA(msifile);
6338 }
6339
6340 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6341 {
6342     MSIHANDLE summary;
6343     UINT r;
6344
6345     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6347
6348     r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6350
6351     r = MsiSummaryInfoPersist(summary);
6352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6353
6354     MsiCloseHandle(summary);
6355 }
6356
6357 static void test_MsiGetSourcePath(void)
6358 {
6359     MSIHANDLE hdb, hpkg;
6360     CHAR path[MAX_PATH];
6361     CHAR cwd[MAX_PATH];
6362     CHAR subsrc[MAX_PATH];
6363     CHAR sub2[MAX_PATH];
6364     DWORD size;
6365     UINT r;
6366
6367     lstrcpyA(cwd, CURR_DIR);
6368     lstrcatA(cwd, "\\");
6369
6370     lstrcpyA(subsrc, cwd);
6371     lstrcatA(subsrc, "subsource");
6372     lstrcatA(subsrc, "\\");
6373
6374     lstrcpyA(sub2, subsrc);
6375     lstrcatA(sub2, "sub2");
6376     lstrcatA(sub2, "\\");
6377
6378     /* uncompressed source */
6379
6380     hdb = create_package_db();
6381     ok( hdb, "failed to create database\n");
6382
6383     set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6384
6385     r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6386     ok(r == S_OK, "failed\n");
6387
6388     r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6389     ok(r == S_OK, "failed\n");
6390
6391     r = add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6392     ok(r == S_OK, "failed\n");
6393
6394     r = MsiDatabaseCommit(hdb);
6395     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6396
6397     r = package_from_db(hdb, &hpkg);
6398     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6399     {
6400         skip("Not enough rights to perform tests\n");
6401         DeleteFile(msifile);
6402         return;
6403     }
6404     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6405
6406     MsiCloseHandle(hdb);
6407
6408     /* invalid database handle */
6409     size = MAX_PATH;
6410     lstrcpyA(path, "kiwi");
6411     r = MsiGetSourcePath(-1, "TARGETDIR", path, &size);
6412     ok(r == ERROR_INVALID_HANDLE,
6413        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6414     ok(!lstrcmpA(path, "kiwi"),
6415        "Expected path to be unchanged, got \"%s\"\n", path);
6416     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6417
6418     /* NULL szFolder */
6419     size = MAX_PATH;
6420     lstrcpyA(path, "kiwi");
6421     r = MsiGetSourcePath(hpkg, NULL, path, &size);
6422     ok(r == ERROR_INVALID_PARAMETER,
6423        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6424     ok(!lstrcmpA(path, "kiwi"),
6425        "Expected path to be unchanged, got \"%s\"\n", path);
6426     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6427
6428     /* empty szFolder */
6429     size = MAX_PATH;
6430     lstrcpyA(path, "kiwi");
6431     r = MsiGetSourcePath(hpkg, "", path, &size);
6432     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6433     ok(!lstrcmpA(path, "kiwi"),
6434        "Expected path to be unchanged, got \"%s\"\n", path);
6435     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6436
6437     /* try TARGETDIR */
6438     size = MAX_PATH;
6439     lstrcpyA(path, "kiwi");
6440     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6441     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6442     ok(!lstrcmpA(path, "kiwi"),
6443        "Expected path to be unchanged, got \"%s\"\n", path);
6444     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6445
6446     size = MAX_PATH;
6447     lstrcpyA(path, "kiwi");
6448     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6450     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6451     ok(size == 0, "Expected 0, got %d\n", size);
6452
6453     size = MAX_PATH;
6454     lstrcpyA(path, "kiwi");
6455     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6457     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6458     ok(size == 0, "Expected 0, got %d\n", size);
6459
6460     /* try SourceDir */
6461     size = MAX_PATH;
6462     lstrcpyA(path, "kiwi");
6463     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6464     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6465     ok(!lstrcmpA(path, "kiwi"),
6466        "Expected path to be unchanged, got \"%s\"\n", path);
6467     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6468
6469     /* try SOURCEDIR */
6470     size = MAX_PATH;
6471     lstrcpyA(path, "kiwi");
6472     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6473     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6474     ok(!lstrcmpA(path, "kiwi"),
6475        "Expected path to be unchanged, got \"%s\"\n", path);
6476     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6477
6478     /* source path does not exist, but the property exists */
6479     size = MAX_PATH;
6480     lstrcpyA(path, "kiwi");
6481     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6483     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6484     ok(size == 0, "Expected 0, got %d\n", size);
6485
6486     size = MAX_PATH;
6487     lstrcpyA(path, "kiwi");
6488     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6490     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6491     ok(size == 0, "Expected 0, got %d\n", size);
6492
6493     /* try SubDir */
6494     size = MAX_PATH;
6495     lstrcpyA(path, "kiwi");
6496     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6497     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6498     ok(!lstrcmpA(path, "kiwi"),
6499        "Expected path to be unchanged, got \"%s\"\n", path);
6500     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6501
6502     /* try SubDir2 */
6503     size = MAX_PATH;
6504     lstrcpyA(path, "kiwi");
6505     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6506     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6507     ok(!lstrcmpA(path, "kiwi"),
6508        "Expected path to be unchanged, got \"%s\"\n", path);
6509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6510
6511     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6512
6513     r = MsiDoAction(hpkg, "CostInitialize");
6514     ok(r == ERROR_SUCCESS, "cost init failed\n");
6515
6516     /* try TARGETDIR after CostInitialize */
6517     size = MAX_PATH;
6518     lstrcpyA(path, "kiwi");
6519     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6521     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6522     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6523
6524     /* try SourceDir after CostInitialize */
6525     size = MAX_PATH;
6526     lstrcpyA(path, "kiwi");
6527     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6529     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6530     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6531
6532     /* try SOURCEDIR after CostInitialize */
6533     size = MAX_PATH;
6534     lstrcpyA(path, "kiwi");
6535     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6536     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6537     ok(!lstrcmpA(path, "kiwi"),
6538        "Expected path to be unchanged, got \"%s\"\n", path);
6539     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6540
6541     /* source path does not exist, but the property exists */
6542     size = MAX_PATH;
6543     lstrcpyA(path, "kiwi");
6544     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6546     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6547     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6548
6549     size = MAX_PATH;
6550     lstrcpyA(path, "kiwi");
6551     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6553     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6554     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6555
6556     /* try SubDir after CostInitialize */
6557     size = MAX_PATH;
6558     lstrcpyA(path, "kiwi");
6559     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6561     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6562     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6563
6564     /* try SubDir2 after CostInitialize */
6565     size = MAX_PATH;
6566     lstrcpyA(path, "kiwi");
6567     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6569     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6570     ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6571
6572     r = MsiDoAction(hpkg, "ResolveSource");
6573     ok(r == ERROR_SUCCESS, "file cost failed\n");
6574
6575     /* try TARGETDIR after ResolveSource */
6576     size = MAX_PATH;
6577     lstrcpyA(path, "kiwi");
6578     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6580     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6581     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6582
6583     /* try SourceDir after ResolveSource */
6584     size = MAX_PATH;
6585     lstrcpyA(path, "kiwi");
6586     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6588     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6589     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6590
6591     /* try SOURCEDIR after ResolveSource */
6592     size = MAX_PATH;
6593     lstrcpyA(path, "kiwi");
6594     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6595     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6596     ok(!lstrcmpA(path, "kiwi"),
6597        "Expected path to be unchanged, got \"%s\"\n", path);
6598     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6599
6600     /* source path does not exist, but the property exists */
6601     size = MAX_PATH;
6602     lstrcpyA(path, "kiwi");
6603     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6604     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6605     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6606     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6607
6608     size = MAX_PATH;
6609     lstrcpyA(path, "kiwi");
6610     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6611     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6612     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6613     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6614
6615     /* try SubDir after ResolveSource */
6616     size = MAX_PATH;
6617     lstrcpyA(path, "kiwi");
6618     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6620     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6621     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6622
6623     /* try SubDir2 after ResolveSource */
6624     size = MAX_PATH;
6625     lstrcpyA(path, "kiwi");
6626     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6628     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6629     ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6630
6631     r = MsiDoAction(hpkg, "FileCost");
6632     ok(r == ERROR_SUCCESS, "file cost failed\n");
6633
6634     /* try TARGETDIR after FileCost */
6635     size = MAX_PATH;
6636     lstrcpyA(path, "kiwi");
6637     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6638     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6639     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6640     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6641
6642     /* try SourceDir after FileCost */
6643     size = MAX_PATH;
6644     lstrcpyA(path, "kiwi");
6645     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6647     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6648     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6649
6650     /* try SOURCEDIR after FileCost */
6651     size = MAX_PATH;
6652     lstrcpyA(path, "kiwi");
6653     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6654     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6655     ok(!lstrcmpA(path, "kiwi"),
6656        "Expected path to be unchanged, got \"%s\"\n", path);
6657     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6658
6659     /* source path does not exist, but the property exists */
6660     size = MAX_PATH;
6661     lstrcpyA(path, "kiwi");
6662     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6663     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6664     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6665     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6666
6667     size = MAX_PATH;
6668     lstrcpyA(path, "kiwi");
6669     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6671     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6672     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6673
6674     /* try SubDir after FileCost */
6675     size = MAX_PATH;
6676     lstrcpyA(path, "kiwi");
6677     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6678     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6679     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6680     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6681
6682     /* try SubDir2 after FileCost */
6683     size = MAX_PATH;
6684     lstrcpyA(path, "kiwi");
6685     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6686     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6687     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6688     ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6689
6690     r = MsiDoAction(hpkg, "CostFinalize");
6691     ok(r == ERROR_SUCCESS, "file cost failed\n");
6692
6693     /* try TARGETDIR after CostFinalize */
6694     size = MAX_PATH;
6695     lstrcpyA(path, "kiwi");
6696     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6698     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6699     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6700
6701     /* try SourceDir after CostFinalize */
6702     size = MAX_PATH;
6703     lstrcpyA(path, "kiwi");
6704     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6706     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6707     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6708
6709     /* try SOURCEDIR after CostFinalize */
6710     size = MAX_PATH;
6711     lstrcpyA(path, "kiwi");
6712     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6713     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6714     ok(!lstrcmpA(path, "kiwi"),
6715        "Expected path to be unchanged, got \"%s\"\n", path);
6716     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6717
6718     /* source path does not exist, but the property exists */
6719     size = MAX_PATH;
6720     lstrcpyA(path, "kiwi");
6721     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6724     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6725
6726     size = MAX_PATH;
6727     lstrcpyA(path, "kiwi");
6728     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6730     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6731     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6732
6733     /* try SubDir after CostFinalize */
6734     size = MAX_PATH;
6735     lstrcpyA(path, "kiwi");
6736     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6738     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6739     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6740
6741     /* try SubDir2 after CostFinalize */
6742     size = MAX_PATH;
6743     lstrcpyA(path, "kiwi");
6744     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6746     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6747     ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6748
6749     /* nonexistent directory */
6750     size = MAX_PATH;
6751     lstrcpyA(path, "kiwi");
6752     r = MsiGetSourcePath(hpkg, "IDontExist", path, &size);
6753     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6754     ok(!lstrcmpA(path, "kiwi"),
6755        "Expected path to be unchanged, got \"%s\"\n", path);
6756     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6757
6758     /* NULL szPathBuf */
6759     size = MAX_PATH;
6760     r = MsiGetSourcePath(hpkg, "SourceDir", NULL, &size);
6761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6762     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6763
6764     /* NULL pcchPathBuf */
6765     lstrcpyA(path, "kiwi");
6766     r = MsiGetSourcePath(hpkg, "SourceDir", path, NULL);
6767     ok(r == ERROR_INVALID_PARAMETER,
6768        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6769     ok(!lstrcmpA(path, "kiwi"),
6770        "Expected path to be unchanged, got \"%s\"\n", path);
6771
6772     /* pcchPathBuf is 0 */
6773     size = 0;
6774     lstrcpyA(path, "kiwi");
6775     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6776     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6777     ok(!lstrcmpA(path, "kiwi"),
6778        "Expected path to be unchanged, got \"%s\"\n", path);
6779     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6780
6781     /* pcchPathBuf does not have room for NULL terminator */
6782     size = lstrlenA(cwd);
6783     lstrcpyA(path, "kiwi");
6784     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6785     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6786     ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6787        "Expected path with no backslash, got \"%s\"\n", path);
6788     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6789
6790     /* pcchPathBuf has room for NULL terminator */
6791     size = lstrlenA(cwd) + 1;
6792     lstrcpyA(path, "kiwi");
6793     r = MsiGetSourcePath(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);
6797
6798     /* remove property */
6799     r = MsiSetProperty(hpkg, "SourceDir", NULL);
6800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6801
6802     /* try SourceDir again */
6803     size = MAX_PATH;
6804     lstrcpyA(path, "kiwi");
6805     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6807     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6808     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6809
6810     /* set property to a valid directory */
6811     r = MsiSetProperty(hpkg, "SOURCEDIR", cwd);
6812     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6813
6814     /* try SOURCEDIR again */
6815     size = MAX_PATH;
6816     lstrcpyA(path, "kiwi");
6817     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6818     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6819     ok(!lstrcmpA(path, "kiwi"),
6820        "Expected path to be unchanged, got \"%s\"\n", path);
6821     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6822
6823     MsiCloseHandle(hpkg);
6824
6825     /* compressed source */
6826
6827     r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
6828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6829
6830     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
6831
6832     r = package_from_db(hdb, &hpkg);
6833     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6834
6835     /* try TARGETDIR */
6836     size = MAX_PATH;
6837     lstrcpyA(path, "kiwi");
6838     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6839     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6840     ok(!lstrcmpA(path, "kiwi"),
6841        "Expected path to be unchanged, got \"%s\"\n", path);
6842     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6843
6844     /* try SourceDir */
6845     size = MAX_PATH;
6846     lstrcpyA(path, "kiwi");
6847     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6848     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6849     ok(!lstrcmpA(path, "kiwi"),
6850        "Expected path to be unchanged, got \"%s\"\n", path);
6851     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6852
6853     /* try SOURCEDIR */
6854     size = MAX_PATH;
6855     lstrcpyA(path, "kiwi");
6856     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6857     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6858     ok(!lstrcmpA(path, "kiwi"),
6859        "Expected path to be unchanged, got \"%s\"\n", path);
6860     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6861
6862     /* source path nor the property exist */
6863     size = MAX_PATH;
6864     lstrcpyA(path, "kiwi");
6865     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6867     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6868     ok(size == 0, "Expected 0, got %d\n", size);
6869
6870     size = MAX_PATH;
6871     lstrcpyA(path, "kiwi");
6872     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6874     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6875     ok(size == 0, "Expected 0, got %d\n", size);
6876
6877     /* try SubDir */
6878     size = MAX_PATH;
6879     lstrcpyA(path, "kiwi");
6880     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6881     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6882     ok(!lstrcmpA(path, "kiwi"),
6883        "Expected path to be unchanged, got \"%s\"\n", path);
6884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6885
6886     /* try SubDir2 */
6887     size = MAX_PATH;
6888     lstrcpyA(path, "kiwi");
6889     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6890     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6891     ok(!lstrcmpA(path, "kiwi"),
6892        "Expected path to be unchanged, got \"%s\"\n", path);
6893     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6894
6895     r = MsiDoAction(hpkg, "CostInitialize");
6896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6897
6898     /* try TARGETDIR after CostInitialize */
6899     size = MAX_PATH;
6900     lstrcpyA(path, "kiwi");
6901     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6903     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6904     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6905
6906     /* try SourceDir after CostInitialize */
6907     size = MAX_PATH;
6908     lstrcpyA(path, "kiwi");
6909     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6911     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6912     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6913
6914     /* try SOURCEDIR after CostInitialize */
6915     size = MAX_PATH;
6916     lstrcpyA(path, "kiwi");
6917     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6918     todo_wine
6919     {
6920         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6921         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6922         ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6923     }
6924
6925     /* source path does not exist, but the property exists */
6926     size = MAX_PATH;
6927     lstrcpyA(path, "kiwi");
6928     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6930     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6931     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6932
6933     size = MAX_PATH;
6934     lstrcpyA(path, "kiwi");
6935     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6937     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6938     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6939
6940     /* try SubDir after CostInitialize */
6941     size = MAX_PATH;
6942     lstrcpyA(path, "kiwi");
6943     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
6944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6946     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6947
6948     /* try SubDir2 after CostInitialize */
6949     size = MAX_PATH;
6950     lstrcpyA(path, "kiwi");
6951     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
6952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6953     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6954     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6955
6956     r = MsiDoAction(hpkg, "ResolveSource");
6957     ok(r == ERROR_SUCCESS, "file cost failed\n");
6958
6959     /* try TARGETDIR after ResolveSource */
6960     size = MAX_PATH;
6961     lstrcpyA(path, "kiwi");
6962     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
6963     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6964     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6965     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6966
6967     /* try SourceDir after ResolveSource */
6968     size = MAX_PATH;
6969     lstrcpyA(path, "kiwi");
6970     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
6971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6972     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6973     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6974
6975     /* try SOURCEDIR after ResolveSource */
6976     size = MAX_PATH;
6977     lstrcpyA(path, "kiwi");
6978     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
6979     todo_wine
6980     {
6981         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6982         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6983         ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6984     }
6985
6986     /* source path and the property exist */
6987     size = MAX_PATH;
6988     lstrcpyA(path, "kiwi");
6989     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
6990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6991     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6992     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6993
6994     size = MAX_PATH;
6995     lstrcpyA(path, "kiwi");
6996     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
6997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6998     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6999     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7000
7001     /* try SubDir after ResolveSource */
7002     size = MAX_PATH;
7003     lstrcpyA(path, "kiwi");
7004     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7006     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7007     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7008
7009     /* try SubDir2 after ResolveSource */
7010     size = MAX_PATH;
7011     lstrcpyA(path, "kiwi");
7012     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
7013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7014     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7015     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7016
7017     r = MsiDoAction(hpkg, "FileCost");
7018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7019
7020     /* try TARGETDIR after CostFinalize */
7021     size = MAX_PATH;
7022     lstrcpyA(path, "kiwi");
7023     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
7024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7025     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7026     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7027
7028     /* try SourceDir after CostFinalize */
7029     size = MAX_PATH;
7030     lstrcpyA(path, "kiwi");
7031     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
7032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7033     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7034     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7035
7036     /* try SOURCEDIR after CostFinalize */
7037     size = MAX_PATH;
7038     lstrcpyA(path, "kiwi");
7039     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7040     todo_wine
7041     {
7042         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7043         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7044         ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7045     }
7046
7047     /* source path and the property exist */
7048     size = MAX_PATH;
7049     lstrcpyA(path, "kiwi");
7050     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7052     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7053     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7054
7055     size = MAX_PATH;
7056     lstrcpyA(path, "kiwi");
7057     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7058     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7059     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7060     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7061
7062     /* try SubDir after CostFinalize */
7063     size = MAX_PATH;
7064     lstrcpyA(path, "kiwi");
7065     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7067     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7068     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7069
7070     /* try SubDir2 after CostFinalize */
7071     size = MAX_PATH;
7072     lstrcpyA(path, "kiwi");
7073     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
7074     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7075     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7076     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7077
7078     r = MsiDoAction(hpkg, "CostFinalize");
7079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7080
7081     /* try TARGETDIR after CostFinalize */
7082     size = MAX_PATH;
7083     lstrcpyA(path, "kiwi");
7084     r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size);
7085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7086     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7087     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7088
7089     /* try SourceDir after CostFinalize */
7090     size = MAX_PATH;
7091     lstrcpyA(path, "kiwi");
7092     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
7093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7094     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7095     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7096
7097     /* try SOURCEDIR after CostFinalize */
7098     size = MAX_PATH;
7099     lstrcpyA(path, "kiwi");
7100     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7101     todo_wine
7102     {
7103         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7104         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7105         ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7106     }
7107
7108     /* source path and the property exist */
7109     size = MAX_PATH;
7110     lstrcpyA(path, "kiwi");
7111     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7113     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7114     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7115
7116     size = MAX_PATH;
7117     lstrcpyA(path, "kiwi");
7118     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7120     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7121     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7122
7123     /* try SubDir after CostFinalize */
7124     size = MAX_PATH;
7125     lstrcpyA(path, "kiwi");
7126     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7128     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7129     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7130
7131     /* try SubDir2 after CostFinalize */
7132     size = MAX_PATH;
7133     lstrcpyA(path, "kiwi");
7134     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
7135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7136     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7137     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7138
7139     MsiCloseHandle(hpkg);
7140     DeleteFile(msifile);
7141 }
7142
7143 static void test_shortlongsource(void)
7144 {
7145     MSIHANDLE hdb, hpkg;
7146     CHAR path[MAX_PATH];
7147     CHAR cwd[MAX_PATH];
7148     CHAR subsrc[MAX_PATH];
7149     DWORD size;
7150     UINT r;
7151
7152     lstrcpyA(cwd, CURR_DIR);
7153     lstrcatA(cwd, "\\");
7154
7155     lstrcpyA(subsrc, cwd);
7156     lstrcatA(subsrc, "long");
7157     lstrcatA(subsrc, "\\");
7158
7159     /* long file names */
7160
7161     hdb = create_package_db();
7162     ok( hdb, "failed to create database\n");
7163
7164     set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
7165
7166     r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7167     ok(r == S_OK, "failed\n");
7168
7169     r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
7170     ok(r == S_OK, "failed\n");
7171
7172     /* CostInitialize:short */
7173     r = add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
7174     ok(r == S_OK, "failed\n");
7175
7176     /* CostInitialize:long */
7177     r = add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
7178     ok(r == S_OK, "failed\n");
7179
7180     /* FileCost:short */
7181     r = add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
7182     ok(r == S_OK, "failed\n");
7183
7184     /* FileCost:long */
7185     r = add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
7186     ok(r == S_OK, "failed\n");
7187
7188     /* CostFinalize:short */
7189     r = add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
7190     ok(r == S_OK, "failed\n");
7191
7192     /* CostFinalize:long */
7193     r = add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
7194     ok(r == S_OK, "failed\n");
7195
7196     MsiDatabaseCommit(hdb);
7197
7198     r = package_from_db(hdb, &hpkg);
7199     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7200     {
7201         skip("Not enough rights to perform tests\n");
7202         DeleteFile(msifile);
7203         return;
7204     }
7205     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7206
7207     MsiCloseHandle(hdb);
7208
7209     CreateDirectoryA("one", NULL);
7210     CreateDirectoryA("four", NULL);
7211
7212     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7213
7214     r = MsiDoAction(hpkg, "CostInitialize");
7215     ok(r == ERROR_SUCCESS, "file cost failed\n");
7216
7217     CreateDirectory("five", NULL);
7218     CreateDirectory("eight", NULL);
7219
7220     r = MsiDoAction(hpkg, "FileCost");
7221     ok(r == ERROR_SUCCESS, "file cost failed\n");
7222
7223     CreateDirectory("nine", NULL);
7224     CreateDirectory("twelve", NULL);
7225
7226     r = MsiDoAction(hpkg, "CostFinalize");
7227     ok(r == ERROR_SUCCESS, "file cost failed\n");
7228
7229     /* neither short nor long source directories exist */
7230     size = MAX_PATH;
7231     lstrcpyA(path, "kiwi");
7232     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7234     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7235     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7236
7237     CreateDirectoryA("short", NULL);
7238
7239     /* short source directory exists */
7240     size = MAX_PATH;
7241     lstrcpyA(path, "kiwi");
7242     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7244     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7245     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7246
7247     CreateDirectoryA("long", NULL);
7248
7249     /* both short and long source directories exist */
7250     size = MAX_PATH;
7251     lstrcpyA(path, "kiwi");
7252     r = MsiGetSourcePath(hpkg, "SubDir", 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);
7256
7257     lstrcpyA(subsrc, cwd);
7258     lstrcatA(subsrc, "two");
7259     lstrcatA(subsrc, "\\");
7260
7261     /* short dir exists before CostInitialize */
7262     size = MAX_PATH;
7263     lstrcpyA(path, "kiwi");
7264     r = MsiGetSourcePath(hpkg, "SubDir2", 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);
7268
7269     lstrcpyA(subsrc, cwd);
7270     lstrcatA(subsrc, "four");
7271     lstrcatA(subsrc, "\\");
7272
7273     /* long dir exists before CostInitialize */
7274     size = MAX_PATH;
7275     lstrcpyA(path, "kiwi");
7276     r = MsiGetSourcePath(hpkg, "SubDir3", path, &size);
7277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7278     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7279     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7280
7281     lstrcpyA(subsrc, cwd);
7282     lstrcatA(subsrc, "six");
7283     lstrcatA(subsrc, "\\");
7284
7285     /* short dir exists before FileCost */
7286     size = MAX_PATH;
7287     lstrcpyA(path, "kiwi");
7288     r = MsiGetSourcePath(hpkg, "SubDir4", path, &size);
7289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7290     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7291     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7292
7293     lstrcpyA(subsrc, cwd);
7294     lstrcatA(subsrc, "eight");
7295     lstrcatA(subsrc, "\\");
7296
7297     /* long dir exists before FileCost */
7298     size = MAX_PATH;
7299     lstrcpyA(path, "kiwi");
7300     r = MsiGetSourcePath(hpkg, "SubDir5", path, &size);
7301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7302     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7303     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7304
7305     lstrcpyA(subsrc, cwd);
7306     lstrcatA(subsrc, "ten");
7307     lstrcatA(subsrc, "\\");
7308
7309     /* short dir exists before CostFinalize */
7310     size = MAX_PATH;
7311     lstrcpyA(path, "kiwi");
7312     r = MsiGetSourcePath(hpkg, "SubDir6", path, &size);
7313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7314     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7315     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7316
7317     lstrcpyA(subsrc, cwd);
7318     lstrcatA(subsrc, "twelve");
7319     lstrcatA(subsrc, "\\");
7320
7321     /* long dir exists before CostFinalize */
7322     size = MAX_PATH;
7323     lstrcpyA(path, "kiwi");
7324     r = MsiGetSourcePath(hpkg, "SubDir7", path, &size);
7325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7326     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7327     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7328
7329     MsiCloseHandle(hpkg);
7330     RemoveDirectoryA("short");
7331     RemoveDirectoryA("long");
7332     RemoveDirectoryA("one");
7333     RemoveDirectoryA("four");
7334     RemoveDirectoryA("five");
7335     RemoveDirectoryA("eight");
7336     RemoveDirectoryA("nine");
7337     RemoveDirectoryA("twelve");
7338
7339     /* short file names */
7340
7341     r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
7342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7343
7344     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7345
7346     r = package_from_db(hdb, &hpkg);
7347     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7348
7349     MsiCloseHandle(hdb);
7350
7351     CreateDirectoryA("one", NULL);
7352     CreateDirectoryA("four", NULL);
7353
7354     r = MsiDoAction(hpkg, "CostInitialize");
7355     ok(r == ERROR_SUCCESS, "file cost failed\n");
7356
7357     CreateDirectory("five", NULL);
7358     CreateDirectory("eight", NULL);
7359
7360     r = MsiDoAction(hpkg, "FileCost");
7361     ok(r == ERROR_SUCCESS, "file cost failed\n");
7362
7363     CreateDirectory("nine", NULL);
7364     CreateDirectory("twelve", NULL);
7365
7366     r = MsiDoAction(hpkg, "CostFinalize");
7367     ok(r == ERROR_SUCCESS, "file cost failed\n");
7368
7369     lstrcpyA(subsrc, cwd);
7370     lstrcatA(subsrc, "short");
7371     lstrcatA(subsrc, "\\");
7372
7373     /* neither short nor long source directories exist */
7374     size = MAX_PATH;
7375     lstrcpyA(path, "kiwi");
7376     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7378     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7379     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7380
7381     CreateDirectoryA("short", NULL);
7382
7383     /* short source directory exists */
7384     size = MAX_PATH;
7385     lstrcpyA(path, "kiwi");
7386     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7388     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7389     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7390
7391     CreateDirectoryA("long", NULL);
7392
7393     /* both short and long source directories exist */
7394     size = MAX_PATH;
7395     lstrcpyA(path, "kiwi");
7396     r = MsiGetSourcePath(hpkg, "SubDir", path, &size);
7397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7398     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7399     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7400
7401     lstrcpyA(subsrc, cwd);
7402     lstrcatA(subsrc, "one");
7403     lstrcatA(subsrc, "\\");
7404
7405     /* short dir exists before CostInitialize */
7406     size = MAX_PATH;
7407     lstrcpyA(path, "kiwi");
7408     r = MsiGetSourcePath(hpkg, "SubDir2", path, &size);
7409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7410     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7411     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7412
7413     lstrcpyA(subsrc, cwd);
7414     lstrcatA(subsrc, "three");
7415     lstrcatA(subsrc, "\\");
7416
7417     /* long dir exists before CostInitialize */
7418     size = MAX_PATH;
7419     lstrcpyA(path, "kiwi");
7420     r = MsiGetSourcePath(hpkg, "SubDir3", path, &size);
7421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7422     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7423     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7424
7425     lstrcpyA(subsrc, cwd);
7426     lstrcatA(subsrc, "five");
7427     lstrcatA(subsrc, "\\");
7428
7429     /* short dir exists before FileCost */
7430     size = MAX_PATH;
7431     lstrcpyA(path, "kiwi");
7432     r = MsiGetSourcePath(hpkg, "SubDir4", path, &size);
7433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7434     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7435     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7436
7437     lstrcpyA(subsrc, cwd);
7438     lstrcatA(subsrc, "seven");
7439     lstrcatA(subsrc, "\\");
7440
7441     /* long dir exists before FileCost */
7442     size = MAX_PATH;
7443     lstrcpyA(path, "kiwi");
7444     r = MsiGetSourcePath(hpkg, "SubDir5", path, &size);
7445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7446     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7447     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7448
7449     lstrcpyA(subsrc, cwd);
7450     lstrcatA(subsrc, "nine");
7451     lstrcatA(subsrc, "\\");
7452
7453     /* short dir exists before CostFinalize */
7454     size = MAX_PATH;
7455     lstrcpyA(path, "kiwi");
7456     r = MsiGetSourcePath(hpkg, "SubDir6", path, &size);
7457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7458     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7459     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7460
7461     lstrcpyA(subsrc, cwd);
7462     lstrcatA(subsrc, "eleven");
7463     lstrcatA(subsrc, "\\");
7464
7465     /* long dir exists before CostFinalize */
7466     size = MAX_PATH;
7467     lstrcpyA(path, "kiwi");
7468     r = MsiGetSourcePath(hpkg, "SubDir7", path, &size);
7469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7470     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7471     ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7472
7473     MsiCloseHandle(hpkg);
7474     RemoveDirectoryA("short");
7475     RemoveDirectoryA("long");
7476     RemoveDirectoryA("one");
7477     RemoveDirectoryA("four");
7478     RemoveDirectoryA("five");
7479     RemoveDirectoryA("eight");
7480     RemoveDirectoryA("nine");
7481     RemoveDirectoryA("twelve");
7482     DeleteFileA(msifile);
7483 }
7484
7485 static void test_sourcedir(void)
7486 {
7487     MSIHANDLE hdb, hpkg;
7488     CHAR package[12];
7489     CHAR path[MAX_PATH];
7490     CHAR cwd[MAX_PATH];
7491     CHAR subsrc[MAX_PATH];
7492     DWORD size;
7493     UINT r;
7494
7495     lstrcpyA(cwd, CURR_DIR);
7496     lstrcatA(cwd, "\\");
7497
7498     lstrcpyA(subsrc, cwd);
7499     lstrcatA(subsrc, "long");
7500     lstrcatA(subsrc, "\\");
7501
7502     hdb = create_package_db();
7503     ok( hdb, "failed to create database\n");
7504
7505     r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7506     ok(r == S_OK, "failed\n");
7507
7508     sprintf(package, "#%u", hdb);
7509     r = MsiOpenPackage(package, &hpkg);
7510     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7511     {
7512         skip("Not enough rights to perform tests\n");
7513         goto error;
7514     }
7515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7516
7517     /* properties only */
7518
7519     /* SourceDir prop */
7520     size = MAX_PATH;
7521     lstrcpyA(path, "kiwi");
7522     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7524     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7525     ok(size == 0, "Expected 0, got %d\n", size);
7526
7527     /* SOURCEDIR prop */
7528     size = MAX_PATH;
7529     lstrcpyA(path, "kiwi");
7530     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7532     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7533     ok(size == 0, "Expected 0, got %d\n", size);
7534
7535     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7536
7537     r = MsiDoAction(hpkg, "CostInitialize");
7538     ok(r == ERROR_SUCCESS, "file cost failed\n");
7539
7540     /* SourceDir after CostInitialize */
7541     size = MAX_PATH;
7542     lstrcpyA(path, "kiwi");
7543     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7545     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7546     ok(size == 0, "Expected 0, got %d\n", size);
7547
7548     /* SOURCEDIR after CostInitialize */
7549     size = MAX_PATH;
7550     lstrcpyA(path, "kiwi");
7551     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7553     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7554     ok(size == 0, "Expected 0, got %d\n", size);
7555
7556     r = MsiDoAction(hpkg, "FileCost");
7557     ok(r == ERROR_SUCCESS, "file cost failed\n");
7558
7559     /* SourceDir after FileCost */
7560     size = MAX_PATH;
7561     lstrcpyA(path, "kiwi");
7562     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7564     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7565     ok(size == 0, "Expected 0, got %d\n", size);
7566
7567     /* SOURCEDIR after FileCost */
7568     size = MAX_PATH;
7569     lstrcpyA(path, "kiwi");
7570     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7572     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7573     ok(size == 0, "Expected 0, got %d\n", size);
7574
7575     r = MsiDoAction(hpkg, "CostFinalize");
7576     ok(r == ERROR_SUCCESS, "file cost failed\n");
7577
7578     /* SourceDir after CostFinalize */
7579     size = MAX_PATH;
7580     lstrcpyA(path, "kiwi");
7581     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7583     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7584     ok(size == 0, "Expected 0, got %d\n", size);
7585
7586     /* SOURCEDIR after CostFinalize */
7587     size = MAX_PATH;
7588     lstrcpyA(path, "kiwi");
7589     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7591     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7592     ok(size == 0, "Expected 0, got %d\n", size);
7593
7594     size = MAX_PATH;
7595     lstrcpyA(path, "kiwi");
7596     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7597     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7598     ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7599     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
7600
7601     /* SOURCEDIR after calling MsiGetSourcePath */
7602     size = MAX_PATH;
7603     lstrcpyA(path, "kiwi");
7604     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7606     todo_wine {
7607     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7608     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7609     }
7610
7611     r = MsiDoAction(hpkg, "ResolveSource");
7612     ok(r == ERROR_SUCCESS, "file cost failed\n");
7613
7614     /* SourceDir after ResolveSource */
7615     size = MAX_PATH;
7616     lstrcpyA(path, "kiwi");
7617     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7619     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7620     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7621
7622     /* SOURCEDIR after ResolveSource */
7623     size = MAX_PATH;
7624     lstrcpyA(path, "kiwi");
7625     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7626     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7627     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7628     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7629
7630     /* random casing */
7631     size = MAX_PATH;
7632     lstrcpyA(path, "kiwi");
7633     r = MsiGetProperty(hpkg, "SoUrCeDiR", path, &size);
7634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7635     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7636     ok(size == 0, "Expected 0, got %d\n", size);
7637
7638     MsiCloseHandle(hpkg);
7639
7640     /* reset the package state */
7641     sprintf(package, "#%i", hdb);
7642     r = MsiOpenPackage(package, &hpkg);
7643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7644
7645     /* test how MsiGetSourcePath affects the properties */
7646
7647     /* SourceDir prop */
7648     size = MAX_PATH;
7649     lstrcpyA(path, "kiwi");
7650     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7652     todo_wine
7653     {
7654         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7655         ok(size == 0, "Expected 0, got %d\n", size);
7656     }
7657
7658     size = MAX_PATH;
7659     lstrcpyA(path, "kiwi");
7660     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
7661     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7662     ok(!lstrcmpA(path, "kiwi"),
7663        "Expected path to be unchanged, got \"%s\"\n", path);
7664     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7665
7666     /* SourceDir after MsiGetSourcePath */
7667     size = MAX_PATH;
7668     lstrcpyA(path, "kiwi");
7669     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7671     todo_wine
7672     {
7673         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7674         ok(size == 0, "Expected 0, got %d\n", size);
7675     }
7676
7677     /* SOURCEDIR prop */
7678     size = MAX_PATH;
7679     lstrcpyA(path, "kiwi");
7680     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7682     todo_wine
7683     {
7684         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7685         ok(size == 0, "Expected 0, got %d\n", size);
7686     }
7687
7688     size = MAX_PATH;
7689     lstrcpyA(path, "kiwi");
7690     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7691     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7692     ok(!lstrcmpA(path, "kiwi"),
7693        "Expected path to be unchanged, got \"%s\"\n", path);
7694     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7695
7696     /* SOURCEDIR prop after MsiGetSourcePath */
7697     size = MAX_PATH;
7698     lstrcpyA(path, "kiwi");
7699     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7701     todo_wine
7702     {
7703         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7704         ok(size == 0, "Expected 0, got %d\n", size);
7705     }
7706
7707     r = MsiDoAction(hpkg, "CostInitialize");
7708     ok(r == ERROR_SUCCESS, "file cost failed\n");
7709
7710     /* SourceDir after CostInitialize */
7711     size = MAX_PATH;
7712     lstrcpyA(path, "kiwi");
7713     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7715     todo_wine
7716     {
7717         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7718         ok(size == 0, "Expected 0, got %d\n", size);
7719     }
7720
7721     size = MAX_PATH;
7722     lstrcpyA(path, "kiwi");
7723     r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
7724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7725     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7726     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7727
7728     /* SourceDir after MsiGetSourcePath */
7729     size = MAX_PATH;
7730     lstrcpyA(path, "kiwi");
7731     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7733     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7734     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7735
7736     /* SOURCEDIR after CostInitialize */
7737     size = MAX_PATH;
7738     lstrcpyA(path, "kiwi");
7739     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7741     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7742     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7743
7744     /* SOURCEDIR source path still does not exist */
7745     size = MAX_PATH;
7746     lstrcpyA(path, "kiwi");
7747     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7748     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7749     ok(!lstrcmpA(path, "kiwi"),
7750        "Expected path to be unchanged, got \"%s\"\n", path);
7751     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7752
7753     r = MsiDoAction(hpkg, "FileCost");
7754     ok(r == ERROR_SUCCESS, "file cost failed\n");
7755
7756     /* SourceDir after FileCost */
7757     size = MAX_PATH;
7758     lstrcpyA(path, "kiwi");
7759     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7760     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7761     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7762     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7763
7764     /* SOURCEDIR after FileCost */
7765     size = MAX_PATH;
7766     lstrcpyA(path, "kiwi");
7767     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7769     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7770     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7771
7772     /* SOURCEDIR source path still does not exist */
7773     size = MAX_PATH;
7774     lstrcpyA(path, "kiwi");
7775     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7776     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7777     ok(!lstrcmpA(path, "kiwi"),
7778        "Expected path to be unchanged, got \"%s\"\n", path);
7779     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7780
7781     r = MsiDoAction(hpkg, "CostFinalize");
7782     ok(r == ERROR_SUCCESS, "file cost failed\n");
7783
7784     /* SourceDir after CostFinalize */
7785     size = MAX_PATH;
7786     lstrcpyA(path, "kiwi");
7787     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7789     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7790     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7791
7792     /* SOURCEDIR after CostFinalize */
7793     size = MAX_PATH;
7794     lstrcpyA(path, "kiwi");
7795     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7797     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7798     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7799
7800     /* SOURCEDIR source path still does not exist */
7801     size = MAX_PATH;
7802     lstrcpyA(path, "kiwi");
7803     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7804     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7805     ok(!lstrcmpA(path, "kiwi"),
7806        "Expected path to be unchanged, got \"%s\"\n", path);
7807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7808
7809     r = MsiDoAction(hpkg, "ResolveSource");
7810     ok(r == ERROR_SUCCESS, "file cost failed\n");
7811
7812     /* SourceDir after ResolveSource */
7813     size = MAX_PATH;
7814     lstrcpyA(path, "kiwi");
7815     r = MsiGetProperty(hpkg, "SourceDir", path, &size);
7816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7817     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7818     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7819
7820     /* SOURCEDIR after ResolveSource */
7821     size = MAX_PATH;
7822     lstrcpyA(path, "kiwi");
7823     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
7824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7825     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7826     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7827
7828     /* SOURCEDIR source path still does not exist */
7829     size = MAX_PATH;
7830     lstrcpyA(path, "kiwi");
7831     r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
7832     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7833     ok(!lstrcmpA(path, "kiwi"),
7834        "Expected path to be unchanged, got \"%s\"\n", path);
7835     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7836
7837     MsiCloseHandle(hpkg);
7838
7839 error:
7840     MsiCloseHandle(hdb);
7841     DeleteFileA(msifile);
7842 }
7843
7844 struct access_res
7845 {
7846     BOOL gothandle;
7847     DWORD lasterr;
7848     BOOL ignore;
7849 };
7850
7851 static const struct access_res create[16] =
7852 {
7853     { TRUE, ERROR_SUCCESS, TRUE },
7854     { TRUE, ERROR_SUCCESS, TRUE },
7855     { TRUE, ERROR_SUCCESS, FALSE },
7856     { TRUE, ERROR_SUCCESS, FALSE },
7857     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7858     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7859     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7860     { TRUE, ERROR_SUCCESS, FALSE },
7861     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7862     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7863     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7864     { TRUE, ERROR_SUCCESS, TRUE },
7865     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7866     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7867     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7868     { TRUE, ERROR_SUCCESS, TRUE }
7869 };
7870
7871 static const struct access_res create_commit[16] =
7872 {
7873     { TRUE, ERROR_SUCCESS, TRUE },
7874     { TRUE, ERROR_SUCCESS, TRUE },
7875     { TRUE, ERROR_SUCCESS, FALSE },
7876     { TRUE, ERROR_SUCCESS, FALSE },
7877     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7878     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7879     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7880     { TRUE, ERROR_SUCCESS, FALSE },
7881     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7882     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7883     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7884     { TRUE, ERROR_SUCCESS, TRUE },
7885     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7886     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7887     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7888     { TRUE, ERROR_SUCCESS, TRUE }
7889 };
7890
7891 static const struct access_res create_close[16] =
7892 {
7893     { TRUE, ERROR_SUCCESS, FALSE },
7894     { TRUE, ERROR_SUCCESS, FALSE },
7895     { TRUE, ERROR_SUCCESS, FALSE },
7896     { TRUE, ERROR_SUCCESS, FALSE },
7897     { TRUE, ERROR_SUCCESS, FALSE },
7898     { TRUE, ERROR_SUCCESS, FALSE },
7899     { TRUE, ERROR_SUCCESS, FALSE },
7900     { TRUE, ERROR_SUCCESS, FALSE },
7901     { TRUE, ERROR_SUCCESS, FALSE },
7902     { TRUE, ERROR_SUCCESS, FALSE },
7903     { TRUE, ERROR_SUCCESS, FALSE },
7904     { TRUE, ERROR_SUCCESS, FALSE },
7905     { TRUE, ERROR_SUCCESS, FALSE },
7906     { TRUE, ERROR_SUCCESS, FALSE },
7907     { TRUE, ERROR_SUCCESS, FALSE },
7908     { TRUE, ERROR_SUCCESS }
7909 };
7910
7911 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7912 {
7913     DWORD access = 0, share = 0;
7914     DWORD lasterr;
7915     HANDLE hfile;
7916     int i, j, idx = 0;
7917
7918     for (i = 0; i < 4; i++)
7919     {
7920         if (i == 0) access = 0;
7921         if (i == 1) access = GENERIC_READ;
7922         if (i == 2) access = GENERIC_WRITE;
7923         if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7924
7925         for (j = 0; j < 4; j++)
7926         {
7927             if (ares[idx].ignore)
7928                 continue;
7929
7930             if (j == 0) share = 0;
7931             if (j == 1) share = FILE_SHARE_READ;
7932             if (j == 2) share = FILE_SHARE_WRITE;
7933             if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7934
7935             SetLastError(0xdeadbeef);
7936             hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7937                                 FILE_ATTRIBUTE_NORMAL, 0);
7938             lasterr = GetLastError();
7939
7940             ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7941                "(%d, handle, %d): Expected %d, got %d\n",
7942                line, idx, ares[idx].gothandle,
7943                (hfile != INVALID_HANDLE_VALUE));
7944
7945             ok(lasterr == ares[idx].lasterr, "(%d, lasterr, %d): Expected %d, got %d\n",
7946                line, idx, ares[idx].lasterr, lasterr);
7947
7948             CloseHandle(hfile);
7949             idx++;
7950         }
7951     }
7952 }
7953
7954 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7955
7956 static void test_access(void)
7957 {
7958     MSIHANDLE hdb;
7959     UINT r;
7960
7961     r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATE, &hdb);
7962     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7963
7964     test_file_access(msifile, create);
7965
7966     r = MsiDatabaseCommit(hdb);
7967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7968
7969     test_file_access(msifile, create_commit);
7970     MsiCloseHandle(hdb);
7971
7972     test_file_access(msifile, create_close);
7973     DeleteFileA(msifile);
7974
7975     r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATEDIRECT, &hdb);
7976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7977
7978     test_file_access(msifile, create);
7979
7980     r = MsiDatabaseCommit(hdb);
7981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7982
7983     test_file_access(msifile, create_commit);
7984     MsiCloseHandle(hdb);
7985
7986     test_file_access(msifile, create_close);
7987     DeleteFileA(msifile);
7988 }
7989
7990 static void test_emptypackage(void)
7991 {
7992     MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7993     MSIHANDLE hview = 0, hrec = 0;
7994     MSICONDITION condition;
7995     CHAR buffer[MAX_PATH];
7996     DWORD size;
7997     UINT r;
7998
7999     r = MsiOpenPackageA("", &hpkg);
8000     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8001     {
8002         skip("Not enough rights to perform tests\n");
8003         return;
8004     }
8005     todo_wine
8006     {
8007         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8008     }
8009
8010     hdb = MsiGetActiveDatabase(hpkg);
8011     todo_wine
8012     {
8013         ok(hdb != 0, "Expected a valid database handle\n");
8014     }
8015
8016     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Tables`", &hview);
8017     todo_wine
8018     {
8019         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8020     }
8021     r = MsiViewExecute(hview, 0);
8022     todo_wine
8023     {
8024         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8025     }
8026
8027     r = MsiViewFetch(hview, &hrec);
8028     todo_wine
8029     {
8030         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8031     }
8032
8033     buffer[0] = 0;
8034     size = MAX_PATH;
8035     r = MsiRecordGetString(hrec, 1, buffer, &size);
8036     todo_wine
8037     {
8038         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8039         ok(!lstrcmpA(buffer, "_Property"),
8040            "Expected \"_Property\", got \"%s\"\n", buffer);
8041     }
8042
8043     MsiCloseHandle(hrec);
8044
8045     r = MsiViewFetch(hview, &hrec);
8046     todo_wine
8047     {
8048         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8049     }
8050
8051     size = MAX_PATH;
8052     r = MsiRecordGetString(hrec, 1, buffer, &size);
8053     todo_wine
8054     {
8055         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8056         ok(!lstrcmpA(buffer, "#_FolderCache"),
8057            "Expected \"_Property\", got \"%s\"\n", buffer);
8058     }
8059
8060     MsiCloseHandle(hrec);
8061     MsiViewClose(hview);
8062     MsiCloseHandle(hview);
8063
8064     condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
8065     todo_wine
8066     {
8067         ok(condition == MSICONDITION_FALSE,
8068            "Expected MSICONDITION_FALSE, got %d\n", condition);
8069     }
8070
8071     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Property`", &hview);
8072     todo_wine
8073     {
8074         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8075     }
8076     r = MsiViewExecute(hview, 0);
8077     todo_wine
8078     {
8079         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8080     }
8081
8082     /* _Property table is not empty */
8083     r = MsiViewFetch(hview, &hrec);
8084     todo_wine
8085     {
8086         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8087     }
8088
8089     MsiCloseHandle(hrec);
8090     MsiViewClose(hview);
8091     MsiCloseHandle(hview);
8092
8093     condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
8094     todo_wine
8095     {
8096         ok(condition == MSICONDITION_FALSE,
8097            "Expected MSICONDITION_FALSE, got %d\n", condition);
8098     }
8099
8100     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `#_FolderCache`", &hview);
8101     todo_wine
8102     {
8103         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8104     }
8105     r = MsiViewExecute(hview, 0);
8106     todo_wine
8107     {
8108         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8109     }
8110
8111     /* #_FolderCache is not empty */
8112     r = MsiViewFetch(hview, &hrec);
8113     todo_wine
8114     {
8115         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8116     }
8117
8118     MsiCloseHandle(hrec);
8119     MsiViewClose(hview);
8120     MsiCloseHandle(hview);
8121
8122     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Streams`", &hview);
8123     todo_wine
8124     {
8125         ok(r == ERROR_BAD_QUERY_SYNTAX,
8126            "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8127     }
8128
8129     r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Storages`", &hview);
8130     todo_wine
8131     {
8132         ok(r == ERROR_BAD_QUERY_SYNTAX,
8133            "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8134     }
8135
8136     r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
8137     todo_wine
8138     {
8139         ok(r == ERROR_INSTALL_PACKAGE_INVALID,
8140            "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
8141     }
8142
8143     MsiCloseHandle(hsuminfo);
8144
8145     r = MsiDatabaseCommit(hdb);
8146     todo_wine
8147     {
8148         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8149     }
8150
8151     MsiCloseHandle(hdb);
8152     MsiCloseHandle(hpkg);
8153 }
8154
8155 static void test_MsiGetProductProperty(void)
8156 {
8157     MSIHANDLE hprod, hdb;
8158     CHAR val[MAX_PATH];
8159     CHAR path[MAX_PATH];
8160     CHAR query[MAX_PATH];
8161     CHAR keypath[MAX_PATH*2];
8162     CHAR prodcode[MAX_PATH];
8163     CHAR prod_squashed[MAX_PATH];
8164     HKEY prodkey, userkey, props;
8165     DWORD size;
8166     LONG res;
8167     UINT r;
8168     REGSAM access = KEY_ALL_ACCESS;
8169
8170     GetCurrentDirectoryA(MAX_PATH, path);
8171     lstrcatA(path, "\\");
8172
8173     create_test_guid(prodcode, prod_squashed);
8174
8175     if (is_wow64)
8176         access |= KEY_WOW64_64KEY;
8177
8178     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
8179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8180
8181     r = MsiDatabaseCommit(hdb);
8182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8183
8184     r = set_summary_info(hdb);
8185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8186
8187     r = run_query(hdb,
8188             "CREATE TABLE `Directory` ( "
8189             "`Directory` CHAR(255) NOT NULL, "
8190             "`Directory_Parent` CHAR(255), "
8191             "`DefaultDir` CHAR(255) NOT NULL "
8192             "PRIMARY KEY `Directory`)");
8193     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8194
8195     r = run_query(hdb,
8196             "CREATE TABLE `Property` ( "
8197             "`Property` CHAR(72) NOT NULL, "
8198             "`Value` CHAR(255) "
8199             "PRIMARY KEY `Property`)");
8200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8201
8202     sprintf(query, "INSERT INTO `Property` "
8203             "(`Property`, `Value`) "
8204             "VALUES( 'ProductCode', '%s' )", prodcode);
8205     r = run_query(hdb, query);
8206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8207
8208     r = MsiDatabaseCommit(hdb);
8209     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8210
8211     MsiCloseHandle(hdb);
8212
8213     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8214     lstrcatA(keypath, prod_squashed);
8215
8216     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8217     if (res == ERROR_ACCESS_DENIED)
8218     {
8219         skip("Not enough rights to perform tests\n");
8220         DeleteFile(msifile);
8221         return;
8222     }
8223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8224
8225     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8226     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8227     lstrcatA(keypath, prod_squashed);
8228
8229     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8230     if (res == ERROR_ACCESS_DENIED)
8231     {
8232         skip("Not enough rights to perform tests\n");
8233         RegDeleteKeyA(prodkey, "");
8234         RegCloseKey(prodkey);
8235         return;
8236     }
8237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8238
8239     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8241
8242     lstrcpyA(val, path);
8243     lstrcatA(val, "\\");
8244     lstrcatA(val, msifile);
8245     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8246                          (const BYTE *)val, lstrlenA(val) + 1);
8247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8248
8249     hprod = 0xdeadbeef;
8250     r = MsiOpenProductA(prodcode, &hprod);
8251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8252     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8253
8254     /* hProduct is invalid */
8255     size = MAX_PATH;
8256     lstrcpyA(val, "apple");
8257     r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
8258     ok(r == ERROR_INVALID_HANDLE,
8259        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8260     ok(!lstrcmpA(val, "apple"),
8261        "Expected val to be unchanged, got \"%s\"\n", val);
8262     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8263
8264     /* szProperty is NULL */
8265     size = MAX_PATH;
8266     lstrcpyA(val, "apple");
8267     r = MsiGetProductPropertyA(hprod, NULL, val, &size);
8268     ok(r == ERROR_INVALID_PARAMETER,
8269        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8270     ok(!lstrcmpA(val, "apple"),
8271        "Expected val to be unchanged, got \"%s\"\n", val);
8272     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8273
8274     /* szProperty is empty */
8275     size = MAX_PATH;
8276     lstrcpyA(val, "apple");
8277     r = MsiGetProductPropertyA(hprod, "", val, &size);
8278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8279     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8280     ok(size == 0, "Expected 0, got %d\n", size);
8281
8282     /* get the property */
8283     size = MAX_PATH;
8284     lstrcpyA(val, "apple");
8285     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8287     ok(!lstrcmpA(val, prodcode),
8288        "Expected \"%s\", got \"%s\"\n", prodcode, val);
8289     ok(size == lstrlenA(prodcode),
8290        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8291
8292     /* lpValueBuf is NULL */
8293     size = MAX_PATH;
8294     r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8296     ok(size == lstrlenA(prodcode),
8297        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8298
8299     /* pcchValueBuf is NULL */
8300     lstrcpyA(val, "apple");
8301     r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8302     ok(r == ERROR_INVALID_PARAMETER,
8303        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8304     ok(!lstrcmpA(val, "apple"),
8305        "Expected val to be unchanged, got \"%s\"\n", val);
8306     ok(size == lstrlenA(prodcode),
8307        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8308
8309     /* pcchValueBuf is too small */
8310     size = 4;
8311     lstrcpyA(val, "apple");
8312     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8313     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8314     ok(!strncmp(val, prodcode, 3),
8315        "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8316     ok(size == lstrlenA(prodcode),
8317        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8318
8319     /* pcchValueBuf does not leave room for NULL terminator */
8320     size = lstrlenA(prodcode);
8321     lstrcpyA(val, "apple");
8322     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8323     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8324     ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8325        "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8326     ok(size == lstrlenA(prodcode),
8327        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8328
8329     /* pcchValueBuf has enough room for NULL terminator */
8330     size = lstrlenA(prodcode) + 1;
8331     lstrcpyA(val, "apple");
8332     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8334     ok(!lstrcmpA(val, prodcode),
8335        "Expected \"%s\", got \"%s\"\n", prodcode, val);
8336     ok(size == lstrlenA(prodcode),
8337        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8338
8339     /* nonexistent property */
8340     size = MAX_PATH;
8341     lstrcpyA(val, "apple");
8342     r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8344     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8345     ok(size == 0, "Expected 0, got %d\n", size);
8346
8347     r = MsiSetPropertyA(hprod, "NewProperty", "value");
8348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8349
8350     /* non-product property set */
8351     size = MAX_PATH;
8352     lstrcpyA(val, "apple");
8353     r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8355     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8356     ok(size == 0, "Expected 0, got %d\n", size);
8357
8358     r = MsiSetPropertyA(hprod, "ProductCode", "value");
8359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8360
8361     /* non-product property that is also a product property set */
8362     size = MAX_PATH;
8363     lstrcpyA(val, "apple");
8364     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8366     ok(!lstrcmpA(val, prodcode),
8367        "Expected \"%s\", got \"%s\"\n", prodcode, val);
8368     ok(size == lstrlenA(prodcode),
8369        "Expected %d, got %d\n", lstrlenA(prodcode), size);
8370
8371     MsiCloseHandle(hprod);
8372
8373     RegDeleteValueA(props, "LocalPackage");
8374     delete_key(props, "", access);
8375     RegCloseKey(props);
8376     delete_key(userkey, "", access);
8377     RegCloseKey(userkey);
8378     delete_key(prodkey, "", access);
8379     RegCloseKey(prodkey);
8380     DeleteFileA(msifile);
8381 }
8382
8383 static void test_MsiSetProperty(void)
8384 {
8385     MSIHANDLE hpkg, hdb, hrec;
8386     CHAR buf[MAX_PATH];
8387     LPCSTR query;
8388     DWORD size;
8389     UINT r;
8390
8391     r = package_from_db(create_package_db(), &hpkg);
8392     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8393     {
8394         skip("Not enough rights to perform tests\n");
8395         DeleteFile(msifile);
8396         return;
8397     }
8398     ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8399
8400     /* invalid hInstall */
8401     r = MsiSetPropertyA(0, "Prop", "Val");
8402     ok(r == ERROR_INVALID_HANDLE,
8403        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8404
8405     /* invalid hInstall */
8406     r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8407     ok(r == ERROR_INVALID_HANDLE,
8408        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8409
8410     /* szName is NULL */
8411     r = MsiSetPropertyA(hpkg, NULL, "Val");
8412     ok(r == ERROR_INVALID_PARAMETER,
8413        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8414
8415     /* both szName and szValue are NULL */
8416     r = MsiSetPropertyA(hpkg, NULL, NULL);
8417     ok(r == ERROR_INVALID_PARAMETER,
8418        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8419
8420     /* szName is empty */
8421     r = MsiSetPropertyA(hpkg, "", "Val");
8422     ok(r == ERROR_FUNCTION_FAILED,
8423        "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8424
8425     /* szName is empty and szValue is NULL */
8426     r = MsiSetPropertyA(hpkg, "", NULL);
8427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8428
8429     /* set a property */
8430     r = MsiSetPropertyA(hpkg, "Prop", "Val");
8431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8432
8433     /* get the property */
8434     size = MAX_PATH;
8435     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8437     ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8438     ok(size == 3, "Expected 3, got %d\n", size);
8439
8440     /* update the property */
8441     r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8442     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8443
8444     /* get the property */
8445     size = MAX_PATH;
8446     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8448     ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8449     ok(size == 4, "Expected 4, got %d\n", size);
8450
8451     hdb = MsiGetActiveDatabase(hpkg);
8452     ok(hdb != 0, "Expected a valid database handle\n");
8453
8454     /* set prop is not in the _Property table */
8455     query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8456     r = do_query(hdb, query, &hrec);
8457     ok(r == ERROR_BAD_QUERY_SYNTAX,
8458        "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8459
8460     /* set prop is not in the Property table */
8461     query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8462     r = do_query(hdb, query, &hrec);
8463     ok(r == ERROR_BAD_QUERY_SYNTAX,
8464        "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8465
8466     MsiCloseHandle(hdb);
8467
8468     /* szValue is an empty string */
8469     r = MsiSetPropertyA(hpkg, "Prop", "");
8470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8471
8472     /* try to get the property */
8473     size = MAX_PATH;
8474     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8476     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8477     ok(size == 0, "Expected 0, got %d\n", size);
8478
8479     /* reset the property */
8480     r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8482
8483     /* delete the property */
8484     r = MsiSetPropertyA(hpkg, "Prop", NULL);
8485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8486
8487     /* try to get the property */
8488     size = MAX_PATH;
8489     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8491     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8492     ok(size == 0, "Expected 0, got %d\n", size);
8493
8494     MsiCloseHandle(hpkg);
8495     DeleteFileA(msifile);
8496 }
8497
8498 static void test_MsiApplyMultiplePatches(void)
8499 {
8500     UINT r, type = GetDriveType(NULL);
8501
8502     if (!pMsiApplyMultiplePatchesA) {
8503         win_skip("MsiApplyMultiplePatchesA not found\n");
8504         return;
8505     }
8506
8507     r = pMsiApplyMultiplePatchesA(NULL, NULL, NULL);
8508     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8509
8510     r = pMsiApplyMultiplePatchesA("", NULL, NULL);
8511     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8512
8513     r = pMsiApplyMultiplePatchesA(";", NULL, NULL);
8514     if (type == DRIVE_FIXED)
8515         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8516     else
8517         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8518
8519     r = pMsiApplyMultiplePatchesA("  ;", NULL, NULL);
8520     if (type == DRIVE_FIXED)
8521         todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8522     else
8523         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8524
8525     r = pMsiApplyMultiplePatchesA(";;", NULL, NULL);
8526     if (type == DRIVE_FIXED)
8527         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8528     else
8529         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8530
8531     r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8532     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8533
8534     r = pMsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8535     if (type == DRIVE_FIXED)
8536         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8537     else
8538         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8539
8540     r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8541     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8542
8543     r = pMsiApplyMultiplePatchesA("  nosuchpatchpackage  ;  nosuchpatchpackage  ", NULL, NULL);
8544     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8545 }
8546
8547 static void test_MsiApplyPatch(void)
8548 {
8549     UINT r;
8550
8551     r = MsiApplyPatch(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8552     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8553
8554     r = MsiApplyPatch("", NULL, INSTALLTYPE_DEFAULT, NULL);
8555     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8556 }
8557
8558 static void test_MsiEnumComponentCosts(void)
8559 {
8560     MSIHANDLE hdb, hpkg;
8561     char package[12], drive[3];
8562     DWORD len;
8563     UINT r;
8564     int cost, temp;
8565
8566     hdb = create_package_db();
8567     ok( hdb, "failed to create database\n" );
8568
8569     r = create_property_table( hdb );
8570     ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r );
8571
8572     r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8573     ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
8574
8575     r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8576     ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
8577
8578     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8579     ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r );
8580
8581     r = create_media_table( hdb );
8582     ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r );
8583
8584     r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8585     ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r );
8586
8587     r = create_file_table( hdb );
8588     ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r );
8589
8590     r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8591     ok( r == ERROR_SUCCESS, "cannot add file %u\n", r );
8592
8593     r = create_component_table( hdb );
8594     ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r );
8595
8596     r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8597     ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
8598
8599     r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8600     ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
8601
8602     r = create_feature_table( hdb );
8603     ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r );
8604
8605     r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8606     ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
8607
8608     r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8609     ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
8610
8611     r = create_feature_components_table( hdb );
8612     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r );
8613
8614     r = add_feature_components_entry( hdb, "'one', 'one'" );
8615     ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
8616
8617     r = add_feature_components_entry( hdb, "'two', 'two'" );
8618     ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
8619
8620     r = create_install_execute_sequence_table( hdb );
8621     ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r );
8622
8623     r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8624     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8625
8626     r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8627     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8628
8629     r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8630     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8631
8632     r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8633     ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8634
8635     MsiDatabaseCommit( hdb );
8636
8637     sprintf( package, "#%u", hdb );
8638     r = MsiOpenPackageA( package, &hpkg );
8639     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8640     {
8641         skip("Not enough rights to perform tests\n");
8642         goto error;
8643     }
8644     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8645
8646     r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8647     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8648
8649     r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8650     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8651
8652     r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8653     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8654
8655     r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8656     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8657
8658     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8659     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8660
8661     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8662     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8663
8664     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8665     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8666
8667     len = sizeof(drive);
8668     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8669     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8670
8671     len = sizeof(drive);
8672     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8673     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8674
8675     len = sizeof(drive);
8676     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8677     todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8678
8679     len = sizeof(drive);
8680     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8681     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8682
8683     MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
8684
8685     r = MsiDoAction( hpkg, "CostInitialize" );
8686     ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8687
8688     r = MsiDoAction( hpkg, "FileCost" );
8689     ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8690
8691     len = sizeof(drive);
8692     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8693     ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8694
8695     r = MsiDoAction( hpkg, "CostFinalize" );
8696     ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8697
8698     /* contrary to what msdn says InstallValidate must be called too */
8699     len = sizeof(drive);
8700     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8701     todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8702
8703     r = MsiDoAction( hpkg, "InstallValidate" );
8704     ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8705
8706     len = 0;
8707     r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8708     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8709
8710     len = 0;
8711     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8712     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8713     ok( len == 2, "expected len == 2, got %u\n", len );
8714
8715     len = 2;
8716     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8717     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8718     ok( len == 2, "expected len == 2, got %u\n", len );
8719
8720     len = 2;
8721     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8722     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8723     ok( len == 2, "expected len == 2, got %u\n", len );
8724
8725     /* install state doesn't seem to matter */
8726     len = sizeof(drive);
8727     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8728     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8729
8730     len = sizeof(drive);
8731     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8732     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8733
8734     len = sizeof(drive);
8735     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8736     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8737
8738     len = sizeof(drive);
8739     drive[0] = 0;
8740     cost = temp = 0xdead;
8741     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8742     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8743     ok( len == 2, "expected len == 2, got %u\n", len );
8744     ok( drive[0], "expected a drive\n" );
8745     ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
8746     ok( !temp, "expected temp == 0, got %d\n", temp );
8747
8748     len = sizeof(drive);
8749     drive[0] = 0;
8750     cost = temp = 0xdead;
8751     r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8752     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8753     ok( len == 2, "expected len == 2, got %u\n", len );
8754     ok( drive[0], "expected a drive\n" );
8755     ok( !cost, "expected cost == 0, got %d\n", cost );
8756     ok( !temp, "expected temp == 0, got %d\n", temp );
8757
8758     len = sizeof(drive);
8759     drive[0] = 0;
8760     cost = temp = 0xdead;
8761     r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8762     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8763     ok( len == 2, "expected len == 2, got %u\n", len );
8764     ok( drive[0], "expected a drive\n" );
8765     ok( !cost, "expected cost == 0, got %d\n", cost );
8766     ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8767
8768     /* increased index */
8769     len = sizeof(drive);
8770     r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8771     ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8772
8773     len = sizeof(drive);
8774     r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8775     ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8776
8777     MsiCloseHandle( hpkg );
8778 error:
8779     MsiCloseHandle( hdb );
8780     DeleteFileA( msifile );
8781 }
8782
8783 static void test_MsiDatabaseCommit(void)
8784 {
8785     UINT r;
8786     MSIHANDLE hdb, hpkg = 0;
8787     char buf[32], package[12];
8788     DWORD sz;
8789
8790     hdb = create_package_db();
8791     ok( hdb, "failed to create database\n" );
8792
8793     r = create_property_table( hdb );
8794     ok( r == ERROR_SUCCESS, "can't create Property table %u\n", r );
8795
8796     sprintf( package, "#%u", hdb );
8797     r = MsiOpenPackage( package, &hpkg );
8798     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8799     {
8800         skip("Not enough rights to perform tests\n");
8801         goto error;
8802     }
8803     ok( r == ERROR_SUCCESS, "got %u\n", r );
8804
8805     r = MsiSetPropertyA( hpkg, "PROP", "value" );
8806     ok( r == ERROR_SUCCESS, "got %u\n", r );
8807
8808     buf[0] = 0;
8809     sz = sizeof(buf);
8810     r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8811     ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8812     ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8813
8814     r = MsiDatabaseCommit( hdb );
8815     ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8816
8817     buf[0] = 0;
8818     sz = sizeof(buf);
8819     r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8820     ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8821     ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8822
8823     MsiCloseHandle( hpkg );
8824 error:
8825     MsiCloseHandle( hdb );
8826     DeleteFileA( msifile );
8827 }
8828
8829 START_TEST(package)
8830 {
8831     STATEMGRSTATUS status;
8832     BOOL ret = FALSE;
8833
8834     init_functionpointers();
8835
8836     if (pIsWow64Process)
8837         pIsWow64Process(GetCurrentProcess(), &is_wow64);
8838
8839     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
8840
8841     /* Create a restore point ourselves so we circumvent the multitude of restore points
8842      * that would have been created by all the installation and removal tests.
8843      *
8844      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
8845      * creation of restore points.
8846      */
8847     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
8848     {
8849         memset(&status, 0, sizeof(status));
8850         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
8851     }
8852
8853     test_createpackage();
8854     test_doaction();
8855     test_gettargetpath_bad();
8856     test_settargetpath();
8857     test_props();
8858     test_property_table();
8859     test_condition();
8860     test_msipackage();
8861     test_formatrecord2();
8862     test_states();
8863     test_getproperty();
8864     test_removefiles();
8865     test_appsearch();
8866     test_appsearch_complocator();
8867     test_appsearch_reglocator();
8868     test_appsearch_inilocator();
8869     test_appsearch_drlocator();
8870     test_featureparents();
8871     test_installprops();
8872     test_launchconditions();
8873     test_ccpsearch();
8874     test_complocator();
8875     test_MsiGetSourcePath();
8876     test_shortlongsource();
8877     test_sourcedir();
8878     test_access();
8879     test_emptypackage();
8880     test_MsiGetProductProperty();
8881     test_MsiSetProperty();
8882     test_MsiApplyMultiplePatches();
8883     test_MsiApplyPatch();
8884     test_MsiEnumComponentCosts();
8885     test_MsiDatabaseCommit();
8886
8887     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
8888     {
8889         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
8890         if (ret)
8891             remove_restore_point(status.llSequenceNumber);
8892     }
8893 }