1c2c66affSColin Finck /*
2c2c66affSColin Finck  * tests for Microsoft Installer functionality
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2005 Mike McCormack for CodeWeavers
5c2c66affSColin Finck  * Copyright 2005 Aric Stewart for CodeWeavers
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
2231139640SAmine Khaldi #define COBJMACROS
23c2c66affSColin Finck 
242f8e6f71SAmine Khaldi #include <assert.h>
2531139640SAmine Khaldi #include <stdio.h>
2631139640SAmine Khaldi #include <windows.h>
2731139640SAmine Khaldi #include <msidefs.h>
2831139640SAmine Khaldi #include <msi.h>
2931139640SAmine Khaldi #include <msiquery.h>
3031139640SAmine Khaldi #include <srrestoreptapi.h>
31c2c66affSColin Finck #include <shlobj.h>
32a4930636Swinesync #include <sddl.h>
33c2c66affSColin Finck 
3431139640SAmine Khaldi #include "wine/test.h"
35*f4be6dc3SMikhail #include "utils.h"
3631139640SAmine Khaldi 
37c2c66affSColin Finck static BOOL is_wow64;
38c2c66affSColin Finck static const char msifile[] = "winetest-package.msi";
39f31e4044Swinesync static const WCHAR msifileW[] = L"winetest-package.msi";
40c2c66affSColin Finck 
get_user_sid(void)41c2c66affSColin Finck static char *get_user_sid(void)
42c2c66affSColin Finck {
43c2c66affSColin Finck     HANDLE token;
44c2c66affSColin Finck     DWORD size = 0;
45c2c66affSColin Finck     TOKEN_USER *user;
46c2c66affSColin Finck     char *usersid = NULL;
47c2c66affSColin Finck 
48c2c66affSColin Finck     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
49c2c66affSColin Finck     GetTokenInformation(token, TokenUser, NULL, size, &size);
50c2c66affSColin Finck 
516aefc5b9Swinesync     user = malloc(size);
52c2c66affSColin Finck     GetTokenInformation(token, TokenUser, user, size, &size);
53a4930636Swinesync     ConvertSidToStringSidA(user->User.Sid, &usersid);
546aefc5b9Swinesync     free(user);
55c2c66affSColin Finck 
56c2c66affSColin Finck     CloseHandle(token);
57c2c66affSColin Finck     return usersid;
58c2c66affSColin Finck }
59c2c66affSColin Finck 
60c2c66affSColin Finck /* RegDeleteTreeW from dlls/advapi32/registry.c */
package_RegDeleteTreeW(HKEY hKey,LPCWSTR lpszSubKey,REGSAM access)61c2c66affSColin Finck static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
62c2c66affSColin Finck {
63c2c66affSColin Finck     LONG ret;
64c2c66affSColin Finck     DWORD dwMaxSubkeyLen, dwMaxValueLen;
65c2c66affSColin Finck     DWORD dwMaxLen, dwSize;
66c2c66affSColin Finck     WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
67c2c66affSColin Finck     HKEY hSubKey = hKey;
68c2c66affSColin Finck 
69c2c66affSColin Finck     if(lpszSubKey)
70c2c66affSColin Finck     {
71c2c66affSColin Finck         ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
72c2c66affSColin Finck         if (ret) return ret;
73c2c66affSColin Finck     }
74c2c66affSColin Finck 
75c2c66affSColin Finck     ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
76c2c66affSColin Finck             &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
77c2c66affSColin Finck     if (ret) goto cleanup;
78c2c66affSColin Finck 
79c2c66affSColin Finck     dwMaxSubkeyLen++;
80c2c66affSColin Finck     dwMaxValueLen++;
81c2c66affSColin Finck     dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
8286676451Swinesync     if (dwMaxLen > ARRAY_SIZE(szNameBuf))
83c2c66affSColin Finck     {
84c2c66affSColin Finck         /* Name too big: alloc a buffer for it */
856aefc5b9Swinesync         if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR))))
86c2c66affSColin Finck         {
87c2c66affSColin Finck             ret = ERROR_NOT_ENOUGH_MEMORY;
88c2c66affSColin Finck             goto cleanup;
89c2c66affSColin Finck         }
90c2c66affSColin Finck     }
91c2c66affSColin Finck 
92c2c66affSColin Finck     /* Recursively delete all the subkeys */
93c2c66affSColin Finck     while (TRUE)
94c2c66affSColin Finck     {
95c2c66affSColin Finck         dwSize = dwMaxLen;
96c2c66affSColin Finck         if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
97c2c66affSColin Finck                           NULL, NULL, NULL)) break;
98c2c66affSColin Finck 
99c2c66affSColin Finck         ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
100c2c66affSColin Finck         if (ret) goto cleanup;
101c2c66affSColin Finck     }
102c2c66affSColin Finck 
103c2c66affSColin Finck     if (lpszSubKey)
104*f4be6dc3SMikhail         ret = RegDeleteKeyExW(hKey, lpszSubKey, access, 0);
105c2c66affSColin Finck     else
106c2c66affSColin Finck         while (TRUE)
107c2c66affSColin Finck         {
108c2c66affSColin Finck             dwSize = dwMaxLen;
109c2c66affSColin Finck             if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
110c2c66affSColin Finck                   NULL, NULL, NULL, NULL)) break;
111c2c66affSColin Finck 
112c2c66affSColin Finck             ret = RegDeleteValueW(hKey, lpszName);
113c2c66affSColin Finck             if (ret) goto cleanup;
114c2c66affSColin Finck         }
115c2c66affSColin Finck 
116c2c66affSColin Finck cleanup:
1176aefc5b9Swinesync     if (lpszName != szNameBuf) free(lpszName);
1186aefc5b9Swinesync     if (lpszSubKey) RegCloseKey(hSubKey);
119c2c66affSColin Finck     return ret;
120c2c66affSColin Finck }
121c2c66affSColin Finck 
squash_guid(LPCWSTR in,LPWSTR out)122c2c66affSColin Finck static BOOL squash_guid(LPCWSTR in, LPWSTR out)
123c2c66affSColin Finck {
124c2c66affSColin Finck     DWORD i,n=1;
125c2c66affSColin Finck     GUID guid;
126c2c66affSColin Finck 
127c2c66affSColin Finck     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
128c2c66affSColin Finck         return FALSE;
129c2c66affSColin Finck 
130c2c66affSColin Finck     for(i=0; i<8; i++)
131c2c66affSColin Finck         out[7-i] = in[n++];
132c2c66affSColin Finck     n++;
133c2c66affSColin Finck     for(i=0; i<4; i++)
134c2c66affSColin Finck         out[11-i] = in[n++];
135c2c66affSColin Finck     n++;
136c2c66affSColin Finck     for(i=0; i<4; i++)
137c2c66affSColin Finck         out[15-i] = in[n++];
138c2c66affSColin Finck     n++;
139c2c66affSColin Finck     for(i=0; i<2; i++)
140c2c66affSColin Finck     {
141c2c66affSColin Finck         out[17+i*2] = in[n++];
142c2c66affSColin Finck         out[16+i*2] = in[n++];
143c2c66affSColin Finck     }
144c2c66affSColin Finck     n++;
145c2c66affSColin Finck     for( ; i<8; i++)
146c2c66affSColin Finck     {
147c2c66affSColin Finck         out[17+i*2] = in[n++];
148c2c66affSColin Finck         out[16+i*2] = in[n++];
149c2c66affSColin Finck     }
150c2c66affSColin Finck     out[32]=0;
151c2c66affSColin Finck     return TRUE;
152c2c66affSColin Finck }
153c2c66affSColin Finck 
create_test_guid(LPSTR prodcode,LPSTR squashed)154c2c66affSColin Finck static void create_test_guid(LPSTR prodcode, LPSTR squashed)
155c2c66affSColin Finck {
156c2c66affSColin Finck     WCHAR guidW[MAX_PATH];
157c2c66affSColin Finck     WCHAR squashedW[MAX_PATH];
158c2c66affSColin Finck     GUID guid;
159c2c66affSColin Finck     HRESULT hr;
160c2c66affSColin Finck     int size;
161c2c66affSColin Finck 
162c2c66affSColin Finck     hr = CoCreateGuid(&guid);
1631b4acd3cSwinesync     ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
164c2c66affSColin Finck 
165c2c66affSColin Finck     size = StringFromGUID2(&guid, guidW, MAX_PATH);
1661b4acd3cSwinesync     ok(size == 39, "Expected 39, got %#lx\n", hr);
167c2c66affSColin Finck 
168c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
169c2c66affSColin Finck     squash_guid(guidW, squashedW);
170c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
171c2c66affSColin Finck }
172c2c66affSColin Finck 
set_component_path(LPCSTR filename,MSIINSTALLCONTEXT context,LPCSTR guid,LPSTR usersid,BOOL dir)173c2c66affSColin Finck static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
174c2c66affSColin Finck                                LPCSTR guid, LPSTR usersid, BOOL dir)
175c2c66affSColin Finck {
176c2c66affSColin Finck     WCHAR guidW[MAX_PATH];
177c2c66affSColin Finck     WCHAR squashedW[MAX_PATH];
178c2c66affSColin Finck     CHAR squashed[MAX_PATH];
179484e8280Swinesync     CHAR comppath[MAX_PATH + 81];
180c2c66affSColin Finck     CHAR prodpath[MAX_PATH];
181c2c66affSColin Finck     CHAR path[MAX_PATH];
182c2c66affSColin Finck     LPCSTR prod = NULL;
183c2c66affSColin Finck     HKEY hkey;
184c2c66affSColin Finck     REGSAM access = KEY_ALL_ACCESS;
185c2c66affSColin Finck 
186c2c66affSColin Finck     if (is_wow64)
187c2c66affSColin Finck         access |= KEY_WOW64_64KEY;
188c2c66affSColin Finck 
189c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
190c2c66affSColin Finck     squash_guid(guidW, squashedW);
191c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
192c2c66affSColin Finck 
193c2c66affSColin Finck     if (context == MSIINSTALLCONTEXT_MACHINE)
194c2c66affSColin Finck     {
195c2c66affSColin Finck         prod = "3D0DAE300FACA1300AD792060BCDAA92";
196c2c66affSColin Finck         sprintf(comppath,
197c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
198c2c66affSColin Finck                 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
199c2c66affSColin Finck         lstrcpyA(prodpath,
200c2c66affSColin Finck                  "SOFTWARE\\Classes\\Installer\\"
201c2c66affSColin Finck                  "Products\\3D0DAE300FACA1300AD792060BCDAA92");
202c2c66affSColin Finck     }
203c2c66affSColin Finck     else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
204c2c66affSColin Finck     {
205c2c66affSColin Finck         prod = "7D2F387510109040002000060BECB6AB";
206c2c66affSColin Finck         sprintf(comppath,
207c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
208c2c66affSColin Finck                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
209c2c66affSColin Finck         sprintf(prodpath,
210c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
211c2c66affSColin Finck                 "Installer\\%s\\Installer\\Products\\"
212c2c66affSColin Finck                 "7D2F387510109040002000060BECB6AB", usersid);
213c2c66affSColin Finck     }
214c2c66affSColin Finck     else if (context == MSIINSTALLCONTEXT_USERMANAGED)
215c2c66affSColin Finck     {
216c2c66affSColin Finck         prod = "7D2F387510109040002000060BECB6AB";
217c2c66affSColin Finck         sprintf(comppath,
218c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
219c2c66affSColin Finck                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
220c2c66affSColin Finck         sprintf(prodpath,
221c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
222c2c66affSColin Finck                 "Installer\\Managed\\%s\\Installer\\Products\\"
223c2c66affSColin Finck                 "7D2F387510109040002000060BECB6AB", usersid);
224c2c66affSColin Finck     }
225c2c66affSColin Finck 
226c2c66affSColin Finck     RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
227c2c66affSColin Finck 
228c2c66affSColin Finck     lstrcpyA(path, CURR_DIR);
229c2c66affSColin Finck     lstrcatA(path, "\\");
230c2c66affSColin Finck     if (!dir) lstrcatA(path, filename);
231c2c66affSColin Finck 
232c2c66affSColin Finck     RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
233c2c66affSColin Finck     RegCloseKey(hkey);
234c2c66affSColin Finck 
235c2c66affSColin Finck     RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
236c2c66affSColin Finck     RegCloseKey(hkey);
237c2c66affSColin Finck }
238c2c66affSColin Finck 
delete_component_path(LPCSTR guid,MSIINSTALLCONTEXT context,LPSTR usersid)239c2c66affSColin Finck static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
240c2c66affSColin Finck {
241c2c66affSColin Finck     WCHAR guidW[MAX_PATH];
242c2c66affSColin Finck     WCHAR squashedW[MAX_PATH];
243c2c66affSColin Finck     WCHAR substrW[MAX_PATH];
244c2c66affSColin Finck     CHAR squashed[MAX_PATH];
245484e8280Swinesync     CHAR comppath[MAX_PATH + 81];
246c2c66affSColin Finck     CHAR prodpath[MAX_PATH];
247c2c66affSColin Finck     REGSAM access = KEY_ALL_ACCESS;
248c2c66affSColin Finck 
249c2c66affSColin Finck     if (is_wow64)
250c2c66affSColin Finck         access |= KEY_WOW64_64KEY;
251c2c66affSColin Finck 
252c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
253c2c66affSColin Finck     squash_guid(guidW, squashedW);
254c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
255c2c66affSColin Finck 
256c2c66affSColin Finck     if (context == MSIINSTALLCONTEXT_MACHINE)
257c2c66affSColin Finck     {
258c2c66affSColin Finck         sprintf(comppath,
259c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
260c2c66affSColin Finck                 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
261c2c66affSColin Finck         lstrcpyA(prodpath,
262c2c66affSColin Finck                  "SOFTWARE\\Classes\\Installer\\"
263c2c66affSColin Finck                  "Products\\3D0DAE300FACA1300AD792060BCDAA92");
264c2c66affSColin Finck     }
265c2c66affSColin Finck     else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
266c2c66affSColin Finck     {
267c2c66affSColin Finck         sprintf(comppath,
268c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
269c2c66affSColin Finck                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
270c2c66affSColin Finck         sprintf(prodpath,
271c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
272c2c66affSColin Finck                 "Installer\\%s\\Installer\\Products\\"
273c2c66affSColin Finck                 "7D2F387510109040002000060BECB6AB", usersid);
274c2c66affSColin Finck     }
275c2c66affSColin Finck     else if (context == MSIINSTALLCONTEXT_USERMANAGED)
276c2c66affSColin Finck     {
277c2c66affSColin Finck         sprintf(comppath,
278c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
279c2c66affSColin Finck                 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
280c2c66affSColin Finck         sprintf(prodpath,
281c2c66affSColin Finck                 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
282c2c66affSColin Finck                 "Installer\\Managed\\%s\\Installer\\Products\\"
283c2c66affSColin Finck                 "7D2F387510109040002000060BECB6AB", usersid);
284c2c66affSColin Finck     }
285c2c66affSColin Finck 
286c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
287c2c66affSColin Finck     package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
288c2c66affSColin Finck 
289c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
290c2c66affSColin Finck     package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
291c2c66affSColin Finck }
292c2c66affSColin Finck 
do_query(MSIHANDLE hdb,const char * query,MSIHANDLE * phrec)293c2c66affSColin Finck static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
294c2c66affSColin Finck {
295c2c66affSColin Finck     MSIHANDLE hview = 0;
296c2c66affSColin Finck     UINT r, ret;
297c2c66affSColin Finck 
298c2c66affSColin Finck     /* open a select query */
299c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, query, &hview);
300c2c66affSColin Finck     if (r != ERROR_SUCCESS)
301c2c66affSColin Finck         return r;
302c2c66affSColin Finck     r = MsiViewExecute(hview, 0);
303c2c66affSColin Finck     if (r != ERROR_SUCCESS)
304c2c66affSColin Finck         return r;
305c2c66affSColin Finck     ret = MsiViewFetch(hview, phrec);
306c2c66affSColin Finck     r = MsiViewClose(hview);
307c2c66affSColin Finck     if (r != ERROR_SUCCESS)
308c2c66affSColin Finck         return r;
309c2c66affSColin Finck     r = MsiCloseHandle(hview);
310c2c66affSColin Finck     if (r != ERROR_SUCCESS)
311c2c66affSColin Finck         return r;
312c2c66affSColin Finck     return ret;
313c2c66affSColin Finck }
314c2c66affSColin Finck 
create_component_table(MSIHANDLE hdb)315c2c66affSColin Finck static UINT create_component_table( MSIHANDLE hdb )
316c2c66affSColin Finck {
317*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
318c2c66affSColin Finck             "CREATE TABLE `Component` ( "
319c2c66affSColin Finck             "`Component` CHAR(72) NOT NULL, "
320c2c66affSColin Finck             "`ComponentId` CHAR(38), "
321c2c66affSColin Finck             "`Directory_` CHAR(72) NOT NULL, "
322c2c66affSColin Finck             "`Attributes` SHORT NOT NULL, "
323c2c66affSColin Finck             "`Condition` CHAR(255), "
324c2c66affSColin Finck             "`KeyPath` CHAR(72) "
325c2c66affSColin Finck             "PRIMARY KEY `Component`)" );
326f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
327f860a780SAmine Khaldi     return r;
328c2c66affSColin Finck }
329c2c66affSColin Finck 
create_feature_table(MSIHANDLE hdb)330c2c66affSColin Finck static UINT create_feature_table( MSIHANDLE hdb )
331c2c66affSColin Finck {
332*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
333c2c66affSColin Finck             "CREATE TABLE `Feature` ( "
334c2c66affSColin Finck             "`Feature` CHAR(38) NOT NULL, "
335c2c66affSColin Finck             "`Feature_Parent` CHAR(38), "
336c2c66affSColin Finck             "`Title` CHAR(64), "
337c2c66affSColin Finck             "`Description` CHAR(255), "
338c2c66affSColin Finck             "`Display` SHORT NOT NULL, "
339c2c66affSColin Finck             "`Level` SHORT NOT NULL, "
340c2c66affSColin Finck             "`Directory_` CHAR(72), "
341c2c66affSColin Finck             "`Attributes` SHORT NOT NULL "
342c2c66affSColin Finck             "PRIMARY KEY `Feature`)" );
343f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r);
344f860a780SAmine Khaldi     return r;
345c2c66affSColin Finck }
346c2c66affSColin Finck 
create_feature_components_table(MSIHANDLE hdb)347c2c66affSColin Finck static UINT create_feature_components_table( MSIHANDLE hdb )
348c2c66affSColin Finck {
349*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
350c2c66affSColin Finck             "CREATE TABLE `FeatureComponents` ( "
351c2c66affSColin Finck             "`Feature_` CHAR(38) NOT NULL, "
352c2c66affSColin Finck             "`Component_` CHAR(72) NOT NULL "
353c2c66affSColin Finck             "PRIMARY KEY `Feature_`, `Component_` )" );
354f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
355f860a780SAmine Khaldi     return r;
356c2c66affSColin Finck }
357c2c66affSColin Finck 
create_file_table(MSIHANDLE hdb)358c2c66affSColin Finck static UINT create_file_table( MSIHANDLE hdb )
359c2c66affSColin Finck {
360*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
361c2c66affSColin Finck             "CREATE TABLE `File` ("
362c2c66affSColin Finck             "`File` CHAR(72) NOT NULL, "
363c2c66affSColin Finck             "`Component_` CHAR(72) NOT NULL, "
364c2c66affSColin Finck             "`FileName` CHAR(255) NOT NULL, "
365c2c66affSColin Finck             "`FileSize` LONG NOT NULL, "
366c2c66affSColin Finck             "`Version` CHAR(72), "
367c2c66affSColin Finck             "`Language` CHAR(20), "
368c2c66affSColin Finck             "`Attributes` SHORT, "
369c2c66affSColin Finck             "`Sequence` SHORT NOT NULL "
370c2c66affSColin Finck             "PRIMARY KEY `File`)" );
371f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r);
372f860a780SAmine Khaldi     return r;
373c2c66affSColin Finck }
374c2c66affSColin Finck 
create_remove_file_table(MSIHANDLE hdb)375c2c66affSColin Finck static UINT create_remove_file_table( MSIHANDLE hdb )
376c2c66affSColin Finck {
377*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
378c2c66affSColin Finck             "CREATE TABLE `RemoveFile` ("
379c2c66affSColin Finck             "`FileKey` CHAR(72) NOT NULL, "
380c2c66affSColin Finck             "`Component_` CHAR(72) NOT NULL, "
381c2c66affSColin Finck             "`FileName` CHAR(255) LOCALIZABLE, "
382c2c66affSColin Finck             "`DirProperty` CHAR(72) NOT NULL, "
383c2c66affSColin Finck             "`InstallMode` SHORT NOT NULL "
384c2c66affSColin Finck             "PRIMARY KEY `FileKey`)" );
385f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r);
386f860a780SAmine Khaldi     return r;
387c2c66affSColin Finck }
388c2c66affSColin Finck 
create_appsearch_table(MSIHANDLE hdb)389c2c66affSColin Finck static UINT create_appsearch_table( MSIHANDLE hdb )
390c2c66affSColin Finck {
391*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
392c2c66affSColin Finck             "CREATE TABLE `AppSearch` ("
393c2c66affSColin Finck             "`Property` CHAR(72) NOT NULL, "
394c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL "
395c2c66affSColin Finck             "PRIMARY KEY `Property`, `Signature_`)" );
396f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r);
397f860a780SAmine Khaldi     return r;
398c2c66affSColin Finck }
399c2c66affSColin Finck 
create_reglocator_table(MSIHANDLE hdb)400c2c66affSColin Finck static UINT create_reglocator_table( MSIHANDLE hdb )
401c2c66affSColin Finck {
402*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
403c2c66affSColin Finck             "CREATE TABLE `RegLocator` ("
404c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL, "
405c2c66affSColin Finck             "`Root` SHORT NOT NULL, "
406c2c66affSColin Finck             "`Key` CHAR(255) NOT NULL, "
407c2c66affSColin Finck             "`Name` CHAR(255), "
408c2c66affSColin Finck             "`Type` SHORT "
409c2c66affSColin Finck             "PRIMARY KEY `Signature_`)" );
410f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r);
411f860a780SAmine Khaldi     return r;
412c2c66affSColin Finck }
413c2c66affSColin Finck 
create_signature_table(MSIHANDLE hdb)414c2c66affSColin Finck static UINT create_signature_table( MSIHANDLE hdb )
415c2c66affSColin Finck {
416*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
417c2c66affSColin Finck             "CREATE TABLE `Signature` ("
418c2c66affSColin Finck             "`Signature` CHAR(72) NOT NULL, "
419c2c66affSColin Finck             "`FileName` CHAR(255) NOT NULL, "
420c2c66affSColin Finck             "`MinVersion` CHAR(20), "
421c2c66affSColin Finck             "`MaxVersion` CHAR(20), "
422c2c66affSColin Finck             "`MinSize` LONG, "
423c2c66affSColin Finck             "`MaxSize` LONG, "
424c2c66affSColin Finck             "`MinDate` LONG, "
425c2c66affSColin Finck             "`MaxDate` LONG, "
426c2c66affSColin Finck             "`Languages` CHAR(255) "
427c2c66affSColin Finck             "PRIMARY KEY `Signature`)" );
428f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r);
429f860a780SAmine Khaldi     return r;
430c2c66affSColin Finck }
431c2c66affSColin Finck 
create_launchcondition_table(MSIHANDLE hdb)432c2c66affSColin Finck static UINT create_launchcondition_table( MSIHANDLE hdb )
433c2c66affSColin Finck {
434*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
435c2c66affSColin Finck             "CREATE TABLE `LaunchCondition` ("
436c2c66affSColin Finck             "`Condition` CHAR(255) NOT NULL, "
437c2c66affSColin Finck             "`Description` CHAR(255) NOT NULL "
438c2c66affSColin Finck             "PRIMARY KEY `Condition`)" );
439f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r);
440f860a780SAmine Khaldi     return r;
441c2c66affSColin Finck }
442c2c66affSColin Finck 
create_property_table(MSIHANDLE hdb)443c2c66affSColin Finck static UINT create_property_table( MSIHANDLE hdb )
444c2c66affSColin Finck {
445*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
446c2c66affSColin Finck             "CREATE TABLE `Property` ("
447c2c66affSColin Finck             "`Property` CHAR(72) NOT NULL, "
448c2c66affSColin Finck             "`Value` CHAR(0) "
449c2c66affSColin Finck             "PRIMARY KEY `Property`)" );
450f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r);
451f860a780SAmine Khaldi     return r;
452c2c66affSColin Finck }
453c2c66affSColin Finck 
create_install_execute_sequence_table(MSIHANDLE hdb)454c2c66affSColin Finck static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
455c2c66affSColin Finck {
456*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
457c2c66affSColin Finck             "CREATE TABLE `InstallExecuteSequence` ("
458c2c66affSColin Finck             "`Action` CHAR(72) NOT NULL, "
459c2c66affSColin Finck             "`Condition` CHAR(255), "
460c2c66affSColin Finck             "`Sequence` SHORT "
461c2c66affSColin Finck             "PRIMARY KEY `Action`)" );
462f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r);
463f860a780SAmine Khaldi     return r;
464f860a780SAmine Khaldi }
465f860a780SAmine Khaldi 
create_install_ui_sequence_table(MSIHANDLE hdb)466f860a780SAmine Khaldi static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
467f860a780SAmine Khaldi {
468*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
469f860a780SAmine Khaldi             "CREATE TABLE `InstallUISequence` ("
470f860a780SAmine Khaldi             "`Action` CHAR(72) NOT NULL, "
471f860a780SAmine Khaldi             "`Condition` CHAR(255), "
472f860a780SAmine Khaldi             "`Sequence` SHORT "
473f860a780SAmine Khaldi             "PRIMARY KEY `Action`)" );
474f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r);
475f860a780SAmine Khaldi     return r;
476c2c66affSColin Finck }
477c2c66affSColin Finck 
create_media_table(MSIHANDLE hdb)478c2c66affSColin Finck static UINT create_media_table( MSIHANDLE hdb )
479c2c66affSColin Finck {
480*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
481c2c66affSColin Finck             "CREATE TABLE `Media` ("
482c2c66affSColin Finck             "`DiskId` SHORT NOT NULL, "
483c2c66affSColin Finck             "`LastSequence` SHORT NOT NULL, "
484c2c66affSColin Finck             "`DiskPrompt` CHAR(64), "
485c2c66affSColin Finck             "`Cabinet` CHAR(255), "
486c2c66affSColin Finck             "`VolumeLabel` CHAR(32), "
487c2c66affSColin Finck             "`Source` CHAR(72) "
488c2c66affSColin Finck             "PRIMARY KEY `DiskId`)" );
489f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r);
490f860a780SAmine Khaldi     return r;
491c2c66affSColin Finck }
492c2c66affSColin Finck 
create_ccpsearch_table(MSIHANDLE hdb)493c2c66affSColin Finck static UINT create_ccpsearch_table( MSIHANDLE hdb )
494c2c66affSColin Finck {
495*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
496c2c66affSColin Finck             "CREATE TABLE `CCPSearch` ("
497c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL "
498c2c66affSColin Finck             "PRIMARY KEY `Signature_`)" );
499f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r);
500f860a780SAmine Khaldi     return r;
501c2c66affSColin Finck }
502c2c66affSColin Finck 
create_drlocator_table(MSIHANDLE hdb)503c2c66affSColin Finck static UINT create_drlocator_table( MSIHANDLE hdb )
504c2c66affSColin Finck {
505*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
506c2c66affSColin Finck             "CREATE TABLE `DrLocator` ("
507c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL, "
508c2c66affSColin Finck             "`Parent` CHAR(72), "
509c2c66affSColin Finck             "`Path` CHAR(255), "
510c2c66affSColin Finck             "`Depth` SHORT "
511c2c66affSColin Finck             "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
512f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r);
513f860a780SAmine Khaldi     return r;
514c2c66affSColin Finck }
515c2c66affSColin Finck 
create_complocator_table(MSIHANDLE hdb)516c2c66affSColin Finck static UINT create_complocator_table( MSIHANDLE hdb )
517c2c66affSColin Finck {
518*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
519c2c66affSColin Finck             "CREATE TABLE `CompLocator` ("
520c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL, "
521c2c66affSColin Finck             "`ComponentId` CHAR(38) NOT NULL, "
522c2c66affSColin Finck             "`Type` SHORT "
523c2c66affSColin Finck             "PRIMARY KEY `Signature_`)" );
524f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r);
525f860a780SAmine Khaldi     return r;
526c2c66affSColin Finck }
527c2c66affSColin Finck 
create_inilocator_table(MSIHANDLE hdb)528c2c66affSColin Finck static UINT create_inilocator_table( MSIHANDLE hdb )
529c2c66affSColin Finck {
530*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
531c2c66affSColin Finck             "CREATE TABLE `IniLocator` ("
532c2c66affSColin Finck             "`Signature_` CHAR(72) NOT NULL, "
533c2c66affSColin Finck             "`FileName` CHAR(255) NOT NULL, "
534c2c66affSColin Finck             "`Section` CHAR(96)NOT NULL, "
535c2c66affSColin Finck             "`Key` CHAR(128)NOT NULL, "
536c2c66affSColin Finck             "`Field` SHORT, "
537c2c66affSColin Finck             "`Type` SHORT "
538c2c66affSColin Finck             "PRIMARY KEY `Signature_`)" );
539f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r);
540f860a780SAmine Khaldi     return r;
541c2c66affSColin Finck }
542c2c66affSColin Finck 
create_custom_action_table(MSIHANDLE hdb)543c2c66affSColin Finck static UINT create_custom_action_table( MSIHANDLE hdb )
544c2c66affSColin Finck {
545*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
546c2c66affSColin Finck             "CREATE TABLE `CustomAction` ("
547c2c66affSColin Finck             "`Action` CHAR(72) NOT NULL, "
548c2c66affSColin Finck             "`Type` SHORT NOT NULL, "
549c2c66affSColin Finck             "`Source` CHAR(75), "
550c2c66affSColin Finck             "`Target` CHAR(255) "
551c2c66affSColin Finck             "PRIMARY KEY `Action`)" );
552f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
553f860a780SAmine Khaldi     return r;
554c2c66affSColin Finck }
555c2c66affSColin Finck 
create_dialog_table(MSIHANDLE hdb)5562f8e6f71SAmine Khaldi static UINT create_dialog_table( MSIHANDLE hdb )
5572f8e6f71SAmine Khaldi {
558*f4be6dc3SMikhail     UINT r = run_query(hdb, 0,
5592f8e6f71SAmine Khaldi             "CREATE TABLE `Dialog` ("
5602f8e6f71SAmine Khaldi             "`Dialog` CHAR(72) NOT NULL, "
5612f8e6f71SAmine Khaldi             "`HCentering` SHORT NOT NULL, "
5622f8e6f71SAmine Khaldi             "`VCentering` SHORT NOT NULL, "
5632f8e6f71SAmine Khaldi             "`Width` SHORT NOT NULL, "
5642f8e6f71SAmine Khaldi             "`Height` SHORT NOT NULL, "
5652f8e6f71SAmine Khaldi             "`Attributes` LONG, "
5662f8e6f71SAmine Khaldi             "`Title` CHAR(128) LOCALIZABLE, "
5672f8e6f71SAmine Khaldi             "`Control_First` CHAR(50) NOT NULL, "
5682f8e6f71SAmine Khaldi             "`Control_Default` CHAR(50), "
5692f8e6f71SAmine Khaldi             "`Control_Cancel` CHAR(50) "
5702f8e6f71SAmine Khaldi             "PRIMARY KEY `Dialog`)");
571f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r);
572f860a780SAmine Khaldi     return r;
5732f8e6f71SAmine Khaldi }
5742f8e6f71SAmine Khaldi 
create_control_table(MSIHANDLE hdb)5752f8e6f71SAmine Khaldi static UINT create_control_table( MSIHANDLE hdb )
5762f8e6f71SAmine Khaldi {
577*f4be6dc3SMikhail     UINT r = run_query(hdb, 0,
5782f8e6f71SAmine Khaldi             "CREATE TABLE `Control` ("
5792f8e6f71SAmine Khaldi             "`Dialog_` CHAR(72) NOT NULL, "
5802f8e6f71SAmine Khaldi             "`Control` CHAR(50) NOT NULL, "
5812f8e6f71SAmine Khaldi             "`Type` CHAR(20) NOT NULL, "
5822f8e6f71SAmine Khaldi             "`X` SHORT NOT NULL, "
5832f8e6f71SAmine Khaldi             "`Y` SHORT NOT NULL, "
5842f8e6f71SAmine Khaldi             "`Width` SHORT NOT NULL, "
5852f8e6f71SAmine Khaldi             "`Height` SHORT NOT NULL, "
5862f8e6f71SAmine Khaldi             "`Attributes` LONG, "
5872f8e6f71SAmine Khaldi             "`Property` CHAR(50), "
5882f8e6f71SAmine Khaldi             "`Text` CHAR(0) LOCALIZABLE, "
5892f8e6f71SAmine Khaldi             "`Control_Next` CHAR(50), "
5902f8e6f71SAmine Khaldi             "`Help` CHAR(255) LOCALIZABLE "
5912f8e6f71SAmine Khaldi             "PRIMARY KEY `Dialog_`, `Control`)");
592f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r);
593f860a780SAmine Khaldi     return r;
5942f8e6f71SAmine Khaldi }
5952f8e6f71SAmine Khaldi 
create_controlevent_table(MSIHANDLE hdb)5962f8e6f71SAmine Khaldi static UINT create_controlevent_table( MSIHANDLE hdb )
5972f8e6f71SAmine Khaldi {
598*f4be6dc3SMikhail     UINT r = run_query(hdb, 0,
5992f8e6f71SAmine Khaldi             "CREATE TABLE `ControlEvent` ("
6002f8e6f71SAmine Khaldi             "`Dialog_` CHAR(72) NOT NULL, "
6012f8e6f71SAmine Khaldi             "`Control_` CHAR(50) NOT NULL, "
6022f8e6f71SAmine Khaldi             "`Event` CHAR(50) NOT NULL, "
6032f8e6f71SAmine Khaldi             "`Argument` CHAR(255) NOT NULL, "
6042f8e6f71SAmine Khaldi             "`Condition` CHAR(255), "
6052f8e6f71SAmine Khaldi             "`Ordering` SHORT "
6062f8e6f71SAmine Khaldi             "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
607f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r);
608f860a780SAmine Khaldi     return r;
6092f8e6f71SAmine Khaldi }
6102f8e6f71SAmine Khaldi 
create_actiontext_table(MSIHANDLE hdb)6112f8e6f71SAmine Khaldi static UINT create_actiontext_table( MSIHANDLE hdb )
6122f8e6f71SAmine Khaldi {
613*f4be6dc3SMikhail     UINT r = run_query(hdb, 0,
6142f8e6f71SAmine Khaldi             "CREATE TABLE `ActionText` ("
6152f8e6f71SAmine Khaldi             "`Action` CHAR(72) NOT NULL, "
6162f8e6f71SAmine Khaldi             "`Description` CHAR(64) LOCALIZABLE, "
6172f8e6f71SAmine Khaldi             "`Template` CHAR(128) LOCALIZABLE "
6182f8e6f71SAmine Khaldi             "PRIMARY KEY `Action`)");
619f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
620f860a780SAmine Khaldi     return r;
6212f8e6f71SAmine Khaldi }
6222f8e6f71SAmine Khaldi 
create_upgrade_table(MSIHANDLE hdb)62396486643Swinesync static UINT create_upgrade_table( MSIHANDLE hdb )
62496486643Swinesync {
625*f4be6dc3SMikhail     UINT r = run_query( hdb, 0,
62696486643Swinesync             "CREATE TABLE `Upgrade` ("
62796486643Swinesync             "`UpgradeCode` CHAR(38) NOT NULL, "
62896486643Swinesync             "`VersionMin` CHAR(20), "
62996486643Swinesync             "`VersionMax` CHAR(20), "
63096486643Swinesync             "`Language` CHAR(255), "
63196486643Swinesync             "`Attributes` SHORT, "
63296486643Swinesync             "`Remove` CHAR(255), "
63396486643Swinesync             "`ActionProperty` CHAR(72) NOT NULL "
63496486643Swinesync             "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
63596486643Swinesync     ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r);
63696486643Swinesync     return r;
63796486643Swinesync }
63896486643Swinesync 
add_entry(const char * file,int line,const char * type,MSIHANDLE hdb,const char * values,const char * insert)639f860a780SAmine Khaldi static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
640f860a780SAmine Khaldi {
641f860a780SAmine Khaldi     char *query;
642f860a780SAmine Khaldi     UINT sz, r;
643f860a780SAmine Khaldi 
644f860a780SAmine Khaldi     sz = strlen(values) + strlen(insert) + 1;
6456aefc5b9Swinesync     query = malloc(sz);
646f860a780SAmine Khaldi     sprintf(query, insert, values);
647*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
6486aefc5b9Swinesync     free(query);
649f860a780SAmine Khaldi     ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
650f860a780SAmine Khaldi     return r;
651c2c66affSColin Finck }
652c2c66affSColin Finck 
653f860a780SAmine Khaldi #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
654f860a780SAmine Khaldi                "INSERT INTO `Component`  " \
655f860a780SAmine Khaldi                "(`Component`, `ComponentId`, `Directory_`, " \
656c2c66affSColin Finck                "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
657c2c66affSColin Finck 
658f860a780SAmine Khaldi #define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
659f860a780SAmine Khaldi                "INSERT INTO `Directory` " \
660c2c66affSColin Finck                "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
661c2c66affSColin Finck 
662f860a780SAmine Khaldi #define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
663f860a780SAmine Khaldi                "INSERT INTO `Feature` " \
664f860a780SAmine Khaldi                "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
665c2c66affSColin Finck                "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
666c2c66affSColin Finck 
667f860a780SAmine Khaldi #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
668f860a780SAmine Khaldi                "INSERT INTO `FeatureComponents` " \
669c2c66affSColin Finck                "(`Feature_`, `Component_`) VALUES( %s )")
670c2c66affSColin Finck 
671f860a780SAmine Khaldi #define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
672f860a780SAmine Khaldi                "INSERT INTO `File` " \
673f860a780SAmine Khaldi                "(`File`, `Component_`, `FileName`, `FileSize`, " \
674c2c66affSColin Finck                "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
675c2c66affSColin Finck 
676f860a780SAmine Khaldi #define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
677f860a780SAmine Khaldi                "INSERT INTO `AppSearch` " \
678c2c66affSColin Finck                "(`Property`, `Signature_`) VALUES( %s )")
679c2c66affSColin Finck 
680f860a780SAmine Khaldi #define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
681f860a780SAmine Khaldi                "INSERT INTO `Signature` " \
682f860a780SAmine Khaldi                "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
683f860a780SAmine Khaldi                " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
684c2c66affSColin Finck                "VALUES( %s )")
685c2c66affSColin Finck 
686f860a780SAmine Khaldi #define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
687f860a780SAmine Khaldi                "INSERT INTO `LaunchCondition` " \
688c2c66affSColin Finck                "(`Condition`, `Description`) VALUES( %s )")
689c2c66affSColin Finck 
690f860a780SAmine Khaldi #define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
691c2c66affSColin Finck                "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
692c2c66affSColin Finck 
69396486643Swinesync #define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
69496486643Swinesync                "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
69596486643Swinesync 
69696486643Swinesync #define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
69796486643Swinesync                "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
69896486643Swinesync 
699f860a780SAmine Khaldi #define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
700f860a780SAmine Khaldi                "INSERT INTO `InstallExecuteSequence` " \
701c2c66affSColin Finck                "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
702c2c66affSColin Finck 
703f860a780SAmine Khaldi #define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
704f860a780SAmine Khaldi                "INSERT INTO `InstallUISequence` " \
705f860a780SAmine Khaldi                "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
706f860a780SAmine Khaldi 
707f860a780SAmine Khaldi #define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
708f860a780SAmine Khaldi                "INSERT INTO `Media` " \
709f860a780SAmine Khaldi                "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
710c2c66affSColin Finck                "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
711c2c66affSColin Finck 
712f860a780SAmine Khaldi #define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
713c2c66affSColin Finck                "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
714c2c66affSColin Finck 
715f860a780SAmine Khaldi #define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
716f860a780SAmine Khaldi                "INSERT INTO `DrLocator` " \
717c2c66affSColin Finck                "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
718c2c66affSColin Finck 
719f860a780SAmine Khaldi #define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
720f860a780SAmine Khaldi                "INSERT INTO `CompLocator` " \
721c2c66affSColin Finck                "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
722c2c66affSColin Finck 
723f860a780SAmine Khaldi #define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
724f860a780SAmine Khaldi                "INSERT INTO `IniLocator` " \
725f860a780SAmine Khaldi                "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
726c2c66affSColin Finck                "VALUES( %s )")
727c2c66affSColin Finck 
728f860a780SAmine Khaldi #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
729f860a780SAmine Khaldi                "INSERT INTO `CustomAction`  " \
730c2c66affSColin Finck                "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
731c2c66affSColin Finck 
732f860a780SAmine Khaldi #define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
733f860a780SAmine Khaldi                "INSERT INTO `Dialog` " \
7342f8e6f71SAmine Khaldi                "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
7352f8e6f71SAmine Khaldi 
736f860a780SAmine Khaldi #define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
737f860a780SAmine Khaldi                "INSERT INTO `Control` " \
7382f8e6f71SAmine Khaldi                "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
7392f8e6f71SAmine Khaldi 
740f860a780SAmine Khaldi #define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
741f860a780SAmine Khaldi                "INSERT INTO `ControlEvent` " \
7422f8e6f71SAmine Khaldi                "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
7432f8e6f71SAmine Khaldi 
744f860a780SAmine Khaldi #define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
745f860a780SAmine Khaldi                "INSERT INTO `ActionText` " \
7462f8e6f71SAmine Khaldi                "(`Action`, `Description`, `Template`) VALUES( %s )");
7472f8e6f71SAmine Khaldi 
74896486643Swinesync #define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
74996486643Swinesync                "INSERT INTO `Upgrade` " \
75096486643Swinesync                "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
75196486643Swinesync 
add_reglocator_entry(MSIHANDLE hdb,const char * sig,UINT root,const char * path,const char * name,UINT type)752c2c66affSColin Finck static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
753c2c66affSColin Finck                                   const char *name, UINT type )
754c2c66affSColin Finck {
755c2c66affSColin Finck     const char insert[] =
756c2c66affSColin Finck         "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
757c2c66affSColin Finck         "VALUES( '%s', %u, '%s', '%s', %u )";
758c2c66affSColin Finck     char *query;
759c2c66affSColin Finck     UINT sz, r;
760c2c66affSColin Finck 
761c2c66affSColin Finck     sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
7626aefc5b9Swinesync     query = malloc( sz );
763c2c66affSColin Finck     sprintf( query, insert, sig, root, path, name, type );
764*f4be6dc3SMikhail     r = run_query( hdb, 0, query );
7656aefc5b9Swinesync     free( query );
766f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
767c2c66affSColin Finck     return r;
768c2c66affSColin Finck }
769c2c66affSColin Finck 
set_summary_info(MSIHANDLE hdb)770c2c66affSColin Finck static UINT set_summary_info(MSIHANDLE hdb)
771c2c66affSColin Finck {
772c2c66affSColin Finck     UINT res;
773c2c66affSColin Finck     MSIHANDLE suminfo;
774c2c66affSColin Finck 
775c2c66affSColin Finck     /* build summary info */
776c2c66affSColin Finck     res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
777c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
778c2c66affSColin Finck 
779c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL,
780c2c66affSColin Finck                         "Installation Database");
781c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
782c2c66affSColin Finck 
783c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL,
784c2c66affSColin Finck                         "Installation Database");
785c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
786c2c66affSColin Finck 
787c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL,
788c2c66affSColin Finck                         "Wine Hackers");
789c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
790c2c66affSColin Finck 
791c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL,
792c2c66affSColin Finck                     ";1033");
793c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
794c2c66affSColin Finck 
795c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL,
796c2c66affSColin Finck                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
797c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
798c2c66affSColin Finck 
799c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
800c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
801c2c66affSColin Finck 
802c2c66affSColin Finck     res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
803c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
804c2c66affSColin Finck 
805c2c66affSColin Finck     res = MsiSummaryInfoPersist(suminfo);
806c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
807c2c66affSColin Finck 
808c2c66affSColin Finck     res = MsiCloseHandle( suminfo);
809c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
810c2c66affSColin Finck 
811c2c66affSColin Finck     return res;
812c2c66affSColin Finck }
813c2c66affSColin Finck 
814c2c66affSColin Finck 
create_package_db(void)815c2c66affSColin Finck static MSIHANDLE create_package_db(void)
816c2c66affSColin Finck {
817c2c66affSColin Finck     MSIHANDLE hdb = 0;
818c2c66affSColin Finck     UINT res;
819c2c66affSColin Finck 
820c2c66affSColin Finck     DeleteFileA(msifile);
821c2c66affSColin Finck 
822c2c66affSColin Finck     /* create an empty database */
823c2c66affSColin Finck     res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb );
824c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
825c2c66affSColin Finck     if( res != ERROR_SUCCESS )
826c2c66affSColin Finck         return hdb;
827c2c66affSColin Finck 
828c2c66affSColin Finck     res = MsiDatabaseCommit( hdb );
829c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
830c2c66affSColin Finck 
831c2c66affSColin Finck     res = set_summary_info(hdb);
832c2c66affSColin Finck     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
833c2c66affSColin Finck 
834*f4be6dc3SMikhail     res = run_query( hdb, 0,
835c2c66affSColin Finck             "CREATE TABLE `Directory` ( "
836c2c66affSColin Finck             "`Directory` CHAR(255) NOT NULL, "
837c2c66affSColin Finck             "`Directory_Parent` CHAR(255), "
838c2c66affSColin Finck             "`DefaultDir` CHAR(255) NOT NULL "
839c2c66affSColin Finck             "PRIMARY KEY `Directory`)" );
840c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
841c2c66affSColin Finck 
842c2c66affSColin Finck     return hdb;
843c2c66affSColin Finck }
844c2c66affSColin Finck 
package_from_db(MSIHANDLE hdb,MSIHANDLE * handle)845c2c66affSColin Finck static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
846c2c66affSColin Finck {
847c2c66affSColin Finck     UINT res;
848c2c66affSColin Finck     CHAR szPackage[12];
849c2c66affSColin Finck     MSIHANDLE hPackage;
850c2c66affSColin Finck 
8511b4acd3cSwinesync     sprintf(szPackage, "#%lu", hdb);
852c2c66affSColin Finck     res = MsiOpenPackageA(szPackage, &hPackage);
853c2c66affSColin Finck     if (res != ERROR_SUCCESS)
854c2c66affSColin Finck     {
855c2c66affSColin Finck         MsiCloseHandle(hdb);
856c2c66affSColin Finck         return res;
857c2c66affSColin Finck     }
858c2c66affSColin Finck 
859c2c66affSColin Finck     res = MsiCloseHandle(hdb);
860c2c66affSColin Finck     if (res != ERROR_SUCCESS)
861c2c66affSColin Finck     {
862c2c66affSColin Finck         MsiCloseHandle(hPackage);
863c2c66affSColin Finck         return res;
864c2c66affSColin Finck     }
865c2c66affSColin Finck 
866c2c66affSColin Finck     *handle = hPackage;
867c2c66affSColin Finck     return ERROR_SUCCESS;
868c2c66affSColin Finck }
869c2c66affSColin Finck 
create_test_file(const CHAR * name)8702f8e6f71SAmine Khaldi static void create_test_file(const CHAR *name)
8712f8e6f71SAmine Khaldi {
872*f4be6dc3SMikhail     create_file_data(name, name, strlen(name));
8732f8e6f71SAmine Khaldi }
8742f8e6f71SAmine Khaldi 
875c2c66affSColin Finck typedef struct _tagVS_VERSIONINFO
876c2c66affSColin Finck {
877c2c66affSColin Finck     WORD wLength;
878c2c66affSColin Finck     WORD wValueLength;
879c2c66affSColin Finck     WORD wType;
880c2c66affSColin Finck     WCHAR szKey[1];
881c2c66affSColin Finck     WORD wPadding1[1];
882c2c66affSColin Finck     VS_FIXEDFILEINFO Value;
883c2c66affSColin Finck     WORD wPadding2[1];
884c2c66affSColin Finck     WORD wChildren[1];
885c2c66affSColin Finck } VS_VERSIONINFO;
886c2c66affSColin Finck 
887c2c66affSColin Finck #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
888c2c66affSColin Finck #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
889c2c66affSColin Finck 
create_file_with_version(const CHAR * name,LONG ms,LONG ls)890c2c66affSColin Finck static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
891c2c66affSColin Finck {
892c2c66affSColin Finck     VS_VERSIONINFO *pVerInfo;
893c2c66affSColin Finck     VS_FIXEDFILEINFO *pFixedInfo;
894c2c66affSColin Finck     LPBYTE buffer, ofs;
895c2c66affSColin Finck     CHAR path[MAX_PATH];
896c2c66affSColin Finck     DWORD handle, size;
897c2c66affSColin Finck     HANDLE resource;
898c2c66affSColin Finck     BOOL ret = FALSE;
899c2c66affSColin Finck 
900c2c66affSColin Finck     GetSystemDirectoryA(path, MAX_PATH);
901c2c66affSColin Finck     /* Some dlls can't be updated on Vista/W2K8 */
902c2c66affSColin Finck     lstrcatA(path, "\\version.dll");
903c2c66affSColin Finck 
904c2c66affSColin Finck     CopyFileA(path, name, FALSE);
905c2c66affSColin Finck 
906c2c66affSColin Finck     size = GetFileVersionInfoSizeA(path, &handle);
9076aefc5b9Swinesync     buffer = malloc(size);
908c2c66affSColin Finck 
909c2c66affSColin Finck     GetFileVersionInfoA(path, 0, size, buffer);
910c2c66affSColin Finck 
911c2c66affSColin Finck     pVerInfo = (VS_VERSIONINFO *)buffer;
912c2c66affSColin Finck     ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
913c2c66affSColin Finck     pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
914c2c66affSColin Finck 
915c2c66affSColin Finck     pFixedInfo->dwFileVersionMS = ms;
916c2c66affSColin Finck     pFixedInfo->dwFileVersionLS = ls;
917c2c66affSColin Finck     pFixedInfo->dwProductVersionMS = ms;
918c2c66affSColin Finck     pFixedInfo->dwProductVersionLS = ls;
919c2c66affSColin Finck 
920c2c66affSColin Finck     resource = BeginUpdateResourceA(name, FALSE);
921c2c66affSColin Finck     if (!resource)
922c2c66affSColin Finck         goto done;
923c2c66affSColin Finck 
924c2c66affSColin Finck     if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO),
925c2c66affSColin Finck                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
926c2c66affSColin Finck         goto done;
927c2c66affSColin Finck 
928c2c66affSColin Finck     if (!EndUpdateResourceA(resource, FALSE))
929c2c66affSColin Finck         goto done;
930c2c66affSColin Finck 
931c2c66affSColin Finck     ret = TRUE;
932c2c66affSColin Finck 
933c2c66affSColin Finck done:
9346aefc5b9Swinesync     free(buffer);
935c2c66affSColin Finck     return ret;
936c2c66affSColin Finck }
937c2c66affSColin Finck 
is_root(const char * path)938c2c66affSColin Finck static BOOL is_root(const char *path)
939c2c66affSColin Finck {
940c2c66affSColin Finck     return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
941c2c66affSColin Finck }
942c2c66affSColin Finck 
test_createpackage(void)943c2c66affSColin Finck static void test_createpackage(void)
944c2c66affSColin Finck {
945c2c66affSColin Finck     MSIHANDLE hPackage = 0;
946c2c66affSColin Finck     UINT res;
947c2c66affSColin Finck 
948c2c66affSColin Finck     res = package_from_db(create_package_db(), &hPackage);
949c2c66affSColin Finck     if (res == ERROR_INSTALL_PACKAGE_REJECTED)
950c2c66affSColin Finck     {
951c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
952c2c66affSColin Finck         DeleteFileA(msifile);
953c2c66affSColin Finck         return;
954c2c66affSColin Finck     }
955c2c66affSColin Finck     ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
956c2c66affSColin Finck 
957c2c66affSColin Finck     res = MsiCloseHandle( hPackage);
958c2c66affSColin Finck     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
959c2c66affSColin Finck     DeleteFileA(msifile);
960c2c66affSColin Finck }
961c2c66affSColin Finck 
test_doaction(void)962c2c66affSColin Finck static void test_doaction( void )
963c2c66affSColin Finck {
964c2c66affSColin Finck     MSIHANDLE hpkg;
965c2c66affSColin Finck     UINT r;
966c2c66affSColin Finck 
967c2c66affSColin Finck     r = MsiDoActionA( -1, NULL );
968c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
969c2c66affSColin Finck 
970c2c66affSColin Finck     r = package_from_db(create_package_db(), &hpkg);
971c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
972c2c66affSColin Finck     {
973c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
974c2c66affSColin Finck         DeleteFileA(msifile);
975c2c66affSColin Finck         return;
976c2c66affSColin Finck     }
977c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
978c2c66affSColin Finck 
979c2c66affSColin Finck     r = MsiDoActionA(hpkg, NULL);
980c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
981c2c66affSColin Finck 
982c2c66affSColin Finck     r = MsiDoActionA(0, "boo");
983c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
984c2c66affSColin Finck 
985c2c66affSColin Finck     r = MsiDoActionA(hpkg, "boo");
986c2c66affSColin Finck     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
987c2c66affSColin Finck 
988c2c66affSColin Finck     MsiCloseHandle( hpkg );
989c2c66affSColin Finck     DeleteFileA(msifile);
990c2c66affSColin Finck }
991c2c66affSColin Finck 
test_gettargetpath_bad(void)992c2c66affSColin Finck static void test_gettargetpath_bad(void)
993c2c66affSColin Finck {
994c2c66affSColin Finck     char buffer[0x80];
995c2c66affSColin Finck     WCHAR bufferW[0x80];
996c2c66affSColin Finck     MSIHANDLE hpkg;
997c2c66affSColin Finck     DWORD sz;
998c2c66affSColin Finck     UINT r;
999c2c66affSColin Finck 
1000c2c66affSColin Finck     r = package_from_db(create_package_db(), &hpkg);
1001c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1002c2c66affSColin Finck     {
1003c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
1004c2c66affSColin Finck         DeleteFileA(msifile);
1005c2c66affSColin Finck         return;
1006c2c66affSColin Finck     }
1007c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1008c2c66affSColin Finck 
1009c2c66affSColin Finck     r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1010c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1011c2c66affSColin Finck 
1012c2c66affSColin Finck     r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1013c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1014c2c66affSColin Finck 
1015c2c66affSColin Finck     r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1016c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1017c2c66affSColin Finck 
1018c2c66affSColin Finck     r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1019c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1020c2c66affSColin Finck 
1021c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1022c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1023c2c66affSColin Finck 
1024c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1025c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1026c2c66affSColin Finck 
1027c2c66affSColin Finck     sz = 0;
1028c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1029c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1030c2c66affSColin Finck 
1031c2c66affSColin Finck     r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1032c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1033c2c66affSColin Finck 
1034c2c66affSColin Finck     r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1035c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1036c2c66affSColin Finck 
1037f31e4044Swinesync     r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1038c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1039c2c66affSColin Finck 
1040f31e4044Swinesync     r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1041c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1042c2c66affSColin Finck 
1043f31e4044Swinesync     r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL );
1044c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1045c2c66affSColin Finck 
1046f31e4044Swinesync     r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL );
1047c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1048c2c66affSColin Finck 
1049c2c66affSColin Finck     sz = 0;
1050f31e4044Swinesync     r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz );
1051c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1052c2c66affSColin Finck 
1053c2c66affSColin Finck     MsiCloseHandle( hpkg );
1054c2c66affSColin Finck     DeleteFileA(msifile);
1055c2c66affSColin Finck }
1056c2c66affSColin Finck 
query_file_path(MSIHANDLE hpkg,LPCSTR file,LPSTR buff)1057c2c66affSColin Finck static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1058c2c66affSColin Finck {
1059c2c66affSColin Finck     UINT r;
1060c2c66affSColin Finck     DWORD size;
1061c2c66affSColin Finck     MSIHANDLE rec;
1062c2c66affSColin Finck 
1063c2c66affSColin Finck     rec = MsiCreateRecord( 1 );
1064c2c66affSColin Finck     ok(rec, "MsiCreate record failed\n");
1065c2c66affSColin Finck 
1066c2c66affSColin Finck     r = MsiRecordSetStringA( rec, 0, file );
1067c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1068c2c66affSColin Finck 
1069c2c66affSColin Finck     size = MAX_PATH;
1070c2c66affSColin Finck     r = MsiFormatRecordA( hpkg, rec, buff, &size );
1071c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1072c2c66affSColin Finck 
1073c2c66affSColin Finck     MsiCloseHandle( rec );
1074c2c66affSColin Finck }
1075c2c66affSColin Finck 
test_settargetpath(void)1076c2c66affSColin Finck static void test_settargetpath(void)
1077c2c66affSColin Finck {
1078484e8280Swinesync     char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20];
1079c2c66affSColin Finck     DWORD sz;
1080c2c66affSColin Finck     MSIHANDLE hpkg;
1081c2c66affSColin Finck     UINT r;
1082c2c66affSColin Finck     MSIHANDLE hdb;
1083c2c66affSColin Finck 
1084c2c66affSColin Finck     hdb = create_package_db();
1085c2c66affSColin Finck     ok ( hdb, "failed to create package database\n" );
1086c2c66affSColin Finck 
1087f860a780SAmine Khaldi     add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1088c2c66affSColin Finck 
1089f860a780SAmine Khaldi     create_component_table( hdb );
1090f860a780SAmine Khaldi     add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1091f860a780SAmine Khaldi     add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1092c2c66affSColin Finck 
1093f860a780SAmine Khaldi     create_feature_table( hdb );
1094f860a780SAmine Khaldi     add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1095c2c66affSColin Finck 
1096f860a780SAmine Khaldi     create_feature_components_table( hdb );
1097f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1098f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1099c2c66affSColin Finck 
1100c2c66affSColin Finck     add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1101c2c66affSColin Finck     add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1102c2c66affSColin Finck 
1103f860a780SAmine Khaldi     create_file_table( hdb );
1104f860a780SAmine Khaldi     add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1105f860a780SAmine Khaldi     add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1106c2c66affSColin Finck 
1107c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
1108c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1109c2c66affSColin Finck     {
1110c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
1111c2c66affSColin Finck         DeleteFileA(msifile);
1112c2c66affSColin Finck         return;
1113c2c66affSColin Finck     }
1114c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1115c2c66affSColin Finck 
1116c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1117c2c66affSColin Finck 
1118c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
1119c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
1120c2c66affSColin Finck 
1121c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
1122c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
1123c2c66affSColin Finck 
1124c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
1125c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1126c2c66affSColin Finck 
1127c2c66affSColin Finck     buffer[0] = 0;
1128c2c66affSColin Finck     sz = sizeof(buffer);
1129c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1130c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1131c2c66affSColin Finck     trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1132c2c66affSColin Finck 
1133c2c66affSColin Finck     r = MsiSetTargetPathA( 0, NULL, NULL );
1134c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1135c2c66affSColin Finck 
1136c2c66affSColin Finck     r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1137c2c66affSColin Finck     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1138c2c66affSColin Finck 
1139c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "boo", NULL );
1140c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1141c2c66affSColin Finck 
1142c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1143c2c66affSColin Finck     ok( r == ERROR_DIRECTORY, "wrong return val\n");
1144c2c66affSColin Finck 
1145c2c66affSColin Finck     sz = sizeof tempdir - 1;
1146c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1147c2c66affSColin Finck     sprintf( file, "%srootfile.txt", tempdir );
1148c2c66affSColin Finck     buffer[0] = 0;
1149c2c66affSColin Finck     query_file_path( hpkg, "[#RootFile]", buffer );
1150c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1151c2c66affSColin Finck     ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1152c2c66affSColin Finck 
1153c2c66affSColin Finck     GetTempFileNameA( tempdir, "_wt", 0, buffer );
1154c2c66affSColin Finck     sprintf( tempdir, "%s\\subdir", buffer );
1155c2c66affSColin Finck 
1156c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1157c2c66affSColin Finck     ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1158c2c66affSColin Finck         "MsiSetTargetPath on file returned %d\n", r );
1159c2c66affSColin Finck 
1160c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1161c2c66affSColin Finck     ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1162c2c66affSColin Finck         "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1163c2c66affSColin Finck 
1164c2c66affSColin Finck     DeleteFileA( buffer );
1165c2c66affSColin Finck 
1166c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1167c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1168c2c66affSColin Finck 
1169c2c66affSColin Finck     r = GetFileAttributesA( buffer );
1170c2c66affSColin Finck     ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1171c2c66affSColin Finck 
1172c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1173c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1174c2c66affSColin Finck 
1175c2c66affSColin Finck     buffer[0] = 0;
1176c2c66affSColin Finck     sz = sizeof buffer - 1;
1177c2c66affSColin Finck     lstrcatA( tempdir, "\\" );
1178c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1179c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1180c2c66affSColin Finck     ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1181c2c66affSColin Finck 
1182c2c66affSColin Finck     sprintf( file, "%srootfile.txt", tempdir );
1183c2c66affSColin Finck     query_file_path( hpkg, "[#RootFile]", buffer );
1184c2c66affSColin Finck     ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1185c2c66affSColin Finck 
1186c2c66affSColin Finck     buffer[0] = 0;
1187c2c66affSColin Finck     sz = sizeof(buffer);
1188c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1189c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1190c2c66affSColin Finck     lstrcatA( tempdir, "TestParent\\" );
1191c2c66affSColin Finck     ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1192c2c66affSColin Finck 
1193c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1194c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1195c2c66affSColin Finck 
1196c2c66affSColin Finck     buffer[0] = 0;
1197c2c66affSColin Finck     sz = sizeof(buffer);
1198c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1199c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1200c2c66affSColin Finck     ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1201c2c66affSColin Finck         "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1202c2c66affSColin Finck 
1203c2c66affSColin Finck     buffer[0] = 0;
1204c2c66affSColin Finck     query_file_path( hpkg, "[#TestFile]", buffer );
1205c2c66affSColin Finck     ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1206c2c66affSColin Finck         "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1207c2c66affSColin Finck 
1208c2c66affSColin Finck     buffer[0] = 0;
1209c2c66affSColin Finck     sz = sizeof buffer - 1;
1210c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1211c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1212c2c66affSColin Finck     ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1213c2c66affSColin Finck 
1214c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1215c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1216c2c66affSColin Finck 
1217c2c66affSColin Finck     buffer[0] = 0;
1218c2c66affSColin Finck     sz = sizeof buffer - 1;
1219c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1220c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1221c2c66affSColin Finck     ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1222c2c66affSColin Finck 
1223c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two  " );
1224c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1225c2c66affSColin Finck 
1226c2c66affSColin Finck     buffer[0] = 0;
1227c2c66affSColin Finck     sz = sizeof buffer - 1;
1228c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1229c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1230c2c66affSColin Finck     ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1231c2c66affSColin Finck 
1232c2c66affSColin Finck     r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1233c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1234c2c66affSColin Finck 
1235c2c66affSColin Finck     buffer[0] = 0;
1236c2c66affSColin Finck     sz = sizeof buffer - 1;
1237c2c66affSColin Finck     r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1238c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1239c2c66affSColin Finck     ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1240c2c66affSColin Finck 
1241c2c66affSColin Finck     MsiCloseHandle( hpkg );
1242c2c66affSColin Finck }
1243c2c66affSColin Finck 
test_condition(void)1244c2c66affSColin Finck static void test_condition(void)
1245c2c66affSColin Finck {
1246c2c66affSColin Finck     MSICONDITION r;
1247c2c66affSColin Finck     MSIHANDLE hpkg;
1248c2c66affSColin Finck 
1249c2c66affSColin Finck     r = package_from_db(create_package_db(), &hpkg);
1250c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1251c2c66affSColin Finck     {
1252c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
1253c2c66affSColin Finck         DeleteFileA(msifile);
1254c2c66affSColin Finck         return;
1255c2c66affSColin Finck     }
1256c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1257c2c66affSColin Finck 
1258c2c66affSColin Finck     r = MsiEvaluateConditionA(0, NULL);
1259c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1260c2c66affSColin Finck 
1261c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, NULL);
1262c2c66affSColin Finck     ok( r == MSICONDITION_NONE, "wrong return val\n");
1263c2c66affSColin Finck 
1264c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "");
1265c2c66affSColin Finck     ok( r == MSICONDITION_NONE, "wrong return val\n");
1266c2c66affSColin Finck 
1267c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1");
1268c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1269c2c66affSColin Finck 
1270c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0");
1271c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1272c2c66affSColin Finck 
1273c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "-1");
1274c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1275c2c66affSColin Finck 
1276c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 = 0");
1277c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1278c2c66affSColin Finck 
1279c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1280c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1281c2c66affSColin Finck 
1282c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 = 1");
1283c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1284c2c66affSColin Finck 
1285c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 > 1");
1286c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1287c2c66affSColin Finck 
1288c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1289c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1290c2c66affSColin Finck 
1291c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 > 1");
1292c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1293c2c66affSColin Finck 
1294c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1295c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1296c2c66affSColin Finck 
1297c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1298c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1299c2c66affSColin Finck 
1300c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1301c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1302c2c66affSColin Finck 
1303c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1304c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1305c2c66affSColin Finck 
1306c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1307c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1308c2c66affSColin Finck 
1309c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 < 1");
1310c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1311c2c66affSColin Finck 
1312c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1313c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1314c2c66affSColin Finck 
1315c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 < 1");
1316c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1317c2c66affSColin Finck 
1318c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1319c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1320c2c66affSColin Finck 
1321c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1322c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1323c2c66affSColin Finck 
1324c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1325c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1326c2c66affSColin Finck 
1327c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1328c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1329c2c66affSColin Finck 
1330c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1331c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1332c2c66affSColin Finck 
1333c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 >=");
1334c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1335c2c66affSColin Finck 
1336c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " ");
1337c2c66affSColin Finck     ok( r == MSICONDITION_NONE, "wrong return val\n");
1338c2c66affSColin Finck 
1339c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1340c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1341c2c66affSColin Finck 
1342c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1343c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1344c2c66affSColin Finck 
1345c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1346c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1347c2c66affSColin Finck 
1348c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not 0");
1349c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1350c2c66affSColin Finck 
1351c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not LicView");
1352c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1353c2c66affSColin Finck 
1354c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1355c2c66affSColin Finck     ok (r == MSICONDITION_TRUE, "wrong return val\n");
1356c2c66affSColin Finck 
1357c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1358c2c66affSColin Finck     ok (r == MSICONDITION_FALSE, "wrong return val\n");
1359c2c66affSColin Finck 
1360c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1361c2c66affSColin Finck     ok (r == MSICONDITION_TRUE, "wrong return val\n");
1362c2c66affSColin Finck 
1363c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1364c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1365c2c66affSColin Finck 
1366c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1367c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1368c2c66affSColin Finck 
1369c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"0\"");
1370c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1371c2c66affSColin Finck 
1372c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 and 2");
1373c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1374c2c66affSColin Finck 
1375c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1376c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1377c2c66affSColin Finck 
1378c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1379c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1380c2c66affSColin Finck 
1381c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1382c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1383c2c66affSColin Finck 
1384c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "(0)");
1385c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1386c2c66affSColin Finck 
1387c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1388c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1389c2c66affSColin Finck 
1390c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1391c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1392c2c66affSColin Finck 
1393c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1394c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1395c2c66affSColin Finck 
1396c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1397c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1398c2c66affSColin Finck 
1399c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1400c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1401c2c66affSColin Finck 
1402c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1403c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1404c2c66affSColin Finck 
1405c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1406c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1407c2c66affSColin Finck 
1408c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1409c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1410c2c66affSColin Finck 
1411c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1412c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1413c2c66affSColin Finck 
1414c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1415c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1416c2c66affSColin Finck 
1417c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1418c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1419c2c66affSColin Finck 
1420c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1421c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1422c2c66affSColin Finck 
1423c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1424c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1425c2c66affSColin Finck 
1426c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1427c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1428c2c66affSColin Finck 
1429c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1430c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1431c2c66affSColin Finck 
1432c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1433c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1434c2c66affSColin Finck 
1435c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1436c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1437c2c66affSColin Finck 
1438c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1439c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1440c2c66affSColin Finck 
1441c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1442c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1443c2c66affSColin Finck 
1444c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1445c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1446c2c66affSColin Finck 
1447c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1448c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1449c2c66affSColin Finck 
1450c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1451c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1452c2c66affSColin Finck 
1453c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1454c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1455c2c66affSColin Finck 
1456c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1457c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1458c2c66affSColin Finck 
1459c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1460c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1461c2c66affSColin Finck 
1462c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1463c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1464c2c66affSColin Finck 
1465c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1466c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1467c2c66affSColin Finck 
1468c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1469c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1470c2c66affSColin Finck 
1471c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1472c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1473c2c66affSColin Finck 
1474c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1475c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1476c2c66affSColin Finck 
1477c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1478c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1479c2c66affSColin Finck 
1480c2c66affSColin Finck     MsiSetPropertyA(hpkg, "mm", "5" );
1481c2c66affSColin Finck 
1482c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm = 5");
1483c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1484c2c66affSColin Finck 
1485c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm < 6");
1486c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1487c2c66affSColin Finck 
1488c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1489c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1490c2c66affSColin Finck 
1491c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm > 4");
1492c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1493c2c66affSColin Finck 
1494c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm < 12");
1495c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1496c2c66affSColin Finck 
1497c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1498c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1499c2c66affSColin Finck 
1500c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1501c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1502c2c66affSColin Finck 
1503c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1504c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1505c2c66affSColin Finck 
1506c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1507c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1508c2c66affSColin Finck 
1509c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1510c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1511c2c66affSColin Finck 
1512c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1513c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1514c2c66affSColin Finck 
1515c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1516c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1517c2c66affSColin Finck 
1518c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1519c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1520c2c66affSColin Finck 
1521c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1522c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1523c2c66affSColin Finck 
1524c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1525c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1526c2c66affSColin Finck 
1527c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1528c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1529c2c66affSColin Finck 
1530c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1531c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1532c2c66affSColin Finck 
1533c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1534c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1535c2c66affSColin Finck 
1536c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1537c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1538c2c66affSColin Finck 
1539c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1540c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1541c2c66affSColin Finck 
1542c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1543c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1544c2c66affSColin Finck 
1545c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1546c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1547c2c66affSColin Finck 
1548c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1549c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1550c2c66affSColin Finck 
1551c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1552c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1553c2c66affSColin Finck 
1554c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1555c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1556c2c66affSColin Finck 
1557c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1558c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1559c2c66affSColin Finck 
1560c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1561c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1562c2c66affSColin Finck 
1563c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1564c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1565c2c66affSColin Finck 
1566c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1567c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1568c2c66affSColin Finck 
1569c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1570c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1571c2c66affSColin Finck 
1572c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1573c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1574c2c66affSColin Finck 
1575c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0" );
1576c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1577c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1578c2c66affSColin Finck 
1579c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "" );
1580c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1581c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1582c2c66affSColin Finck 
1583c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1584c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1585c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1586c2c66affSColin Finck 
1587c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1588c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1589c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1590c2c66affSColin Finck 
1591c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1592c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1593c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1594c2c66affSColin Finck 
1595c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1596c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1597c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1598c2c66affSColin Finck 
1599c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1600c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1601c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1602c2c66affSColin Finck 
1603c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1604c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1605c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1606c2c66affSColin Finck 
1607c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1608c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1609c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1610c2c66affSColin Finck 
1611c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "-" );
1612c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1613c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1614c2c66affSColin Finck 
1615c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1616c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1617c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1618c2c66affSColin Finck 
1619c2c66affSColin Finck     MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1620c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1621c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1622c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1623c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1624c2c66affSColin Finck 
1625c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hi");
1626c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hithere");
1627c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1628c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1629c2c66affSColin Finck 
1630c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hithere");
1631c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1632c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1633c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1634c2c66affSColin Finck 
1635c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hello");
1636c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1637c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1638c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1639c2c66affSColin Finck 
1640c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hellohithere");
1641c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1642c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1643c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1644c2c66affSColin Finck 
1645c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1646c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1647c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1648c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1649c2c66affSColin Finck 
1650c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hi");
1651c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1652c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1653c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1654c2c66affSColin Finck 
1655c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1656c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1657c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1658c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1659c2c66affSColin Finck 
1660c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "1234");
1661c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "1");
1662c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1663c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1664c2c66affSColin Finck 
1665c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "one 1234");
1666c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "1");
1667c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >< two");
1668c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1669c2c66affSColin Finck 
1670c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hithere");
1671c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1672c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1673c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1674c2c66affSColin Finck 
1675c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hi");
1676c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hithere");
1677c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1678c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1679c2c66affSColin Finck 
1680c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hi");
1681c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1682c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1683c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1684c2c66affSColin Finck 
1685c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "abcdhithere");
1686c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1687c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1688c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1689c2c66affSColin Finck 
1690c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1691c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1692c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1693c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1694c2c66affSColin Finck 
1695c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hithere");
1696c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1697c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1698c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1699c2c66affSColin Finck 
1700c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1701c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1702c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1703c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1704c2c66affSColin Finck 
1705c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "1234");
1706c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "1");
1707c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1708c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1709c2c66affSColin Finck 
1710c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "1234 one");
1711c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "1");
1712c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one << two");
1713c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1714c2c66affSColin Finck 
1715c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hithere");
1716c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "there");
1717c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1718c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1719c2c66affSColin Finck 
1720c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "hithere");
1721c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1722c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1723c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1724c2c66affSColin Finck 
1725c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "there");
1726c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hithere");
1727c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1728c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1729c2c66affSColin Finck 
1730c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "there");
1731c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "there");
1732c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1733c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1734c2c66affSColin Finck 
1735c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "abcdhithere");
1736c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "hi");
1737c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1738c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1739c2c66affSColin Finck 
1740c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1741c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "there");
1742c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1743c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1744c2c66affSColin Finck 
1745c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "there");
1746c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1747c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1748c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1749c2c66affSColin Finck 
1750c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "");
1751c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "");
1752c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1753c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1754c2c66affSColin Finck 
1755c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "1234");
1756c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "4");
1757c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1758c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1759c2c66affSColin Finck 
1760c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "one 1234");
1761c2c66affSColin Finck     MsiSetPropertyA(hpkg, "two", "4");
1762c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one >> two");
1763c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1764c2c66affSColin Finck 
1765c2c66affSColin Finck     MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL);  /* make sure it's empty */
1766c2c66affSColin Finck 
1767c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1768c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1769c2c66affSColin Finck 
1770c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1771c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1772c2c66affSColin Finck 
1773c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1774c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1775c2c66affSColin Finck 
1776c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1777c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1778c2c66affSColin Finck 
1779c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1780c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1781c2c66affSColin Finck 
1782c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1783c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1784c2c66affSColin Finck 
1785c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1786c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1787c2c66affSColin Finck 
1788c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1789c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1790c2c66affSColin Finck 
1791c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1792c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1793c2c66affSColin Finck 
1794c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1795c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1796c2c66affSColin Finck 
1797c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1798c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1799c2c66affSColin Finck 
1800c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1801c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1802c2c66affSColin Finck 
1803c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1804c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1805c2c66affSColin Finck 
1806c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1807c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1808c2c66affSColin Finck 
1809c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1810c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1811c2c66affSColin Finck 
1812c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1813c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1814c2c66affSColin Finck 
1815c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1816c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1817c2c66affSColin Finck 
1818c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1819c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1820c2c66affSColin Finck 
1821c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1822c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1823c2c66affSColin Finck 
1824c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1825c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1826c2c66affSColin Finck 
1827c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1828c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1829c2c66affSColin Finck 
1830c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1831c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1832c2c66affSColin Finck 
1833c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1834c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1835c2c66affSColin Finck 
1836c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1837c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1838c2c66affSColin Finck 
1839c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1840c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1841c2c66affSColin Finck 
1842c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1843c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1844c2c66affSColin Finck 
1845c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1846c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1847c2c66affSColin Finck 
1848c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1849c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1850c2c66affSColin Finck 
1851c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1852c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1853c2c66affSColin Finck 
1854c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1855c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1856c2c66affSColin Finck 
1857c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
1858c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1859c2c66affSColin Finck 
1860c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
1861c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1862c2c66affSColin Finck 
1863c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
1864c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1865c2c66affSColin Finck 
1866c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
1867c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1868c2c66affSColin Finck 
1869c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
1870c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1871c2c66affSColin Finck 
1872c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
1873c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1874c2c66affSColin Finck 
1875c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
1876c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1877c2c66affSColin Finck 
1878c2c66affSColin Finck     MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
1879c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1880c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1881c2c66affSColin Finck 
1882c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
1883c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1884c2c66affSColin Finck 
1885c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
1886c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1887c2c66affSColin Finck 
1888c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1889c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1890c2c66affSColin Finck 
1891c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1892c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1893c2c66affSColin Finck 
1894c2c66affSColin Finck     MsiSetPropertyA(hpkg, "one", "1");
1895c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
1896c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1897c2c66affSColin Finck 
1898c2c66affSColin Finck     MsiSetPropertyA(hpkg, "X", "5.0");
1899c2c66affSColin Finck 
1900c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X != \"\"");
1901c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1902c2c66affSColin Finck 
1903c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
1904c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1905c2c66affSColin Finck 
1906c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
1907c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1908c2c66affSColin Finck 
1909c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
1910c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1911c2c66affSColin Finck 
1912c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
1913c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1914c2c66affSColin Finck 
1915c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1916c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1917c2c66affSColin Finck 
1918c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1919c2c66affSColin Finck     ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1920c2c66affSColin Finck 
1921c2c66affSColin Finck     /* feature doesn't exist */
1922c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "&nofeature");
1923c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1924f860a780SAmine Khaldi     r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\"");
1925f860a780SAmine Khaldi     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1926331be612Swinesync     r = MsiEvaluateConditionA(hpkg, "&nofeature<>3");
1927331be612Swinesync     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1928331be612Swinesync     r = MsiEvaluateConditionA(hpkg, "\"\"<>3");
1929331be612Swinesync     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1930f860a780SAmine Khaldi     r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\"");
1931f860a780SAmine Khaldi     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1932f51751ddSwinesync     r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\"");
1933f860a780SAmine Khaldi     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1934f51751ddSwinesync     r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\"");
1935f860a780SAmine Khaldi     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1936c2c66affSColin Finck 
1937c2c66affSColin Finck     MsiSetPropertyA(hpkg, "A", "2");
1938c2c66affSColin Finck     MsiSetPropertyA(hpkg, "X", "50");
1939c2c66affSColin Finck 
1940c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "2 <= X");
1941c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1942c2c66affSColin Finck 
1943c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= X");
1944c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1945c2c66affSColin Finck 
1946c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= 50");
1947c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1948c2c66affSColin Finck 
1949c2c66affSColin Finck     MsiSetPropertyA(hpkg, "X", "50val");
1950c2c66affSColin Finck 
1951c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "2 <= X");
1952c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1953c2c66affSColin Finck 
1954c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= X");
1955c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1956c2c66affSColin Finck 
1957c2c66affSColin Finck     MsiSetPropertyA(hpkg, "A", "7");
1958c2c66affSColin Finck     MsiSetPropertyA(hpkg, "X", "50");
1959c2c66affSColin Finck 
1960c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "7 <= X");
1961c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1962c2c66affSColin Finck 
1963c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= X");
1964c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1965c2c66affSColin Finck 
1966c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= 50");
1967c2c66affSColin Finck     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1968c2c66affSColin Finck 
1969c2c66affSColin Finck     MsiSetPropertyA(hpkg, "X", "50val");
1970c2c66affSColin Finck 
1971c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "2 <= X");
1972c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1973c2c66affSColin Finck 
1974c2c66affSColin Finck     r = MsiEvaluateConditionA(hpkg, "A <= X");
1975c2c66affSColin Finck     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1976c2c66affSColin Finck 
1977f31e4044Swinesync     r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
1978*f4be6dc3SMikhail     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1979c2c66affSColin Finck 
1980f31e4044Swinesync     r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
1981*f4be6dc3SMikhail     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1982c2c66affSColin Finck 
1983f31e4044Swinesync     r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
1984*f4be6dc3SMikhail     ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1985c2c66affSColin Finck 
1986f31e4044Swinesync     r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
1987*f4be6dc3SMikhail     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1988c2c66affSColin Finck 
1989c2c66affSColin Finck     MsiCloseHandle( hpkg );
1990c2c66affSColin Finck     DeleteFileA(msifile);
1991c2c66affSColin Finck }
1992c2c66affSColin Finck 
check_prop(MSIHANDLE hpkg,const char * prop,const char * expect,int match_case,int todo_value)1993*f4be6dc3SMikhail static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value)
1994c2c66affSColin Finck {
19953ec0ea99Swinesync     char buffer[MAX_PATH] = "x";
1996c2000429Swinesync     DWORD sz = sizeof(buffer);
1997c2000429Swinesync     UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz);
1998c2000429Swinesync     ok(!r, "'%s': got %u\n", prop, r);
19991b4acd3cSwinesync     ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz);
2000461c9cb7Swinesync     if (match_case)
2001*f4be6dc3SMikhail         todo_wine_if (todo_value) ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2002461c9cb7Swinesync     else
2003*f4be6dc3SMikhail         todo_wine_if (todo_value) ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2004c2c66affSColin Finck }
2005c2c66affSColin Finck 
test_props(void)2006c2c66affSColin Finck static void test_props(void)
2007c2c66affSColin Finck {
2008c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
2009c2c66affSColin Finck     UINT r;
2010c2c66affSColin Finck     DWORD sz;
2011c2c66affSColin Finck     char buffer[0x100];
201266669aedSwinesync     WCHAR bufferW[10];
2013c2c66affSColin Finck 
2014c2c66affSColin Finck     hdb = create_package_db();
2015c2c66affSColin Finck 
2016f860a780SAmine Khaldi     create_property_table(hdb);
2017f860a780SAmine Khaldi     add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'");
2018c2c66affSColin Finck 
2019c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
2020c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2021c2c66affSColin Finck     {
2022c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
2023c2c66affSColin Finck         DeleteFileA(msifile);
2024c2c66affSColin Finck         return;
2025c2c66affSColin Finck     }
2026c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2027c2c66affSColin Finck 
2028c2c66affSColin Finck     /* test invalid values */
2029c2c66affSColin Finck     r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2030c2000429Swinesync     ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2031c2c66affSColin Finck 
2032c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2033c2000429Swinesync     ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2034c2c66affSColin Finck 
2035c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2036c2000429Swinesync     ok(!r, "got %u\n", r);
2037c2c66affSColin Finck 
2038c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2039c2000429Swinesync     ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2040c2c66affSColin Finck 
2041c2c66affSColin Finck     /* test retrieving an empty/nonexistent property */
2042c2c66affSColin Finck     sz = sizeof buffer;
2043c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2044c2000429Swinesync     ok(!r, "got %u\n", r);
20451b4acd3cSwinesync     ok(sz == 0, "got size %lu\n", sz);
2046c2c66affSColin Finck 
2047c2c66affSColin Finck     sz = 0;
2048c2c66affSColin Finck     strcpy(buffer,"x");
2049c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2050c2000429Swinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2051c2000429Swinesync     ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer);
20521b4acd3cSwinesync     ok(sz == 0, "got size %lu\n", sz);
2053c2c66affSColin Finck 
2054c2c66affSColin Finck     sz = 1;
2055c2c66affSColin Finck     strcpy(buffer,"x");
2056c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2057c2000429Swinesync     ok(!r, "got %u\n", r);
2058c2000429Swinesync     ok(!buffer[0], "got \"%s\"\n", buffer);
20591b4acd3cSwinesync     ok(sz == 0, "got size %lu\n", sz);
2060c2c66affSColin Finck 
2061c2c66affSColin Finck     /* set the property to something */
2062c2c66affSColin Finck     r = MsiSetPropertyA( 0, NULL, NULL );
2063c2000429Swinesync     ok(r == ERROR_INVALID_HANDLE, "got %u\n", r);
2064c2c66affSColin Finck 
2065c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, NULL, NULL );
2066c2000429Swinesync     ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2067c2c66affSColin Finck 
2068c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "", NULL );
2069c2000429Swinesync     ok(!r, "got %u\n", r);
2070c2c66affSColin Finck 
2071c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "", "asdf" );
2072c2000429Swinesync     ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
2073c2c66affSColin Finck 
2074c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "=", "asdf" );
2075c2000429Swinesync     ok(!r, "got %u\n", r);
2076*f4be6dc3SMikhail     check_prop(hpkg, "=", "asdf", 1, 0);
2077c2c66affSColin Finck 
2078c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, " ", "asdf" );
2079c2000429Swinesync     ok(!r, "got %u\n", r);
2080*f4be6dc3SMikhail     check_prop(hpkg, " ", "asdf", 1, 0);
2081c2c66affSColin Finck 
2082c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "'", "asdf" );
2083c2000429Swinesync     ok(!r, "got %u\n", r);
2084*f4be6dc3SMikhail     check_prop(hpkg, "'", "asdf", 1, 0);
2085c2c66affSColin Finck 
2086c2c66affSColin Finck     /* set empty values */
2087c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "boo", NULL );
2088c2000429Swinesync     ok(!r, "got %u\n", r);
2089*f4be6dc3SMikhail     check_prop(hpkg, "boo", "", 1, 0);
2090c2c66affSColin Finck 
2091c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "boo", "" );
2092c2000429Swinesync     ok(!r, "got %u\n", r);
2093*f4be6dc3SMikhail     check_prop(hpkg, "boo", "", 1, 0);
2094c2c66affSColin Finck 
2095c2c66affSColin Finck     /* set a non-empty value */
2096c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2097c2000429Swinesync     ok(!r, "got %u\n", r);
2098*f4be6dc3SMikhail     check_prop(hpkg, "boo", "xyz", 1, 0);
2099c2000429Swinesync 
2100c2000429Swinesync     r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
2101c2000429Swinesync     ok(!r, "got %u\n", r);
2102c2000429Swinesync 
2103c2000429Swinesync     r = MsiGetPropertyA(hpkg, "boo", buffer, NULL);
2104c2000429Swinesync     ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2105c2000429Swinesync 
2106c2000429Swinesync     sz = 0;
2107c2000429Swinesync     r = MsiGetPropertyA(hpkg, "boo", NULL, &sz);
2108c2000429Swinesync     ok(!r, "got %u\n", r);
21091b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
2110c2000429Swinesync 
2111c2000429Swinesync     sz = 0;
2112c2000429Swinesync     strcpy(buffer, "q");
2113c2000429Swinesync     r = MsiGetPropertyA(hpkg, "boo", buffer, &sz);
2114c2000429Swinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2115c2000429Swinesync     ok(!strcmp(buffer, "q"), "got \"%s\"", buffer);
21161b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
2117c2c66affSColin Finck 
2118c2c66affSColin Finck     sz = 1;
2119c2c66affSColin Finck     strcpy(buffer,"x");
2120c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2121c2000429Swinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2122c2000429Swinesync     ok(!buffer[0], "got \"%s\"\n", buffer);
21231b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
2124c2c66affSColin Finck 
2125c2c66affSColin Finck     sz = 3;
2126c2c66affSColin Finck     strcpy(buffer,"x");
2127c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2128c2000429Swinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2129c2000429Swinesync     ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer);
21301b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
2131c2c66affSColin Finck 
2132c2c66affSColin Finck     sz = 4;
2133c2000429Swinesync     strcpy(buffer,"x");
2134c2000429Swinesync     r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2135c2000429Swinesync     ok(!r, "got %u\n", r);
2136c2000429Swinesync     ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer);
21371b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
2138c2c66affSColin Finck 
213966669aedSwinesync     sz = 0;
2140f31e4044Swinesync     r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz);
214166669aedSwinesync     ok(!r, "got %u\n", r);
21421b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
214366669aedSwinesync 
214466669aedSwinesync     sz = 0;
2145f31e4044Swinesync     lstrcpyW(bufferW, L"boo");
2146f31e4044Swinesync     r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz);
214766669aedSwinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2148f31e4044Swinesync     ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW));
21491b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
215066669aedSwinesync 
215166669aedSwinesync     sz = 1;
2152f31e4044Swinesync     lstrcpyW(bufferW, L"boo");
2153f31e4044Swinesync     r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
215466669aedSwinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
215566669aedSwinesync     ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
21561b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
215766669aedSwinesync 
215866669aedSwinesync     sz = 3;
2159f31e4044Swinesync     lstrcpyW(bufferW, L"boo");
2160f31e4044Swinesync     r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
216166669aedSwinesync     ok(r == ERROR_MORE_DATA, "got %u\n", r);
2162f31e4044Swinesync     ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW));
21631b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
216466669aedSwinesync 
216566669aedSwinesync     sz = 4;
2166f31e4044Swinesync     lstrcpyW(bufferW, L"boo");
2167f31e4044Swinesync     r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
216866669aedSwinesync     ok(!r, "got %u\n", r);
2169f31e4044Swinesync     ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW));
21701b4acd3cSwinesync     ok(sz == 3, "got size %lu\n", sz);
217166669aedSwinesync 
2172c2000429Swinesync     /* properties are case-sensitive */
2173*f4be6dc3SMikhail     check_prop(hpkg, "BOO", "", 1, 0);
2174c2c66affSColin Finck 
2175c2000429Swinesync     /* properties set in Property table should work */
2176*f4be6dc3SMikhail     check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1, 0);
2177c2c66affSColin Finck 
2178c2c66affSColin Finck     MsiCloseHandle( hpkg );
2179c2c66affSColin Finck     DeleteFileA(msifile);
2180c2c66affSColin Finck }
2181c2c66affSColin Finck 
find_prop_in_property(MSIHANDLE hdb,LPCSTR prop,LPCSTR val,int len)2182c2c66affSColin Finck static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2183c2c66affSColin Finck {
2184c2c66affSColin Finck     MSIHANDLE hview, hrec;
2185c2c66affSColin Finck     BOOL found = FALSE;
2186c2c66affSColin Finck     CHAR buffer[MAX_PATH];
2187c2c66affSColin Finck     DWORD sz;
2188c2c66affSColin Finck     UINT r;
2189c2c66affSColin Finck 
2190c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2191c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2192c2c66affSColin Finck     r = MsiViewExecute(hview, 0);
2193c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2194c2c66affSColin Finck 
2195c2c66affSColin Finck     if (len < 0) len = lstrlenA(val);
2196c2c66affSColin Finck 
2197c2c66affSColin Finck     while (r == ERROR_SUCCESS && !found)
2198c2c66affSColin Finck     {
2199c2c66affSColin Finck         r = MsiViewFetch(hview, &hrec);
2200c2c66affSColin Finck         if (r != ERROR_SUCCESS) break;
2201c2c66affSColin Finck 
2202c2c66affSColin Finck         sz = MAX_PATH;
2203c2c66affSColin Finck         r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2204c2c66affSColin Finck         if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2205c2c66affSColin Finck         {
2206c2c66affSColin Finck             sz = MAX_PATH;
2207c2c66affSColin Finck             r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2208c2c66affSColin Finck             if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2209c2c66affSColin Finck             {
22101b4acd3cSwinesync                 ok(sz == len, "wrong size %lu\n", sz);
2211c2c66affSColin Finck                 found = TRUE;
2212c2c66affSColin Finck             }
2213c2c66affSColin Finck         }
2214c2c66affSColin Finck 
2215c2c66affSColin Finck         MsiCloseHandle(hrec);
2216c2c66affSColin Finck     }
2217c2c66affSColin Finck     MsiViewClose(hview);
2218c2c66affSColin Finck     MsiCloseHandle(hview);
2219c2c66affSColin Finck     return found;
2220c2c66affSColin Finck }
2221c2c66affSColin Finck 
test_property_table(void)2222c2c66affSColin Finck static void test_property_table(void)
2223c2c66affSColin Finck {
2224c2c66affSColin Finck     const char *query;
2225c2c66affSColin Finck     UINT r;
2226c2c66affSColin Finck     MSIHANDLE hpkg, hdb, hrec;
2227c2c66affSColin Finck     char buffer[MAX_PATH], package[10];
2228c2c66affSColin Finck     DWORD sz;
2229c2c66affSColin Finck     BOOL found;
2230c2c66affSColin Finck 
2231c2c66affSColin Finck     hdb = create_package_db();
2232c2c66affSColin Finck     ok( hdb, "failed to create package\n");
2233c2c66affSColin Finck 
2234c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
2235c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2236c2c66affSColin Finck     {
2237c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
2238c2c66affSColin Finck         DeleteFileA(msifile);
2239c2c66affSColin Finck         return;
2240c2c66affSColin Finck     }
2241c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2242c2c66affSColin Finck 
2243c2c66affSColin Finck     MsiCloseHandle(hdb);
2244c2c66affSColin Finck 
2245c2c66affSColin Finck     hdb = MsiGetActiveDatabase(hpkg);
2246c2c66affSColin Finck 
2247c2c66affSColin Finck     query = "CREATE TABLE `_Property` ( "
2248c2c66affSColin Finck         "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2249*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
2250c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2251c2c66affSColin Finck 
2252c2c66affSColin Finck     MsiCloseHandle(hdb);
2253c2c66affSColin Finck     MsiCloseHandle(hpkg);
2254c2c66affSColin Finck     DeleteFileA(msifile);
2255c2c66affSColin Finck 
2256c2c66affSColin Finck     hdb = create_package_db();
2257c2c66affSColin Finck     ok( hdb, "failed to create package\n");
2258c2c66affSColin Finck 
2259c2c66affSColin Finck     query = "CREATE TABLE `_Property` ( "
2260c2c66affSColin Finck         "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2261*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
2262c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create table\n");
2263c2c66affSColin Finck 
2264c2c66affSColin Finck     query = "ALTER `_Property` ADD `foo` INTEGER";
2265*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
2266c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2267c2c66affSColin Finck 
2268c2c66affSColin Finck     query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2269*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
2270c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2271c2c66affSColin Finck 
2272c2c66affSColin Finck     query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2273*f4be6dc3SMikhail     r = run_query(hdb, 0, query);
2274c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to add column\n");
2275c2c66affSColin Finck 
22761b4acd3cSwinesync     sprintf(package, "#%lu", hdb);
2277c2c66affSColin Finck     r = MsiOpenPackageA(package, &hpkg);
2278c2c66affSColin Finck     ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2279c2c66affSColin Finck     if (r == ERROR_SUCCESS)
2280c2c66affSColin Finck         MsiCloseHandle(hpkg);
2281c2c66affSColin Finck 
2282c2c66affSColin Finck     r = MsiCloseHandle(hdb);
2283c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2284c2c66affSColin Finck 
2285c2c66affSColin Finck     hdb = create_package_db();
2286c2c66affSColin Finck     ok (hdb, "failed to create package database\n");
2287c2c66affSColin Finck 
2288f860a780SAmine Khaldi     create_property_table(hdb);
2289f860a780SAmine Khaldi     add_property_entry(hdb, "'prop', 'val'");
2290c2c66affSColin Finck 
2291f860a780SAmine Khaldi     create_custom_action_table(hdb);
2292f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2293c2c66affSColin Finck 
2294c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
2295c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2296c2c66affSColin Finck 
2297c2c66affSColin Finck     MsiCloseHandle(hdb);
2298c2c66affSColin Finck 
2299c2c66affSColin Finck     sz = MAX_PATH;
2300c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2301c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2302c2c66affSColin Finck     ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2303c2c66affSColin Finck 
2304c2c66affSColin Finck     hdb = MsiGetActiveDatabase(hpkg);
2305c2c66affSColin Finck 
2306c2c66affSColin Finck     found = find_prop_in_property(hdb, "prop", "val", -1);
2307c2c66affSColin Finck     ok(found, "prop should be in the _Property table\n");
2308c2c66affSColin Finck 
2309f860a780SAmine Khaldi     add_property_entry(hdb, "'dantes', 'mercedes'");
2310c2c66affSColin Finck 
2311c2c66affSColin Finck     query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2312c2c66affSColin Finck     r = do_query(hdb, query, &hrec);
2313c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2314c2c66affSColin Finck 
2315c2c66affSColin Finck     found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2316c2c66affSColin Finck     ok(found == FALSE, "dantes should not be in the _Property table\n");
2317c2c66affSColin Finck 
2318c2c66affSColin Finck     sz = MAX_PATH;
2319c2c66affSColin Finck     lstrcpyA(buffer, "aaa");
2320c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2321c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2322c2c66affSColin Finck     ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2323c2c66affSColin Finck 
2324c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2325c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2326c2c66affSColin Finck 
2327c2c66affSColin Finck     found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2328c2c66affSColin Finck     ok(found == TRUE, "dantes should be in the _Property table\n");
2329c2c66affSColin Finck 
2330c2c66affSColin Finck     r = MsiDoActionA( hpkg, "EmbedNull" );
2331c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2332c2c66affSColin Finck 
2333c2c66affSColin Finck     sz = MAX_PATH;
2334c2c66affSColin Finck     memset( buffer, 'a', sizeof(buffer) );
2335c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2336c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2337c2c66affSColin Finck     ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
23381b4acd3cSwinesync     ok( sz == sizeof("\0np") - 1, "got %lu\n", sz );
2339c2c66affSColin Finck 
2340c2c66affSColin Finck     found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2341c2c66affSColin Finck     ok(found == TRUE, "prop2 should be in the _Property table\n");
2342c2c66affSColin Finck 
2343c2c66affSColin Finck     MsiCloseHandle(hdb);
2344c2c66affSColin Finck     MsiCloseHandle(hpkg);
2345c2c66affSColin Finck     DeleteFileA(msifile);
2346c2c66affSColin Finck }
2347c2c66affSColin Finck 
try_query_param(MSIHANDLE hdb,LPCSTR szQuery,MSIHANDLE hrec)2348c2c66affSColin Finck static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2349c2c66affSColin Finck {
2350c2c66affSColin Finck     MSIHANDLE htab = 0;
2351c2c66affSColin Finck     UINT res;
2352c2c66affSColin Finck 
2353c2c66affSColin Finck     res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2354c2c66affSColin Finck     if( res == ERROR_SUCCESS )
2355c2c66affSColin Finck     {
2356c2c66affSColin Finck         UINT r;
2357c2c66affSColin Finck 
2358c2c66affSColin Finck         r = MsiViewExecute( htab, hrec );
2359c2c66affSColin Finck         if( r != ERROR_SUCCESS )
2360c2c66affSColin Finck         {
2361c2c66affSColin Finck             res = r;
2362c2c66affSColin Finck             fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2363c2c66affSColin Finck         }
2364c2c66affSColin Finck 
2365c2c66affSColin Finck         r = MsiViewClose( htab );
2366c2c66affSColin Finck         if( r != ERROR_SUCCESS )
2367c2c66affSColin Finck             res = r;
2368c2c66affSColin Finck 
2369c2c66affSColin Finck         r = MsiCloseHandle( htab );
2370c2c66affSColin Finck         if( r != ERROR_SUCCESS )
2371c2c66affSColin Finck             res = r;
2372c2c66affSColin Finck     }
2373c2c66affSColin Finck     return res;
2374c2c66affSColin Finck }
2375c2c66affSColin Finck 
try_query(MSIHANDLE hdb,LPCSTR szQuery)2376c2c66affSColin Finck static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2377c2c66affSColin Finck {
2378c2c66affSColin Finck     return try_query_param( hdb, szQuery, 0 );
2379c2c66affSColin Finck }
2380c2c66affSColin Finck 
set_summary_str(MSIHANDLE hdb,DWORD pid,LPCSTR value)2381c2c66affSColin Finck static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2382c2c66affSColin Finck {
2383c2c66affSColin Finck     MSIHANDLE summary;
2384c2c66affSColin Finck     UINT r;
2385c2c66affSColin Finck 
2386c2c66affSColin Finck     r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2387c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2388c2c66affSColin Finck 
2389c2c66affSColin Finck     r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2390c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2391c2c66affSColin Finck 
2392c2c66affSColin Finck     r = MsiSummaryInfoPersist(summary);
2393c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2394c2c66affSColin Finck 
2395c2c66affSColin Finck     MsiCloseHandle(summary);
2396c2c66affSColin Finck }
2397c2c66affSColin Finck 
set_summary_dword(MSIHANDLE hdb,DWORD pid,DWORD value)2398c2c66affSColin Finck static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2399c2c66affSColin Finck {
2400c2c66affSColin Finck     MSIHANDLE summary;
2401c2c66affSColin Finck     UINT r;
2402c2c66affSColin Finck 
2403c2c66affSColin Finck     r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2404c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2405c2c66affSColin Finck 
2406c2c66affSColin Finck     r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2407c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2408c2c66affSColin Finck 
2409c2c66affSColin Finck     r = MsiSummaryInfoPersist(summary);
2410c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2411c2c66affSColin Finck 
2412c2c66affSColin Finck     MsiCloseHandle(summary);
2413c2c66affSColin Finck }
2414c2c66affSColin Finck 
test_msipackage(void)2415c2c66affSColin Finck static void test_msipackage(void)
2416c2c66affSColin Finck {
2417c2c66affSColin Finck     MSIHANDLE hdb = 0, hpack = 100;
2418c2c66affSColin Finck     UINT r;
2419c2c66affSColin Finck     const char *query;
2420c2c66affSColin Finck     char name[10];
2421c2c66affSColin Finck 
2422c2c66affSColin Finck     /* NULL szPackagePath */
2423c2c66affSColin Finck     r = MsiOpenPackageA(NULL, &hpack);
2424c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2425c2c66affSColin Finck 
2426c2c66affSColin Finck     /* empty szPackagePath */
2427c2c66affSColin Finck     r = MsiOpenPackageA("", &hpack);
2428c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2429c2c66affSColin Finck     {
2430c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
2431c2c66affSColin Finck         return;
2432c2c66affSColin Finck     }
2433c2c66affSColin Finck     todo_wine
2434c2c66affSColin Finck     {
2435c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2436c2c66affSColin Finck     }
2437c2c66affSColin Finck 
2438c2c66affSColin Finck     if (r == ERROR_SUCCESS)
2439c2c66affSColin Finck         MsiCloseHandle(hpack);
2440c2c66affSColin Finck 
2441c2c66affSColin Finck     /* nonexistent szPackagePath */
2442c2c66affSColin Finck     r = MsiOpenPackageA("nonexistent", &hpack);
2443c2c66affSColin Finck     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2444c2c66affSColin Finck 
2445c2c66affSColin Finck     /* NULL hProduct */
2446c2c66affSColin Finck     r = MsiOpenPackageA(msifile, NULL);
2447c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2448c2c66affSColin Finck 
2449c2c66affSColin Finck     name[0]='#';
2450c2c66affSColin Finck     name[1]=0;
2451c2c66affSColin Finck     r = MsiOpenPackageA(name, &hpack);
2452c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2453c2c66affSColin Finck 
2454c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2455c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2456c2c66affSColin Finck 
2457c2c66affSColin Finck     /* database exists, but is empty */
24581b4acd3cSwinesync     sprintf(name, "#%lu", hdb);
2459c2c66affSColin Finck     r = MsiOpenPackageA(name, &hpack);
2460c2c66affSColin Finck     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2461c2c66affSColin Finck        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2462c2c66affSColin Finck 
2463c2c66affSColin Finck     query = "CREATE TABLE `Property` ( "
2464c2c66affSColin Finck             "`Property` CHAR(72), `Value` CHAR(0) "
2465c2c66affSColin Finck             "PRIMARY KEY `Property`)";
2466c2c66affSColin Finck     r = try_query(hdb, query);
2467c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2468c2c66affSColin Finck 
2469c2c66affSColin Finck     query = "CREATE TABLE `InstallExecuteSequence` ("
2470c2c66affSColin Finck             "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2471c2c66affSColin Finck             "PRIMARY KEY `Action`)";
2472c2c66affSColin Finck     r = try_query(hdb, query);
2473c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2474c2c66affSColin Finck 
2475c2c66affSColin Finck     /* a few key tables exist */
24761b4acd3cSwinesync     sprintf(name, "#%lu", hdb);
2477c2c66affSColin Finck     r = MsiOpenPackageA(name, &hpack);
2478c2c66affSColin Finck     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2479c2c66affSColin Finck        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2480c2c66affSColin Finck 
2481c2c66affSColin Finck     MsiCloseHandle(hdb);
2482c2c66affSColin Finck     DeleteFileA(msifile);
2483c2c66affSColin Finck 
2484c2c66affSColin Finck     /* start with a clean database to show what constitutes a valid package */
2485c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2486c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2487c2c66affSColin Finck 
24881b4acd3cSwinesync     sprintf(name, "#%lu", hdb);
2489c2c66affSColin Finck 
2490c2c66affSColin Finck     /* The following summary information props must exist:
2491c2c66affSColin Finck      *  - PID_REVNUMBER
2492c2c66affSColin Finck      *  - PID_PAGECOUNT
2493c2c66affSColin Finck      */
2494c2c66affSColin Finck 
2495c2c66affSColin Finck     set_summary_dword(hdb, PID_PAGECOUNT, 100);
2496c2c66affSColin Finck     r = MsiOpenPackageA(name, &hpack);
2497c2c66affSColin Finck     ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2498c2c66affSColin Finck        "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2499c2c66affSColin Finck 
2500c2c66affSColin Finck     set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2501c2c66affSColin Finck     r = MsiOpenPackageA(name, &hpack);
2502c2c66affSColin Finck     ok(r == ERROR_SUCCESS,
2503c2c66affSColin Finck        "Expected ERROR_SUCCESS, got %d\n", r);
2504c2c66affSColin Finck 
2505c2c66affSColin Finck     MsiCloseHandle(hpack);
2506c2c66affSColin Finck     MsiCloseHandle(hdb);
2507c2c66affSColin Finck     DeleteFileA(msifile);
2508c2c66affSColin Finck }
2509c2c66affSColin Finck 
test_formatrecord2(void)2510c2c66affSColin Finck static void test_formatrecord2(void)
2511c2c66affSColin Finck {
2512c2c66affSColin Finck     MSIHANDLE hpkg, hrec ;
2513c2c66affSColin Finck     char buffer[0x100];
2514c2c66affSColin Finck     DWORD sz;
2515c2c66affSColin Finck     UINT r;
2516c2c66affSColin Finck 
2517c2c66affSColin Finck     r = package_from_db(create_package_db(), &hpkg);
2518c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2519c2c66affSColin Finck     {
2520c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
2521c2c66affSColin Finck         DeleteFileA(msifile);
2522c2c66affSColin Finck         return;
2523c2c66affSColin Finck     }
2524c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2525c2c66affSColin Finck 
2526c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2527c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "set property failed\n");
2528c2c66affSColin Finck 
2529c2c66affSColin Finck     hrec = MsiCreateRecord(2);
2530c2c66affSColin Finck     ok(hrec, "create record failed\n");
2531c2c66affSColin Finck 
2532c2c66affSColin Finck     r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2533c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format record failed\n");
2534c2c66affSColin Finck 
2535c2c66affSColin Finck     buffer[0] = 0;
2536c2c66affSColin Finck     sz = sizeof buffer;
2537c2c66affSColin Finck     r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2538c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2539c2c66affSColin Finck 
2540c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2541c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2542c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 1, "hoo");
2543c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2544c2c66affSColin Finck     sz = sizeof buffer;
2545c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2546c2c66affSColin Finck     ok( sz == 3, "size wrong\n");
2547c2c66affSColin Finck     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2548c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2549c2c66affSColin Finck 
2550c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2551c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2552c2c66affSColin Finck     sz = sizeof buffer;
2553c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2554c2c66affSColin Finck     ok( sz == 3, "size wrong\n");
2555c2c66affSColin Finck     ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2556c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2557c2c66affSColin Finck 
2558c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2559c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2560c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 1, "hoo");
2561c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2562c2c66affSColin Finck     sz = sizeof buffer;
2563c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2564c2c66affSColin Finck     ok( sz == 3, "size wrong\n");
2565c2c66affSColin Finck     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2566c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2567c2c66affSColin Finck 
2568c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2569c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2570c2c66affSColin Finck     sz = sizeof buffer;
2571c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2572c2c66affSColin Finck     ok( sz == 1, "size wrong\n");
2573c2c66affSColin Finck     ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2574c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2575c2c66affSColin Finck 
2576c2c66affSColin Finck     SetEnvironmentVariableA("FOO", "BAR");
2577c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2578c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2579c2c66affSColin Finck     sz = sizeof buffer;
2580c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2581c2c66affSColin Finck     ok( sz == 3, "size wrong\n");
2582c2c66affSColin Finck     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2583c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2584c2c66affSColin Finck 
2585c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2586c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2587c2c66affSColin Finck     r = MsiRecordSetStringA(hrec, 1, "%FOO");
2588c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2589c2c66affSColin Finck     sz = sizeof buffer;
2590c2c66affSColin Finck     r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2591c2c66affSColin Finck     ok( sz == 3, "size wrong\n");
2592c2c66affSColin Finck     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2593c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "format failed\n");
2594c2c66affSColin Finck 
2595c2c66affSColin Finck     MsiCloseHandle( hrec );
2596c2c66affSColin Finck     MsiCloseHandle( hpkg );
2597c2c66affSColin Finck     DeleteFileA(msifile);
2598c2c66affSColin Finck }
2599c2c66affSColin Finck 
test_formatrecord_tables(void)2600f860a780SAmine Khaldi static void test_formatrecord_tables(void)
2601f860a780SAmine Khaldi {
2602f860a780SAmine Khaldi     MSIHANDLE hdb, hrec, hpkg = 0;
2603484e8280Swinesync     CHAR buf[MAX_PATH + 41];
2604f860a780SAmine Khaldi     CHAR curr_dir[MAX_PATH];
2605484e8280Swinesync     CHAR expected[MAX_PATH + 45];
2606f860a780SAmine Khaldi     CHAR root[MAX_PATH];
2607f860a780SAmine Khaldi     DWORD size;
2608f860a780SAmine Khaldi     UINT r;
2609f860a780SAmine Khaldi 
2610f860a780SAmine Khaldi     GetCurrentDirectoryA( MAX_PATH, curr_dir );
2611f860a780SAmine Khaldi 
2612f860a780SAmine Khaldi     hdb = create_package_db();
2613f860a780SAmine Khaldi     ok ( hdb, "failed to create package database\n");
2614f860a780SAmine Khaldi 
2615f860a780SAmine Khaldi     add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2616f860a780SAmine Khaldi     add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2617f860a780SAmine Khaldi                              "'I am a really long directory'" );
2618f860a780SAmine Khaldi 
2619f860a780SAmine Khaldi     create_feature_table( hdb );
2620f860a780SAmine Khaldi     add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2621f860a780SAmine Khaldi 
2622f860a780SAmine Khaldi     create_component_table( hdb );
2623f860a780SAmine Khaldi     add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2624f860a780SAmine Khaldi     add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2625f860a780SAmine Khaldi     add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2626f860a780SAmine Khaldi 
2627f860a780SAmine Khaldi     create_feature_components_table( hdb );
2628f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2629f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2630f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2631f860a780SAmine Khaldi 
2632f860a780SAmine Khaldi     create_file_table( hdb );
2633f860a780SAmine Khaldi     add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2634f860a780SAmine Khaldi     add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2635f860a780SAmine Khaldi     add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2636f860a780SAmine Khaldi 
2637f860a780SAmine Khaldi     create_custom_action_table( hdb );
2638f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2639f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2640f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2641f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2642f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2643f860a780SAmine Khaldi 
2644f860a780SAmine Khaldi     r = package_from_db( hdb, &hpkg );
2645f860a780SAmine Khaldi     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2646f860a780SAmine Khaldi     {
2647f860a780SAmine Khaldi         skip("Not enough rights to perform tests\n");
2648f860a780SAmine Khaldi         MsiCloseHandle( hdb );
2649f860a780SAmine Khaldi         DeleteFileA( msifile );
2650f860a780SAmine Khaldi         return;
2651f860a780SAmine Khaldi     }
2652f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2653f860a780SAmine Khaldi 
2654f860a780SAmine Khaldi     MsiCloseHandle( hdb );
2655f860a780SAmine Khaldi 
2656f860a780SAmine Khaldi     r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2657f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2658f860a780SAmine Khaldi 
2659f860a780SAmine Khaldi     hrec = MsiCreateRecord( 1 );
2660f860a780SAmine Khaldi 
2661f860a780SAmine Khaldi     /* property doesn't exist */
2662f860a780SAmine Khaldi     size = MAX_PATH;
2663f860a780SAmine Khaldi     /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2664f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[idontexist]" );
2665f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2666f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2667f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2668f860a780SAmine Khaldi 
2669f860a780SAmine Khaldi     /* property exists */
2670f860a780SAmine Khaldi     size = MAX_PATH;
2671f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[imaprop]" );
2672f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2673f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2674f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2675f860a780SAmine Khaldi 
2676f860a780SAmine Khaldi     size = MAX_PATH;
2677f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 0, "1: [1] " );
2678f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2679f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2680f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2681f860a780SAmine Khaldi 
2682f860a780SAmine Khaldi     /* environment variable doesn't exist */
2683f860a780SAmine Khaldi     size = MAX_PATH;
2684f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[%idontexist]" );
2685f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2686f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2687f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2688f860a780SAmine Khaldi 
2689f860a780SAmine Khaldi     /* environment variable exists */
2690f860a780SAmine Khaldi     size = MAX_PATH;
2691f860a780SAmine Khaldi     SetEnvironmentVariableA( "crazyvar", "crazyval" );
2692f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[%crazyvar]" );
2693f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2694f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2695f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2696f860a780SAmine Khaldi 
2697f860a780SAmine Khaldi     /* file key before CostInitialize */
2698f860a780SAmine Khaldi     size = MAX_PATH;
2699f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2700f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2701f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2702f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2703f860a780SAmine Khaldi 
2704f860a780SAmine Khaldi     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2705f860a780SAmine Khaldi 
2706f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "CostInitialize");
2707f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2708f860a780SAmine Khaldi 
2709f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "FileCost");
2710f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2711f860a780SAmine Khaldi 
2712f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "CostFinalize");
2713f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2714f860a780SAmine Khaldi 
2715f860a780SAmine Khaldi     size = MAX_PATH;
2716f860a780SAmine Khaldi     MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size );
2717f860a780SAmine Khaldi 
2718f860a780SAmine Khaldi     sprintf( expected, "1: %sfrontal.txt ", root);
2719f860a780SAmine Khaldi 
2720f860a780SAmine Khaldi     /* frontal full file key */
2721f860a780SAmine Khaldi     size = MAX_PATH;
2722f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2723f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2724f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2725f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2726f860a780SAmine Khaldi 
2727f860a780SAmine Khaldi     /* frontal short file key */
2728f860a780SAmine Khaldi     size = MAX_PATH;
2729f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[!frontal_file]" );
2730f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2731f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2732f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2733f860a780SAmine Khaldi 
2734f860a780SAmine Khaldi     sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2735f860a780SAmine Khaldi 
2736f860a780SAmine Khaldi     /* temporal full file key */
2737f860a780SAmine Khaldi     size = MAX_PATH;
2738f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[#temporal_file]" );
2739f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2740f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2741f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2742f860a780SAmine Khaldi 
2743f860a780SAmine Khaldi     /* temporal short file key */
2744f860a780SAmine Khaldi     size = MAX_PATH;
2745f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[!temporal_file]" );
2746f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2747f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2748f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2749f860a780SAmine Khaldi 
2750f860a780SAmine Khaldi     /* custom action 51, files don't exist */
2751f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "MyCustom" );
2752f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2753f860a780SAmine Khaldi 
2754f860a780SAmine Khaldi     sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2755f860a780SAmine Khaldi 
2756f860a780SAmine Khaldi     size = MAX_PATH;
2757f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2758f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2759f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2760f860a780SAmine Khaldi 
2761f860a780SAmine Khaldi     sprintf( buf, "%sI am a really long directory", root );
2762f860a780SAmine Khaldi     CreateDirectoryA( buf, NULL );
2763f860a780SAmine Khaldi 
2764f860a780SAmine Khaldi     lstrcatA( buf, "\\temporal.txt" );
2765f860a780SAmine Khaldi     create_test_file( buf );
2766f860a780SAmine Khaldi 
2767f860a780SAmine Khaldi     /* custom action 51, files exist */
2768f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "MyCustom" );
2769f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2770f860a780SAmine Khaldi 
2771f860a780SAmine Khaldi     size = MAX_PATH;
2772f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2773f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2774f860a780SAmine Khaldi     todo_wine
2775f860a780SAmine Khaldi     {
2776f860a780SAmine Khaldi         ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2777f860a780SAmine Khaldi     }
2778f860a780SAmine Khaldi 
2779f860a780SAmine Khaldi     /* custom action 51, escaped text 1 */
2780f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "EscapeIt1" );
2781f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2782f860a780SAmine Khaldi 
2783f860a780SAmine Khaldi     size = MAX_PATH;
2784f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2785f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2786f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2787f860a780SAmine Khaldi 
2788f860a780SAmine Khaldi     /* custom action 51, escaped text 2 */
2789f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "EscapeIt2" );
2790f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2791f860a780SAmine Khaldi 
2792f860a780SAmine Khaldi     size = MAX_PATH;
2793f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2794f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2795f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf);
2796f860a780SAmine Khaldi 
2797f860a780SAmine Khaldi     /* custom action 51, escaped text 3 */
2798f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "EscapeIt3" );
2799f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2800f860a780SAmine Khaldi 
2801f860a780SAmine Khaldi     size = MAX_PATH;
2802f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2803f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2804f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf);
2805f860a780SAmine Khaldi 
2806f860a780SAmine Khaldi     /* custom action 51, embedded null */
2807f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "EmbedNull" );
2808f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2809f860a780SAmine Khaldi 
2810f860a780SAmine Khaldi     size = MAX_PATH;
2811f860a780SAmine Khaldi     memset( buf, 'a', sizeof(buf) );
2812f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2813f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2814f860a780SAmine Khaldi     ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
28151b4acd3cSwinesync     ok( size == sizeof("\0np") - 1, "got %lu\n", size );
2816f860a780SAmine Khaldi 
2817f860a780SAmine Khaldi     r = MsiSetPropertyA( hpkg, "prop", "[~]np" );
2818f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2819f860a780SAmine Khaldi 
2820f860a780SAmine Khaldi     size = MAX_PATH;
2821f860a780SAmine Khaldi     memset( buf, 'a', sizeof(buf) );
2822f860a780SAmine Khaldi     r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2823f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2824f860a780SAmine Khaldi     ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2825f860a780SAmine Khaldi 
2826f860a780SAmine Khaldi     sprintf( expected, "1: %sI am a really long directory\\ ", root);
2827f860a780SAmine Khaldi 
2828f860a780SAmine Khaldi     /* component with INSTALLSTATE_LOCAL */
2829f860a780SAmine Khaldi     size = MAX_PATH;
2830f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[$temporal]" );
2831f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2832f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2833f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2834f860a780SAmine Khaldi 
2835f860a780SAmine Khaldi     r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE );
2836f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2837f860a780SAmine Khaldi 
2838f860a780SAmine Khaldi     /* component with INSTALLSTATE_SOURCE */
2839f860a780SAmine Khaldi     lstrcpyA( expected, "1: " );
2840f860a780SAmine Khaldi     lstrcatA( expected, curr_dir );
2841f860a780SAmine Khaldi     if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" );
2842f860a780SAmine Khaldi     lstrcatA( expected, " " );
2843f860a780SAmine Khaldi     size = MAX_PATH;
2844f860a780SAmine Khaldi     MsiRecordSetStringA( hrec, 1, "[$parietal]" );
2845f860a780SAmine Khaldi     r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2846f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2847f860a780SAmine Khaldi     ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2848f860a780SAmine Khaldi 
2849f860a780SAmine Khaldi     sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2850f860a780SAmine Khaldi     DeleteFileA( buf );
2851f860a780SAmine Khaldi 
2852f860a780SAmine Khaldi     sprintf( buf, "%sI am a really long directory", root );
2853f860a780SAmine Khaldi     RemoveDirectoryA( buf );
2854f860a780SAmine Khaldi 
2855f860a780SAmine Khaldi     MsiCloseHandle( hrec );
2856f860a780SAmine Khaldi     MsiCloseHandle( hpkg );
2857f860a780SAmine Khaldi     DeleteFileA( msifile );
2858f860a780SAmine Khaldi }
2859f860a780SAmine Khaldi 
test_feature_states(UINT line,MSIHANDLE package,const char * feature,UINT error,INSTALLSTATE expected_state,INSTALLSTATE expected_action,BOOL todo)2860c2c66affSColin Finck static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
2861c2c66affSColin Finck                                  INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2862c2c66affSColin Finck {
2863c2c66affSColin Finck     UINT r;
2864c2c66affSColin Finck     INSTALLSTATE state = 0xdeadbee;
2865c2c66affSColin Finck     INSTALLSTATE action = 0xdeadbee;
2866c2c66affSColin Finck 
2867c2c66affSColin Finck     r = MsiGetFeatureStateA( package, feature, &state, &action );
2868c2c66affSColin Finck     ok( r == error, "%u: expected %d got %d\n", line, error, r );
2869c2c66affSColin Finck     if (r == ERROR_SUCCESS)
2870c2c66affSColin Finck     {
2871c2c66affSColin Finck         ok( state == expected_state, "%u: expected state %d got %d\n",
2872c2c66affSColin Finck             line, expected_state, state );
2873c2c66affSColin Finck         todo_wine_if (todo)
2874c2c66affSColin Finck             ok( action == expected_action, "%u: expected action %d got %d\n",
2875c2c66affSColin Finck                 line, expected_action, action );
2876c2c66affSColin Finck     }
2877c2c66affSColin Finck     else
2878c2c66affSColin Finck     {
2879c2c66affSColin Finck         ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
2880c2c66affSColin Finck         todo_wine_if (todo)
2881c2c66affSColin Finck             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2882c2c66affSColin Finck 
2883c2c66affSColin Finck     }
2884c2c66affSColin Finck }
2885c2c66affSColin Finck 
test_component_states(UINT line,MSIHANDLE package,const char * component,UINT error,INSTALLSTATE expected_state,INSTALLSTATE expected_action,BOOL todo)2886c2c66affSColin Finck static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
2887c2c66affSColin Finck                                    INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2888c2c66affSColin Finck {
2889c2c66affSColin Finck     UINT r;
2890c2c66affSColin Finck     INSTALLSTATE state = 0xdeadbee;
2891c2c66affSColin Finck     INSTALLSTATE action = 0xdeadbee;
2892c2c66affSColin Finck 
2893c2c66affSColin Finck     r = MsiGetComponentStateA( package, component, &state, &action );
2894c2c66affSColin Finck     ok( r == error, "%u: expected %d got %d\n", line, error, r );
2895c2c66affSColin Finck     if (r == ERROR_SUCCESS)
2896c2c66affSColin Finck     {
2897c2c66affSColin Finck         ok( state == expected_state, "%u: expected state %d got %d\n",
2898c2c66affSColin Finck             line, expected_state, state );
2899c2c66affSColin Finck         todo_wine_if (todo)
2900c2c66affSColin Finck             ok( action == expected_action, "%u: expected action %d got %d\n",
2901c2c66affSColin Finck                 line, expected_action, action );
2902c2c66affSColin Finck     }
2903c2c66affSColin Finck     else
2904c2c66affSColin Finck     {
2905c2c66affSColin Finck         ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2906c2c66affSColin Finck             line, state );
2907c2c66affSColin Finck         todo_wine_if (todo)
2908c2c66affSColin Finck             ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2909c2c66affSColin Finck                 line, action );
2910c2c66affSColin Finck     }
2911c2c66affSColin Finck }
2912c2c66affSColin Finck 
test_states(void)2913c2c66affSColin Finck static void test_states(void)
2914c2c66affSColin Finck {
2915c2c66affSColin Finck     static const char msifile2[] = "winetest2-package.msi";
2916c2c66affSColin Finck     static const char msifile3[] = "winetest3-package.msi";
2917c2c66affSColin Finck     static const char msifile4[] = "winetest4-package.msi";
2918f31e4044Swinesync     static const WCHAR msifile2W[] = L"winetest2-package.msi";
2919f31e4044Swinesync     static const WCHAR msifile3W[] = L"winetest3-package.msi";
2920f31e4044Swinesync     static const WCHAR msifile4W[] = L"winetest4-package.msi";
2921f860a780SAmine Khaldi     char msi_cache_file[MAX_PATH];
2922f860a780SAmine Khaldi     DWORD cache_file_name_len;
2923c2c66affSColin Finck     INSTALLSTATE state;
292496486643Swinesync     MSIHANDLE hpkg, hprod;
2925c2c66affSColin Finck     UINT r;
2926c2c66affSColin Finck     MSIHANDLE hdb;
292796486643Swinesync     char value[MAX_PATH];
292896486643Swinesync     DWORD size;
2929c2c66affSColin Finck 
2930*f4be6dc3SMikhail     if (!is_process_elevated())
2931c2c66affSColin Finck     {
2932c2c66affSColin Finck         skip("process is limited\n");
2933c2c66affSColin Finck         return;
2934c2c66affSColin Finck     }
2935c2c66affSColin Finck 
2936c2c66affSColin Finck     hdb = create_package_db();
2937c2c66affSColin Finck     ok ( hdb, "failed to create package database\n" );
2938c2c66affSColin Finck 
2939f860a780SAmine Khaldi     add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2940c2c66affSColin Finck 
2941f860a780SAmine Khaldi     create_property_table( hdb );
2942f860a780SAmine Khaldi     add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2943f860a780SAmine Khaldi     add_property_entry( hdb, "'ProductLanguage', '1033'" );
2944f860a780SAmine Khaldi     add_property_entry( hdb, "'ProductName', 'MSITEST'" );
2945f860a780SAmine Khaldi     add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
2946f860a780SAmine Khaldi     add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
294796486643Swinesync     add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
2948c2c66affSColin Finck 
2949f860a780SAmine Khaldi     create_install_execute_sequence_table( hdb );
2950f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
2951f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
2952f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
2953f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
2954f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
2955f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
2956f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
2957f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
2958f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
2959f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
2960f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
2961c2c66affSColin Finck 
2962f860a780SAmine Khaldi     create_media_table( hdb );
2963f860a780SAmine Khaldi     add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
2964c2c66affSColin Finck 
2965f860a780SAmine Khaldi     create_feature_table( hdb );
2966c2c66affSColin Finck 
2967f860a780SAmine Khaldi     create_component_table( hdb );
2968c2c66affSColin Finck 
2969c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal */
2970f860a780SAmine Khaldi     add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2971c2c66affSColin Finck 
2972c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2973f860a780SAmine Khaldi     add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
2974c2c66affSColin Finck 
2975c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2976f860a780SAmine Khaldi     add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
2977c2c66affSColin Finck 
2978c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2979f860a780SAmine Khaldi     add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
2980c2c66affSColin Finck 
2981c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
2982f860a780SAmine Khaldi     add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
2983c2c66affSColin Finck 
2984c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource */
2985f860a780SAmine Khaldi     add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
2986c2c66affSColin Finck 
2987c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2988f860a780SAmine Khaldi     add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
2989c2c66affSColin Finck 
2990c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2991f860a780SAmine Khaldi     add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
2992c2c66affSColin Finck 
2993c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2994f860a780SAmine Khaldi     add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
2995c2c66affSColin Finck 
2996c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
2997f860a780SAmine Khaldi     add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
2998c2c66affSColin Finck 
2999c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource */
3000f860a780SAmine Khaldi     add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
3001c2c66affSColin Finck 
3002c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal */
3003f860a780SAmine Khaldi     add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
3004c2c66affSColin Finck 
3005c2c66affSColin Finck     /* disabled */
3006f860a780SAmine Khaldi     add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
3007c2c66affSColin Finck 
3008c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3009f860a780SAmine Khaldi     add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3010c2c66affSColin Finck 
3011c2c66affSColin Finck     /* no feature parent:msidbComponentAttributesLocalOnly */
3012f860a780SAmine Khaldi     add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3013c2c66affSColin Finck 
3014c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:removed */
3015f860a780SAmine Khaldi     add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
3016c2c66affSColin Finck 
3017c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3018f860a780SAmine Khaldi     add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3019c2c66affSColin Finck 
3020c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3021f860a780SAmine Khaldi     add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3022c2c66affSColin Finck 
3023c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3024f860a780SAmine Khaldi     add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3025c2c66affSColin Finck 
3026c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3027f860a780SAmine Khaldi     add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3028c2c66affSColin Finck 
3029c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:removed */
3030f860a780SAmine Khaldi     add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
3031c2c66affSColin Finck 
3032c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3033f860a780SAmine Khaldi     add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3034c2c66affSColin Finck 
3035c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3036f860a780SAmine Khaldi     add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3037c2c66affSColin Finck 
3038c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3039f860a780SAmine Khaldi     add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3040c2c66affSColin Finck 
3041c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3042f860a780SAmine Khaldi     add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3043c2c66affSColin Finck 
3044c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal */
3045f860a780SAmine Khaldi     add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
3046c2c66affSColin Finck 
3047f860a780SAmine Khaldi     add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3048c2c66affSColin Finck 
3049c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource */
3050f860a780SAmine Khaldi     add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
3051c2c66affSColin Finck 
3052f860a780SAmine Khaldi     add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3053c2c66affSColin Finck 
3054c2c66affSColin Finck     /* msidbFeatureAttributesFavorAdvertise */
3055f860a780SAmine Khaldi     add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
3056c2c66affSColin Finck 
3057f860a780SAmine Khaldi     add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3058c2c66affSColin Finck 
3059c2c66affSColin Finck     /* msidbFeatureAttributesUIDisallowAbsent */
3060f860a780SAmine Khaldi     add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
3061c2c66affSColin Finck 
3062f860a780SAmine Khaldi     add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3063c2c66affSColin Finck 
3064c2c66affSColin Finck     /* high install level */
3065f860a780SAmine Khaldi     add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
3066c2c66affSColin Finck 
3067f860a780SAmine Khaldi     add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3068c2c66affSColin Finck 
3069c2c66affSColin Finck     /* msidbFeatureAttributesFollowParent */
3070f860a780SAmine Khaldi     add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
3071c2c66affSColin Finck 
3072f860a780SAmine Khaldi     create_feature_components_table( hdb );
3073f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'alpha'" );
3074f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'beta'" );
3075f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'gamma'" );
3076f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'theta'" );
3077f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'two', 'delta'" );
3078f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'two', 'epsilon'" );
3079f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'two', 'zeta'" );
3080f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'two', 'iota'" );
3081f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'three', 'eta'" );
3082f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'four', 'eta'" );
3083f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'five', 'eta'" );
3084f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'six', 'lambda'" );
3085f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'six', 'mu'" );
3086f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'six', 'nu'" );
3087f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'six', 'xi'" );
3088f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'seven', 'omicron'" );
3089f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'seven', 'pi'" );
3090f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'seven', 'rho'" );
3091f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'seven', 'sigma'" );
3092f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'eight', 'tau'" );
3093f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'nine', 'phi'" );
3094f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'ten', 'chi'" );
3095f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'eleven', 'psi'" );
3096f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3097f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3098c2c66affSColin Finck 
3099f860a780SAmine Khaldi     create_file_table( hdb );
3100f860a780SAmine Khaldi     add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3101f860a780SAmine Khaldi     add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3102f860a780SAmine Khaldi     add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3103f860a780SAmine Khaldi     add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3104f860a780SAmine Khaldi     add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3105f860a780SAmine Khaldi     add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3106f860a780SAmine Khaldi     add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3107f860a780SAmine Khaldi     add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3108c2c66affSColin Finck 
3109c2c66affSColin Finck     /* compressed file */
3110f860a780SAmine Khaldi     add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3111c2c66affSColin Finck 
3112f860a780SAmine Khaldi     add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3113f860a780SAmine Khaldi     add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3114f860a780SAmine Khaldi     add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3115f860a780SAmine Khaldi     add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3116f860a780SAmine Khaldi     add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3117f860a780SAmine Khaldi     add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3118f860a780SAmine Khaldi     add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3119f860a780SAmine Khaldi     add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3120f860a780SAmine Khaldi     add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3121f860a780SAmine Khaldi     add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3122f860a780SAmine Khaldi     add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3123f860a780SAmine Khaldi     add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3124f860a780SAmine Khaldi     add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3125f860a780SAmine Khaldi     add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3126c2c66affSColin Finck 
3127f860a780SAmine Khaldi     r = MsiDatabaseCommit(hdb);
3128f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
3129c2c66affSColin Finck 
3130c2c66affSColin Finck     /* these properties must not be in the saved msi file */
3131f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3132f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3133f860a780SAmine Khaldi     add_property_entry( hdb, "'REMOVE', 'six,seven'");
3134f860a780SAmine Khaldi     add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3135f860a780SAmine Khaldi     add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3136c2c66affSColin Finck 
3137c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3138c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3139c2c66affSColin Finck     {
3140c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
3141c2c66affSColin Finck         DeleteFileA(msifile);
3142c2c66affSColin Finck         return;
3143c2c66affSColin Finck     }
3144c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3145c2c66affSColin Finck 
3146c2c66affSColin Finck     MsiCloseHandle(hdb);
3147c2c66affSColin Finck 
3148c2c66affSColin Finck     CopyFileA(msifile, msifile2, FALSE);
3149c2c66affSColin Finck     CopyFileA(msifile, msifile3, FALSE);
3150c2c66affSColin Finck     CopyFileA(msifile, msifile4, FALSE);
3151c2c66affSColin Finck 
3152fbdb719bSwinesync     size = sizeof(value);
3153fbdb719bSwinesync     memset(value, 0, sizeof(value));
3154fbdb719bSwinesync     r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3155fbdb719bSwinesync     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3156fbdb719bSwinesync     ok(!value[0], "ProductToBeRegistered = %s\n", value);
3157fbdb719bSwinesync 
3158c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3159c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3160c2c66affSColin Finck 
3161c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3162c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3163c2c66affSColin Finck 
3164c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3165c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3166c2c66affSColin Finck 
3167c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3168c2c66affSColin Finck 
3169c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
3170c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
3171c2c66affSColin Finck 
3172c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3173c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3174c2c66affSColin Finck 
3175c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3176c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3177c2c66affSColin Finck 
3178c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3179c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3180c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3181c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3182c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3183c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3184c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3185c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3186c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3187c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3188c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3189c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3190c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3191c2c66affSColin Finck 
3192c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3193c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3194c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3195c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3196c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3197c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3198c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3199c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3200c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3201c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3202c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3203c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3204c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3205c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3206c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3207c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3208c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3209c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3210c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3211c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3212c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3213c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3214c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3215c2c66affSColin Finck 
3216c2c66affSColin Finck     MsiCloseHandle( hpkg );
3217c2c66affSColin Finck 
3218c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3219c2c66affSColin Finck 
3220c2c66affSColin Finck     /* publish the features and components */
3221c2c66affSColin Finck     r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3222c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223c2c66affSColin Finck 
3224c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
3225c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3226c2c66affSColin Finck 
3227c2c66affSColin Finck     /* these properties must not be in the saved msi file */
3228f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3229f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3230f860a780SAmine Khaldi     add_property_entry( hdb, "'REMOVE', 'six,seven'");
3231f860a780SAmine Khaldi     add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3232c2c66affSColin Finck 
3233c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3234c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3235c2c66affSColin Finck 
3236c2c66affSColin Finck     MsiCloseHandle(hdb);
3237c2c66affSColin Finck 
3238fbdb719bSwinesync     size = sizeof(value);
3239fbdb719bSwinesync     memset(value, 0, sizeof(value));
3240fbdb719bSwinesync     r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3241fbdb719bSwinesync     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3242fbdb719bSwinesync     ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value);
3243fbdb719bSwinesync 
3244c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3245c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3246c2c66affSColin Finck 
3247c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3248c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3249c2c66affSColin Finck 
3250c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3251c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3252c2c66affSColin Finck 
3253c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
3254c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
3255c2c66affSColin Finck 
3256c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3257c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3258c2c66affSColin Finck 
3259c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3260c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3261c2c66affSColin Finck 
3262c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3263c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3264c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3265c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3266c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3267c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3268c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3269c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3270c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3271c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3272c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3273c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3274c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3275c2c66affSColin Finck 
3276c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3277c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3278c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3279c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3280c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3281c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3282c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3283c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3284c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3285c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3286c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3287c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3288c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3289c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3290c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3291c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3292c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3293c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3294c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3295c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3296c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3297c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3298c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3299c2c66affSColin Finck 
3300c2c66affSColin Finck     MsiCloseHandle(hpkg);
3301c2c66affSColin Finck 
3302c2c66affSColin Finck     /* uninstall the product */
3303c2c66affSColin Finck     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3304c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3305c2c66affSColin Finck 
3306c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3307c2c66affSColin Finck     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3308c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3309c2c66affSColin Finck     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3310c2c66affSColin Finck 
3311c2c66affSColin Finck     /* all features installed locally */
3312c2c66affSColin Finck     r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3313c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3314c2c66affSColin Finck 
3315c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3316c2c66affSColin Finck     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3317c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3318c2c66affSColin Finck     ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3319c2c66affSColin Finck 
3320c2c66affSColin Finck     r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb);
3321c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3322c2c66affSColin Finck 
3323c2c66affSColin Finck     /* these properties must not be in the saved msi file */
3324f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3325c2c66affSColin Finck 
3326c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3327c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3328c2c66affSColin Finck 
3329c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3330c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3331c2c66affSColin Finck 
3332c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3333c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3334c2c66affSColin Finck 
3335c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3336c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3337c2c66affSColin Finck 
3338c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3339c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3340c2c66affSColin Finck 
3341c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3342c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3343c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3344c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3345c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3346c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3347c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3348c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3349c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3350c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3351c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3352c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3353c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3354c2c66affSColin Finck 
3355c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3356c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3357c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3358c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3359c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3360c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3361c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3362c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3363c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3364c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3365c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3366c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3367c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3368c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3369c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3370c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3371c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3372c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3373c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3374c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3375c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3376c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3377c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3378c2c66affSColin Finck 
3379c2c66affSColin Finck     MsiCloseHandle(hpkg);
3380c2c66affSColin Finck 
3381c2c66affSColin Finck     /* uninstall the product */
3382c2c66affSColin Finck     r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3383c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384c2c66affSColin Finck 
3385c2c66affSColin Finck     /* all features installed from source */
3386c2c66affSColin Finck     r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3387c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3388c2c66affSColin Finck 
3389c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3390c2c66affSColin Finck     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3391c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3392c2c66affSColin Finck     ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3393c2c66affSColin Finck 
3394c2c66affSColin Finck     r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3395c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3396c2c66affSColin Finck 
3397c2c66affSColin Finck     /* this property must not be in the saved msi file */
3398f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3399c2c66affSColin Finck 
3400c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3401c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3402c2c66affSColin Finck 
3403c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3404c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3405c2c66affSColin Finck 
3406c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3407c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3408c2c66affSColin Finck 
3409c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3410c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3411c2c66affSColin Finck 
3412c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
3413c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
3414c2c66affSColin Finck 
3415c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3416c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3417c2c66affSColin Finck 
3418c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3419c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3420c2c66affSColin Finck 
3421c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3422c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3423c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3424c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3425c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3426c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3427c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3428c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3429c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3430c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3431c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3432c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3433c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3434c2c66affSColin Finck 
3435c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3436c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3437c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3438c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3439c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3440c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3441c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3442c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3443c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3444c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3445c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3446c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3447c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3448c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3449c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3450c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3451c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3452c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3453c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3454c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3455c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3456c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3457f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3458c2c66affSColin Finck 
3459c2c66affSColin Finck     MsiCloseHandle(hpkg);
3460c2c66affSColin Finck 
3461c2c66affSColin Finck     /* reinstall the product */
3462c2c66affSColin Finck     r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3463*f4be6dc3SMikhail     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464c2c66affSColin Finck 
3465c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3466c2c66affSColin Finck     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3467c2c66affSColin Finck     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3468c2c66affSColin Finck     ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3469c2c66affSColin Finck 
3470c2c66affSColin Finck     r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3471c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3472c2c66affSColin Finck 
3473c2c66affSColin Finck     /* this property must not be in the saved msi file */
3474f860a780SAmine Khaldi     add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3475c2c66affSColin Finck 
3476c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3477c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3478c2c66affSColin Finck 
3479c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3480c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3481c2c66affSColin Finck 
3482c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3483c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3484c2c66affSColin Finck 
3485c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3486c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3487c2c66affSColin Finck 
3488c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
3489c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
3490c2c66affSColin Finck 
3491c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3492c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3493c2c66affSColin Finck 
3494c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3495c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3496c2c66affSColin Finck 
3497c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3498c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3499c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3500c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3501c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3502c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3503c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3504c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3505c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3506c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3507c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3508c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3509c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3510c2c66affSColin Finck 
3511c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3512c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3513c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3514c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3515c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3516c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3517c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3518c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3519c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3520c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3521c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3522c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3523c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3524c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3525c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3526c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3527c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3528c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3529c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3530c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3531c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3532c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3533f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3534c2c66affSColin Finck 
3535c2c66affSColin Finck     MsiCloseHandle(hpkg);
3536c2c66affSColin Finck 
3537f860a780SAmine Khaldi     /* test source only install */
3538f860a780SAmine Khaldi     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3539f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3540f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3541f860a780SAmine Khaldi     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3542f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3543f860a780SAmine Khaldi     ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3544f860a780SAmine Khaldi 
3545f860a780SAmine Khaldi     r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3546f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3547f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3548f860a780SAmine Khaldi     ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3549f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3550f860a780SAmine Khaldi     ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3551f860a780SAmine Khaldi 
3552f860a780SAmine Khaldi     /* no arguments test */
3553f860a780SAmine Khaldi     cache_file_name_len = sizeof(msi_cache_file);
3554f860a780SAmine Khaldi     r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3555f860a780SAmine Khaldi             INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3556f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557f860a780SAmine Khaldi     r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3558f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3559f860a780SAmine Khaldi 
3560f860a780SAmine Khaldi     create_custom_action_table( hdb );
3561f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3562f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3563f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3564f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3565f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3566f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3567f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3568f860a780SAmine Khaldi     add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
35692dce4ee7Swinesync     add_custom_action_entry( hdb,
357018123440Swinesync             "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3571f860a780SAmine Khaldi 
3572f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3573f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
35742dce4ee7Swinesync     add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3575f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3576f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3577f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3578f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3579f860a780SAmine Khaldi     /* Add "one" feature action tests */
3580f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3581f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3582f860a780SAmine Khaldi     r = MsiDatabaseCommit(hdb);
3583f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3584f860a780SAmine Khaldi     r = package_from_db( hdb, &hpkg );
3585f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3586f860a780SAmine Khaldi     MsiCloseHandle(hdb);
3587f860a780SAmine Khaldi 
3588f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3589f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3590f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "CostInitialize");
3591f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3592f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3593f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3594f860a780SAmine Khaldi 
3595f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "FileCost");
3596f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "FileCost failed\n");
3597f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3598f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3599f860a780SAmine Khaldi 
3600f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "CostFinalize");
3601f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3602f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3603f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3604f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3605f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3606f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3607f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3608f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3609f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3610f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3611f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3612f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3613f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3614f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3615f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3616f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3617f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3618f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3619f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3620f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3621f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3622f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3623f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3624f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3625f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3626f860a780SAmine Khaldi     test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3627f860a780SAmine Khaldi 
3628f860a780SAmine Khaldi     r = MsiDoActionA( hpkg, "InstallValidate");
3629f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3630f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3631f860a780SAmine Khaldi     test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3632f860a780SAmine Khaldi     MsiCloseHandle( hpkg );
3633f860a780SAmine Khaldi 
3634f860a780SAmine Khaldi     r = MsiInstallProductA(msifile, "");
3635*f4be6dc3SMikhail     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3637f860a780SAmine Khaldi     ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3638f860a780SAmine Khaldi     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3639f860a780SAmine Khaldi     ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
36402dce4ee7Swinesync     state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
36412dce4ee7Swinesync     ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3642f860a780SAmine Khaldi 
364396486643Swinesync     /* minor upgrade test with no REINSTALL argument */
364496486643Swinesync     r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
364596486643Swinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
364696486643Swinesync     size = MAX_PATH;
364796486643Swinesync     r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
364896486643Swinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
364996486643Swinesync     ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
365096486643Swinesync     MsiCloseHandle(hprod);
365196486643Swinesync 
365296486643Swinesync     r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
365396486643Swinesync     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
365496486643Swinesync     update_ProductVersion_property( hdb, "1.1.2" );
365596486643Swinesync     set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
365696486643Swinesync     r = MsiDatabaseCommit(hdb);
365796486643Swinesync     ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
365896486643Swinesync     MsiCloseHandle(hdb);
365996486643Swinesync 
366096486643Swinesync     r = MsiInstallProductA(msifile2, "");
3661b7b9c0c4Swinesync     ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
366296486643Swinesync 
3663a2371385Swinesync     r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3664a2371385Swinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3665366dd26eSwinesync 
3666366dd26eSwinesync     r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3667366dd26eSwinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668366dd26eSwinesync     size = MAX_PATH;
3669366dd26eSwinesync     r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3670366dd26eSwinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671a2371385Swinesync     ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3672366dd26eSwinesync     MsiCloseHandle(hprod);
3673366dd26eSwinesync 
367496486643Swinesync     /* major upgrade test */
367596486643Swinesync     r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
367696486643Swinesync     ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3677366dd26eSwinesync     add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3678366dd26eSwinesync     add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3679366dd26eSwinesync     create_upgrade_table( hdb );
3680366dd26eSwinesync     add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
368196486643Swinesync     update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3682366dd26eSwinesync     update_ProductVersion_property( hdb, "1.1.3" );
3683366dd26eSwinesync     set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
368496486643Swinesync     r = MsiDatabaseCommit(hdb);
368596486643Swinesync     ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
368696486643Swinesync     MsiCloseHandle(hdb);
368796486643Swinesync 
368896486643Swinesync     r = MsiInstallProductA(msifile2, "");
3689366dd26eSwinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
369096486643Swinesync 
369196486643Swinesync     r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
369296486643Swinesync     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
369396486643Swinesync     r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
369496486643Swinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
369596486643Swinesync     size = MAX_PATH;
369696486643Swinesync     r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
369796486643Swinesync     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698366dd26eSwinesync     ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
369996486643Swinesync     MsiCloseHandle(hprod);
370096486643Swinesync 
3701c2c66affSColin Finck     /* uninstall the product */
370296486643Swinesync     r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3703c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3704c2c66affSColin Finck 
3705c2c66affSColin Finck     DeleteFileA(msifile);
3706c2c66affSColin Finck     DeleteFileA(msifile2);
3707c2c66affSColin Finck     DeleteFileA(msifile3);
3708c2c66affSColin Finck     DeleteFileA(msifile4);
3709c2c66affSColin Finck }
3710c2c66affSColin Finck 
test_removefiles(void)3711c2c66affSColin Finck static void test_removefiles(void)
3712c2c66affSColin Finck {
3713c2c66affSColin Finck     MSIHANDLE hpkg;
3714c2c66affSColin Finck     UINT r;
3715c2c66affSColin Finck     MSIHANDLE hdb;
3716c2c66affSColin Finck     INSTALLSTATE installed, action;
3717c2c66affSColin Finck 
3718c2c66affSColin Finck     hdb = create_package_db();
3719c2c66affSColin Finck     ok ( hdb, "failed to create package database\n" );
3720c2c66affSColin Finck 
3721f860a780SAmine Khaldi     add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3722c2c66affSColin Finck 
3723f860a780SAmine Khaldi     create_feature_table( hdb );
3724f860a780SAmine Khaldi     add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3725c2c66affSColin Finck 
3726f860a780SAmine Khaldi     create_component_table( hdb );
3727f860a780SAmine Khaldi     add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3728f860a780SAmine Khaldi     add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3729f860a780SAmine Khaldi     add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3730f860a780SAmine Khaldi     add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3731f860a780SAmine Khaldi     add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3732f860a780SAmine Khaldi     add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3733f860a780SAmine Khaldi     add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3734c2c66affSColin Finck 
3735f860a780SAmine Khaldi     create_feature_components_table( hdb );
3736f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3737f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'helium'" );
3738f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'lithium'" );
3739f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'beryllium'" );
3740f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'boron'" );
3741f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'carbon'" );
3742f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'oxygen'" );
3743c2c66affSColin Finck 
3744f860a780SAmine Khaldi     create_file_table( hdb );
3745f860a780SAmine Khaldi     add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3746f860a780SAmine Khaldi     add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3747f860a780SAmine Khaldi     add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3748f860a780SAmine Khaldi     add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3749f860a780SAmine Khaldi     add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3750f860a780SAmine Khaldi     add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3751f860a780SAmine Khaldi     add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3752c2c66affSColin Finck 
3753f860a780SAmine Khaldi     create_remove_file_table( hdb );
3754c2c66affSColin Finck 
3755c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3756c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3757c2c66affSColin Finck     {
3758c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
3759c2c66affSColin Finck         DeleteFileA(msifile);
3760c2c66affSColin Finck         return;
3761c2c66affSColin Finck     }
3762c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3763c2c66affSColin Finck 
3764c2c66affSColin Finck     MsiCloseHandle( hdb );
3765c2c66affSColin Finck 
3766c2c66affSColin Finck     create_test_file( "hydrogen.txt" );
3767c2c66affSColin Finck     create_test_file( "helium.txt" );
3768c2c66affSColin Finck     create_test_file( "lithium.txt" );
3769c2c66affSColin Finck     create_test_file( "beryllium.txt" );
3770c2c66affSColin Finck     create_test_file( "boron.txt" );
3771c2c66affSColin Finck     create_test_file( "carbon.txt" );
3772c2c66affSColin Finck     create_test_file( "oxygen.txt" );
3773c2c66affSColin Finck 
3774c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3775c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "set property failed\n");
3776c2c66affSColin Finck 
3777c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3778c2c66affSColin Finck 
3779c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3780c2c66affSColin Finck     ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3781c2c66affSColin Finck 
3782c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
3783c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
3784c2c66affSColin Finck 
3785c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
3786c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
3787c2c66affSColin Finck 
3788c2c66affSColin Finck     installed = action = 0xdeadbeef;
3789c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3790c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3791c2c66affSColin Finck     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3792c2c66affSColin Finck     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3793c2c66affSColin Finck 
3794c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
3795c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3796c2c66affSColin Finck 
3797c2c66affSColin Finck     r = MsiDoActionA( hpkg, "InstallValidate");
3798c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "install validate failed\n");
3799c2c66affSColin Finck 
3800c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3801c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3802c2c66affSColin Finck 
3803c2c66affSColin Finck     installed = action = 0xdeadbeef;
3804c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3805c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3806c2c66affSColin Finck     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3807c2c66affSColin Finck     todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3808c2c66affSColin Finck 
3809c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3810c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3811c2c66affSColin Finck 
3812c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3813c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3814c2c66affSColin Finck 
3815c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3816c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3817c2c66affSColin Finck 
3818c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3819c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3820c2c66affSColin Finck 
3821c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3822c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3823c2c66affSColin Finck 
3824c2c66affSColin Finck     installed = action = 0xdeadbeef;
3825c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3826c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3827c2c66affSColin Finck     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3828c2c66affSColin Finck     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3829c2c66affSColin Finck 
3830c2c66affSColin Finck     r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3831c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3832c2c66affSColin Finck 
3833c2c66affSColin Finck     installed = action = 0xdeadbeef;
3834c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3835c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3836c2c66affSColin Finck     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3837c2c66affSColin Finck     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3838c2c66affSColin Finck 
3839c2c66affSColin Finck     r = MsiDoActionA( hpkg, "RemoveFiles");
3840c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "remove files failed\n");
3841c2c66affSColin Finck 
3842c2c66affSColin Finck     installed = action = 0xdeadbeef;
3843c2c66affSColin Finck     r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3844c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3845c2c66affSColin Finck     ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3846c2c66affSColin Finck     ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3847c2c66affSColin Finck 
3848c2c66affSColin Finck     ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3849c2c66affSColin Finck     ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
3850c2c66affSColin Finck     ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
3851c2c66affSColin Finck     ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
3852c2c66affSColin Finck     ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
3853c2c66affSColin Finck     ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
3854c2c66affSColin Finck     ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
3855c2c66affSColin Finck 
3856c2c66affSColin Finck     MsiCloseHandle( hpkg );
3857c2c66affSColin Finck     DeleteFileA(msifile);
3858c2c66affSColin Finck }
3859c2c66affSColin Finck 
test_appsearch(void)3860c2c66affSColin Finck static void test_appsearch(void)
3861c2c66affSColin Finck {
3862c2c66affSColin Finck     MSIHANDLE hpkg;
3863c2c66affSColin Finck     UINT r;
3864c2c66affSColin Finck     MSIHANDLE hdb;
3865c2c66affSColin Finck     CHAR prop[MAX_PATH];
3866c2c66affSColin Finck     DWORD size;
3867c2c66affSColin Finck     HKEY hkey;
3868c2c66affSColin Finck     const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
3869c2c66affSColin Finck 
3870c2c66affSColin Finck     hdb = create_package_db();
3871c2c66affSColin Finck     ok ( hdb, "failed to create package database\n" );
3872c2c66affSColin Finck 
3873f860a780SAmine Khaldi     create_appsearch_table( hdb );
3874f860a780SAmine Khaldi     add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
3875f860a780SAmine Khaldi     add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
3876f860a780SAmine Khaldi     add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
3877435274d1Swinesync     add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
3878435274d1Swinesync     add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
3879c2c66affSColin Finck 
3880f860a780SAmine Khaldi     create_reglocator_table( hdb );
3881f860a780SAmine Khaldi     add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
3882c2c66affSColin Finck 
3883c2c66affSColin Finck     r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
3884c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3885c2c66affSColin Finck     r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
3886c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3887c2c66affSColin Finck     RegCloseKey(hkey);
3888435274d1Swinesync     add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3889435274d1Swinesync 
3890435274d1Swinesync     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
3891435274d1Swinesync                         NULL, &hkey, NULL);
3892d7c30ed1Swinesync     if (r == ERROR_ACCESS_DENIED)
3893d7c30ed1Swinesync     {
3894d7c30ed1Swinesync         skip("insufficient rights\n");
3895d7c30ed1Swinesync         RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3896d7c30ed1Swinesync         MsiCloseHandle(hdb);
3897d7c30ed1Swinesync         DeleteFileA(msifile);
3898d7c30ed1Swinesync         return;
3899d7c30ed1Swinesync     }
3900fb0b5225Swinesync     ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3901d7c30ed1Swinesync 
3902435274d1Swinesync     r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3903435274d1Swinesync                        sizeof("c:\\windows\\system32\\notepad.exe"));
3904435274d1Swinesync     ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3905435274d1Swinesync     RegCloseKey(hkey);
3906435274d1Swinesync     add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3907435274d1Swinesync 
3908435274d1Swinesync     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
3909435274d1Swinesync                         NULL, &hkey, NULL);
3910435274d1Swinesync     ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3911435274d1Swinesync     r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3912435274d1Swinesync                        sizeof("c:\\windows\\system32\\notepad.exe"));
3913435274d1Swinesync     ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3914435274d1Swinesync     RegCloseKey(hkey);
3915435274d1Swinesync     add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
3916435274d1Swinesync                           msidbLocatorTypeFileName|msidbLocatorType64bit );
3917c2c66affSColin Finck 
3918f860a780SAmine Khaldi     create_drlocator_table( hdb );
3919f860a780SAmine Khaldi     add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
3920c2c66affSColin Finck 
3921f860a780SAmine Khaldi     create_signature_table( hdb );
3922f860a780SAmine Khaldi     add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
3923f860a780SAmine Khaldi     add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3924f860a780SAmine Khaldi     add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3925435274d1Swinesync     add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3926435274d1Swinesync     add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3927c2c66affSColin Finck 
3928c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
3929c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3930c2c66affSColin Finck     {
3931c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
3932c2c66affSColin Finck         DeleteFileA(msifile);
3933c2c66affSColin Finck         return;
3934c2c66affSColin Finck     }
3935c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3936c2c66affSColin Finck     MsiCloseHandle( hdb );
3937c2c66affSColin Finck     if (r != ERROR_SUCCESS)
3938c2c66affSColin Finck         goto done;
3939c2c66affSColin Finck 
3940c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3941c2c66affSColin Finck 
3942c2c66affSColin Finck     r = MsiDoActionA( hpkg, "AppSearch" );
3943c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
3944c2c66affSColin Finck 
3945c2c66affSColin Finck     size = sizeof(prop);
3946c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
3947c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3948c2c66affSColin Finck     ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3949c2c66affSColin Finck 
3950c2c66affSColin Finck     size = sizeof(prop);
3951c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
3952c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3953c2c66affSColin Finck 
3954c2c66affSColin Finck     size = sizeof(prop);
3955c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
3956c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3957c2c66affSColin Finck     ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3958c2c66affSColin Finck 
3959435274d1Swinesync     size = sizeof(prop);
3960435274d1Swinesync     r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
3961435274d1Swinesync     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3962435274d1Swinesync     ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3963435274d1Swinesync 
3964435274d1Swinesync     size = sizeof(prop);
3965435274d1Swinesync     r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
3966435274d1Swinesync     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3967435274d1Swinesync     ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3968435274d1Swinesync 
3969c2c66affSColin Finck done:
3970c2c66affSColin Finck     MsiCloseHandle( hpkg );
3971c2c66affSColin Finck     DeleteFileA(msifile);
3972c2c66affSColin Finck     RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3973*f4be6dc3SMikhail     RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY, 0);
3974*f4be6dc3SMikhail     RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY, 0);
3975c2c66affSColin Finck }
3976c2c66affSColin Finck 
test_appsearch_complocator(void)3977c2c66affSColin Finck static void test_appsearch_complocator(void)
3978c2c66affSColin Finck {
3979c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
3980484e8280Swinesync     char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
3981c2c66affSColin Finck     LPSTR usersid;
3982c2c66affSColin Finck     DWORD size;
3983c2c66affSColin Finck     UINT r;
3984c2c66affSColin Finck 
3985c2c66affSColin Finck     if (!(usersid = get_user_sid()))
3986c2c66affSColin Finck         return;
3987c2c66affSColin Finck 
3988*f4be6dc3SMikhail     if (!is_process_elevated())
3989c2c66affSColin Finck     {
3990c2c66affSColin Finck         skip("process is limited\n");
3991c2c66affSColin Finck         return;
3992c2c66affSColin Finck     }
3993c2c66affSColin Finck 
3994c2c66affSColin Finck     create_test_file("FileName1");
3995c2c66affSColin Finck     create_test_file("FileName4");
3996c2c66affSColin Finck     set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
3997c2c66affSColin Finck                        "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
3998c2c66affSColin Finck 
3999c2c66affSColin Finck     create_test_file("FileName2");
4000c2c66affSColin Finck     set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
4001c2c66affSColin Finck                        "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4002c2c66affSColin Finck 
4003c2c66affSColin Finck     create_test_file("FileName3");
4004c2c66affSColin Finck     set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
4005c2c66affSColin Finck                        "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4006c2c66affSColin Finck 
4007c2c66affSColin Finck     create_test_file("FileName5");
4008c2c66affSColin Finck     set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
4009c2c66affSColin Finck                        "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4010c2c66affSColin Finck 
4011c2c66affSColin Finck     create_test_file("FileName6");
4012c2c66affSColin Finck     set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
4013c2c66affSColin Finck                        "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4014c2c66affSColin Finck 
4015c2c66affSColin Finck     create_test_file("FileName7");
4016c2c66affSColin Finck     set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
4017c2c66affSColin Finck                        "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4018c2c66affSColin Finck 
4019c2c66affSColin Finck     /* dir is FALSE, but we're pretending it's a directory */
4020c2c66affSColin Finck     set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
4021c2c66affSColin Finck                        "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4022c2c66affSColin Finck 
4023c2c66affSColin Finck     create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4024c2c66affSColin Finck     set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
4025c2c66affSColin Finck                        "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4026c2c66affSColin Finck 
4027c2c66affSColin Finck     create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4028c2c66affSColin Finck     set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
4029c2c66affSColin Finck                        "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4030c2c66affSColin Finck 
4031c2c66affSColin Finck     create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4032c2c66affSColin Finck     set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
4033c2c66affSColin Finck                        "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4034c2c66affSColin Finck 
4035c2c66affSColin Finck     hdb = create_package_db();
4036c2c66affSColin Finck     ok(hdb, "Expected a valid database handle\n");
4037c2c66affSColin Finck 
4038f860a780SAmine Khaldi     create_appsearch_table(hdb);
4039f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4040f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4041f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4042f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4043f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4044f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4045f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4046f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4047f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4048f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4049f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4050f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4051c2c66affSColin Finck 
4052f860a780SAmine Khaldi     create_complocator_table(hdb);
4053c2c66affSColin Finck 
4054c2c66affSColin Finck     /* published component, machine, file, signature, misdbLocatorTypeFile */
4055f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4056c2c66affSColin Finck 
4057c2c66affSColin Finck     /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4058f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4059c2c66affSColin Finck 
4060c2c66affSColin Finck     /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4061f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4062c2c66affSColin Finck 
4063c2c66affSColin Finck     /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4064f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4065c2c66affSColin Finck 
4066c2c66affSColin Finck     /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4067f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4068c2c66affSColin Finck 
4069c2c66affSColin Finck     /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4070f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4071c2c66affSColin Finck 
4072c2c66affSColin Finck     /* published component, machine, file, no signature, misdbLocatorTypeFile */
4073f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4074c2c66affSColin Finck 
4075c2c66affSColin Finck     /* unpublished component, no signature, misdbLocatorTypeDir */
4076f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4077c2c66affSColin Finck 
4078c2c66affSColin Finck     /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4079f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4080c2c66affSColin Finck 
4081c2c66affSColin Finck     /* published component, signature w/ ver, misdbLocatorTypeFile */
4082f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4083c2c66affSColin Finck 
4084c2c66affSColin Finck     /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4085f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4086c2c66affSColin Finck 
4087c2c66affSColin Finck     /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4088f860a780SAmine Khaldi     add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4089c2c66affSColin Finck 
4090f860a780SAmine Khaldi     create_signature_table(hdb);
4091f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4092f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4093f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4094f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4095f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4096f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4097f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4098f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4099c2c66affSColin Finck 
4100c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
4101c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4102c2c66affSColin Finck     {
4103c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
4104c2c66affSColin Finck         goto error;
4105c2c66affSColin Finck     }
4106c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4107c2c66affSColin Finck 
4108c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4109c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4110c2c66affSColin Finck 
4111c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4112c2c66affSColin Finck 
4113c2c66affSColin Finck     r = MsiDoActionA(hpkg, "AppSearch");
4114c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115c2c66affSColin Finck 
4116c2c66affSColin Finck     strcpy(expected, CURR_DIR);
4117c2c66affSColin Finck     if (is_root(CURR_DIR)) expected[2] = 0;
4118c2c66affSColin Finck 
4119c2c66affSColin Finck     size = MAX_PATH;
4120c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4121c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4122c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4124c2c66affSColin Finck 
4125c2c66affSColin Finck     size = MAX_PATH;
4126c2c66affSColin Finck     sprintf(path, "%s\\FileName2", expected);
4127c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4128c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4129c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4130c2c66affSColin Finck 
4131c2c66affSColin Finck     size = MAX_PATH;
4132c2c66affSColin Finck     sprintf(path, "%s\\FileName3", expected);
4133c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4134c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4135c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4136c2c66affSColin Finck 
4137c2c66affSColin Finck     size = MAX_PATH;
4138c2c66affSColin Finck     sprintf(path, "%s\\FileName4", expected);
4139c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4140c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4141c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4142c2c66affSColin Finck 
4143c2c66affSColin Finck     size = MAX_PATH;
4144c2c66affSColin Finck     sprintf(path, "%s\\FileName5", expected);
4145c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4146c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4147c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4148c2c66affSColin Finck 
4149c2c66affSColin Finck     size = MAX_PATH;
4150c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4151c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4152c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4153c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4154c2c66affSColin Finck 
4155c2c66affSColin Finck     size = MAX_PATH;
4156c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4157c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4158c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4159c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4160c2c66affSColin Finck 
4161c2c66affSColin Finck     size = MAX_PATH;
4162c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4163c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4164c2c66affSColin Finck     ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4165c2c66affSColin Finck 
4166c2c66affSColin Finck     size = MAX_PATH;
4167c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4168c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4169c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4170c2c66affSColin Finck 
4171c2c66affSColin Finck     size = MAX_PATH;
4172c2c66affSColin Finck     sprintf(path, "%s\\FileName8.dll", expected);
4173c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4174c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4175c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4176c2c66affSColin Finck 
4177c2c66affSColin Finck     size = MAX_PATH;
4178c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4179c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4181c2c66affSColin Finck 
4182c2c66affSColin Finck     size = MAX_PATH;
4183c2c66affSColin Finck     sprintf(path, "%s\\FileName10.dll", expected);
4184c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4185c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4186c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4187c2c66affSColin Finck 
4188c2c66affSColin Finck     delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4189c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4190c2c66affSColin Finck     delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4191c2c66affSColin Finck                           MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
4192c2c66affSColin Finck     delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4193c2c66affSColin Finck                           MSIINSTALLCONTEXT_USERMANAGED, usersid);
4194c2c66affSColin Finck     delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4195c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4196c2c66affSColin Finck     delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4197c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4198c2c66affSColin Finck     delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4199c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4200c2c66affSColin Finck     delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4201c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4202c2c66affSColin Finck     delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4203c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4204c2c66affSColin Finck     delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4205c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4206c2c66affSColin Finck     delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4207c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
4208c2c66affSColin Finck 
4209c2c66affSColin Finck     MsiCloseHandle(hpkg);
4210c2c66affSColin Finck 
4211c2c66affSColin Finck error:
4212c2c66affSColin Finck     DeleteFileA("FileName1");
4213c2c66affSColin Finck     DeleteFileA("FileName2");
4214c2c66affSColin Finck     DeleteFileA("FileName3");
4215c2c66affSColin Finck     DeleteFileA("FileName4");
4216c2c66affSColin Finck     DeleteFileA("FileName5");
4217c2c66affSColin Finck     DeleteFileA("FileName6");
4218c2c66affSColin Finck     DeleteFileA("FileName7");
4219c2c66affSColin Finck     DeleteFileA("FileName8.dll");
4220c2c66affSColin Finck     DeleteFileA("FileName9.dll");
4221c2c66affSColin Finck     DeleteFileA("FileName10.dll");
4222c2c66affSColin Finck     DeleteFileA(msifile);
4223c2c66affSColin Finck     LocalFree(usersid);
4224c2c66affSColin Finck }
4225c2c66affSColin Finck 
test_appsearch_reglocator(void)4226c2c66affSColin Finck static void test_appsearch_reglocator(void)
4227c2c66affSColin Finck {
4228c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
4229484e8280Swinesync     char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4230c2c66affSColin Finck     DWORD binary[2], size, val;
4231c2c66affSColin Finck     BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4232c2c66affSColin Finck     HKEY hklm, classes, hkcu, users;
4233c2c66affSColin Finck     LPSTR pathdata, pathvar, ptr;
4234c2c66affSColin Finck     LONG res;
4235c2c66affSColin Finck     UINT r, type = 0;
4236c2c66affSColin Finck     SYSTEM_INFO si;
4237c2c66affSColin Finck 
4238c2c66affSColin Finck     version = TRUE;
4239c2c66affSColin Finck     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4240c2c66affSColin Finck         version = FALSE;
4241c2c66affSColin Finck 
4242c2c66affSColin Finck     DeleteFileA("test.dll");
4243c2c66affSColin Finck 
4244c2c66affSColin Finck     res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4245c2c66affSColin Finck     if (res == ERROR_ACCESS_DENIED)
4246c2c66affSColin Finck     {
4247c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
4248c2c66affSColin Finck         return;
4249c2c66affSColin Finck     }
42501b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4251c2c66affSColin Finck 
4252c2c66affSColin Finck     res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4253c2c66affSColin Finck                          (const BYTE *)"regszdata", 10);
42541b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4255c2c66affSColin Finck 
4256c2c66affSColin Finck     res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
42571b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4258c2c66affSColin Finck 
4259c2c66affSColin Finck     res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4260c2c66affSColin Finck                          (const BYTE *)"regszdata", 10);
42611b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4262c2c66affSColin Finck 
4263c2c66affSColin Finck     users = 0;
4264c2c66affSColin Finck     res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4265*f4be6dc3SMikhail     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4266c2c66affSColin Finck 
4267c2c66affSColin Finck     if (res == ERROR_SUCCESS)
4268c2c66affSColin Finck     {
4269c2c66affSColin Finck         res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4270c2c66affSColin Finck                              (const BYTE *)"regszdata", 10);
42711b4acd3cSwinesync         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4272c2c66affSColin Finck     }
4273c2c66affSColin Finck 
4274c2c66affSColin Finck     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
42751b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4276c2c66affSColin Finck 
4277c2c66affSColin Finck     res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
42781b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4279c2c66affSColin Finck 
4280c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4281c2c66affSColin Finck                          (const BYTE *)"regszdata", 10);
42821b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4283c2c66affSColin Finck 
4284c2c66affSColin Finck     val = 42;
4285c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4286c2c66affSColin Finck                          (const BYTE *)&val, sizeof(DWORD));
42871b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4288c2c66affSColin Finck 
4289c2c66affSColin Finck     val = -42;
4290c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4291c2c66affSColin Finck                          (const BYTE *)&val, sizeof(DWORD));
42921b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4293c2c66affSColin Finck 
4294c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4295c2c66affSColin Finck                          (const BYTE *)"%PATH%", 7);
42961b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4297c2c66affSColin Finck 
4298c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4299c2c66affSColin Finck                          (const BYTE *)"my%NOVAR%", 10);
43001b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4301c2c66affSColin Finck 
4302c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4303c2c66affSColin Finck                          (const BYTE *)"one\0two\0", 9);
43041b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4305c2c66affSColin Finck 
4306c2c66affSColin Finck     binary[0] = 0x1234abcd;
4307c2c66affSColin Finck     binary[1] = 0x567890ef;
4308c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4309c2c66affSColin Finck                          (const BYTE *)binary, sizeof(binary));
43101b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4311c2c66affSColin Finck 
4312c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4313c2c66affSColin Finck                          (const BYTE *)"#regszdata", 11);
43141b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4315c2c66affSColin Finck 
4316c2c66affSColin Finck     strcpy(expected, CURR_DIR);
4317c2c66affSColin Finck     if (is_root(CURR_DIR)) expected[2] = 0;
4318c2c66affSColin Finck 
4319c2c66affSColin Finck     create_test_file("FileName1");
4320c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4321c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4322c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43231b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4324c2c66affSColin Finck 
4325c2c66affSColin Finck     sprintf(path, "%s\\FileName2", expected);
4326c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4327c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43281b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4329c2c66affSColin Finck 
4330c2c66affSColin Finck     lstrcpyA(path, expected);
4331c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4332c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43331b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4334c2c66affSColin Finck 
4335c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4336c2c66affSColin Finck                          (const BYTE *)"", 1);
43371b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4338c2c66affSColin Finck 
4339c2c66affSColin Finck     create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4340c2c66affSColin Finck     sprintf(path, "%s\\FileName3.dll", expected);
4341c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4342c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43431b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4344c2c66affSColin Finck 
4345c2c66affSColin Finck     create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4346c2c66affSColin Finck     sprintf(path, "%s\\FileName4.dll", expected);
4347c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4348c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43491b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4350c2c66affSColin Finck 
4351c2c66affSColin Finck     create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4352c2c66affSColin Finck     sprintf(path, "%s\\FileName5.dll", expected);
4353c2c66affSColin Finck     res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4354c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43551b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4356c2c66affSColin Finck 
4357c2c66affSColin Finck     sprintf(path, "\"%s\\FileName1\" -option", expected);
4358c2c66affSColin Finck     res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4359c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43601b4acd3cSwinesync     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4361c2c66affSColin Finck 
4362c2c66affSColin Finck     space = strchr(expected, ' ') != NULL;
4363c2c66affSColin Finck     sprintf(path, "%s\\FileName1 -option", expected);
4364c2c66affSColin Finck     res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4365c2c66affSColin Finck                          (const BYTE *)path, lstrlenA(path) + 1);
43661b4acd3cSwinesync     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4367c2c66affSColin Finck 
4368c2c66affSColin Finck     hdb = create_package_db();
4369c2c66affSColin Finck     ok(hdb, "Expected a valid database handle\n");
4370c2c66affSColin Finck 
4371f860a780SAmine Khaldi     create_appsearch_table(hdb);
4372f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4373f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4374f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4375f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4376f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4377f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4378f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4379f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4380f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4381f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4382f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4383f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4384f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4385f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4386f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4387f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4388f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4389f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4390f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4391f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4392f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4393f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4394f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4395f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4396f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4397f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4398f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4399f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4400f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4401f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4402c2c66affSColin Finck 
4403f860a780SAmine Khaldi     create_reglocator_table(hdb);
4404c2c66affSColin Finck 
4405c2c66affSColin Finck     type = msidbLocatorTypeRawValue;
4406c2c66affSColin Finck     if (is_64bit)
4407c2c66affSColin Finck         type |= msidbLocatorType64bit;
4408c2c66affSColin Finck 
4409c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4410f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4411c2c66affSColin Finck 
4412c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4413f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4414c2c66affSColin Finck 
4415c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4416f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4417c2c66affSColin Finck 
4418c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4419f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4420c2c66affSColin Finck 
4421c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4422f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4423c2c66affSColin Finck 
4424c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4425f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4426c2c66affSColin Finck 
4427c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4428f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4429c2c66affSColin Finck 
4430c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4431f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4432c2c66affSColin Finck 
4433c2c66affSColin Finck     type = msidbLocatorTypeFileName;
4434c2c66affSColin Finck     if (is_64bit)
4435c2c66affSColin Finck         type |= msidbLocatorType64bit;
4436c2c66affSColin Finck 
4437c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4438f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4439c2c66affSColin Finck 
4440c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4441f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4442c2c66affSColin Finck 
4443c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, no signature */
4444f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4445c2c66affSColin Finck 
4446c2c66affSColin Finck     type = msidbLocatorTypeDirectory;
4447c2c66affSColin Finck     if (is_64bit)
4448c2c66affSColin Finck         type |= msidbLocatorType64bit;
4449c2c66affSColin Finck 
4450c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4451f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4452c2c66affSColin Finck 
4453c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4454f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4455c2c66affSColin Finck 
4456c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4457f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4458c2c66affSColin Finck 
4459c2c66affSColin Finck     type = msidbLocatorTypeRawValue;
4460c2c66affSColin Finck     if (is_64bit)
4461c2c66affSColin Finck         type |= msidbLocatorType64bit;
4462c2c66affSColin Finck 
4463c2c66affSColin Finck     /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4464f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4465c2c66affSColin Finck 
4466c2c66affSColin Finck     /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4467f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4468c2c66affSColin Finck 
4469c2c66affSColin Finck     /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4470f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4471c2c66affSColin Finck 
4472c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4473f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4474c2c66affSColin Finck 
4475c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4476f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4477c2c66affSColin Finck 
4478c2c66affSColin Finck     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4479f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4480c2c66affSColin Finck 
4481c2c66affSColin Finck     type = msidbLocatorTypeFileName;
4482c2c66affSColin Finck     if (is_64bit)
4483c2c66affSColin Finck         type |= msidbLocatorType64bit;
4484c2c66affSColin Finck 
4485c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4486f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4487c2c66affSColin Finck 
4488c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4489f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4490c2c66affSColin Finck 
4491c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4492f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4493c2c66affSColin Finck 
4494c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4495f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4496c2c66affSColin Finck 
4497c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4498f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4499c2c66affSColin Finck 
4500c2c66affSColin Finck     type = msidbLocatorTypeDirectory;
4501c2c66affSColin Finck     if (is_64bit)
4502c2c66affSColin Finck         type |= msidbLocatorType64bit;
4503c2c66affSColin Finck 
4504c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4505f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4506c2c66affSColin Finck 
4507c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4508f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4509c2c66affSColin Finck 
4510c2c66affSColin Finck     /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4511f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4512c2c66affSColin Finck 
4513c2c66affSColin Finck     type = msidbLocatorTypeFileName;
4514c2c66affSColin Finck     if (is_64bit)
4515c2c66affSColin Finck         type |= msidbLocatorType64bit;
4516c2c66affSColin Finck 
4517c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4518f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4519c2c66affSColin Finck 
4520c2c66affSColin Finck     /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4521f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4522c2c66affSColin Finck 
4523f860a780SAmine Khaldi     create_signature_table(hdb);
4524f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4525f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4526f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4527f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4528f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4529f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4530c2c66affSColin Finck 
4531c2c66affSColin Finck     if (!is_root(CURR_DIR))
4532c2c66affSColin Finck     {
4533c2c66affSColin Finck         ptr = strrchr(expected, '\\') + 1;
4534c2c66affSColin Finck         sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4535f860a780SAmine Khaldi         add_signature_entry(hdb, path);
4536c2c66affSColin Finck     }
4537f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4538f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4539f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4540c2c66affSColin Finck 
4541c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
4542c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4543c2c66affSColin Finck 
4544c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4545c2c66affSColin Finck 
4546c2c66affSColin Finck     r = MsiDoActionA(hpkg, "AppSearch");
4547c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4548c2c66affSColin Finck 
4549c2c66affSColin Finck     size = MAX_PATH;
4550c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4551c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4552c2c66affSColin Finck     ok(!lstrcmpA(prop, "regszdata"),
4553c2c66affSColin Finck        "Expected \"regszdata\", got \"%s\"\n", prop);
4554c2c66affSColin Finck 
4555c2c66affSColin Finck     size = MAX_PATH;
4556c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4557c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4558c2c66affSColin Finck     ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4559c2c66affSColin Finck 
4560c2c66affSColin Finck     size = MAX_PATH;
4561c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4562c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4563c2c66affSColin Finck     ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4564c2c66affSColin Finck 
4565c2c66affSColin Finck     memset(&si, 0, sizeof(si));
4566a4930636Swinesync     GetNativeSystemInfo(&si);
4567c2c66affSColin Finck 
4568*f4be6dc3SMikhail     if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4569c2c66affSColin Finck     {
4570c2c66affSColin Finck         size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
45716aefc5b9Swinesync         pathvar = malloc(size);
4572c2c66affSColin Finck         ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4573c2c66affSColin Finck 
4574c2c66affSColin Finck         size = 0;
4575c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4576c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4577c2c66affSColin Finck 
45786aefc5b9Swinesync         pathdata = malloc(++size);
4579c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4580c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4581c2c66affSColin Finck         ok(!lstrcmpA(pathdata, pathvar),
4582c2c66affSColin Finck             "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4583c2c66affSColin Finck 
45846aefc5b9Swinesync         free(pathvar);
45856aefc5b9Swinesync         free(pathdata);
4586c2c66affSColin Finck     }
4587c2c66affSColin Finck 
4588c2c66affSColin Finck     size = MAX_PATH;
4589c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4590c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4591c2c66affSColin Finck     ok(!lstrcmpA(prop,
4592c2c66affSColin Finck        "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4593c2c66affSColin Finck 
4594c2c66affSColin Finck     size = MAX_PATH;
4595c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4596c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4597c2c66affSColin Finck     todo_wine
4598c2c66affSColin Finck     {
4599c2c66affSColin Finck         ok(!memcmp(prop, "\0one\0two\0\0", 10),
4600c2c66affSColin Finck            "Expected \"\\0one\\0two\\0\\0\"\n");
4601c2c66affSColin Finck     }
4602c2c66affSColin Finck 
4603c2c66affSColin Finck     size = MAX_PATH;
4604c2c66affSColin Finck     lstrcpyA(path, "#xCDAB3412EF907856");
4605c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4606c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4607c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4608c2c66affSColin Finck 
4609c2c66affSColin Finck     size = MAX_PATH;
4610c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4611c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4612c2c66affSColin Finck     ok(!lstrcmpA(prop, "##regszdata"),
4613c2c66affSColin Finck        "Expected \"##regszdata\", got \"%s\"\n", prop);
4614c2c66affSColin Finck 
4615c2c66affSColin Finck     size = MAX_PATH;
4616c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4617c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4618c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4619c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4620c2c66affSColin Finck 
4621c2c66affSColin Finck     size = MAX_PATH;
4622c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4623c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4624c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4625c2c66affSColin Finck 
4626c2c66affSColin Finck     size = MAX_PATH;
4627c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4628c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4629c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4630c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4631c2c66affSColin Finck 
4632c2c66affSColin Finck     size = MAX_PATH;
4633c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4634c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4635c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4636c2c66affSColin Finck 
4637c2c66affSColin Finck     size = MAX_PATH;
4638c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4639c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4640c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4641c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4642c2c66affSColin Finck 
4643c2c66affSColin Finck     size = MAX_PATH;
4644c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4645c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4646c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4647c2c66affSColin Finck 
4648c2c66affSColin Finck     size = MAX_PATH;
4649c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4650c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4651c2c66affSColin Finck     ok(!lstrcmpA(prop, "regszdata"),
4652c2c66affSColin Finck        "Expected \"regszdata\", got \"%s\"\n", prop);
4653c2c66affSColin Finck 
4654c2c66affSColin Finck     size = MAX_PATH;
4655c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4656c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4657c2c66affSColin Finck     ok(!lstrcmpA(prop, "regszdata"),
4658c2c66affSColin Finck        "Expected \"regszdata\", got \"%s\"\n", prop);
4659c2c66affSColin Finck 
4660c2c66affSColin Finck     if (users)
4661c2c66affSColin Finck     {
4662c2c66affSColin Finck         size = MAX_PATH;
4663c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4664c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4665c2c66affSColin Finck         ok(!lstrcmpA(prop, "regszdata"),
4666c2c66affSColin Finck            "Expected \"regszdata\", got \"%s\"\n", prop);
4667c2c66affSColin Finck     }
4668c2c66affSColin Finck 
4669c2c66affSColin Finck     size = MAX_PATH;
4670c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4671c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4672c2c66affSColin Finck     ok(!lstrcmpA(prop, "defvalue"),
4673c2c66affSColin Finck        "Expected \"defvalue\", got \"%s\"\n", prop);
4674c2c66affSColin Finck 
4675c2c66affSColin Finck     size = MAX_PATH;
4676c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4677c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4679c2c66affSColin Finck 
4680c2c66affSColin Finck     size = MAX_PATH;
4681c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4682c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4683c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4684c2c66affSColin Finck 
4685c2c66affSColin Finck     if (version)
4686c2c66affSColin Finck     {
4687c2c66affSColin Finck         size = MAX_PATH;
4688c2c66affSColin Finck         sprintf(path, "%s\\FileName3.dll", expected);
4689c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4690c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4692c2c66affSColin Finck 
4693c2c66affSColin Finck         size = MAX_PATH;
4694c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4695c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4697c2c66affSColin Finck 
4698c2c66affSColin Finck         size = MAX_PATH;
4699c2c66affSColin Finck         sprintf(path, "%s\\FileName5.dll", expected);
4700c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4701c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4703c2c66affSColin Finck     }
4704c2c66affSColin Finck 
4705c2c66affSColin Finck     if (!is_root(CURR_DIR))
4706c2c66affSColin Finck     {
4707c2c66affSColin Finck         size = MAX_PATH;
4708c2c66affSColin Finck         lstrcpyA(path, expected);
4709c2c66affSColin Finck         ptr = strrchr(path, '\\') + 1;
4710c2c66affSColin Finck         *ptr = '\0';
4711c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4712c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4713c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4714c2c66affSColin Finck     }
4715c2c66affSColin Finck     size = MAX_PATH;
4716c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4717c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4718c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4719c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4720c2c66affSColin Finck 
4721c2c66affSColin Finck     size = MAX_PATH;
4722c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4723c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4724c2c66affSColin Finck     if (is_root(CURR_DIR))
4725c2c66affSColin Finck         ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4726c2c66affSColin Finck     else
4727c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4728c2c66affSColin Finck 
4729c2c66affSColin Finck     size = MAX_PATH;
4730c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4731c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4732c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4733c2c66affSColin Finck 
4734c2c66affSColin Finck     size = MAX_PATH;
4735c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4736c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4737c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4738c2c66affSColin Finck 
4739c2c66affSColin Finck     size = MAX_PATH;
4740c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4741c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4742c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4744c2c66affSColin Finck 
4745c2c66affSColin Finck     size = MAX_PATH;
4746c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4747c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4748c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749c2c66affSColin Finck     if (space)
4750c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4751c2c66affSColin Finck     else
4752c2c66affSColin Finck         todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4753c2c66affSColin Finck 
4754c2c66affSColin Finck     RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4755c2c66affSColin Finck     RegDeleteValueA(hklm, "Value1");
4756c2c66affSColin Finck     RegDeleteValueA(hklm, "Value2");
4757c2c66affSColin Finck     RegDeleteValueA(hklm, "Value3");
4758c2c66affSColin Finck     RegDeleteValueA(hklm, "Value4");
4759c2c66affSColin Finck     RegDeleteValueA(hklm, "Value5");
4760c2c66affSColin Finck     RegDeleteValueA(hklm, "Value6");
4761c2c66affSColin Finck     RegDeleteValueA(hklm, "Value7");
4762c2c66affSColin Finck     RegDeleteValueA(hklm, "Value8");
4763c2c66affSColin Finck     RegDeleteValueA(hklm, "Value9");
4764c2c66affSColin Finck     RegDeleteValueA(hklm, "Value10");
4765c2c66affSColin Finck     RegDeleteValueA(hklm, "Value11");
4766c2c66affSColin Finck     RegDeleteValueA(hklm, "Value12");
4767c2c66affSColin Finck     RegDeleteValueA(hklm, "Value13");
4768c2c66affSColin Finck     RegDeleteValueA(hklm, "Value14");
4769c2c66affSColin Finck     RegDeleteValueA(hklm, "Value15");
4770c2c66affSColin Finck     RegDeleteValueA(hklm, "Value16");
4771c2c66affSColin Finck     RegDeleteValueA(hklm, "Value17");
4772c2c66affSColin Finck     RegDeleteKeyA(hklm, "");
4773c2c66affSColin Finck     RegCloseKey(hklm);
4774c2c66affSColin Finck 
4775c2c66affSColin Finck     RegDeleteValueA(classes, "Value1");
4776c2c66affSColin Finck     RegDeleteKeyA(classes, "");
4777c2c66affSColin Finck     RegCloseKey(classes);
4778c2c66affSColin Finck 
4779c2c66affSColin Finck     RegDeleteValueA(hkcu, "Value1");
4780c2c66affSColin Finck     RegDeleteKeyA(hkcu, "");
4781c2c66affSColin Finck     RegCloseKey(hkcu);
4782c2c66affSColin Finck 
4783c2c66affSColin Finck     RegDeleteValueA(users, "Value1");
4784c2c66affSColin Finck     RegDeleteKeyA(users, "");
4785c2c66affSColin Finck     RegCloseKey(users);
4786c2c66affSColin Finck 
4787c2c66affSColin Finck     DeleteFileA("FileName1");
4788c2c66affSColin Finck     DeleteFileA("FileName3.dll");
4789c2c66affSColin Finck     DeleteFileA("FileName4.dll");
4790c2c66affSColin Finck     DeleteFileA("FileName5.dll");
4791c2c66affSColin Finck     MsiCloseHandle(hpkg);
4792c2c66affSColin Finck     DeleteFileA(msifile);
4793c2c66affSColin Finck }
4794c2c66affSColin Finck 
delete_win_ini(LPCSTR file)4795c2c66affSColin Finck static void delete_win_ini(LPCSTR file)
4796c2c66affSColin Finck {
4797c2c66affSColin Finck     CHAR path[MAX_PATH];
4798c2c66affSColin Finck 
4799c2c66affSColin Finck     GetWindowsDirectoryA(path, MAX_PATH);
4800c2c66affSColin Finck     lstrcatA(path, "\\");
4801c2c66affSColin Finck     lstrcatA(path, file);
4802c2c66affSColin Finck 
4803c2c66affSColin Finck     DeleteFileA(path);
4804c2c66affSColin Finck }
4805c2c66affSColin Finck 
test_appsearch_inilocator(void)4806c2c66affSColin Finck static void test_appsearch_inilocator(void)
4807c2c66affSColin Finck {
4808c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
4809484e8280Swinesync     char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4810c2c66affSColin Finck     BOOL version;
4811c2c66affSColin Finck     LPSTR ptr;
4812c2c66affSColin Finck     DWORD size;
4813c2c66affSColin Finck     UINT r;
4814c2c66affSColin Finck 
4815c2c66affSColin Finck     version = TRUE;
4816c2c66affSColin Finck     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4817c2c66affSColin Finck         version = FALSE;
4818c2c66affSColin Finck 
4819c2c66affSColin Finck     DeleteFileA("test.dll");
4820c2c66affSColin Finck 
4821c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4822c2c66affSColin Finck 
4823c2c66affSColin Finck     strcpy(expected, CURR_DIR);
4824c2c66affSColin Finck     if (is_root(CURR_DIR)) expected[2] = 0;
4825c2c66affSColin Finck 
4826c2c66affSColin Finck     create_test_file("FileName1");
4827c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4828c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4829c2c66affSColin Finck 
4830c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4831c2c66affSColin Finck 
4832c2c66affSColin Finck     sprintf(path, "%s\\IDontExist", expected);
4833c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4834c2c66affSColin Finck 
4835c2c66affSColin Finck     create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4836c2c66affSColin Finck     sprintf(path, "%s\\FileName2.dll", expected);
4837c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4838c2c66affSColin Finck 
4839c2c66affSColin Finck     create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4840c2c66affSColin Finck     sprintf(path, "%s\\FileName3.dll", expected);
4841c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4842c2c66affSColin Finck 
4843c2c66affSColin Finck     create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4844c2c66affSColin Finck     sprintf(path, "%s\\FileName4.dll", expected);
4845c2c66affSColin Finck     WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4846c2c66affSColin Finck 
4847c2c66affSColin Finck     hdb = create_package_db();
4848c2c66affSColin Finck     ok(hdb, "Expected a valid database handle\n");
4849c2c66affSColin Finck 
4850f860a780SAmine Khaldi     create_appsearch_table(hdb);
4851f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4852f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4853f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4854f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4855f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4856f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4857f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4858f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4859f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4860f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4861f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4862f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4863c2c66affSColin Finck 
4864f860a780SAmine Khaldi     create_inilocator_table(hdb);
4865c2c66affSColin Finck 
4866c2c66affSColin Finck     /* msidbLocatorTypeRawValue, field 1 */
4867f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
4868c2c66affSColin Finck 
4869c2c66affSColin Finck     /* msidbLocatorTypeRawValue, field 2 */
4870f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
4871c2c66affSColin Finck 
4872c2c66affSColin Finck     /* msidbLocatorTypeRawValue, entire field */
4873f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
4874c2c66affSColin Finck 
4875c2c66affSColin Finck     /* msidbLocatorTypeFile */
4876f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4877c2c66affSColin Finck 
4878c2c66affSColin Finck     /* msidbLocatorTypeDirectory, file */
4879f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
4880c2c66affSColin Finck 
4881c2c66affSColin Finck     /* msidbLocatorTypeDirectory, directory */
4882f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
4883c2c66affSColin Finck 
4884c2c66affSColin Finck     /* msidbLocatorTypeFile, file, no signature */
4885f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4886c2c66affSColin Finck 
4887c2c66affSColin Finck     /* msidbLocatorTypeFile, dir, no signature */
4888f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
4889c2c66affSColin Finck 
4890c2c66affSColin Finck     /* msidbLocatorTypeFile, file does not exist */
4891f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
4892c2c66affSColin Finck 
4893c2c66affSColin Finck     /* msidbLocatorTypeFile, signature with version */
4894f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
4895c2c66affSColin Finck 
4896c2c66affSColin Finck     /* msidbLocatorTypeFile, signature with version, ver > max */
4897f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
4898c2c66affSColin Finck 
4899c2c66affSColin Finck     /* msidbLocatorTypeFile, signature with version, sig->name ignored */
4900f860a780SAmine Khaldi     add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
4901c2c66affSColin Finck 
4902f860a780SAmine Khaldi     create_signature_table(hdb);
4903f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
4904f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
4905f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4906f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4907f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4908c2c66affSColin Finck 
4909c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
4910c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4911c2c66affSColin Finck     {
4912c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
4913c2c66affSColin Finck         goto error;
4914c2c66affSColin Finck     }
4915c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4916c2c66affSColin Finck 
4917*f4be6dc3SMikhail     MsiCloseHandle( hdb );
4918c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4919c2c66affSColin Finck 
4920c2c66affSColin Finck     r = MsiDoActionA(hpkg, "AppSearch");
4921c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4922c2c66affSColin Finck 
4923c2c66affSColin Finck     size = MAX_PATH;
4924c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4925c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4926*f4be6dc3SMikhail     if (!prop[0])
4927*f4be6dc3SMikhail     {
4928*f4be6dc3SMikhail         win_skip("broken result\n");
4929*f4be6dc3SMikhail         MsiCloseHandle(hpkg);
4930*f4be6dc3SMikhail         goto error;
4931*f4be6dc3SMikhail     }
4932c2c66affSColin Finck     ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
4933c2c66affSColin Finck 
4934c2c66affSColin Finck     size = MAX_PATH;
4935c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4936c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4937c2c66affSColin Finck     ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
4938c2c66affSColin Finck 
4939c2c66affSColin Finck     size = MAX_PATH;
4940c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4941c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942c2c66affSColin Finck     ok(!lstrcmpA(prop, "keydata,field2"),
4943c2c66affSColin Finck        "Expected \"keydata,field2\", got \"%s\"\n", prop);
4944c2c66affSColin Finck 
4945c2c66affSColin Finck     size = MAX_PATH;
4946c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
4947c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4948c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4950c2c66affSColin Finck 
4951c2c66affSColin Finck     size = MAX_PATH;
4952c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4953c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4955c2c66affSColin Finck 
4956c2c66affSColin Finck     size = MAX_PATH;
4957c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4958c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4959c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4961c2c66affSColin Finck 
4962c2c66affSColin Finck     size = MAX_PATH;
4963c2c66affSColin Finck     sprintf(path, "%s\\", expected);
4964c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4965c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4966c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4967c2c66affSColin Finck 
4968c2c66affSColin Finck     if (!is_root(CURR_DIR))
4969c2c66affSColin Finck     {
4970c2c66affSColin Finck         size = MAX_PATH;
4971c2c66affSColin Finck         lstrcpyA(path, expected);
4972c2c66affSColin Finck         ptr = strrchr(path, '\\');
4973c2c66affSColin Finck         *(ptr + 1) = 0;
4974c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4975c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4976c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4977c2c66affSColin Finck     }
4978c2c66affSColin Finck     size = MAX_PATH;
4979c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4980c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4981c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4982c2c66affSColin Finck 
4983c2c66affSColin Finck     if (version)
4984c2c66affSColin Finck     {
4985c2c66affSColin Finck         size = MAX_PATH;
4986c2c66affSColin Finck         sprintf(path, "%s\\FileName2.dll", expected);
4987c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4988c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4989c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4990c2c66affSColin Finck 
4991c2c66affSColin Finck         size = MAX_PATH;
4992c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4993c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4994c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4995c2c66affSColin Finck 
4996c2c66affSColin Finck         size = MAX_PATH;
4997c2c66affSColin Finck         sprintf(path, "%s\\FileName4.dll", expected);
4998c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4999c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5000c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5001c2c66affSColin Finck     }
5002c2c66affSColin Finck 
5003c2c66affSColin Finck     MsiCloseHandle(hpkg);
5004c2c66affSColin Finck 
5005c2c66affSColin Finck error:
5006c2c66affSColin Finck     delete_win_ini("IniFile.ini");
5007c2c66affSColin Finck     DeleteFileA("FileName1");
5008c2c66affSColin Finck     DeleteFileA("FileName2.dll");
5009c2c66affSColin Finck     DeleteFileA("FileName3.dll");
5010c2c66affSColin Finck     DeleteFileA("FileName4.dll");
5011c2c66affSColin Finck     DeleteFileA(msifile);
5012c2c66affSColin Finck }
5013c2c66affSColin Finck 
5014c2c66affSColin Finck /*
5015c2c66affSColin Finck  * MSI AppSearch action on DrLocator table always returns absolute paths.
5016c2c66affSColin Finck  * If a relative path was set, it returns the first absolute path that
5017c2c66affSColin Finck  * matches or an empty string if it didn't find anything.
5018c2c66affSColin Finck  * This helper function replicates this behaviour.
5019c2c66affSColin Finck  */
search_absolute_directory(LPSTR absolute,LPCSTR relative)5020c2c66affSColin Finck static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5021c2c66affSColin Finck {
5022c2c66affSColin Finck     int i, size;
5023c2c66affSColin Finck     DWORD attr, drives;
5024c2c66affSColin Finck 
5025c2c66affSColin Finck     size = lstrlenA(relative);
5026c2c66affSColin Finck     drives = GetLogicalDrives();
5027c2c66affSColin Finck     lstrcpyA(absolute, "A:\\");
5028c2c66affSColin Finck     for (i = 0; i < 26; absolute[0] = '\0', i++)
5029c2c66affSColin Finck     {
5030c2c66affSColin Finck         if (!(drives & (1 << i)))
5031c2c66affSColin Finck             continue;
5032c2c66affSColin Finck 
5033c2c66affSColin Finck         absolute[0] = 'A' + i;
5034c2c66affSColin Finck         if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5035c2c66affSColin Finck             continue;
5036c2c66affSColin Finck 
5037c2c66affSColin Finck         lstrcpynA(absolute + 3, relative, size + 1);
5038c2c66affSColin Finck         attr = GetFileAttributesA(absolute);
5039c2c66affSColin Finck         if (attr != INVALID_FILE_ATTRIBUTES &&
5040c2c66affSColin Finck             (attr & FILE_ATTRIBUTE_DIRECTORY))
5041c2c66affSColin Finck         {
5042c2c66affSColin Finck             if (absolute[3 + size - 1] != '\\')
5043c2c66affSColin Finck                 lstrcatA(absolute, "\\");
5044c2c66affSColin Finck             break;
5045c2c66affSColin Finck         }
5046c2c66affSColin Finck         absolute[3] = '\0';
5047c2c66affSColin Finck     }
5048c2c66affSColin Finck }
5049c2c66affSColin Finck 
test_appsearch_drlocator(void)5050c2c66affSColin Finck static void test_appsearch_drlocator(void)
5051c2c66affSColin Finck {
5052c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
5053484e8280Swinesync     char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5054c2c66affSColin Finck     BOOL version;
5055c2c66affSColin Finck     DWORD size;
5056c2c66affSColin Finck     UINT r;
5057c2c66affSColin Finck 
5058c2c66affSColin Finck     version = TRUE;
5059c2c66affSColin Finck     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5060c2c66affSColin Finck         version = FALSE;
5061c2c66affSColin Finck 
5062c2c66affSColin Finck     DeleteFileA("test.dll");
5063c2c66affSColin Finck 
5064c2c66affSColin Finck     create_test_file("FileName1");
5065c2c66affSColin Finck     CreateDirectoryA("one", NULL);
5066c2c66affSColin Finck     CreateDirectoryA("one\\two", NULL);
5067c2c66affSColin Finck     CreateDirectoryA("one\\two\\three", NULL);
5068c2c66affSColin Finck     create_test_file("one\\two\\three\\FileName2");
5069c2c66affSColin Finck     CreateDirectoryA("another", NULL);
5070c2c66affSColin Finck     create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5071c2c66affSColin Finck     create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5072c2c66affSColin Finck     create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5073c2c66affSColin Finck 
5074c2c66affSColin Finck     hdb = create_package_db();
5075c2c66affSColin Finck     ok(hdb, "Expected a valid database handle\n");
5076c2c66affSColin Finck 
5077f860a780SAmine Khaldi     create_appsearch_table(hdb);
5078f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5079f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5080f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5081f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5082f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5083f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5084f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5085f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5086f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5087f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5088f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5089f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5090c2c66affSColin Finck 
5091f860a780SAmine Khaldi     create_drlocator_table(hdb);
5092c2c66affSColin Finck 
5093c2c66affSColin Finck     strcpy(expected, CURR_DIR);
5094c2c66affSColin Finck     if (is_root(CURR_DIR)) expected[2] = 0;
5095c2c66affSColin Finck 
5096c2c66affSColin Finck     /* no parent, full path, depth 0, signature */
5097c2c66affSColin Finck     sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5098f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5099c2c66affSColin Finck 
5100c2c66affSColin Finck     /* no parent, full path, depth 0, no signature */
5101c2c66affSColin Finck     sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5102f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5103c2c66affSColin Finck 
5104c2c66affSColin Finck     /* no parent, relative path, depth 0, no signature */
5105c2c66affSColin Finck     sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5106f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5107c2c66affSColin Finck 
5108c2c66affSColin Finck     /* no parent, full path, depth 2, signature */
5109c2c66affSColin Finck     sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5110f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5111c2c66affSColin Finck 
5112c2c66affSColin Finck     /* no parent, full path, depth 3, signature */
5113c2c66affSColin Finck     sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5114f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5115c2c66affSColin Finck 
5116c2c66affSColin Finck     /* no parent, full path, depth 1, signature is dir */
5117c2c66affSColin Finck     sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5118f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5119c2c66affSColin Finck 
5120c2c66affSColin Finck     /* parent is in DrLocator, relative path, depth 0, signature */
5121c2c66affSColin Finck     sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5122f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5123c2c66affSColin Finck 
5124c2c66affSColin Finck     /* no parent, full path, depth 0, signature w/ version */
5125c2c66affSColin Finck     sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5126f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5127c2c66affSColin Finck 
5128c2c66affSColin Finck     /* no parent, full path, depth 0, signature w/ version, ver > max */
5129c2c66affSColin Finck     sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5130f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5131c2c66affSColin Finck 
5132c2c66affSColin Finck     /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5133c2c66affSColin Finck     sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5134f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5135c2c66affSColin Finck 
5136c2c66affSColin Finck     /* no parent, relative empty path, depth 0, no signature */
5137c2c66affSColin Finck     sprintf(path, "'NewSignature11', '', '', 0");
5138f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5139c2c66affSColin Finck 
5140f860a780SAmine Khaldi     create_reglocator_table(hdb);
5141c2c66affSColin Finck 
5142c2c66affSColin Finck     /* parent */
5143f860a780SAmine Khaldi     add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5144c2c66affSColin Finck 
5145c2c66affSColin Finck     /* parent is in RegLocator, no path, depth 0, no signature */
5146c2c66affSColin Finck     sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5147f860a780SAmine Khaldi     add_drlocator_entry(hdb, path);
5148c2c66affSColin Finck 
5149f860a780SAmine Khaldi     create_signature_table(hdb);
5150f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5151f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5152f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5153f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5154f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5155f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5156f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5157f860a780SAmine Khaldi     add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5158c2c66affSColin Finck 
5159c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
5160c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5161c2c66affSColin Finck     {
5162c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5163c2c66affSColin Finck         goto error;
5164c2c66affSColin Finck     }
5165c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5166c2c66affSColin Finck 
5167c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5168c2c66affSColin Finck 
5169c2c66affSColin Finck     r = MsiDoActionA(hpkg, "AppSearch");
5170c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5171c2c66affSColin Finck 
5172c2c66affSColin Finck     size = MAX_PATH;
5173c2c66affSColin Finck     sprintf(path, "%s\\FileName1", expected);
5174c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5175c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5176c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5177c2c66affSColin Finck 
5178c2c66affSColin Finck     size = MAX_PATH;
5179c2c66affSColin Finck     sprintf(path, "%s\\", expected);
5180c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5181c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5182c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5183c2c66affSColin Finck 
5184c2c66affSColin Finck     size = MAX_PATH;
5185c2c66affSColin Finck     search_absolute_directory(path, expected + 3);
5186c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5187c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5188c2c66affSColin Finck     ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5189c2c66affSColin Finck 
5190c2c66affSColin Finck     size = MAX_PATH;
5191c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5192c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5193c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5194c2c66affSColin Finck 
5195c2c66affSColin Finck     size = MAX_PATH;
5196c2c66affSColin Finck     sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5197c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5198c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5199c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5200c2c66affSColin Finck 
5201c2c66affSColin Finck     size = MAX_PATH;
5202c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5203c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5204c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5205c2c66affSColin Finck 
5206c2c66affSColin Finck     size = MAX_PATH;
5207c2c66affSColin Finck     sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5208c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5209c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5210c2c66affSColin Finck     ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5211c2c66affSColin Finck 
5212c2c66affSColin Finck     if (version)
5213c2c66affSColin Finck     {
5214c2c66affSColin Finck         size = MAX_PATH;
5215c2c66affSColin Finck         sprintf(path, "%s\\FileName3.dll", expected);
5216c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5217c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5218c2c66affSColin Finck         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5219c2c66affSColin Finck 
5220c2c66affSColin Finck         size = MAX_PATH;
5221c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5222c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5223c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5224c2c66affSColin Finck 
5225c2c66affSColin Finck         size = MAX_PATH;
5226c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5227c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5228c2c66affSColin Finck         ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5229c2c66affSColin Finck     }
5230c2c66affSColin Finck 
5231c2c66affSColin Finck     size = MAX_PATH;
5232c2c66affSColin Finck     search_absolute_directory(path, "");
5233c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5234c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235c2c66affSColin Finck     ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5236c2c66affSColin Finck 
5237c2c66affSColin Finck     size = MAX_PATH;
5238c2c66affSColin Finck     strcpy(path, "c:\\");
5239c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5240c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241c2c66affSColin Finck     ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5242c2c66affSColin Finck 
5243c2c66affSColin Finck     MsiCloseHandle(hpkg);
5244c2c66affSColin Finck 
5245c2c66affSColin Finck error:
5246c2c66affSColin Finck     DeleteFileA("FileName1");
5247c2c66affSColin Finck     DeleteFileA("FileName3.dll");
5248c2c66affSColin Finck     DeleteFileA("FileName4.dll");
5249c2c66affSColin Finck     DeleteFileA("FileName5.dll");
5250c2c66affSColin Finck     DeleteFileA("one\\two\\three\\FileName2");
5251c2c66affSColin Finck     RemoveDirectoryA("one\\two\\three");
5252c2c66affSColin Finck     RemoveDirectoryA("one\\two");
5253c2c66affSColin Finck     RemoveDirectoryA("one");
5254c2c66affSColin Finck     RemoveDirectoryA("another");
5255c2c66affSColin Finck     DeleteFileA(msifile);
5256c2c66affSColin Finck }
5257c2c66affSColin Finck 
test_featureparents(void)5258c2c66affSColin Finck static void test_featureparents(void)
5259c2c66affSColin Finck {
5260c2c66affSColin Finck     MSIHANDLE hpkg;
5261c2c66affSColin Finck     UINT r;
5262c2c66affSColin Finck     MSIHANDLE hdb;
5263c2c66affSColin Finck 
5264c2c66affSColin Finck     hdb = create_package_db();
5265c2c66affSColin Finck     ok ( hdb, "failed to create package database\n" );
5266c2c66affSColin Finck 
5267f860a780SAmine Khaldi     add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5268c2c66affSColin Finck 
5269f860a780SAmine Khaldi     create_feature_table( hdb );
5270f860a780SAmine Khaldi     create_component_table( hdb );
5271f860a780SAmine Khaldi     create_feature_components_table( hdb );
5272f860a780SAmine Khaldi     create_file_table( hdb );
5273c2c66affSColin Finck 
5274c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal */
5275f860a780SAmine Khaldi     add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5276c2c66affSColin Finck 
5277c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource */
5278f860a780SAmine Khaldi     add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5279c2c66affSColin Finck 
5280c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal */
5281f860a780SAmine Khaldi     add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5282c2c66affSColin Finck 
5283c2c66affSColin Finck     /* msidbFeatureAttributesUIDisallowAbsent */
5284f860a780SAmine Khaldi     add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5285c2c66affSColin Finck 
5286c2c66affSColin Finck     /* disabled because of install level */
5287f860a780SAmine Khaldi     add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5288c2c66affSColin Finck 
5289c2c66affSColin Finck     /* child feature of disabled feature */
5290f860a780SAmine Khaldi     add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5291c2c66affSColin Finck 
5292c2c66affSColin Finck     /* component of disabled feature (install level) */
5293f860a780SAmine Khaldi     add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5294c2c66affSColin Finck 
5295c2c66affSColin Finck     /* component of disabled child feature (install level) */
5296f860a780SAmine Khaldi     add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5297c2c66affSColin Finck 
5298c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5299f860a780SAmine Khaldi     add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5300c2c66affSColin Finck 
5301c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5302f860a780SAmine Khaldi     add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5303c2c66affSColin Finck 
5304c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5305f860a780SAmine Khaldi     add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5306c2c66affSColin Finck 
5307c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5308f860a780SAmine Khaldi     add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5309c2c66affSColin Finck 
5310c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5311f860a780SAmine Khaldi     add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5312c2c66affSColin Finck 
5313c2c66affSColin Finck     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5314f860a780SAmine Khaldi     add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5315c2c66affSColin Finck 
5316c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5317f860a780SAmine Khaldi     add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5318c2c66affSColin Finck 
5319c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5320f860a780SAmine Khaldi     add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5321c2c66affSColin Finck 
5322c2c66affSColin Finck     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5323f860a780SAmine Khaldi     add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5324c2c66affSColin Finck 
5325f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5326f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5327f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5328f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5329f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5330f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5331f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'leo'" );
5332f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'virgo'" );
5333f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'libra'" );
5334f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5335f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5336f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5337f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'canis'" );
5338f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5339f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'orion', 'lepus'" );
5340f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5341f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5342c2c66affSColin Finck 
5343f860a780SAmine Khaldi     add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5344f860a780SAmine Khaldi     add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5345f860a780SAmine Khaldi     add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5346f860a780SAmine Khaldi     add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5347f860a780SAmine Khaldi     add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5348f860a780SAmine Khaldi     add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5349f860a780SAmine Khaldi     add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5350f860a780SAmine Khaldi     add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5351f860a780SAmine Khaldi     add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5352f860a780SAmine Khaldi     add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5353f860a780SAmine Khaldi     add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5354c2c66affSColin Finck 
5355c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
5356c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5357c2c66affSColin Finck     {
5358c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5359c2c66affSColin Finck         DeleteFileA(msifile);
5360c2c66affSColin Finck         return;
5361c2c66affSColin Finck     }
5362c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5363c2c66affSColin Finck 
5364c2c66affSColin Finck     MsiCloseHandle( hdb );
5365c2c66affSColin Finck 
5366c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5367c2c66affSColin Finck 
5368c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize");
5369c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n");
5370c2c66affSColin Finck 
5371c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost");
5372c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "file cost failed\n");
5373c2c66affSColin Finck 
5374c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize");
5375c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5376c2c66affSColin Finck 
5377c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5378c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5379c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5380c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5381c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5382c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5383c2c66affSColin Finck 
5384c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5385c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5386c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5387c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5388c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5389c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5390c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5391c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5392c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5393c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5394c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5395c2c66affSColin Finck 
5396c2c66affSColin Finck     r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5397c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5398c2c66affSColin Finck 
5399c2c66affSColin Finck     r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5400c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5401c2c66affSColin Finck 
5402c2c66affSColin Finck     r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5403c2c66affSColin Finck     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5404c2c66affSColin Finck 
5405c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5406c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5407c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5408c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5409c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5410c2c66affSColin Finck     test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5411c2c66affSColin Finck 
5412c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5413c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5414c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5415c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5416c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5417c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5418c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5419c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5420c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5421c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5422c2c66affSColin Finck     test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5423c2c66affSColin Finck 
5424c2c66affSColin Finck     MsiCloseHandle(hpkg);
5425c2c66affSColin Finck     DeleteFileA(msifile);
5426c2c66affSColin Finck }
5427c2c66affSColin Finck 
test_installprops(void)5428c2c66affSColin Finck static void test_installprops(void)
5429c2c66affSColin Finck {
5430c2c66affSColin Finck     MSIHANDLE hpkg, hdb;
5431c2c66affSColin Finck     CHAR path[MAX_PATH], buf[MAX_PATH];
5432c2c66affSColin Finck     DWORD size, type;
5433c2c66affSColin Finck     LANGID langid;
5434*f4be6dc3SMikhail     HKEY hkey1, hkey2, pathkey = NULL;
5435c2c66affSColin Finck     int res;
5436c2c66affSColin Finck     UINT r;
5437c2c66affSColin Finck     REGSAM access = KEY_ALL_ACCESS;
5438c2c66affSColin Finck     SYSTEM_INFO si;
5439c2c66affSColin Finck     INSTALLUILEVEL uilevel;
5440c2c66affSColin Finck 
5441c2c66affSColin Finck     if (is_wow64)
5442c2c66affSColin Finck         access |= KEY_WOW64_64KEY;
5443c2c66affSColin Finck 
5444c2c66affSColin Finck     lstrcpyA(path, CURR_DIR);
5445c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5446c2c66affSColin Finck     lstrcatA(path, msifile);
5447c2c66affSColin Finck 
5448c2c66affSColin Finck     uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5449c2c66affSColin Finck 
5450c2c66affSColin Finck     hdb = create_package_db();
5451c2c66affSColin Finck     ok( hdb, "failed to create database\n");
5452c2c66affSColin Finck 
5453c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
5454c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5455c2c66affSColin Finck     {
5456c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5457c2c66affSColin Finck         MsiSetInternalUI(uilevel, NULL);
5458c2c66affSColin Finck         DeleteFileA(msifile);
5459c2c66affSColin Finck         return;
5460c2c66affSColin Finck     }
5461c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5462c2c66affSColin Finck 
5463c2c66affSColin Finck     MsiCloseHandle(hdb);
5464c2c66affSColin Finck 
5465c2c66affSColin Finck     buf[0] = 0;
5466c2c66affSColin Finck     size = MAX_PATH;
5467c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5468c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5469c2c66affSColin Finck     ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5470c2c66affSColin Finck 
5471c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5472c2c66affSColin Finck 
5473c2c66affSColin Finck     buf[0] = 0;
5474c2c66affSColin Finck     size = MAX_PATH;
5475c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5476c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5477c2c66affSColin Finck     ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5478c2c66affSColin Finck 
5479c2c66affSColin Finck     buf[0] = 0;
5480c2c66affSColin Finck     size = MAX_PATH;
5481c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5482c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5483c2c66affSColin Finck     ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5484c2c66affSColin Finck 
5485c2c66affSColin Finck     RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5486*f4be6dc3SMikhail     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5487*f4be6dc3SMikhail     if (res == ERROR_ACCESS_DENIED)
5488*f4be6dc3SMikhail     {
5489*f4be6dc3SMikhail         win_skip("no access\n");
5490*f4be6dc3SMikhail         goto done;
5491*f4be6dc3SMikhail     }
54923ec0ea99Swinesync     RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
54933ec0ea99Swinesync         0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5494c2c66affSColin Finck 
5495c2c66affSColin Finck     size = MAX_PATH;
5496c2c66affSColin Finck     type = REG_SZ;
5497c2c66affSColin Finck     *path = '\0';
5498c2c66affSColin Finck     if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5499c2c66affSColin Finck     {
5500c2c66affSColin Finck         size = MAX_PATH;
5501c2c66affSColin Finck         type = REG_SZ;
5502c2c66affSColin Finck         RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5503c2c66affSColin Finck     }
5504c2c66affSColin Finck 
5505c2c66affSColin Finck     buf[0] = 0;
5506c2c66affSColin Finck     size = MAX_PATH;
5507c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5508c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5509c2c66affSColin Finck     ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5510c2c66affSColin Finck 
5511c2c66affSColin Finck     size = MAX_PATH;
5512c2c66affSColin Finck     type = REG_SZ;
5513c2c66affSColin Finck     *path = '\0';
5514c2c66affSColin Finck     if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5515c2c66affSColin Finck     {
5516c2c66affSColin Finck         size = MAX_PATH;
5517c2c66affSColin Finck         type = REG_SZ;
5518c2c66affSColin Finck         RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5519c2c66affSColin Finck     }
5520c2c66affSColin Finck 
5521c2c66affSColin Finck     if (*path)
5522c2c66affSColin Finck     {
5523c2c66affSColin Finck         buf[0] = 0;
5524c2c66affSColin Finck         size = MAX_PATH;
5525c2c66affSColin Finck         r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5526c2c66affSColin Finck         ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5527c2c66affSColin Finck         ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5528c2c66affSColin Finck     }
5529c2c66affSColin Finck 
5530c2c66affSColin Finck     buf[0] = 0;
5531c2c66affSColin Finck     size = MAX_PATH;
5532c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5533c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5534c2c66affSColin Finck     trace("VersionDatabase = %s\n", buf);
5535c2c66affSColin Finck 
5536c2c66affSColin Finck     buf[0] = 0;
5537c2c66affSColin Finck     size = MAX_PATH;
5538c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5539c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5540c2c66affSColin Finck     trace("VersionMsi = %s\n", buf);
5541c2c66affSColin Finck 
5542c2c66affSColin Finck     buf[0] = 0;
5543c2c66affSColin Finck     size = MAX_PATH;
5544c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5545c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5546c2c66affSColin Finck     trace("Date = %s\n", buf);
5547c2c66affSColin Finck 
5548c2c66affSColin Finck     buf[0] = 0;
5549c2c66affSColin Finck     size = MAX_PATH;
5550c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5551c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5552c2c66affSColin Finck     trace("Time = %s\n", buf);
5553c2c66affSColin Finck 
5554c2c66affSColin Finck     buf[0] = 0;
5555c2c66affSColin Finck     size = MAX_PATH;
5556c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5557c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5558c2c66affSColin Finck     trace("PackageCode = %s\n", buf);
5559c2c66affSColin Finck 
5560c2c66affSColin Finck     buf[0] = 0;
5561c2c66affSColin Finck     size = MAX_PATH;
5562c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5563c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5564c2c66affSColin Finck     trace("ComputerName = %s\n", buf);
5565c2c66affSColin Finck 
5566c2c66affSColin Finck     langid = GetUserDefaultLangID();
5567c2c66affSColin Finck     sprintf(path, "%d", langid);
5568c2c66affSColin Finck 
5569c2c66affSColin Finck     buf[0] = 0;
5570c2c66affSColin Finck     size = MAX_PATH;
5571c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5572c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5573c2c66affSColin Finck     ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5574c2c66affSColin Finck 
5575c2c66affSColin Finck     res = GetSystemMetrics(SM_CXSCREEN);
5576c2c66affSColin Finck     buf[0] = 0;
5577c2c66affSColin Finck     size = MAX_PATH;
5578c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5579c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
55803b835aa0Swinesync     ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5581c2c66affSColin Finck 
5582c2c66affSColin Finck     res = GetSystemMetrics(SM_CYSCREEN);
5583c2c66affSColin Finck     buf[0] = 0;
5584c2c66affSColin Finck     size = MAX_PATH;
5585c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5586c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
55873b835aa0Swinesync     ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5588c2c66affSColin Finck 
558931139640SAmine Khaldi     buf[0] = 0;
559031139640SAmine Khaldi     size = MAX_PATH;
559131139640SAmine Khaldi     r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
559231139640SAmine Khaldi     if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
559331139640SAmine Khaldi 
5594a4930636Swinesync     GetNativeSystemInfo(&si);
55953ec0ea99Swinesync 
5596b6228b29Swinesync     sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5597*f4be6dc3SMikhail     check_prop(hpkg, "VersionNT", buf, 1, 1);
5598b6228b29Swinesync 
5599*f4be6dc3SMikhail     if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5600c2c66affSColin Finck     {
56013ec0ea99Swinesync         sprintf(buf, "%d", si.wProcessorLevel);
5602*f4be6dc3SMikhail         check_prop(hpkg, "Intel", buf, 1, 0);
5603*f4be6dc3SMikhail         check_prop(hpkg, "MsiAMD64", buf, 1, 0);
5604*f4be6dc3SMikhail         check_prop(hpkg, "Msix64", buf, 1, 0);
56053ec0ea99Swinesync         sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5606*f4be6dc3SMikhail         check_prop(hpkg, "VersionNT64", buf, 1, 1);
5607c2c66affSColin Finck 
5608c2c66affSColin Finck         GetSystemDirectoryA(path, MAX_PATH);
56093ec0ea99Swinesync         strcat(path, "\\");
5610*f4be6dc3SMikhail         check_prop(hpkg, "System64Folder", path, 0, 0);
5611c2c66affSColin Finck 
5612a4930636Swinesync         GetSystemWow64DirectoryA(path, MAX_PATH);
56133ec0ea99Swinesync         strcat(path, "\\");
5614*f4be6dc3SMikhail         check_prop(hpkg, "SystemFolder", path, 0, 0);
5615c2c66affSColin Finck 
5616c2c66affSColin Finck         size = MAX_PATH;
56173ec0ea99Swinesync         r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
56183ec0ea99Swinesync         strcat(path, "\\");
5619*f4be6dc3SMikhail         check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5620c2c66affSColin Finck 
5621c2c66affSColin Finck         size = MAX_PATH;
56223ec0ea99Swinesync         RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
56233ec0ea99Swinesync         strcat(path, "\\");
5624*f4be6dc3SMikhail         check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0);
5625c2c66affSColin Finck 
5626c2c66affSColin Finck         size = MAX_PATH;
56273ec0ea99Swinesync         RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
56283ec0ea99Swinesync         strcat(path, "\\");
5629*f4be6dc3SMikhail         check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5630c2c66affSColin Finck 
5631c2c66affSColin Finck         size = MAX_PATH;
56323ec0ea99Swinesync         RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
56333ec0ea99Swinesync         strcat(path, "\\");
5634*f4be6dc3SMikhail         check_prop(hpkg, "CommonFiles64Folder", path, 0, 0);
5635c2c66affSColin Finck     }
5636*f4be6dc3SMikhail     else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5637c2c66affSColin Finck     {
56383ec0ea99Swinesync         sprintf(buf, "%d", si.wProcessorLevel);
5639*f4be6dc3SMikhail         check_prop(hpkg, "Intel", buf, 1, 0);
5640c2c66affSColin Finck 
5641c2c66affSColin Finck         GetSystemDirectoryA(path, MAX_PATH);
56423ec0ea99Swinesync         strcat(path, "\\");
5643*f4be6dc3SMikhail         check_prop(hpkg, "SystemFolder", path, 0, 0);
5644c2c66affSColin Finck 
5645c2c66affSColin Finck         size = MAX_PATH;
56463ec0ea99Swinesync         RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
56473ec0ea99Swinesync         strcat(path, "\\");
5648*f4be6dc3SMikhail         check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5649c2c66affSColin Finck 
5650c2c66affSColin Finck         size = MAX_PATH;
56513ec0ea99Swinesync         RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
56523ec0ea99Swinesync         strcat(path, "\\");
5653*f4be6dc3SMikhail         check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5654c2c66affSColin Finck 
5655*f4be6dc3SMikhail         check_prop(hpkg, "MsiAMD64", "", 1, 0);
5656*f4be6dc3SMikhail         check_prop(hpkg, "Msix64", "", 1, 0);
5657*f4be6dc3SMikhail         check_prop(hpkg, "VersionNT64", "", 1, 0);
5658*f4be6dc3SMikhail         check_prop(hpkg, "System64Folder", "", 0, 0);
5659*f4be6dc3SMikhail         check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0);
5660*f4be6dc3SMikhail         check_prop(hpkg, "CommonFiles64Dir", "", 0, 0);
5661c2c66affSColin Finck     }
5662c2c66affSColin Finck 
5663*f4be6dc3SMikhail done:
5664c2c66affSColin Finck     CloseHandle(hkey1);
5665c2c66affSColin Finck     CloseHandle(hkey2);
56663ec0ea99Swinesync     RegCloseKey(pathkey);
5667c2c66affSColin Finck     MsiCloseHandle(hpkg);
5668c2c66affSColin Finck     DeleteFileA(msifile);
5669c2c66affSColin Finck     MsiSetInternalUI(uilevel, NULL);
5670c2c66affSColin Finck }
5671c2c66affSColin Finck 
test_launchconditions(void)5672c2c66affSColin Finck static void test_launchconditions(void)
5673c2c66affSColin Finck {
5674c2c66affSColin Finck     MSIHANDLE hpkg;
5675c2c66affSColin Finck     MSIHANDLE hdb;
5676c2c66affSColin Finck     UINT r;
5677c2c66affSColin Finck 
5678c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5679c2c66affSColin Finck 
5680c2c66affSColin Finck     hdb = create_package_db();
5681c2c66affSColin Finck     ok( hdb, "failed to create package database\n" );
5682c2c66affSColin Finck 
5683f860a780SAmine Khaldi     create_launchcondition_table( hdb );
5684c2c66affSColin Finck 
5685f860a780SAmine Khaldi     add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5686c2c66affSColin Finck 
5687c2c66affSColin Finck     /* invalid condition */
5688f860a780SAmine Khaldi     add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5689c2c66affSColin Finck 
5690c2c66affSColin Finck     r = package_from_db( hdb, &hpkg );
5691c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5692c2c66affSColin Finck     {
5693c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5694c2c66affSColin Finck         DeleteFileA(msifile);
5695c2c66affSColin Finck         return;
5696c2c66affSColin Finck     }
5697c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5698c2c66affSColin Finck 
5699c2c66affSColin Finck     MsiCloseHandle( hdb );
5700c2c66affSColin Finck 
5701c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "X", "1" );
5702c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set property\n" );
5703c2c66affSColin Finck 
5704c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5705c2c66affSColin Finck 
5706c2c66affSColin Finck     /* invalid conditions are ignored */
5707c2c66affSColin Finck     r = MsiDoActionA( hpkg, "LaunchConditions" );
5708c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "cost init failed\n" );
5709c2c66affSColin Finck 
5710c2c66affSColin Finck     /* verify LaunchConditions still does some verification */
5711c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "X", "2" );
5712c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "failed to set property\n" );
5713c2c66affSColin Finck 
5714c2c66affSColin Finck     r = MsiDoActionA( hpkg, "LaunchConditions" );
5715c2c66affSColin Finck     ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5716c2c66affSColin Finck 
5717c2c66affSColin Finck     MsiCloseHandle( hpkg );
5718c2c66affSColin Finck     DeleteFileA( msifile );
5719c2c66affSColin Finck }
5720c2c66affSColin Finck 
test_ccpsearch(void)5721c2c66affSColin Finck static void test_ccpsearch(void)
5722c2c66affSColin Finck {
5723c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
5724c2c66affSColin Finck     CHAR prop[MAX_PATH];
5725c2c66affSColin Finck     DWORD size = MAX_PATH;
5726c2c66affSColin Finck     UINT r;
5727c2c66affSColin Finck 
5728c2c66affSColin Finck     hdb = create_package_db();
5729c2c66affSColin Finck     ok(hdb, "failed to create package database\n");
5730c2c66affSColin Finck 
5731f860a780SAmine Khaldi     create_ccpsearch_table(hdb);
5732f860a780SAmine Khaldi     add_ccpsearch_entry(hdb, "'CCP_random'");
5733f860a780SAmine Khaldi     add_ccpsearch_entry(hdb, "'RMCCP_random'");
5734c2c66affSColin Finck 
5735f860a780SAmine Khaldi     create_reglocator_table(hdb);
5736f860a780SAmine Khaldi     add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5737c2c66affSColin Finck 
5738f860a780SAmine Khaldi     create_drlocator_table(hdb);
5739f860a780SAmine Khaldi     add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5740c2c66affSColin Finck 
5741f860a780SAmine Khaldi     create_signature_table(hdb);
5742c2c66affSColin Finck 
5743c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
5744c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5745c2c66affSColin Finck     {
5746c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5747c2c66affSColin Finck         DeleteFileA(msifile);
5748c2c66affSColin Finck         return;
5749c2c66affSColin Finck     }
5750c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5751c2c66affSColin Finck 
5752c2c66affSColin Finck     MsiCloseHandle(hdb);
5753c2c66affSColin Finck 
5754c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5755c2c66affSColin Finck 
5756c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CCPSearch");
5757c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5758c2c66affSColin Finck 
5759c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5760c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5761c2c66affSColin Finck     ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5762c2c66affSColin Finck 
5763c2c66affSColin Finck     MsiCloseHandle(hpkg);
5764c2c66affSColin Finck     DeleteFileA(msifile);
5765c2c66affSColin Finck }
5766c2c66affSColin Finck 
test_complocator(void)5767c2c66affSColin Finck static void test_complocator(void)
5768c2c66affSColin Finck {
5769c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
5770c2c66affSColin Finck     UINT r;
5771c2c66affSColin Finck     CHAR prop[MAX_PATH];
5772c2c66affSColin Finck     CHAR expected[MAX_PATH];
5773c2c66affSColin Finck     DWORD size = MAX_PATH;
5774c2c66affSColin Finck 
5775c2c66affSColin Finck     hdb = create_package_db();
5776c2c66affSColin Finck     ok(hdb, "failed to create package database\n");
5777c2c66affSColin Finck 
5778f860a780SAmine Khaldi     create_appsearch_table(hdb);
5779f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5780f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5781f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5782f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5783f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5784f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5785f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5786f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5787f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5788f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5789f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5790f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5791f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5792f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5793f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5794f860a780SAmine Khaldi     add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5795c2c66affSColin Finck 
5796f860a780SAmine Khaldi     create_complocator_table(hdb);
5797f860a780SAmine Khaldi     add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5798f860a780SAmine Khaldi     add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5799f860a780SAmine Khaldi     add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5800f860a780SAmine Khaldi     add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5801f860a780SAmine Khaldi     add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5802f860a780SAmine Khaldi     add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5803f860a780SAmine Khaldi     add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5804f860a780SAmine Khaldi     add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5805f860a780SAmine Khaldi     add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5806f860a780SAmine Khaldi     add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5807f860a780SAmine Khaldi     add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5808f860a780SAmine Khaldi     add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5809f860a780SAmine Khaldi     add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5810f860a780SAmine Khaldi     add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5811f860a780SAmine Khaldi     add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5812f860a780SAmine Khaldi     add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5813c2c66affSColin Finck 
5814f860a780SAmine Khaldi     create_signature_table(hdb);
5815f860a780SAmine Khaldi     add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5816f860a780SAmine Khaldi     add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5817f860a780SAmine Khaldi     add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5818f860a780SAmine Khaldi     add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5819f860a780SAmine Khaldi     add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5820f860a780SAmine Khaldi     add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5821f860a780SAmine Khaldi     add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5822f860a780SAmine Khaldi     add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5823c2c66affSColin Finck 
5824c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
5825c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5826c2c66affSColin Finck     {
5827c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
5828c2c66affSColin Finck         DeleteFileA(msifile);
5829c2c66affSColin Finck         return;
5830c2c66affSColin Finck     }
5831c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5832c2c66affSColin Finck 
5833c2c66affSColin Finck     MsiCloseHandle(hdb);
5834c2c66affSColin Finck 
5835c2c66affSColin Finck     create_test_file("abelisaurus");
5836c2c66affSColin Finck     create_test_file("bactrosaurus");
5837c2c66affSColin Finck     create_test_file("camelotia");
5838c2c66affSColin Finck     create_test_file("diclonius");
5839c2c66affSColin Finck     create_test_file("echinodon");
5840c2c66affSColin Finck     create_test_file("falcarius");
5841c2c66affSColin Finck     create_test_file("gallimimus");
5842c2c66affSColin Finck     create_test_file("hagryphus");
5843c2c66affSColin Finck     CreateDirectoryA("iguanodon", NULL);
5844c2c66affSColin Finck     CreateDirectoryA("jobaria", NULL);
5845c2c66affSColin Finck     CreateDirectoryA("kakuru", NULL);
5846c2c66affSColin Finck     CreateDirectoryA("labocania", NULL);
5847c2c66affSColin Finck     CreateDirectoryA("megaraptor", NULL);
5848c2c66affSColin Finck     CreateDirectoryA("neosodon", NULL);
5849c2c66affSColin Finck     CreateDirectoryA("olorotitan", NULL);
5850c2c66affSColin Finck     CreateDirectoryA("pantydraco", NULL);
5851c2c66affSColin Finck 
5852c2c66affSColin Finck     set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
5853c2c66affSColin Finck                        "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5854c2c66affSColin Finck     set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
5855c2c66affSColin Finck                        "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5856c2c66affSColin Finck     set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
5857c2c66affSColin Finck                        "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5858c2c66affSColin Finck     set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
5859c2c66affSColin Finck                        "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
5860c2c66affSColin Finck     set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
5861c2c66affSColin Finck                        "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
5862c2c66affSColin Finck     set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
5863c2c66affSColin Finck                        "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
5864c2c66affSColin Finck     set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
5865c2c66affSColin Finck                        "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
5866c2c66affSColin Finck     set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
5867c2c66affSColin Finck                        "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
5868c2c66affSColin Finck 
5869c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5870c2c66affSColin Finck 
5871c2c66affSColin Finck     r = MsiDoActionA(hpkg, "AppSearch");
5872c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5873c2c66affSColin Finck 
5874c2c66affSColin Finck     size = MAX_PATH;
5875c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
5876c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5877c2c66affSColin Finck 
5878c2c66affSColin Finck     lstrcpyA(expected, CURR_DIR);
5879c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5880c2c66affSColin Finck     lstrcatA(expected, "abelisaurus");
5881c2c66affSColin Finck     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5882c2c66affSColin Finck        "Expected %s or empty string, got %s\n", expected, prop);
5883c2c66affSColin Finck 
5884c2c66affSColin Finck     size = MAX_PATH;
5885c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
5886c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5887c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5888c2c66affSColin Finck 
5889c2c66affSColin Finck     size = MAX_PATH;
5890c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
5891c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5892c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5893c2c66affSColin Finck 
5894c2c66affSColin Finck     size = MAX_PATH;
5895c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
5896c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5897c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5898c2c66affSColin Finck 
5899c2c66affSColin Finck     size = MAX_PATH;
5900c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
5901c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5902c2c66affSColin Finck 
5903c2c66affSColin Finck     lstrcpyA(expected, CURR_DIR);
5904c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5905c2c66affSColin Finck     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5906c2c66affSColin Finck        "Expected %s or empty string, got %s\n", expected, prop);
5907c2c66affSColin Finck 
5908c2c66affSColin Finck     size = MAX_PATH;
5909c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
5910c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5911c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5912c2c66affSColin Finck 
5913c2c66affSColin Finck     size = MAX_PATH;
5914c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
5915c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5916c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5917c2c66affSColin Finck 
5918c2c66affSColin Finck     size = MAX_PATH;
5919c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
5920c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5921c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5922c2c66affSColin Finck 
5923c2c66affSColin Finck     size = MAX_PATH;
5924c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
5925c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5926c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5927c2c66affSColin Finck 
5928c2c66affSColin Finck     size = MAX_PATH;
5929c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
5930c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5931c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5932c2c66affSColin Finck 
5933c2c66affSColin Finck     size = MAX_PATH;
5934c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
5935c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5936c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5937c2c66affSColin Finck 
5938c2c66affSColin Finck     size = MAX_PATH;
5939c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
5940c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5941c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5942c2c66affSColin Finck 
5943c2c66affSColin Finck     size = MAX_PATH;
5944c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
5945c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5946c2c66affSColin Finck 
5947c2c66affSColin Finck     lstrcpyA(expected, CURR_DIR);
5948c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5949c2c66affSColin Finck     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5950c2c66affSColin Finck        "Expected %s or empty string, got %s\n", expected, prop);
5951c2c66affSColin Finck 
5952c2c66affSColin Finck     size = MAX_PATH;
5953c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
5954c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5955c2c66affSColin Finck 
5956c2c66affSColin Finck     lstrcpyA(expected, CURR_DIR);
5957c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5958c2c66affSColin Finck     lstrcatA(expected, "neosodon\\");
5959c2c66affSColin Finck     ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5960c2c66affSColin Finck        "Expected %s or empty string, got %s\n", expected, prop);
5961c2c66affSColin Finck 
5962c2c66affSColin Finck     size = MAX_PATH;
5963c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
5964c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5965c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5966c2c66affSColin Finck 
5967c2c66affSColin Finck     size = MAX_PATH;
5968c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
5969c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5970c2c66affSColin Finck     ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5971c2c66affSColin Finck 
5972c2c66affSColin Finck     MsiCloseHandle(hpkg);
5973c2c66affSColin Finck     DeleteFileA("abelisaurus");
5974c2c66affSColin Finck     DeleteFileA("bactrosaurus");
5975c2c66affSColin Finck     DeleteFileA("camelotia");
5976c2c66affSColin Finck     DeleteFileA("diclonius");
5977c2c66affSColin Finck     DeleteFileA("echinodon");
5978c2c66affSColin Finck     DeleteFileA("falcarius");
5979c2c66affSColin Finck     DeleteFileA("gallimimus");
5980c2c66affSColin Finck     DeleteFileA("hagryphus");
5981c2c66affSColin Finck     RemoveDirectoryA("iguanodon");
5982c2c66affSColin Finck     RemoveDirectoryA("jobaria");
5983c2c66affSColin Finck     RemoveDirectoryA("kakuru");
5984c2c66affSColin Finck     RemoveDirectoryA("labocania");
5985c2c66affSColin Finck     RemoveDirectoryA("megaraptor");
5986c2c66affSColin Finck     RemoveDirectoryA("neosodon");
5987c2c66affSColin Finck     RemoveDirectoryA("olorotitan");
5988c2c66affSColin Finck     RemoveDirectoryA("pantydraco");
5989c2c66affSColin Finck     delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
5990c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
5991c2c66affSColin Finck     delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
5992c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
5993c2c66affSColin Finck     delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
5994c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
5995c2c66affSColin Finck     delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
5996c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
5997c2c66affSColin Finck     delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
5998c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
5999c2c66affSColin Finck     delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6000c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
6001c2c66affSColin Finck     delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6002c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
6003c2c66affSColin Finck     delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6004c2c66affSColin Finck                           MSIINSTALLCONTEXT_MACHINE, NULL);
6005c2c66affSColin Finck     DeleteFileA(msifile);
6006c2c66affSColin Finck }
6007c2c66affSColin Finck 
set_suminfo_prop(MSIHANDLE db,DWORD prop,DWORD val)6008c2c66affSColin Finck static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6009c2c66affSColin Finck {
6010c2c66affSColin Finck     MSIHANDLE summary;
6011c2c66affSColin Finck     UINT r;
6012c2c66affSColin Finck 
6013c2c66affSColin Finck     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6014c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6015c2c66affSColin Finck 
6016c2c66affSColin Finck     r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6017c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6018c2c66affSColin Finck 
6019c2c66affSColin Finck     r = MsiSummaryInfoPersist(summary);
6020c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6021c2c66affSColin Finck 
6022c2c66affSColin Finck     MsiCloseHandle(summary);
6023c2c66affSColin Finck }
6024c2c66affSColin Finck 
test_MsiGetSourcePath(void)6025c2c66affSColin Finck static void test_MsiGetSourcePath(void)
6026c2c66affSColin Finck {
6027c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
6028c2c66affSColin Finck     CHAR path[MAX_PATH];
6029c2c66affSColin Finck     CHAR cwd[MAX_PATH];
6030c2c66affSColin Finck     CHAR subsrc[MAX_PATH];
6031c2c66affSColin Finck     CHAR sub2[MAX_PATH];
6032c2c66affSColin Finck     DWORD size;
6033c2c66affSColin Finck     UINT r;
6034c2c66affSColin Finck 
6035c2c66affSColin Finck     lstrcpyA(cwd, CURR_DIR);
6036c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6037c2c66affSColin Finck 
6038c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6039c2c66affSColin Finck     lstrcatA(subsrc, "subsource");
6040c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6041c2c66affSColin Finck 
6042c2c66affSColin Finck     lstrcpyA(sub2, subsrc);
6043c2c66affSColin Finck     lstrcatA(sub2, "sub2");
6044c2c66affSColin Finck     lstrcatA(sub2, "\\");
6045c2c66affSColin Finck 
6046c2c66affSColin Finck     /* uncompressed source */
6047c2c66affSColin Finck 
6048c2c66affSColin Finck     hdb = create_package_db();
6049c2c66affSColin Finck     ok( hdb, "failed to create database\n");
6050c2c66affSColin Finck 
6051c2c66affSColin Finck     set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6052c2c66affSColin Finck 
6053f860a780SAmine Khaldi     add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6054f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6055f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6056c2c66affSColin Finck 
6057c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
6058c2c66affSColin Finck     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6059c2c66affSColin Finck 
6060c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
6061c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6062c2c66affSColin Finck     {
6063c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
6064c2c66affSColin Finck         DeleteFileA(msifile);
6065c2c66affSColin Finck         return;
6066c2c66affSColin Finck     }
6067c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6068c2c66affSColin Finck 
6069c2c66affSColin Finck     MsiCloseHandle(hdb);
6070c2c66affSColin Finck 
6071c2c66affSColin Finck     /* invalid database handle */
6072c2c66affSColin Finck     size = MAX_PATH;
6073c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6074c2c66affSColin Finck     r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6075c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE,
6076c2c66affSColin Finck        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6077c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6078c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
60791b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6080c2c66affSColin Finck 
6081c2c66affSColin Finck     /* NULL szFolder */
6082c2c66affSColin Finck     size = MAX_PATH;
6083c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6084c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6085c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
6086c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6087c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6088c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
60891b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6090c2c66affSColin Finck 
6091c2c66affSColin Finck     /* empty szFolder */
6092c2c66affSColin Finck     size = MAX_PATH;
6093c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6094c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "", path, &size);
6095c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6096c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6097c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
60981b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6099c2c66affSColin Finck 
6100c2c66affSColin Finck     /* try TARGETDIR */
6101c2c66affSColin Finck     size = MAX_PATH;
6102c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6103c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6104c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6105c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6106c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
61071b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6108c2c66affSColin Finck 
6109c2c66affSColin Finck     size = MAX_PATH;
6110c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6111c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6112c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6113c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
61141b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6115c2c66affSColin Finck 
6116c2c66affSColin Finck     size = MAX_PATH;
6117c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6118c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6119c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6120c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
61211b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6122c2c66affSColin Finck 
6123c2c66affSColin Finck     /* try SourceDir */
6124c2c66affSColin Finck     size = MAX_PATH;
6125c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6126c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6127c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6128c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6129c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
61301b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6131c2c66affSColin Finck 
6132c2c66affSColin Finck     /* try SOURCEDIR */
6133c2c66affSColin Finck     size = MAX_PATH;
6134c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6135c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6136c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6137c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6138c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
61391b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6140c2c66affSColin Finck 
6141c2c66affSColin Finck     /* source path does not exist, but the property exists */
6142c2c66affSColin Finck     size = MAX_PATH;
6143c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6144c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6145c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6146c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
61471b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6148c2c66affSColin Finck 
6149c2c66affSColin Finck     size = MAX_PATH;
6150c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6151c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6152c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6153c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
61541b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6155c2c66affSColin Finck 
6156c2c66affSColin Finck     /* try SubDir */
6157c2c66affSColin Finck     size = MAX_PATH;
6158c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6159c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6160c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6161c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6162c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
61631b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6164c2c66affSColin Finck 
6165c2c66affSColin Finck     /* try SubDir2 */
6166c2c66affSColin Finck     size = MAX_PATH;
6167c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6168c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6169c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6170c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6171c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
61721b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6173c2c66affSColin Finck 
6174c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6175c2c66affSColin Finck 
6176c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
6177c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "cost init failed\n");
6178c2c66affSColin Finck 
6179c2c66affSColin Finck     /* try TARGETDIR after CostInitialize */
6180c2c66affSColin Finck     size = MAX_PATH;
6181c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6182c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6183c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6184c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
61851b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6186c2c66affSColin Finck 
6187c2c66affSColin Finck     /* try SourceDir after CostInitialize */
6188c2c66affSColin Finck     size = MAX_PATH;
6189c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6190c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6191c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
61931b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6194c2c66affSColin Finck 
6195c2c66affSColin Finck     /* try SOURCEDIR after CostInitialize */
6196c2c66affSColin Finck     size = MAX_PATH;
6197c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6198c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6199c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6200c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6201c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
62021b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6203c2c66affSColin Finck 
6204c2c66affSColin Finck     /* source path does not exist, but the property exists */
6205c2c66affSColin Finck     size = MAX_PATH;
6206c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6207c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6208c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6209c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62101b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6211c2c66affSColin Finck 
6212c2c66affSColin Finck     size = MAX_PATH;
6213c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6214c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6215c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6216c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62171b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6218c2c66affSColin Finck 
6219c2c66affSColin Finck     /* try SubDir after CostInitialize */
6220c2c66affSColin Finck     size = MAX_PATH;
6221c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6222c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6223c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6224c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
62251b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6226c2c66affSColin Finck 
6227c2c66affSColin Finck     /* try SubDir2 after CostInitialize */
6228c2c66affSColin Finck     size = MAX_PATH;
6229c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6230c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6231c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6232c2c66affSColin Finck     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
62331b4acd3cSwinesync     ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6234c2c66affSColin Finck 
6235c2c66affSColin Finck     r = MsiDoActionA(hpkg, "ResolveSource");
6236c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6237c2c66affSColin Finck 
6238c2c66affSColin Finck     /* try TARGETDIR after ResolveSource */
6239c2c66affSColin Finck     size = MAX_PATH;
6240c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6241c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6242c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6243c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62441b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6245c2c66affSColin Finck 
6246c2c66affSColin Finck     /* try SourceDir after ResolveSource */
6247c2c66affSColin Finck     size = MAX_PATH;
6248c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6249c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6250c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6251c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62521b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6253c2c66affSColin Finck 
6254c2c66affSColin Finck     /* try SOURCEDIR after ResolveSource */
6255c2c66affSColin Finck     size = MAX_PATH;
6256c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6257c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6258c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6259c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6260c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
62611b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6262c2c66affSColin Finck 
6263c2c66affSColin Finck     /* source path does not exist, but the property exists */
6264c2c66affSColin Finck     size = MAX_PATH;
6265c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6266c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6267c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6268c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62691b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6270c2c66affSColin Finck 
6271c2c66affSColin Finck     size = MAX_PATH;
6272c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6273c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6274c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6275c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
62761b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6277c2c66affSColin Finck 
6278c2c66affSColin Finck     /* try SubDir after ResolveSource */
6279c2c66affSColin Finck     size = MAX_PATH;
6280c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6281c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6282c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6283c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
62841b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6285c2c66affSColin Finck 
6286c2c66affSColin Finck     /* try SubDir2 after ResolveSource */
6287c2c66affSColin Finck     size = MAX_PATH;
6288c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6289c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6290c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6291c2c66affSColin Finck     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
62921b4acd3cSwinesync     ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6293c2c66affSColin Finck 
6294c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
6295c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6296c2c66affSColin Finck 
6297c2c66affSColin Finck     /* try TARGETDIR after FileCost */
6298c2c66affSColin Finck     size = MAX_PATH;
6299c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6300c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6301c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6302c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63031b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6304c2c66affSColin Finck 
6305c2c66affSColin Finck     /* try SourceDir after FileCost */
6306c2c66affSColin Finck     size = MAX_PATH;
6307c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6308c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6309c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6310c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63111b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6312c2c66affSColin Finck 
6313c2c66affSColin Finck     /* try SOURCEDIR after FileCost */
6314c2c66affSColin Finck     size = MAX_PATH;
6315c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6316c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6317c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6318c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6319c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
63201b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6321c2c66affSColin Finck 
6322c2c66affSColin Finck     /* source path does not exist, but the property exists */
6323c2c66affSColin Finck     size = MAX_PATH;
6324c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6325c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6326c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6327c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63281b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6329c2c66affSColin Finck 
6330c2c66affSColin Finck     size = MAX_PATH;
6331c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6332c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6333c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6334c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63351b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6336c2c66affSColin Finck 
6337c2c66affSColin Finck     /* try SubDir after FileCost */
6338c2c66affSColin Finck     size = MAX_PATH;
6339c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6340c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6341c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6342c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
63431b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6344c2c66affSColin Finck 
6345c2c66affSColin Finck     /* try SubDir2 after FileCost */
6346c2c66affSColin Finck     size = MAX_PATH;
6347c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6348c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6349c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6350c2c66affSColin Finck     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
63511b4acd3cSwinesync     ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6352c2c66affSColin Finck 
6353c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
6354c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6355c2c66affSColin Finck 
6356c2c66affSColin Finck     /* try TARGETDIR after CostFinalize */
6357c2c66affSColin Finck     size = MAX_PATH;
6358c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6359c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6360c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6361c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63621b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6363c2c66affSColin Finck 
6364c2c66affSColin Finck     /* try SourceDir after CostFinalize */
6365c2c66affSColin Finck     size = MAX_PATH;
6366c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6367c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6368c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63701b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6371c2c66affSColin Finck 
6372c2c66affSColin Finck     /* try SOURCEDIR after CostFinalize */
6373c2c66affSColin Finck     size = MAX_PATH;
6374c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6375c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6376c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6377c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6378c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
63791b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6380c2c66affSColin Finck 
6381c2c66affSColin Finck     /* source path does not exist, but the property exists */
6382c2c66affSColin Finck     size = MAX_PATH;
6383c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6384c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6385c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6386c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63871b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6388c2c66affSColin Finck 
6389c2c66affSColin Finck     size = MAX_PATH;
6390c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6391c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6392c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6393c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
63941b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6395c2c66affSColin Finck 
6396c2c66affSColin Finck     /* try SubDir after CostFinalize */
6397c2c66affSColin Finck     size = MAX_PATH;
6398c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6399c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6400c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6401c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
64021b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6403c2c66affSColin Finck 
6404c2c66affSColin Finck     /* try SubDir2 after CostFinalize */
6405c2c66affSColin Finck     size = MAX_PATH;
6406c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6407c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6408c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6409c2c66affSColin Finck     ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
64101b4acd3cSwinesync     ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6411c2c66affSColin Finck 
6412c2c66affSColin Finck     /* nonexistent directory */
6413c2c66affSColin Finck     size = MAX_PATH;
6414c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6415c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6416c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6417c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6418c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
64191b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6420c2c66affSColin Finck 
6421c2c66affSColin Finck     /* NULL szPathBuf */
6422c2c66affSColin Finck     size = MAX_PATH;
6423c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6424c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
64251b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6426c2c66affSColin Finck 
6427c2c66affSColin Finck     /* NULL pcchPathBuf */
6428c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6429c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6430c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
6431c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6432c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6433c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
6434c2c66affSColin Finck 
6435c2c66affSColin Finck     /* pcchPathBuf is 0 */
6436c2c66affSColin Finck     size = 0;
6437c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6438c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6439c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6440c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6441c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
64421b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6443c2c66affSColin Finck 
6444c2c66affSColin Finck     /* pcchPathBuf does not have room for NULL terminator */
6445c2c66affSColin Finck     size = lstrlenA(cwd);
6446c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6447c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6448c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6449c2c66affSColin Finck     ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6450c2c66affSColin Finck        "Expected path with no backslash, got \"%s\"\n", path);
64511b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6452c2c66affSColin Finck 
6453c2c66affSColin Finck     /* pcchPathBuf has room for NULL terminator */
6454c2c66affSColin Finck     size = lstrlenA(cwd) + 1;
6455c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6456c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6457c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6458c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
64591b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6460c2c66affSColin Finck 
6461c2c66affSColin Finck     /* remove property */
6462c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6463c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6464c2c66affSColin Finck 
6465c2c66affSColin Finck     /* try SourceDir again */
6466c2c66affSColin Finck     size = MAX_PATH;
6467c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6468c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6469c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6470c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
64711b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6472c2c66affSColin Finck 
6473c2c66affSColin Finck     /* set property to a valid directory */
6474c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6475c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6476c2c66affSColin Finck 
6477c2c66affSColin Finck     /* try SOURCEDIR again */
6478c2c66affSColin Finck     size = MAX_PATH;
6479c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6480c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6481c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6482c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6483c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
64841b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6485c2c66affSColin Finck 
6486c2c66affSColin Finck     MsiCloseHandle(hpkg);
6487c2c66affSColin Finck 
6488c2c66affSColin Finck     /* compressed source */
6489c2c66affSColin Finck 
6490c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6491c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6492c2c66affSColin Finck 
6493c2c66affSColin Finck     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
6494c2c66affSColin Finck 
6495c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
6496c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6497c2c66affSColin Finck 
6498c2c66affSColin Finck     /* try TARGETDIR */
6499c2c66affSColin Finck     size = MAX_PATH;
6500c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6501c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6502c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6503c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6504c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
65051b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6506c2c66affSColin Finck 
6507c2c66affSColin Finck     /* try SourceDir */
6508c2c66affSColin Finck     size = MAX_PATH;
6509c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6510c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6511c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6512c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6513c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
65141b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6515c2c66affSColin Finck 
6516c2c66affSColin Finck     /* try SOURCEDIR */
6517c2c66affSColin Finck     size = MAX_PATH;
6518c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6519c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6520c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6521c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6522c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
65231b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6524c2c66affSColin Finck 
6525c2c66affSColin Finck     /* source path nor the property exist */
6526c2c66affSColin Finck     size = MAX_PATH;
6527c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6528c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6529c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6530c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
65311b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6532c2c66affSColin Finck 
6533c2c66affSColin Finck     size = MAX_PATH;
6534c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6535c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6536c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6537c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
65381b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
6539c2c66affSColin Finck 
6540c2c66affSColin Finck     /* try SubDir */
6541c2c66affSColin Finck     size = MAX_PATH;
6542c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6543c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6544c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6545c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6546c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
65471b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6548c2c66affSColin Finck 
6549c2c66affSColin Finck     /* try SubDir2 */
6550c2c66affSColin Finck     size = MAX_PATH;
6551c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6552c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6553c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6554c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
6555c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
65561b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6557c2c66affSColin Finck 
6558c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
6559c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6560c2c66affSColin Finck 
6561c2c66affSColin Finck     /* try TARGETDIR after CostInitialize */
6562c2c66affSColin Finck     size = MAX_PATH;
6563c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6564c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6565c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6566c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
65671b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6568c2c66affSColin Finck 
6569c2c66affSColin Finck     /* try SourceDir after CostInitialize */
6570c2c66affSColin Finck     size = MAX_PATH;
6571c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6572c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6573c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6574c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
65751b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6576c2c66affSColin Finck 
6577c2c66affSColin Finck     /* try SOURCEDIR after CostInitialize */
6578c2c66affSColin Finck     size = MAX_PATH;
6579c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6580c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6581c2c66affSColin Finck     todo_wine
6582c2c66affSColin Finck     {
6583c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6584c2c66affSColin Finck         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
65851b4acd3cSwinesync         ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6586c2c66affSColin Finck     }
6587c2c66affSColin Finck 
6588c2c66affSColin Finck     /* source path does not exist, but the property exists */
6589c2c66affSColin Finck     size = MAX_PATH;
6590c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6591c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6592c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6593c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
65941b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6595c2c66affSColin Finck 
6596c2c66affSColin Finck     size = MAX_PATH;
6597c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6598c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6599c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6600c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66011b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6602c2c66affSColin Finck 
6603c2c66affSColin Finck     /* try SubDir after CostInitialize */
6604c2c66affSColin Finck     size = MAX_PATH;
6605c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6606c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6607c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6608c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66091b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6610c2c66affSColin Finck 
6611c2c66affSColin Finck     /* try SubDir2 after CostInitialize */
6612c2c66affSColin Finck     size = MAX_PATH;
6613c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6614c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6615c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6616c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66171b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6618c2c66affSColin Finck 
6619c2c66affSColin Finck     r = MsiDoActionA(hpkg, "ResolveSource");
6620c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6621c2c66affSColin Finck 
6622c2c66affSColin Finck     /* try TARGETDIR after ResolveSource */
6623c2c66affSColin Finck     size = MAX_PATH;
6624c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6625c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6626c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6627c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66281b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6629c2c66affSColin Finck 
6630c2c66affSColin Finck     /* try SourceDir after ResolveSource */
6631c2c66affSColin Finck     size = MAX_PATH;
6632c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6633c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6634c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6635c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66361b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6637c2c66affSColin Finck 
6638c2c66affSColin Finck     /* try SOURCEDIR after ResolveSource */
6639c2c66affSColin Finck     size = MAX_PATH;
6640c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6641c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6642c2c66affSColin Finck     todo_wine
6643c2c66affSColin Finck     {
6644c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6645c2c66affSColin Finck         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66461b4acd3cSwinesync         ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6647c2c66affSColin Finck     }
6648c2c66affSColin Finck 
6649c2c66affSColin Finck     /* source path and the property exist */
6650c2c66affSColin Finck     size = MAX_PATH;
6651c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6652c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6653c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6654c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66551b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6656c2c66affSColin Finck 
6657c2c66affSColin Finck     size = MAX_PATH;
6658c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6659c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6660c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6661c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66621b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6663c2c66affSColin Finck 
6664c2c66affSColin Finck     /* try SubDir after ResolveSource */
6665c2c66affSColin Finck     size = MAX_PATH;
6666c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6667c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6668c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66701b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6671c2c66affSColin Finck 
6672c2c66affSColin Finck     /* try SubDir2 after ResolveSource */
6673c2c66affSColin Finck     size = MAX_PATH;
6674c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6675c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6676c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6677c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66781b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6679c2c66affSColin Finck 
6680c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
6681c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6682c2c66affSColin Finck 
6683c2c66affSColin Finck     /* try TARGETDIR after CostFinalize */
6684c2c66affSColin Finck     size = MAX_PATH;
6685c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6686c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6687c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6688c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66891b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6690c2c66affSColin Finck 
6691c2c66affSColin Finck     /* try SourceDir after CostFinalize */
6692c2c66affSColin Finck     size = MAX_PATH;
6693c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6694c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6695c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6696c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
66971b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6698c2c66affSColin Finck 
6699c2c66affSColin Finck     /* try SOURCEDIR after CostFinalize */
6700c2c66affSColin Finck     size = MAX_PATH;
6701c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6702c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6703c2c66affSColin Finck     todo_wine
6704c2c66affSColin Finck     {
6705c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6706c2c66affSColin Finck         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67071b4acd3cSwinesync         ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6708c2c66affSColin Finck     }
6709c2c66affSColin Finck 
6710c2c66affSColin Finck     /* source path and the property exist */
6711c2c66affSColin Finck     size = MAX_PATH;
6712c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6713c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6714c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6715c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67161b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6717c2c66affSColin Finck 
6718c2c66affSColin Finck     size = MAX_PATH;
6719c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6720c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6721c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6722c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67231b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6724c2c66affSColin Finck 
6725c2c66affSColin Finck     /* try SubDir after CostFinalize */
6726c2c66affSColin Finck     size = MAX_PATH;
6727c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6728c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6729c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6730c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67311b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6732c2c66affSColin Finck 
6733c2c66affSColin Finck     /* try SubDir2 after CostFinalize */
6734c2c66affSColin Finck     size = MAX_PATH;
6735c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6736c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6737c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6738c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67391b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6740c2c66affSColin Finck 
6741c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
6742c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6743c2c66affSColin Finck 
6744c2c66affSColin Finck     /* try TARGETDIR after CostFinalize */
6745c2c66affSColin Finck     size = MAX_PATH;
6746c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6747c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6748c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6749c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67501b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6751c2c66affSColin Finck 
6752c2c66affSColin Finck     /* try SourceDir after CostFinalize */
6753c2c66affSColin Finck     size = MAX_PATH;
6754c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6755c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6756c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6757c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67581b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6759c2c66affSColin Finck 
6760c2c66affSColin Finck     /* try SOURCEDIR after CostFinalize */
6761c2c66affSColin Finck     size = MAX_PATH;
6762c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6763c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6764c2c66affSColin Finck     todo_wine
6765c2c66affSColin Finck     {
6766c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6767c2c66affSColin Finck         ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67681b4acd3cSwinesync         ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6769c2c66affSColin Finck     }
6770c2c66affSColin Finck 
6771c2c66affSColin Finck     /* source path and the property exist */
6772c2c66affSColin Finck     size = MAX_PATH;
6773c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6774c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6775c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6776c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67771b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6778c2c66affSColin Finck 
6779c2c66affSColin Finck     size = MAX_PATH;
6780c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6781c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6782c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6783c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67841b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6785c2c66affSColin Finck 
6786c2c66affSColin Finck     /* try SubDir after CostFinalize */
6787c2c66affSColin Finck     size = MAX_PATH;
6788c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6789c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6790c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6791c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
67921b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6793c2c66affSColin Finck 
6794c2c66affSColin Finck     /* try SubDir2 after CostFinalize */
6795c2c66affSColin Finck     size = MAX_PATH;
6796c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6797c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6798c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6799c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
68001b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6801c2c66affSColin Finck 
6802c2c66affSColin Finck     MsiCloseHandle(hpkg);
6803c2c66affSColin Finck     DeleteFileA(msifile);
6804c2c66affSColin Finck }
6805c2c66affSColin Finck 
test_shortlongsource(void)6806c2c66affSColin Finck static void test_shortlongsource(void)
6807c2c66affSColin Finck {
6808c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
6809c2c66affSColin Finck     CHAR path[MAX_PATH];
6810c2c66affSColin Finck     CHAR cwd[MAX_PATH];
6811c2c66affSColin Finck     CHAR subsrc[MAX_PATH];
6812c2c66affSColin Finck     DWORD size;
6813c2c66affSColin Finck     UINT r;
6814c2c66affSColin Finck 
6815c2c66affSColin Finck     lstrcpyA(cwd, CURR_DIR);
6816c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6817c2c66affSColin Finck 
6818c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6819c2c66affSColin Finck     lstrcatA(subsrc, "long");
6820c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6821c2c66affSColin Finck 
6822c2c66affSColin Finck     /* long file names */
6823c2c66affSColin Finck 
6824c2c66affSColin Finck     hdb = create_package_db();
6825c2c66affSColin Finck     ok( hdb, "failed to create database\n");
6826c2c66affSColin Finck 
6827c2c66affSColin Finck     set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6828c2c66affSColin Finck 
6829f860a780SAmine Khaldi     add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6830f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6831c2c66affSColin Finck 
6832c2c66affSColin Finck     /* CostInitialize:short */
6833f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6834c2c66affSColin Finck 
6835c2c66affSColin Finck     /* CostInitialize:long */
6836f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6837c2c66affSColin Finck 
6838c2c66affSColin Finck     /* FileCost:short */
6839f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6840c2c66affSColin Finck 
6841c2c66affSColin Finck     /* FileCost:long */
6842f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6843c2c66affSColin Finck 
6844c2c66affSColin Finck     /* CostFinalize:short */
6845f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6846c2c66affSColin Finck 
6847c2c66affSColin Finck     /* CostFinalize:long */
6848f860a780SAmine Khaldi     add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6849c2c66affSColin Finck 
6850f860a780SAmine Khaldi     r = MsiDatabaseCommit(hdb);
6851f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6852c2c66affSColin Finck 
6853c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
6854c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6855c2c66affSColin Finck     {
6856c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
6857c2c66affSColin Finck         DeleteFileA(msifile);
6858c2c66affSColin Finck         return;
6859c2c66affSColin Finck     }
6860c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6861c2c66affSColin Finck 
6862c2c66affSColin Finck     MsiCloseHandle(hdb);
6863c2c66affSColin Finck 
6864c2c66affSColin Finck     CreateDirectoryA("one", NULL);
6865c2c66affSColin Finck     CreateDirectoryA("four", NULL);
6866c2c66affSColin Finck 
6867c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6868c2c66affSColin Finck 
6869c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
6870c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6871c2c66affSColin Finck 
6872c2c66affSColin Finck     CreateDirectoryA("five", NULL);
6873c2c66affSColin Finck     CreateDirectoryA("eight", NULL);
6874c2c66affSColin Finck 
6875c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
6876c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6877c2c66affSColin Finck 
6878c2c66affSColin Finck     CreateDirectoryA("nine", NULL);
6879c2c66affSColin Finck     CreateDirectoryA("twelve", NULL);
6880c2c66affSColin Finck 
6881c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
6882c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
6883c2c66affSColin Finck 
6884c2c66affSColin Finck     /* neither short nor long source directories exist */
6885c2c66affSColin Finck     size = MAX_PATH;
6886c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6887c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6888c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6889c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
68901b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6891c2c66affSColin Finck 
6892c2c66affSColin Finck     CreateDirectoryA("short", NULL);
6893c2c66affSColin Finck 
6894c2c66affSColin Finck     /* short source directory exists */
6895c2c66affSColin Finck     size = MAX_PATH;
6896c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6897c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6898c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6899c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69001b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6901c2c66affSColin Finck 
6902c2c66affSColin Finck     CreateDirectoryA("long", NULL);
6903c2c66affSColin Finck 
6904c2c66affSColin Finck     /* both short and long source directories exist */
6905c2c66affSColin Finck     size = MAX_PATH;
6906c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6907c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6908c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6909c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69101b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6911c2c66affSColin Finck 
6912c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6913c2c66affSColin Finck     lstrcatA(subsrc, "two");
6914c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6915c2c66affSColin Finck 
6916c2c66affSColin Finck     /* short dir exists before CostInitialize */
6917c2c66affSColin Finck     size = MAX_PATH;
6918c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6919c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6920c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6921c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69221b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6923c2c66affSColin Finck 
6924c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6925c2c66affSColin Finck     lstrcatA(subsrc, "four");
6926c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6927c2c66affSColin Finck 
6928c2c66affSColin Finck     /* long dir exists before CostInitialize */
6929c2c66affSColin Finck     size = MAX_PATH;
6930c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6931c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
6932c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6933c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69341b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6935c2c66affSColin Finck 
6936c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6937c2c66affSColin Finck     lstrcatA(subsrc, "six");
6938c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6939c2c66affSColin Finck 
6940c2c66affSColin Finck     /* short dir exists before FileCost */
6941c2c66affSColin Finck     size = MAX_PATH;
6942c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6943c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
6944c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69461b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6947c2c66affSColin Finck 
6948c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6949c2c66affSColin Finck     lstrcatA(subsrc, "eight");
6950c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6951c2c66affSColin Finck 
6952c2c66affSColin Finck     /* long dir exists before FileCost */
6953c2c66affSColin Finck     size = MAX_PATH;
6954c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6955c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
6956c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6957c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69581b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6959c2c66affSColin Finck 
6960c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6961c2c66affSColin Finck     lstrcatA(subsrc, "ten");
6962c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6963c2c66affSColin Finck 
6964c2c66affSColin Finck     /* short dir exists before CostFinalize */
6965c2c66affSColin Finck     size = MAX_PATH;
6966c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6967c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
6968c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6969c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69701b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6971c2c66affSColin Finck 
6972c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
6973c2c66affSColin Finck     lstrcatA(subsrc, "twelve");
6974c2c66affSColin Finck     lstrcatA(subsrc, "\\");
6975c2c66affSColin Finck 
6976c2c66affSColin Finck     /* long dir exists before CostFinalize */
6977c2c66affSColin Finck     size = MAX_PATH;
6978c2c66affSColin Finck     lstrcpyA(path, "kiwi");
6979c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
6980c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6981c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
69821b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6983c2c66affSColin Finck 
6984c2c66affSColin Finck     MsiCloseHandle(hpkg);
6985c2c66affSColin Finck     RemoveDirectoryA("short");
6986c2c66affSColin Finck     RemoveDirectoryA("long");
6987c2c66affSColin Finck     RemoveDirectoryA("one");
6988c2c66affSColin Finck     RemoveDirectoryA("four");
6989c2c66affSColin Finck     RemoveDirectoryA("five");
6990c2c66affSColin Finck     RemoveDirectoryA("eight");
6991c2c66affSColin Finck     RemoveDirectoryA("nine");
6992c2c66affSColin Finck     RemoveDirectoryA("twelve");
6993c2c66affSColin Finck 
6994c2c66affSColin Finck     /* short file names */
6995c2c66affSColin Finck 
6996c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
6997c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6998c2c66affSColin Finck 
6999c2c66affSColin Finck     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7000c2c66affSColin Finck 
7001c2c66affSColin Finck     r = package_from_db(hdb, &hpkg);
7002c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7003c2c66affSColin Finck 
7004c2c66affSColin Finck     MsiCloseHandle(hdb);
7005c2c66affSColin Finck 
7006c2c66affSColin Finck     CreateDirectoryA("one", NULL);
7007c2c66affSColin Finck     CreateDirectoryA("four", NULL);
7008c2c66affSColin Finck 
7009c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
7010c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7011c2c66affSColin Finck 
7012c2c66affSColin Finck     CreateDirectoryA("five", NULL);
7013c2c66affSColin Finck     CreateDirectoryA("eight", NULL);
7014c2c66affSColin Finck 
7015c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
7016c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7017c2c66affSColin Finck 
7018c2c66affSColin Finck     CreateDirectoryA("nine", NULL);
7019c2c66affSColin Finck     CreateDirectoryA("twelve", NULL);
7020c2c66affSColin Finck 
7021c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
7022c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7023c2c66affSColin Finck 
7024c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7025c2c66affSColin Finck     lstrcatA(subsrc, "short");
7026c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7027c2c66affSColin Finck 
7028c2c66affSColin Finck     /* neither short nor long source directories exist */
7029c2c66affSColin Finck     size = MAX_PATH;
7030c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7031c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7032c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7033c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70341b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7035c2c66affSColin Finck 
7036c2c66affSColin Finck     CreateDirectoryA("short", NULL);
7037c2c66affSColin Finck 
7038c2c66affSColin Finck     /* short source directory exists */
7039c2c66affSColin Finck     size = MAX_PATH;
7040c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7041c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7042c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7043c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70441b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7045c2c66affSColin Finck 
7046c2c66affSColin Finck     CreateDirectoryA("long", NULL);
7047c2c66affSColin Finck 
7048c2c66affSColin Finck     /* both short and long source directories exist */
7049c2c66affSColin Finck     size = MAX_PATH;
7050c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7051c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7052c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7053c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70541b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7055c2c66affSColin Finck 
7056c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7057c2c66affSColin Finck     lstrcatA(subsrc, "one");
7058c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7059c2c66affSColin Finck 
7060c2c66affSColin Finck     /* short dir exists before CostInitialize */
7061c2c66affSColin Finck     size = MAX_PATH;
7062c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7063c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7064c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7065c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70661b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7067c2c66affSColin Finck 
7068c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7069c2c66affSColin Finck     lstrcatA(subsrc, "three");
7070c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7071c2c66affSColin Finck 
7072c2c66affSColin Finck     /* long dir exists before CostInitialize */
7073c2c66affSColin Finck     size = MAX_PATH;
7074c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7075c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7076c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7077c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70781b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7079c2c66affSColin Finck 
7080c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7081c2c66affSColin Finck     lstrcatA(subsrc, "five");
7082c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7083c2c66affSColin Finck 
7084c2c66affSColin Finck     /* short dir exists before FileCost */
7085c2c66affSColin Finck     size = MAX_PATH;
7086c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7087c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7088c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7089c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
70901b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7091c2c66affSColin Finck 
7092c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7093c2c66affSColin Finck     lstrcatA(subsrc, "seven");
7094c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7095c2c66affSColin Finck 
7096c2c66affSColin Finck     /* long dir exists before FileCost */
7097c2c66affSColin Finck     size = MAX_PATH;
7098c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7099c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7100c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7101c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
71021b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7103c2c66affSColin Finck 
7104c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7105c2c66affSColin Finck     lstrcatA(subsrc, "nine");
7106c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7107c2c66affSColin Finck 
7108c2c66affSColin Finck     /* short dir exists before CostFinalize */
7109c2c66affSColin Finck     size = MAX_PATH;
7110c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7111c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7112c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7113c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
71141b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7115c2c66affSColin Finck 
7116c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7117c2c66affSColin Finck     lstrcatA(subsrc, "eleven");
7118c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7119c2c66affSColin Finck 
7120c2c66affSColin Finck     /* long dir exists before CostFinalize */
7121c2c66affSColin Finck     size = MAX_PATH;
7122c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7123c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7124c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7125c2c66affSColin Finck     ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
71261b4acd3cSwinesync     ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7127c2c66affSColin Finck 
7128c2c66affSColin Finck     MsiCloseHandle(hpkg);
7129c2c66affSColin Finck     RemoveDirectoryA("short");
7130c2c66affSColin Finck     RemoveDirectoryA("long");
7131c2c66affSColin Finck     RemoveDirectoryA("one");
7132c2c66affSColin Finck     RemoveDirectoryA("four");
7133c2c66affSColin Finck     RemoveDirectoryA("five");
7134c2c66affSColin Finck     RemoveDirectoryA("eight");
7135c2c66affSColin Finck     RemoveDirectoryA("nine");
7136c2c66affSColin Finck     RemoveDirectoryA("twelve");
7137c2c66affSColin Finck     DeleteFileA(msifile);
7138c2c66affSColin Finck }
7139c2c66affSColin Finck 
test_sourcedir(void)7140c2c66affSColin Finck static void test_sourcedir(void)
7141c2c66affSColin Finck {
7142c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
7143c2c66affSColin Finck     CHAR package[12];
7144c2c66affSColin Finck     CHAR path[MAX_PATH];
7145c2c66affSColin Finck     CHAR cwd[MAX_PATH];
7146c2c66affSColin Finck     CHAR subsrc[MAX_PATH];
7147c2c66affSColin Finck     DWORD size;
7148c2c66affSColin Finck     UINT r;
7149c2c66affSColin Finck 
7150c2c66affSColin Finck     lstrcpyA(cwd, CURR_DIR);
7151c2c66affSColin Finck     if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7152c2c66affSColin Finck 
7153c2c66affSColin Finck     lstrcpyA(subsrc, cwd);
7154c2c66affSColin Finck     lstrcatA(subsrc, "long");
7155c2c66affSColin Finck     lstrcatA(subsrc, "\\");
7156c2c66affSColin Finck 
7157c2c66affSColin Finck     hdb = create_package_db();
7158c2c66affSColin Finck     ok( hdb, "failed to create database\n");
7159c2c66affSColin Finck 
7160f860a780SAmine Khaldi     add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7161c2c66affSColin Finck 
71621b4acd3cSwinesync     sprintf(package, "#%lu", hdb);
7163c2c66affSColin Finck     r = MsiOpenPackageA(package, &hpkg);
7164c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7165c2c66affSColin Finck     {
7166c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
7167c2c66affSColin Finck         goto error;
7168c2c66affSColin Finck     }
7169c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7170c2c66affSColin Finck 
7171c2c66affSColin Finck     /* properties only */
7172c2c66affSColin Finck 
7173c2c66affSColin Finck     /* SourceDir prop */
7174c2c66affSColin Finck     size = MAX_PATH;
7175c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7176c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7177c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7178c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
71791b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7180c2c66affSColin Finck 
7181c2c66affSColin Finck     /* SOURCEDIR prop */
7182c2c66affSColin Finck     size = MAX_PATH;
7183c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7184c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7185c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7186c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
71871b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7188c2c66affSColin Finck 
7189c2c66affSColin Finck     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7190c2c66affSColin Finck 
7191c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
7192c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7193c2c66affSColin Finck 
7194c2c66affSColin Finck     /* SourceDir after CostInitialize */
7195c2c66affSColin Finck     size = MAX_PATH;
7196c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7197c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7198c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7199c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72001b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7201c2c66affSColin Finck 
7202c2c66affSColin Finck     /* SOURCEDIR after CostInitialize */
7203c2c66affSColin Finck     size = MAX_PATH;
7204c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7205c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7206c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7207c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72081b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7209c2c66affSColin Finck 
7210c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
7211c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7212c2c66affSColin Finck 
7213c2c66affSColin Finck     /* SourceDir after FileCost */
7214c2c66affSColin Finck     size = MAX_PATH;
7215c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7216c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7217c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7218c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72191b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7220c2c66affSColin Finck 
7221c2c66affSColin Finck     /* SOURCEDIR after FileCost */
7222c2c66affSColin Finck     size = MAX_PATH;
7223c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7224c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7225c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7226c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72271b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7228c2c66affSColin Finck 
7229c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
7230c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7231c2c66affSColin Finck 
7232c2c66affSColin Finck     /* SourceDir after CostFinalize */
7233c2c66affSColin Finck     size = MAX_PATH;
7234c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7235c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7236c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7237c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72381b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7239c2c66affSColin Finck 
7240c2c66affSColin Finck     /* SOURCEDIR after CostFinalize */
7241c2c66affSColin Finck     size = MAX_PATH;
7242c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7243c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7244c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7245c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72461b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7247c2c66affSColin Finck 
7248c2c66affSColin Finck     size = MAX_PATH;
7249c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7250c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7251c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7252c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
72531b4acd3cSwinesync     ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
7254c2c66affSColin Finck 
7255c2c66affSColin Finck     /* SOURCEDIR after calling MsiGetSourcePath */
7256c2c66affSColin Finck     size = MAX_PATH;
7257c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7258c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7259c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7260c2c66affSColin Finck     todo_wine {
7261c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
72621b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7263c2c66affSColin Finck     }
7264c2c66affSColin Finck 
7265c2c66affSColin Finck     r = MsiDoActionA(hpkg, "ResolveSource");
7266c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7267c2c66affSColin Finck 
7268c2c66affSColin Finck     /* SourceDir after ResolveSource */
7269c2c66affSColin Finck     size = MAX_PATH;
7270c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7271c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7272c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7273c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
72741b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7275c2c66affSColin Finck 
7276c2c66affSColin Finck     /* SOURCEDIR after ResolveSource */
7277c2c66affSColin Finck     size = MAX_PATH;
7278c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7279c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7280c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7281c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
72821b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7283c2c66affSColin Finck 
7284c2c66affSColin Finck     /* random casing */
7285c2c66affSColin Finck     size = MAX_PATH;
7286c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7287c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7288c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7289c2c66affSColin Finck     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
72901b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7291c2c66affSColin Finck 
7292c2c66affSColin Finck     MsiCloseHandle(hpkg);
7293c2c66affSColin Finck 
7294c2c66affSColin Finck     /* reset the package state */
72951b4acd3cSwinesync     sprintf(package, "#%lu", hdb);
7296c2c66affSColin Finck     r = MsiOpenPackageA(package, &hpkg);
7297c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7298c2c66affSColin Finck 
7299c2c66affSColin Finck     /* test how MsiGetSourcePath affects the properties */
7300c2c66affSColin Finck 
7301c2c66affSColin Finck     /* SourceDir prop */
7302c2c66affSColin Finck     size = MAX_PATH;
7303c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7304c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7305c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7306c2c66affSColin Finck     todo_wine
7307c2c66affSColin Finck     {
7308c2c66affSColin Finck         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
73091b4acd3cSwinesync         ok(size == 0, "Expected 0, got %lu\n", size);
7310c2c66affSColin Finck     }
7311c2c66affSColin Finck 
7312c2c66affSColin Finck     size = MAX_PATH;
7313c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7314c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7315c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7316c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7317c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
73181b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7319c2c66affSColin Finck 
7320c2c66affSColin Finck     /* SourceDir after MsiGetSourcePath */
7321c2c66affSColin Finck     size = MAX_PATH;
7322c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7323c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7324c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7325c2c66affSColin Finck     todo_wine
7326c2c66affSColin Finck     {
7327c2c66affSColin Finck         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
73281b4acd3cSwinesync         ok(size == 0, "Expected 0, got %lu\n", size);
7329c2c66affSColin Finck     }
7330c2c66affSColin Finck 
7331c2c66affSColin Finck     /* SOURCEDIR prop */
7332c2c66affSColin Finck     size = MAX_PATH;
7333c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7334c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7335c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7336c2c66affSColin Finck     todo_wine
7337c2c66affSColin Finck     {
7338c2c66affSColin Finck         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
73391b4acd3cSwinesync         ok(size == 0, "Expected 0, got %lu\n", size);
7340c2c66affSColin Finck     }
7341c2c66affSColin Finck 
7342c2c66affSColin Finck     size = MAX_PATH;
7343c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7344c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7345c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7346c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7347c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
73481b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7349c2c66affSColin Finck 
7350c2c66affSColin Finck     /* SOURCEDIR prop after MsiGetSourcePath */
7351c2c66affSColin Finck     size = MAX_PATH;
7352c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7353c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7354c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7355c2c66affSColin Finck     todo_wine
7356c2c66affSColin Finck     {
7357c2c66affSColin Finck         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
73581b4acd3cSwinesync         ok(size == 0, "Expected 0, got %lu\n", size);
7359c2c66affSColin Finck     }
7360c2c66affSColin Finck 
7361c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostInitialize");
7362c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7363c2c66affSColin Finck 
7364c2c66affSColin Finck     /* SourceDir after CostInitialize */
7365c2c66affSColin Finck     size = MAX_PATH;
7366c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7367c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7368c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7369c2c66affSColin Finck     todo_wine
7370c2c66affSColin Finck     {
7371c2c66affSColin Finck         ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
73721b4acd3cSwinesync         ok(size == 0, "Expected 0, got %lu\n", size);
7373c2c66affSColin Finck     }
7374c2c66affSColin Finck 
7375c2c66affSColin Finck     size = MAX_PATH;
7376c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7377c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7378c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7379c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
73801b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7381c2c66affSColin Finck 
7382c2c66affSColin Finck     /* SourceDir after MsiGetSourcePath */
7383c2c66affSColin Finck     size = MAX_PATH;
7384c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7385c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7386c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7387c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
73881b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7389c2c66affSColin Finck 
7390c2c66affSColin Finck     /* SOURCEDIR after CostInitialize */
7391c2c66affSColin Finck     size = MAX_PATH;
7392c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7393c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7394c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7395c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
73961b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7397c2c66affSColin Finck 
7398c2c66affSColin Finck     /* SOURCEDIR source path still does not exist */
7399c2c66affSColin Finck     size = MAX_PATH;
7400c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7401c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7402c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7403c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7404c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
74051b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7406c2c66affSColin Finck 
7407c2c66affSColin Finck     r = MsiDoActionA(hpkg, "FileCost");
7408c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7409c2c66affSColin Finck 
7410c2c66affSColin Finck     /* SourceDir after FileCost */
7411c2c66affSColin Finck     size = MAX_PATH;
7412c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7413c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7414c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7415c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74161b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7417c2c66affSColin Finck 
7418c2c66affSColin Finck     /* SOURCEDIR after FileCost */
7419c2c66affSColin Finck     size = MAX_PATH;
7420c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7421c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7422c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7423c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74241b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7425c2c66affSColin Finck 
7426c2c66affSColin Finck     /* SOURCEDIR source path still does not exist */
7427c2c66affSColin Finck     size = MAX_PATH;
7428c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7429c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7430c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7431c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7432c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
74331b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7434c2c66affSColin Finck 
7435c2c66affSColin Finck     r = MsiDoActionA(hpkg, "CostFinalize");
7436c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7437c2c66affSColin Finck 
7438c2c66affSColin Finck     /* SourceDir after CostFinalize */
7439c2c66affSColin Finck     size = MAX_PATH;
7440c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7441c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7442c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7443c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74441b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7445c2c66affSColin Finck 
7446c2c66affSColin Finck     /* SOURCEDIR after CostFinalize */
7447c2c66affSColin Finck     size = MAX_PATH;
7448c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7449c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7450c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7451c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74521b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7453c2c66affSColin Finck 
7454c2c66affSColin Finck     /* SOURCEDIR source path still does not exist */
7455c2c66affSColin Finck     size = MAX_PATH;
7456c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7457c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7458c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7459c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7460c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
74611b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7462c2c66affSColin Finck 
7463c2c66affSColin Finck     r = MsiDoActionA(hpkg, "ResolveSource");
7464c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "file cost failed\n");
7465c2c66affSColin Finck 
7466c2c66affSColin Finck     /* SourceDir after ResolveSource */
7467c2c66affSColin Finck     size = MAX_PATH;
7468c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7469c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7470c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7471c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74721b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7473c2c66affSColin Finck 
7474c2c66affSColin Finck     /* SOURCEDIR after ResolveSource */
7475c2c66affSColin Finck     size = MAX_PATH;
7476c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7477c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7478c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7479c2c66affSColin Finck     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
74801b4acd3cSwinesync     ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7481c2c66affSColin Finck 
7482c2c66affSColin Finck     /* SOURCEDIR source path still does not exist */
7483c2c66affSColin Finck     size = MAX_PATH;
7484c2c66affSColin Finck     lstrcpyA(path, "kiwi");
7485c2c66affSColin Finck     r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7486c2c66affSColin Finck     ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7487c2c66affSColin Finck     ok(!lstrcmpA(path, "kiwi"),
7488c2c66affSColin Finck        "Expected path to be unchanged, got \"%s\"\n", path);
74891b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7490c2c66affSColin Finck 
7491c2c66affSColin Finck     MsiCloseHandle(hpkg);
7492c2c66affSColin Finck 
7493c2c66affSColin Finck error:
7494c2c66affSColin Finck     MsiCloseHandle(hdb);
7495c2c66affSColin Finck     DeleteFileA(msifile);
7496c2c66affSColin Finck }
7497c2c66affSColin Finck 
7498c2c66affSColin Finck struct access_res
7499c2c66affSColin Finck {
7500c2c66affSColin Finck     BOOL gothandle;
7501c2c66affSColin Finck     DWORD lasterr;
7502c2c66affSColin Finck     BOOL ignore;
7503c2c66affSColin Finck };
7504c2c66affSColin Finck 
7505c2c66affSColin Finck static const struct access_res create[16] =
7506c2c66affSColin Finck {
7507c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7508c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7509c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7510c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7511c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7512c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7513c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7514c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7515c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7516c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7517c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7518c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7519c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7520c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7521c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7522c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE }
7523c2c66affSColin Finck };
7524c2c66affSColin Finck 
7525c2c66affSColin Finck static const struct access_res create_commit[16] =
7526c2c66affSColin Finck {
7527c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7528c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7529c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7530c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7531c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7532c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7533c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7534c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7535c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7536c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7537c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7538c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE },
7539c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7540c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7541c2c66affSColin Finck     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
7542c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, TRUE }
7543c2c66affSColin Finck };
7544c2c66affSColin Finck 
7545c2c66affSColin Finck static const struct access_res create_close[16] =
7546c2c66affSColin Finck {
7547c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7548c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7549c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7550c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7551c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7552c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7553c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7554c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7555c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7556c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7557c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7558c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7559c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7560c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7561c2c66affSColin Finck     { TRUE, ERROR_SUCCESS, FALSE },
7562c2c66affSColin Finck     { TRUE, ERROR_SUCCESS }
7563c2c66affSColin Finck };
7564c2c66affSColin Finck 
_test_file_access(LPCSTR file,const struct access_res * ares,DWORD line)7565c2c66affSColin Finck static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7566c2c66affSColin Finck {
7567c2c66affSColin Finck     DWORD access = 0, share = 0;
7568c2c66affSColin Finck     DWORD lasterr;
7569c2c66affSColin Finck     HANDLE hfile;
7570c2c66affSColin Finck     int i, j, idx = 0;
7571c2c66affSColin Finck 
7572c2c66affSColin Finck     for (i = 0; i < 4; i++)
7573c2c66affSColin Finck     {
7574c2c66affSColin Finck         if (i == 0) access = 0;
7575c2c66affSColin Finck         if (i == 1) access = GENERIC_READ;
7576c2c66affSColin Finck         if (i == 2) access = GENERIC_WRITE;
7577c2c66affSColin Finck         if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7578c2c66affSColin Finck 
7579c2c66affSColin Finck         for (j = 0; j < 4; j++)
7580c2c66affSColin Finck         {
7581c2c66affSColin Finck             if (ares[idx].ignore)
7582c2c66affSColin Finck                 continue;
7583c2c66affSColin Finck 
7584c2c66affSColin Finck             if (j == 0) share = 0;
7585c2c66affSColin Finck             if (j == 1) share = FILE_SHARE_READ;
7586c2c66affSColin Finck             if (j == 2) share = FILE_SHARE_WRITE;
7587c2c66affSColin Finck             if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7588c2c66affSColin Finck 
7589c2c66affSColin Finck             SetLastError(0xdeadbeef);
7590c2c66affSColin Finck             hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7591c2c66affSColin Finck                                 FILE_ATTRIBUTE_NORMAL, 0);
7592c2c66affSColin Finck             lasterr = GetLastError();
7593c2c66affSColin Finck 
7594c2c66affSColin Finck             ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
75951b4acd3cSwinesync                "(%lu, handle, %d): Expected %d, got %d\n",
7596c2c66affSColin Finck                line, idx, ares[idx].gothandle,
7597c2c66affSColin Finck                (hfile != INVALID_HANDLE_VALUE));
7598c2c66affSColin Finck 
75991b4acd3cSwinesync             ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n",
7600c2c66affSColin Finck                line, idx, ares[idx].lasterr, lasterr);
7601c2c66affSColin Finck 
7602c2c66affSColin Finck             CloseHandle(hfile);
7603c2c66affSColin Finck             idx++;
7604c2c66affSColin Finck         }
7605c2c66affSColin Finck     }
7606c2c66affSColin Finck }
7607c2c66affSColin Finck 
7608c2c66affSColin Finck #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7609c2c66affSColin Finck 
test_access(void)7610c2c66affSColin Finck static void test_access(void)
7611c2c66affSColin Finck {
7612c2c66affSColin Finck     MSIHANDLE hdb;
7613c2c66affSColin Finck     UINT r;
7614c2c66affSColin Finck 
7615c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7616c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7617c2c66affSColin Finck 
7618c2c66affSColin Finck     test_file_access(msifile, create);
7619c2c66affSColin Finck 
7620c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
7621c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7622c2c66affSColin Finck 
7623c2c66affSColin Finck     test_file_access(msifile, create_commit);
7624c2c66affSColin Finck     MsiCloseHandle(hdb);
7625c2c66affSColin Finck 
7626c2c66affSColin Finck     test_file_access(msifile, create_close);
7627c2c66affSColin Finck     DeleteFileA(msifile);
7628c2c66affSColin Finck 
7629c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
7630c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7631c2c66affSColin Finck 
7632c2c66affSColin Finck     test_file_access(msifile, create);
7633c2c66affSColin Finck 
7634c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
7635c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7636c2c66affSColin Finck 
7637c2c66affSColin Finck     test_file_access(msifile, create_commit);
7638c2c66affSColin Finck     MsiCloseHandle(hdb);
7639c2c66affSColin Finck 
7640c2c66affSColin Finck     test_file_access(msifile, create_close);
7641c2c66affSColin Finck     DeleteFileA(msifile);
7642c2c66affSColin Finck }
7643c2c66affSColin Finck 
test_emptypackage(void)7644c2c66affSColin Finck static void test_emptypackage(void)
7645c2c66affSColin Finck {
7646c2c66affSColin Finck     MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7647c2c66affSColin Finck     MSIHANDLE hview = 0, hrec = 0;
7648c2c66affSColin Finck     MSICONDITION condition;
7649c2c66affSColin Finck     CHAR buffer[MAX_PATH];
7650c2c66affSColin Finck     DWORD size;
7651c2c66affSColin Finck     UINT r;
7652c2c66affSColin Finck 
7653c2c66affSColin Finck     r = MsiOpenPackageA("", &hpkg);
7654c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7655c2c66affSColin Finck     {
7656c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
7657c2c66affSColin Finck         return;
7658c2c66affSColin Finck     }
7659c2c66affSColin Finck     todo_wine
7660c2c66affSColin Finck     {
7661c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7662c2c66affSColin Finck     }
7663c2c66affSColin Finck 
7664c2c66affSColin Finck     hdb = MsiGetActiveDatabase(hpkg);
7665c2c66affSColin Finck     todo_wine
7666c2c66affSColin Finck     {
7667c2c66affSColin Finck         ok(hdb != 0, "Expected a valid database handle\n");
7668c2c66affSColin Finck     }
7669c2c66affSColin Finck 
7670c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7671c2c66affSColin Finck     todo_wine
7672c2c66affSColin Finck     {
7673c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7674c2c66affSColin Finck     }
7675c2c66affSColin Finck     r = MsiViewExecute(hview, 0);
7676c2c66affSColin Finck     todo_wine
7677c2c66affSColin Finck     {
7678c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7679c2c66affSColin Finck     }
7680c2c66affSColin Finck 
7681c2c66affSColin Finck     r = MsiViewFetch(hview, &hrec);
7682c2c66affSColin Finck     todo_wine
7683c2c66affSColin Finck     {
7684c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7685c2c66affSColin Finck     }
7686c2c66affSColin Finck 
7687c2c66affSColin Finck     buffer[0] = 0;
7688c2c66affSColin Finck     size = MAX_PATH;
7689c2c66affSColin Finck     r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7690c2c66affSColin Finck     todo_wine
7691c2c66affSColin Finck     {
7692c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7693c2c66affSColin Finck         ok(!lstrcmpA(buffer, "_Property"),
7694c2c66affSColin Finck            "Expected \"_Property\", got \"%s\"\n", buffer);
7695c2c66affSColin Finck     }
7696c2c66affSColin Finck 
7697c2c66affSColin Finck     MsiCloseHandle(hrec);
7698c2c66affSColin Finck 
7699c2c66affSColin Finck     r = MsiViewFetch(hview, &hrec);
7700c2c66affSColin Finck     todo_wine
7701c2c66affSColin Finck     {
7702c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7703c2c66affSColin Finck     }
7704c2c66affSColin Finck 
7705c2c66affSColin Finck     size = MAX_PATH;
7706c2c66affSColin Finck     r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7707c2c66affSColin Finck     todo_wine
7708c2c66affSColin Finck     {
7709c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7710c2c66affSColin Finck         ok(!lstrcmpA(buffer, "#_FolderCache"),
7711c2c66affSColin Finck            "Expected \"_Property\", got \"%s\"\n", buffer);
7712c2c66affSColin Finck     }
7713c2c66affSColin Finck 
7714c2c66affSColin Finck     MsiCloseHandle(hrec);
7715c2c66affSColin Finck     MsiViewClose(hview);
7716c2c66affSColin Finck     MsiCloseHandle(hview);
7717c2c66affSColin Finck 
7718c2c66affSColin Finck     condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7719c2c66affSColin Finck     todo_wine
7720c2c66affSColin Finck     {
7721c2c66affSColin Finck         ok(condition == MSICONDITION_FALSE,
7722c2c66affSColin Finck            "Expected MSICONDITION_FALSE, got %d\n", condition);
7723c2c66affSColin Finck     }
7724c2c66affSColin Finck 
7725c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7726c2c66affSColin Finck     todo_wine
7727c2c66affSColin Finck     {
7728c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7729c2c66affSColin Finck     }
7730c2c66affSColin Finck     r = MsiViewExecute(hview, 0);
7731c2c66affSColin Finck     todo_wine
7732c2c66affSColin Finck     {
7733c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7734c2c66affSColin Finck     }
7735c2c66affSColin Finck 
7736c2c66affSColin Finck     /* _Property table is not empty */
7737c2c66affSColin Finck     r = MsiViewFetch(hview, &hrec);
7738c2c66affSColin Finck     todo_wine
7739c2c66affSColin Finck     {
7740c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7741c2c66affSColin Finck     }
7742c2c66affSColin Finck 
7743c2c66affSColin Finck     MsiCloseHandle(hrec);
7744c2c66affSColin Finck     MsiViewClose(hview);
7745c2c66affSColin Finck     MsiCloseHandle(hview);
7746c2c66affSColin Finck 
7747c2c66affSColin Finck     condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7748c2c66affSColin Finck     todo_wine
7749c2c66affSColin Finck     {
7750c2c66affSColin Finck         ok(condition == MSICONDITION_FALSE,
7751c2c66affSColin Finck            "Expected MSICONDITION_FALSE, got %d\n", condition);
7752c2c66affSColin Finck     }
7753c2c66affSColin Finck 
7754c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7755c2c66affSColin Finck     todo_wine
7756c2c66affSColin Finck     {
7757c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7758c2c66affSColin Finck     }
7759c2c66affSColin Finck     r = MsiViewExecute(hview, 0);
7760c2c66affSColin Finck     todo_wine
7761c2c66affSColin Finck     {
7762c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7763c2c66affSColin Finck     }
7764c2c66affSColin Finck 
7765c2c66affSColin Finck     /* #_FolderCache is not empty */
7766c2c66affSColin Finck     r = MsiViewFetch(hview, &hrec);
7767c2c66affSColin Finck     todo_wine
7768c2c66affSColin Finck     {
7769c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7770c2c66affSColin Finck     }
7771c2c66affSColin Finck 
7772c2c66affSColin Finck     MsiCloseHandle(hrec);
7773c2c66affSColin Finck     MsiViewClose(hview);
7774c2c66affSColin Finck     MsiCloseHandle(hview);
7775c2c66affSColin Finck 
7776c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7777c2c66affSColin Finck     todo_wine
7778c2c66affSColin Finck     {
7779c2c66affSColin Finck         ok(r == ERROR_BAD_QUERY_SYNTAX,
7780c2c66affSColin Finck            "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7781c2c66affSColin Finck     }
7782c2c66affSColin Finck 
7783c2c66affSColin Finck     r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7784c2c66affSColin Finck     todo_wine
7785c2c66affSColin Finck     {
7786c2c66affSColin Finck         ok(r == ERROR_BAD_QUERY_SYNTAX,
7787c2c66affSColin Finck            "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7788c2c66affSColin Finck     }
7789c2c66affSColin Finck 
7790c2c66affSColin Finck     r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7791c2c66affSColin Finck     todo_wine
7792c2c66affSColin Finck     {
7793c2c66affSColin Finck         ok(r == ERROR_INSTALL_PACKAGE_INVALID,
7794c2c66affSColin Finck            "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7795c2c66affSColin Finck     }
7796c2c66affSColin Finck 
7797c2c66affSColin Finck     MsiCloseHandle(hsuminfo);
7798c2c66affSColin Finck 
7799c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
7800c2c66affSColin Finck     todo_wine
7801c2c66affSColin Finck     {
7802c2c66affSColin Finck         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7803c2c66affSColin Finck     }
7804c2c66affSColin Finck 
7805c2c66affSColin Finck     MsiCloseHandle(hdb);
7806c2c66affSColin Finck     MsiCloseHandle(hpkg);
7807c2c66affSColin Finck }
7808c2c66affSColin Finck 
test_MsiGetProductProperty(void)7809c2c66affSColin Finck static void test_MsiGetProductProperty(void)
7810c2c66affSColin Finck {
7811c2c66affSColin Finck     WCHAR valW[MAX_PATH];
7812c2c66affSColin Finck     MSIHANDLE hprod, hdb;
7813c2c66affSColin Finck     CHAR val[MAX_PATH];
7814c2c66affSColin Finck     CHAR path[MAX_PATH];
7815484e8280Swinesync     CHAR query[MAX_PATH + 17];
7816c2c66affSColin Finck     CHAR keypath[MAX_PATH*2];
7817c2c66affSColin Finck     CHAR prodcode[MAX_PATH];
7818c2c66affSColin Finck     WCHAR prodcodeW[MAX_PATH];
7819c2c66affSColin Finck     CHAR prod_squashed[MAX_PATH];
7820c2c66affSColin Finck     WCHAR prod_squashedW[MAX_PATH];
7821c2c66affSColin Finck     HKEY prodkey, userkey, props;
7822c2c66affSColin Finck     DWORD size;
7823c2c66affSColin Finck     LONG res;
7824c2c66affSColin Finck     UINT r;
7825c2c66affSColin Finck     REGSAM access = KEY_ALL_ACCESS;
7826c2c66affSColin Finck 
7827c2c66affSColin Finck     GetCurrentDirectoryA(MAX_PATH, path);
7828c2c66affSColin Finck     lstrcatA(path, "\\");
7829c2c66affSColin Finck 
7830c2c66affSColin Finck     create_test_guid(prodcode, prod_squashed);
7831c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7832c2c66affSColin Finck     squash_guid(prodcodeW, prod_squashedW);
7833c2c66affSColin Finck 
7834c2c66affSColin Finck     if (is_wow64)
7835c2c66affSColin Finck         access |= KEY_WOW64_64KEY;
7836c2c66affSColin Finck 
7837c2c66affSColin Finck     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
7838c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7839c2c66affSColin Finck 
7840c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
7841c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7842c2c66affSColin Finck 
7843c2c66affSColin Finck     r = set_summary_info(hdb);
7844c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7845c2c66affSColin Finck 
7846*f4be6dc3SMikhail     r = run_query(hdb, 0,
7847c2c66affSColin Finck             "CREATE TABLE `Directory` ( "
7848c2c66affSColin Finck             "`Directory` CHAR(255) NOT NULL, "
7849c2c66affSColin Finck             "`Directory_Parent` CHAR(255), "
7850c2c66affSColin Finck             "`DefaultDir` CHAR(255) NOT NULL "
7851c2c66affSColin Finck             "PRIMARY KEY `Directory`)");
7852c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7853c2c66affSColin Finck 
7854f860a780SAmine Khaldi     create_property_table(hdb);
7855c2c66affSColin Finck 
7856f860a780SAmine Khaldi     sprintf(query, "'ProductCode', '%s'", prodcode);
7857f860a780SAmine Khaldi     r = add_property_entry(hdb, query);
7858c2c66affSColin Finck 
7859c2c66affSColin Finck     r = MsiDatabaseCommit(hdb);
7860c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7861c2c66affSColin Finck 
7862c2c66affSColin Finck     MsiCloseHandle(hdb);
7863c2c66affSColin Finck 
7864c2c66affSColin Finck     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7865c2c66affSColin Finck     lstrcatA(keypath, prod_squashed);
7866c2c66affSColin Finck 
7867c2c66affSColin Finck     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7868c2c66affSColin Finck     if (res == ERROR_ACCESS_DENIED)
7869c2c66affSColin Finck     {
7870c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
7871c2c66affSColin Finck         DeleteFileA(msifile);
7872c2c66affSColin Finck         return;
7873c2c66affSColin Finck     }
78741b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7875c2c66affSColin Finck 
7876c2c66affSColin Finck     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7877c2c66affSColin Finck     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7878c2c66affSColin Finck     lstrcatA(keypath, prod_squashed);
7879c2c66affSColin Finck 
7880c2c66affSColin Finck     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7881c2c66affSColin Finck     if (res == ERROR_ACCESS_DENIED)
7882c2c66affSColin Finck     {
7883c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
7884c2c66affSColin Finck         RegDeleteKeyA(prodkey, "");
7885c2c66affSColin Finck         RegCloseKey(prodkey);
7886*f4be6dc3SMikhail         DeleteFileA(msifile);
7887c2c66affSColin Finck         return;
7888c2c66affSColin Finck     }
78891b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7890c2c66affSColin Finck 
7891c2c66affSColin Finck     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
78921b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7893c2c66affSColin Finck 
7894c2c66affSColin Finck     lstrcpyA(val, path);
7895c2c66affSColin Finck     lstrcatA(val, "\\");
7896c2c66affSColin Finck     lstrcatA(val, msifile);
7897*f4be6dc3SMikhail     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1);
78981b4acd3cSwinesync     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7899c2c66affSColin Finck 
7900c2c66affSColin Finck     hprod = 0xdeadbeef;
7901c2c66affSColin Finck     r = MsiOpenProductA(prodcode, &hprod);
7902*f4be6dc3SMikhail     if (r == ERROR_UNKNOWN_PRODUCT)
7903*f4be6dc3SMikhail     {
7904*f4be6dc3SMikhail         win_skip("broken result, skipping tests\n");
7905*f4be6dc3SMikhail         goto done;
7906*f4be6dc3SMikhail     }
7907c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7908c2c66affSColin Finck     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7909c2c66affSColin Finck 
7910c2c66affSColin Finck     /* hProduct is invalid */
7911c2c66affSColin Finck     size = MAX_PATH;
7912c2c66affSColin Finck     lstrcpyA(val, "apple");
7913c2c66affSColin Finck     r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
7914c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE,
7915c2c66affSColin Finck        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7916c2c66affSColin Finck     ok(!lstrcmpA(val, "apple"),
7917c2c66affSColin Finck        "Expected val to be unchanged, got \"%s\"\n", val);
79181b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7919c2c66affSColin Finck 
7920c2c66affSColin Finck     size = MAX_PATH;
7921f31e4044Swinesync     lstrcpyW(valW, L"apple");
7922f31e4044Swinesync     r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
7923c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE,
7924c2c66affSColin Finck        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7925f31e4044Swinesync     ok(!lstrcmpW(valW, L"apple"),
7926c2c66affSColin Finck        "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
79271b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7928c2c66affSColin Finck 
7929c2c66affSColin Finck     /* szProperty is NULL */
7930c2c66affSColin Finck     size = MAX_PATH;
7931c2c66affSColin Finck     lstrcpyA(val, "apple");
7932c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, NULL, val, &size);
7933c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
7934c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7935c2c66affSColin Finck     ok(!lstrcmpA(val, "apple"),
7936c2c66affSColin Finck        "Expected val to be unchanged, got \"%s\"\n", val);
79371b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7938c2c66affSColin Finck 
7939c2c66affSColin Finck     size = MAX_PATH;
7940f31e4044Swinesync     lstrcpyW(valW, L"apple");
7941c2c66affSColin Finck     r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
7942c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
7943c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7944f31e4044Swinesync     ok(!lstrcmpW(valW, L"apple"),
7945c2c66affSColin Finck        "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
79461b4acd3cSwinesync     ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7947c2c66affSColin Finck 
7948c2c66affSColin Finck     /* szProperty is empty */
7949c2c66affSColin Finck     size = MAX_PATH;
7950c2c66affSColin Finck     lstrcpyA(val, "apple");
7951c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "", val, &size);
7952c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7953c2c66affSColin Finck     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
79541b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7955c2c66affSColin Finck 
7956c2c66affSColin Finck     size = MAX_PATH;
7957f31e4044Swinesync     lstrcpyW(valW, L"apple");
7958f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"", valW, &size);
7959c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7960c2c66affSColin Finck     ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
79611b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
7962c2c66affSColin Finck 
7963c2c66affSColin Finck     /* get the property */
7964c2c66affSColin Finck     size = MAX_PATH;
7965c2c66affSColin Finck     lstrcpyA(val, "apple");
7966c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
7967c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7968c2c66affSColin Finck     ok(!lstrcmpA(val, prodcode),
7969c2c66affSColin Finck        "Expected \"%s\", got \"%s\"\n", prodcode, val);
7970c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
79711b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
7972c2c66affSColin Finck 
7973c2c66affSColin Finck     size = MAX_PATH;
7974f31e4044Swinesync     lstrcpyW(valW, L"apple");
7975f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
7976c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7977c2c66affSColin Finck     ok(!lstrcmpW(valW, prodcodeW),
7978c2c66affSColin Finck        "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
7979c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
79801b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
7981c2c66affSColin Finck 
7982c2c66affSColin Finck     /* lpValueBuf is NULL */
7983c2c66affSColin Finck     size = MAX_PATH;
7984c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
7985c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7986c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
79871b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
7988c2c66affSColin Finck 
7989c2c66affSColin Finck     size = MAX_PATH;
7990f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
7991c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7992c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
79931b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
7994c2c66affSColin Finck 
7995c2c66affSColin Finck     /* pcchValueBuf is NULL */
7996c2c66affSColin Finck     lstrcpyA(val, "apple");
7997c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
7998c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
7999c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8000c2c66affSColin Finck     ok(!lstrcmpA(val, "apple"),
8001c2c66affSColin Finck        "Expected val to be unchanged, got \"%s\"\n", val);
8002c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
80031b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8004c2c66affSColin Finck 
8005f31e4044Swinesync     lstrcpyW(valW, L"apple");
8006f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8007c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
8008c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8009f31e4044Swinesync     ok(!lstrcmpW(valW, L"apple"),
8010c2c66affSColin Finck        "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8011c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
80121b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8013c2c66affSColin Finck 
8014c2c66affSColin Finck     /* pcchValueBuf is too small */
8015c2c66affSColin Finck     size = 4;
8016c2c66affSColin Finck     lstrcpyA(val, "apple");
8017c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8018c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8019c2c66affSColin Finck     ok(!strncmp(val, prodcode, 3),
8020c2c66affSColin Finck        "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8021c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
80221b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8023c2c66affSColin Finck 
8024c2c66affSColin Finck     size = 4;
8025f31e4044Swinesync     lstrcpyW(valW, L"apple");
8026f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8027c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8028c2c66affSColin Finck     ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8029c2c66affSColin Finck        "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8030c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
80311b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8032c2c66affSColin Finck 
8033c2c66affSColin Finck     /* pcchValueBuf does not leave room for NULL terminator */
8034c2c66affSColin Finck     size = lstrlenA(prodcode);
8035c2c66affSColin Finck     lstrcpyA(val, "apple");
8036c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8037c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8038c2c66affSColin Finck     ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8039c2c66affSColin Finck        "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8040c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
80411b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8042c2c66affSColin Finck 
8043c2c66affSColin Finck     size = lstrlenW(prodcodeW);
8044f31e4044Swinesync     lstrcpyW(valW, L"apple");
8045f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8046c2c66affSColin Finck     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8047c2c66affSColin Finck     ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8048c2c66affSColin Finck        "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8049c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
80501b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8051c2c66affSColin Finck 
8052c2c66affSColin Finck     /* pcchValueBuf has enough room for NULL terminator */
8053c2c66affSColin Finck     size = lstrlenA(prodcode) + 1;
8054c2c66affSColin Finck     lstrcpyA(val, "apple");
8055c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8056c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8057c2c66affSColin Finck     ok(!lstrcmpA(val, prodcode),
8058c2c66affSColin Finck        "Expected \"%s\", got \"%s\"\n", prodcode, val);
8059c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
80601b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8061c2c66affSColin Finck 
8062c2c66affSColin Finck     size = lstrlenW(prodcodeW) + 1;
8063f31e4044Swinesync     lstrcpyW(valW, L"apple");
8064f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8065c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8066c2c66affSColin Finck     ok(!lstrcmpW(valW, prodcodeW),
8067c2c66affSColin Finck        "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8068c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
80691b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8070c2c66affSColin Finck 
8071c2c66affSColin Finck     /* nonexistent property */
8072c2c66affSColin Finck     size = MAX_PATH;
8073c2c66affSColin Finck     lstrcpyA(val, "apple");
8074c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8075c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8076c2c66affSColin Finck     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
80771b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8078c2c66affSColin Finck 
8079c2c66affSColin Finck     size = MAX_PATH;
8080f31e4044Swinesync     lstrcpyW(valW, L"apple");
8081f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8082c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8083f31e4044Swinesync     ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
80841b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8085c2c66affSColin Finck 
8086c2c66affSColin Finck     r = MsiSetPropertyA(hprod, "NewProperty", "value");
8087c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8088c2c66affSColin Finck 
8089c2c66affSColin Finck     /* non-product property set */
8090c2c66affSColin Finck     size = MAX_PATH;
8091c2c66affSColin Finck     lstrcpyA(val, "apple");
8092c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8093c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094c2c66affSColin Finck     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
80951b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8096c2c66affSColin Finck 
8097c2c66affSColin Finck     size = MAX_PATH;
8098f31e4044Swinesync     lstrcpyW(valW, L"apple");
8099f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8100c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8101f31e4044Swinesync     ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
81021b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8103c2c66affSColin Finck 
8104c2c66affSColin Finck     r = MsiSetPropertyA(hprod, "ProductCode", "value");
8105c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8106c2c66affSColin Finck 
8107c2c66affSColin Finck     /* non-product property that is also a product property set */
8108c2c66affSColin Finck     size = MAX_PATH;
8109c2c66affSColin Finck     lstrcpyA(val, "apple");
8110c2c66affSColin Finck     r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8111c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8112c2c66affSColin Finck     ok(!lstrcmpA(val, prodcode),
8113c2c66affSColin Finck        "Expected \"%s\", got \"%s\"\n", prodcode, val);
8114c2c66affSColin Finck     ok(size == lstrlenA(prodcode),
81151b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8116c2c66affSColin Finck 
8117c2c66affSColin Finck     size = MAX_PATH;
8118f31e4044Swinesync     lstrcpyW(valW, L"apple");
8119f31e4044Swinesync     r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8120c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8121c2c66affSColin Finck     ok(!lstrcmpW(valW, prodcodeW),
8122c2c66affSColin Finck        "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8123c2c66affSColin Finck     ok(size == lstrlenW(prodcodeW),
81241b4acd3cSwinesync        "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8125c2c66affSColin Finck 
8126c2c66affSColin Finck     MsiCloseHandle(hprod);
8127*f4be6dc3SMikhail done:
8128c2c66affSColin Finck     RegDeleteValueA(props, "LocalPackage");
8129*f4be6dc3SMikhail     RegDeleteKeyExA(props, "", access, 0);
8130c2c66affSColin Finck     RegCloseKey(props);
8131*f4be6dc3SMikhail     RegDeleteKeyExA(userkey, "", access, 0);
8132c2c66affSColin Finck     RegCloseKey(userkey);
8133*f4be6dc3SMikhail     RegDeleteKeyExA(prodkey, "", access, 0);
8134c2c66affSColin Finck     RegCloseKey(prodkey);
8135c2c66affSColin Finck     DeleteFileA(msifile);
8136c2c66affSColin Finck }
8137c2c66affSColin Finck 
test_MsiSetProperty(void)8138c2c66affSColin Finck static void test_MsiSetProperty(void)
8139c2c66affSColin Finck {
8140c2c66affSColin Finck     MSIHANDLE hpkg, hdb, hrec;
8141c2c66affSColin Finck     CHAR buf[MAX_PATH];
8142c2c66affSColin Finck     LPCSTR query;
8143c2c66affSColin Finck     DWORD size;
8144c2c66affSColin Finck     UINT r;
8145c2c66affSColin Finck 
8146c2c66affSColin Finck     r = package_from_db(create_package_db(), &hpkg);
8147c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8148c2c66affSColin Finck     {
8149c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
8150c2c66affSColin Finck         DeleteFileA(msifile);
8151c2c66affSColin Finck         return;
8152c2c66affSColin Finck     }
8153c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8154c2c66affSColin Finck 
8155c2c66affSColin Finck     /* invalid hInstall */
8156c2c66affSColin Finck     r = MsiSetPropertyA(0, "Prop", "Val");
8157c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE,
8158c2c66affSColin Finck        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8159c2c66affSColin Finck 
8160c2c66affSColin Finck     /* invalid hInstall */
8161c2c66affSColin Finck     r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8162c2c66affSColin Finck     ok(r == ERROR_INVALID_HANDLE,
8163c2c66affSColin Finck        "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8164c2c66affSColin Finck 
8165c2c66affSColin Finck     /* szName is NULL */
8166c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, NULL, "Val");
8167c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
8168c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8169c2c66affSColin Finck 
8170c2c66affSColin Finck     /* both szName and szValue are NULL */
8171c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, NULL, NULL);
8172c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER,
8173c2c66affSColin Finck        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8174c2c66affSColin Finck 
8175c2c66affSColin Finck     /* szName is empty */
8176c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "", "Val");
8177c2c66affSColin Finck     ok(r == ERROR_FUNCTION_FAILED,
8178c2c66affSColin Finck        "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8179c2c66affSColin Finck 
8180c2c66affSColin Finck     /* szName is empty and szValue is NULL */
8181c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "", NULL);
8182c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8183c2c66affSColin Finck 
8184c2c66affSColin Finck     /* set a property */
8185c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Prop", "Val");
8186c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8187c2c66affSColin Finck 
8188c2c66affSColin Finck     /* get the property */
8189c2c66affSColin Finck     size = MAX_PATH;
8190c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8191c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8192c2c66affSColin Finck     ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
81931b4acd3cSwinesync     ok(size == 3, "Expected 3, got %lu\n", size);
8194c2c66affSColin Finck 
8195c2c66affSColin Finck     /* update the property */
8196c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8197c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8198c2c66affSColin Finck 
8199c2c66affSColin Finck     /* get the property */
8200c2c66affSColin Finck     size = MAX_PATH;
8201c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8202c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8203c2c66affSColin Finck     ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
82041b4acd3cSwinesync     ok(size == 4, "Expected 4, got %lu\n", size);
8205c2c66affSColin Finck 
8206c2c66affSColin Finck     hdb = MsiGetActiveDatabase(hpkg);
8207c2c66affSColin Finck     ok(hdb != 0, "Expected a valid database handle\n");
8208c2c66affSColin Finck 
8209c2c66affSColin Finck     /* set prop is not in the _Property table */
8210c2c66affSColin Finck     query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8211c2c66affSColin Finck     r = do_query(hdb, query, &hrec);
8212c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX,
8213c2c66affSColin Finck        "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8214c2c66affSColin Finck 
8215c2c66affSColin Finck     /* set prop is not in the Property table */
8216c2c66affSColin Finck     query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8217c2c66affSColin Finck     r = do_query(hdb, query, &hrec);
8218c2c66affSColin Finck     ok(r == ERROR_BAD_QUERY_SYNTAX,
8219c2c66affSColin Finck        "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8220c2c66affSColin Finck 
8221c2c66affSColin Finck     MsiCloseHandle(hdb);
8222c2c66affSColin Finck 
8223c2c66affSColin Finck     /* szValue is an empty string */
8224c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Prop", "");
8225c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8226c2c66affSColin Finck 
8227c2c66affSColin Finck     /* try to get the property */
8228c2c66affSColin Finck     size = MAX_PATH;
8229c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8230c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8231c2c66affSColin Finck     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
82321b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8233c2c66affSColin Finck 
8234c2c66affSColin Finck     /* reset the property */
8235c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8236c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8237c2c66affSColin Finck 
8238c2c66affSColin Finck     /* delete the property */
8239c2c66affSColin Finck     r = MsiSetPropertyA(hpkg, "Prop", NULL);
8240c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8241c2c66affSColin Finck 
8242c2c66affSColin Finck     /* try to get the property */
8243c2c66affSColin Finck     size = MAX_PATH;
8244c2c66affSColin Finck     r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8245c2c66affSColin Finck     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8246c2c66affSColin Finck     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
82471b4acd3cSwinesync     ok(size == 0, "Expected 0, got %lu\n", size);
8248c2c66affSColin Finck 
8249c2c66affSColin Finck     MsiCloseHandle(hpkg);
8250c2c66affSColin Finck     DeleteFileA(msifile);
8251c2c66affSColin Finck }
8252c2c66affSColin Finck 
test_MsiApplyMultiplePatches(void)8253c2c66affSColin Finck static void test_MsiApplyMultiplePatches(void)
8254c2c66affSColin Finck {
8255c2c66affSColin Finck     UINT r, type = GetDriveTypeW(NULL);
8256c2c66affSColin Finck 
82572f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
8258c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8259c2c66affSColin Finck 
82602f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA("", NULL, NULL);
8261c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8262c2c66affSColin Finck 
82632f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA(";", NULL, NULL);
8264c2c66affSColin Finck     if (type == DRIVE_FIXED)
8265c2c66affSColin Finck         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8266c2c66affSColin Finck     else
8267c2c66affSColin Finck         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8268c2c66affSColin Finck 
82692f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA("  ;", NULL, NULL);
8270c2c66affSColin Finck     if (type == DRIVE_FIXED)
8271c2c66affSColin Finck         todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8272c2c66affSColin Finck     else
8273c2c66affSColin Finck         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8274c2c66affSColin Finck 
82752f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
8276c2c66affSColin Finck     if (type == DRIVE_FIXED)
8277c2c66affSColin Finck         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8278c2c66affSColin Finck     else
8279c2c66affSColin Finck         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8280c2c66affSColin Finck 
82812f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8282c2c66affSColin Finck     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8283c2c66affSColin Finck 
82842f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8285c2c66affSColin Finck     if (type == DRIVE_FIXED)
8286c2c66affSColin Finck         todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8287c2c66affSColin Finck     else
8288c2c66affSColin Finck         ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8289c2c66affSColin Finck 
82902f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8291c2c66affSColin Finck     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8292c2c66affSColin Finck 
82932f8e6f71SAmine Khaldi     r = MsiApplyMultiplePatchesA("  nosuchpatchpackage  ;  nosuchpatchpackage  ", NULL, NULL);
8294c2c66affSColin Finck     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8295c2c66affSColin Finck }
8296c2c66affSColin Finck 
test_MsiApplyPatch(void)8297c2c66affSColin Finck static void test_MsiApplyPatch(void)
8298c2c66affSColin Finck {
8299c2c66affSColin Finck     UINT r;
8300c2c66affSColin Finck 
8301c2c66affSColin Finck     r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8302c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8303c2c66affSColin Finck 
8304c2c66affSColin Finck     r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL);
8305c2c66affSColin Finck     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8306c2c66affSColin Finck }
8307c2c66affSColin Finck 
test_costs(void)8308818a84ddSwinesync static void test_costs(void)
8309c2c66affSColin Finck {
8310c2c66affSColin Finck     MSIHANDLE hdb, hpkg;
8311c2c66affSColin Finck     char package[12], drive[3];
8312c2c66affSColin Finck     DWORD len;
8313c2c66affSColin Finck     UINT r;
8314c2c66affSColin Finck     int cost, temp;
8315c2c66affSColin Finck 
8316c2c66affSColin Finck     hdb = create_package_db();
8317c2c66affSColin Finck     ok( hdb, "failed to create database\n" );
8318c2c66affSColin Finck 
8319f860a780SAmine Khaldi     create_property_table( hdb );
8320f860a780SAmine Khaldi     add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8321f860a780SAmine Khaldi     add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8322f860a780SAmine Khaldi     add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8323c2c66affSColin Finck 
8324f860a780SAmine Khaldi     create_media_table( hdb );
8325f860a780SAmine Khaldi     add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8326c2c66affSColin Finck 
8327f860a780SAmine Khaldi     create_file_table( hdb );
8328*f4be6dc3SMikhail     add_file_entry( hdb, "'a.txt', 'one', 'a.txt', 2048000000, '', '', 8192, 1" );
8329*f4be6dc3SMikhail     add_file_entry( hdb, "'b.txt', 'one', 'b.txt', 2048000000, '', '', 8192, 1" );
8330*f4be6dc3SMikhail     add_file_entry( hdb, "'c.txt', 'one', 'c.txt', 2048000000, '', '', 8192, 1" );
8331*f4be6dc3SMikhail     add_file_entry( hdb, "'d.txt', 'one', 'd.txt', 4097, '', '', 8192, 1" );
8332*f4be6dc3SMikhail     add_file_entry( hdb, "'e.txt', 'one', 'e.txt', 1, '', '', 8192, 1" );
8333c2c66affSColin Finck 
8334f860a780SAmine Khaldi     create_component_table( hdb );
8335*f4be6dc3SMikhail     add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'a.txt'" );
8336f860a780SAmine Khaldi     add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8337c2c66affSColin Finck 
8338f860a780SAmine Khaldi     create_feature_table( hdb );
8339f860a780SAmine Khaldi     add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8340f860a780SAmine Khaldi     add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8341c2c66affSColin Finck 
8342f860a780SAmine Khaldi     create_feature_components_table( hdb );
8343f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'one', 'one'" );
8344f860a780SAmine Khaldi     add_feature_components_entry( hdb, "'two', 'two'" );
8345c2c66affSColin Finck 
8346f860a780SAmine Khaldi     create_install_execute_sequence_table( hdb );
8347f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8348f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8349f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8350f860a780SAmine Khaldi     add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8351c2c66affSColin Finck 
8352f860a780SAmine Khaldi     r = MsiDatabaseCommit( hdb );
8353f860a780SAmine Khaldi     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8354c2c66affSColin Finck 
83551b4acd3cSwinesync     sprintf( package, "#%lu", hdb );
8356c2c66affSColin Finck     r = MsiOpenPackageA( package, &hpkg );
8357c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8358c2c66affSColin Finck     {
8359c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
8360c2c66affSColin Finck         goto error;
8361c2c66affSColin Finck     }
8362c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8363c2c66affSColin Finck 
8364c2c66affSColin Finck     r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8365c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8366c2c66affSColin Finck 
8367c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8368c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8369c2c66affSColin Finck 
8370c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8371c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8372c2c66affSColin Finck 
8373c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8374c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8375c2c66affSColin Finck 
8376c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8377c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8378c2c66affSColin Finck 
8379c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8380c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8381c2c66affSColin Finck 
8382c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8383c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8384c2c66affSColin Finck 
8385c2c66affSColin Finck     len = sizeof(drive);
8386c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8387c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8388c2c66affSColin Finck 
8389c2c66affSColin Finck     len = sizeof(drive);
8390c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8391c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8392c2c66affSColin Finck 
8393c2c66affSColin Finck     len = sizeof(drive);
8394c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8395c2c66affSColin Finck     todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8396c2c66affSColin Finck 
8397c2c66affSColin Finck     len = sizeof(drive);
8398c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8399c2c66affSColin Finck     ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8400c2c66affSColin Finck 
8401c2c66affSColin Finck     MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
8402c2c66affSColin Finck 
8403c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostInitialize" );
8404c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8405c2c66affSColin Finck 
8406c2c66affSColin Finck     r = MsiDoActionA( hpkg, "FileCost" );
8407c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8408c2c66affSColin Finck 
8409c2c66affSColin Finck     len = sizeof(drive);
8410c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8411c2c66affSColin Finck     ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8412c2c66affSColin Finck 
8413c2c66affSColin Finck     r = MsiDoActionA( hpkg, "CostFinalize" );
8414c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8415c2c66affSColin Finck 
8416c2c66affSColin Finck     /* contrary to what msdn says InstallValidate must be called too */
8417c2c66affSColin Finck     len = sizeof(drive);
8418c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8419c2c66affSColin Finck     todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8420c2c66affSColin Finck 
8421c2c66affSColin Finck     r = MsiDoActionA( hpkg, "InstallValidate" );
8422c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8423c2c66affSColin Finck 
8424c2c66affSColin Finck     len = 0;
8425c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8426c2c66affSColin Finck     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8427c2c66affSColin Finck 
8428c2c66affSColin Finck     len = 0;
8429c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8430c2c66affSColin Finck     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
84311b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8432c2c66affSColin Finck 
8433c2c66affSColin Finck     len = 2;
8434c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8435c2c66affSColin Finck     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
84361b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8437c2c66affSColin Finck 
8438c2c66affSColin Finck     len = 2;
8439c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8440c2c66affSColin Finck     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
84411b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8442c2c66affSColin Finck 
8443c2c66affSColin Finck     /* install state doesn't seem to matter */
8444c2c66affSColin Finck     len = sizeof(drive);
8445c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8446c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8447c2c66affSColin Finck 
8448c2c66affSColin Finck     len = sizeof(drive);
8449c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8450c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8451c2c66affSColin Finck 
8452c2c66affSColin Finck     len = sizeof(drive);
8453c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8454c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8455c2c66affSColin Finck 
8456c2c66affSColin Finck     len = sizeof(drive);
8457c2c66affSColin Finck     drive[0] = 0;
8458c2c66affSColin Finck     cost = temp = 0xdead;
8459c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8460c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
84611b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8462c2c66affSColin Finck     ok( drive[0], "expected a drive\n" );
8463*f4be6dc3SMikhail     ok( cost == 12000024, "got %d\n", cost );
8464c2c66affSColin Finck     ok( !temp, "expected temp == 0, got %d\n", temp );
8465c2c66affSColin Finck 
8466c2c66affSColin Finck     len = sizeof(drive);
8467c2c66affSColin Finck     drive[0] = 0;
8468c2c66affSColin Finck     cost = temp = 0xdead;
8469c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8470c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
84711b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8472c2c66affSColin Finck     ok( drive[0], "expected a drive\n" );
8473c2c66affSColin Finck     ok( !cost, "expected cost == 0, got %d\n", cost );
8474c2c66affSColin Finck     ok( !temp, "expected temp == 0, got %d\n", temp );
8475c2c66affSColin Finck 
8476c2c66affSColin Finck     len = sizeof(drive);
8477c2c66affSColin Finck     drive[0] = 0;
8478c2c66affSColin Finck     cost = temp = 0xdead;
8479c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8480c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
84811b4acd3cSwinesync     ok( len == 2, "expected len == 2, got %lu\n", len );
8482c2c66affSColin Finck     ok( drive[0], "expected a drive\n" );
8483c2c66affSColin Finck     ok( !cost, "expected cost == 0, got %d\n", cost );
8484*f4be6dc3SMikhail     todo_wine ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8485c2c66affSColin Finck 
8486c2c66affSColin Finck     /* increased index */
8487c2c66affSColin Finck     len = sizeof(drive);
8488c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8489c2c66affSColin Finck     ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8490c2c66affSColin Finck 
8491c2c66affSColin Finck     len = sizeof(drive);
8492c2c66affSColin Finck     r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8493c2c66affSColin Finck     ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8494c2c66affSColin Finck 
8495818a84ddSwinesync     /* test MsiGetFeatureCost */
8496818a84ddSwinesync     cost = 0xdead;
8497818a84ddSwinesync     r = MsiGetFeatureCostA( hpkg, NULL, MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8498818a84ddSwinesync     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8499818a84ddSwinesync     ok( cost == 0xdead, "got %d\n", cost );
8500818a84ddSwinesync 
8501818a84ddSwinesync     r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, NULL );
8502818a84ddSwinesync     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8503818a84ddSwinesync 
8504818a84ddSwinesync     cost = 0xdead;
8505818a84ddSwinesync     r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
8506818a84ddSwinesync     ok( !r, "got %u\n", r);
8507*f4be6dc3SMikhail     ok( cost == 12000024, "got %d\n", cost );
8508818a84ddSwinesync 
8509c2c66affSColin Finck     MsiCloseHandle( hpkg );
8510c2c66affSColin Finck error:
8511c2c66affSColin Finck     MsiCloseHandle( hdb );
8512c2c66affSColin Finck     DeleteFileA( msifile );
8513c2c66affSColin Finck }
8514c2c66affSColin Finck 
test_MsiDatabaseCommit(void)8515c2c66affSColin Finck static void test_MsiDatabaseCommit(void)
8516c2c66affSColin Finck {
8517c2c66affSColin Finck     UINT r;
8518c2c66affSColin Finck     MSIHANDLE hdb, hpkg = 0;
8519c2c66affSColin Finck     char buf[32], package[12];
8520c2c66affSColin Finck     DWORD sz;
8521c2c66affSColin Finck 
8522c2c66affSColin Finck     hdb = create_package_db();
8523c2c66affSColin Finck     ok( hdb, "failed to create database\n" );
8524c2c66affSColin Finck 
8525f860a780SAmine Khaldi     create_property_table( hdb );
8526c2c66affSColin Finck 
85271b4acd3cSwinesync     sprintf( package, "#%lu", hdb );
8528c2c66affSColin Finck     r = MsiOpenPackageA( package, &hpkg );
8529c2c66affSColin Finck     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8530c2c66affSColin Finck     {
8531c2c66affSColin Finck         skip("Not enough rights to perform tests\n");
8532c2c66affSColin Finck         goto error;
8533c2c66affSColin Finck     }
8534c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "got %u\n", r );
8535c2c66affSColin Finck 
8536c2c66affSColin Finck     r = MsiSetPropertyA( hpkg, "PROP", "value" );
8537c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "got %u\n", r );
8538c2c66affSColin Finck 
8539c2c66affSColin Finck     buf[0] = 0;
8540c2c66affSColin Finck     sz = sizeof(buf);
8541c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8542c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8543c2c66affSColin Finck     ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8544c2c66affSColin Finck 
8545c2c66affSColin Finck     r = MsiDatabaseCommit( hdb );
8546c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8547c2c66affSColin Finck 
8548c2c66affSColin Finck     buf[0] = 0;
8549c2c66affSColin Finck     sz = sizeof(buf);
8550c2c66affSColin Finck     r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8551c2c66affSColin Finck     ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8552c2c66affSColin Finck     ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8553c2c66affSColin Finck 
8554c2c66affSColin Finck     MsiCloseHandle( hpkg );
8555c2c66affSColin Finck error:
8556c2c66affSColin Finck     MsiCloseHandle( hdb );
8557c2c66affSColin Finck     DeleteFileA( msifile );
8558c2c66affSColin Finck }
8559c2c66affSColin Finck 
85602f8e6f71SAmine Khaldi static int externalui_ran;
85612f8e6f71SAmine Khaldi 
externalui_callback(void * context,UINT message_type,LPCSTR message)85622f8e6f71SAmine Khaldi static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
85632f8e6f71SAmine Khaldi {
85642f8e6f71SAmine Khaldi     externalui_ran = 1;
85652f8e6f71SAmine Khaldi     ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
85662f8e6f71SAmine Khaldi     return 0;
85672f8e6f71SAmine Khaldi }
85682f8e6f71SAmine Khaldi 
85692f8e6f71SAmine Khaldi static int externalui_record_ran;
85702f8e6f71SAmine Khaldi 
externalui_record_callback(void * context,UINT message_type,MSIHANDLE hrecord)85712f8e6f71SAmine Khaldi static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
85722f8e6f71SAmine Khaldi {
85732f8e6f71SAmine Khaldi     INT retval = context ? *((INT *)context) : 0;
85742f8e6f71SAmine Khaldi     UINT r;
85752f8e6f71SAmine Khaldi     externalui_record_ran = 1;
85762f8e6f71SAmine Khaldi     ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
85772f8e6f71SAmine Khaldi     r = MsiRecordGetFieldCount(hrecord);
85782f8e6f71SAmine Khaldi     ok(r == 1, "expected 1, got %u\n", r);
85792f8e6f71SAmine Khaldi     r = MsiRecordGetInteger(hrecord, 1);
85802f8e6f71SAmine Khaldi     ok(r == 12345, "expected 12345, got %u\n", r);
85812f8e6f71SAmine Khaldi     return retval;
85822f8e6f71SAmine Khaldi }
85832f8e6f71SAmine Khaldi 
test_externalui(void)85842f8e6f71SAmine Khaldi static void test_externalui(void)
85852f8e6f71SAmine Khaldi {
85862f8e6f71SAmine Khaldi     /* test that external UI handlers work correctly */
85872f8e6f71SAmine Khaldi 
85882f8e6f71SAmine Khaldi     INSTALLUI_HANDLERA prev;
85892f8e6f71SAmine Khaldi     INSTALLUI_HANDLER_RECORD prev_record;
85902f8e6f71SAmine Khaldi     MSIHANDLE hpkg, hrecord;
85912f8e6f71SAmine Khaldi     UINT r;
85922f8e6f71SAmine Khaldi     INT retval = 0;
85932f8e6f71SAmine Khaldi 
85942f8e6f71SAmine Khaldi     prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
85952f8e6f71SAmine Khaldi 
85962f8e6f71SAmine Khaldi     r = package_from_db(create_package_db(), &hpkg);
85972f8e6f71SAmine Khaldi     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
85982f8e6f71SAmine Khaldi     {
85992f8e6f71SAmine Khaldi         skip("Not enough rights to perform tests\n");
86002f8e6f71SAmine Khaldi         DeleteFileA(msifile);
86012f8e6f71SAmine Khaldi         return;
86022f8e6f71SAmine Khaldi     }
86032f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
86042f8e6f71SAmine Khaldi 
86052f8e6f71SAmine Khaldi     hrecord = MsiCreateRecord(1);
86062f8e6f71SAmine Khaldi     ok(hrecord, "Expected a valid record\n");
86072f8e6f71SAmine Khaldi     r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
86082f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
86092f8e6f71SAmine Khaldi     r = MsiRecordSetInteger(hrecord, 1, 12345);
86102f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
86112f8e6f71SAmine Khaldi 
86122f8e6f71SAmine Khaldi     externalui_ran = 0;
86132f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
86142f8e6f71SAmine Khaldi     ok(r == 0, "expected 0, got %u\n", r);
86152f8e6f71SAmine Khaldi     ok(externalui_ran == 1, "external UI callback did not run\n");
86162f8e6f71SAmine Khaldi 
86172f8e6f71SAmine Khaldi     prev = MsiSetExternalUIA(prev, 0, NULL);
86182f8e6f71SAmine Khaldi     ok(prev == externalui_callback, "wrong callback function %p\n", prev);
86192f8e6f71SAmine Khaldi     r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record);
86202f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
86212f8e6f71SAmine Khaldi 
86222f8e6f71SAmine Khaldi     externalui_ran = externalui_record_ran = 0;
86232f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
86242f8e6f71SAmine Khaldi     ok(r == 0, "expected 0, got %u\n", r);
86252f8e6f71SAmine Khaldi     ok(externalui_ran == 0, "external UI callback should not have run\n");
86262f8e6f71SAmine Khaldi     ok(externalui_record_ran == 1, "external UI record callback did not run\n");
86272f8e6f71SAmine Khaldi 
86282f8e6f71SAmine Khaldi     MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
86292f8e6f71SAmine Khaldi 
86302f8e6f71SAmine Khaldi     externalui_ran = externalui_record_ran = 0;
86312f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
86322f8e6f71SAmine Khaldi     ok(r == 0, "expected 0, got %u\n", r);
86332f8e6f71SAmine Khaldi     ok(externalui_ran == 1, "external UI callback did not run\n");
86342f8e6f71SAmine Khaldi     ok(externalui_record_ran == 1, "external UI record callback did not run\n");
86352f8e6f71SAmine Khaldi 
86362f8e6f71SAmine Khaldi     retval = 1;
86372f8e6f71SAmine Khaldi     externalui_ran = externalui_record_ran = 0;
86382f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
86392f8e6f71SAmine Khaldi     ok(r == 1, "expected 1, got %u\n", r);
86402f8e6f71SAmine Khaldi     ok(externalui_ran == 0, "external UI callback should not have run\n");
86412f8e6f71SAmine Khaldi     ok(externalui_record_ran == 1, "external UI record callback did not run\n");
86422f8e6f71SAmine Khaldi 
86432f8e6f71SAmine Khaldi     /* filter and context should be kept separately */
86442f8e6f71SAmine Khaldi     r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record);
86452f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
86462f8e6f71SAmine Khaldi 
86472f8e6f71SAmine Khaldi     externalui_ran = externalui_record_ran = 0;
86482f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
86492f8e6f71SAmine Khaldi     ok(r == 0, "expected 0, got %u\n", r);
86502f8e6f71SAmine Khaldi     ok(externalui_ran == 1, "external UI callback did not run\n");
86512f8e6f71SAmine Khaldi     ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
86522f8e6f71SAmine Khaldi 
86532f8e6f71SAmine Khaldi     MsiCloseHandle(hpkg);
86542f8e6f71SAmine Khaldi     DeleteFileA(msifile);
86552f8e6f71SAmine Khaldi }
86562f8e6f71SAmine Khaldi 
86572f8e6f71SAmine Khaldi struct externalui_message {
86582f8e6f71SAmine Khaldi     UINT message;
86592f8e6f71SAmine Khaldi     int field_count;
86602f8e6f71SAmine Khaldi     char field[4][100];
86612f8e6f71SAmine Khaldi     int match[4]; /* should we test for a match */
86622f8e6f71SAmine Khaldi     int optional;
86632f8e6f71SAmine Khaldi };
86642f8e6f71SAmine Khaldi 
86652f8e6f71SAmine Khaldi static struct externalui_message *sequence;
86662f8e6f71SAmine Khaldi static int sequence_count, sequence_size;
86672f8e6f71SAmine Khaldi 
add_message(const struct externalui_message * msg)86682f8e6f71SAmine Khaldi static void add_message(const struct externalui_message *msg)
86692f8e6f71SAmine Khaldi {
86702f8e6f71SAmine Khaldi     if (!sequence)
86712f8e6f71SAmine Khaldi     {
86722f8e6f71SAmine Khaldi         sequence_size = 10;
86736aefc5b9Swinesync         sequence = malloc(sequence_size * sizeof(*sequence));
86742f8e6f71SAmine Khaldi     }
86752f8e6f71SAmine Khaldi     if (sequence_count == sequence_size)
86762f8e6f71SAmine Khaldi     {
86772f8e6f71SAmine Khaldi         sequence_size *= 2;
86786aefc5b9Swinesync         sequence = realloc(sequence, sequence_size * sizeof(*sequence));
86792f8e6f71SAmine Khaldi     }
86802f8e6f71SAmine Khaldi 
86812f8e6f71SAmine Khaldi     assert(sequence);
86822f8e6f71SAmine Khaldi     sequence[sequence_count++] = *msg;
86832f8e6f71SAmine Khaldi }
86842f8e6f71SAmine Khaldi 
flush_sequence(void)86852f8e6f71SAmine Khaldi static void flush_sequence(void)
86862f8e6f71SAmine Khaldi {
86876aefc5b9Swinesync     free(sequence);
86882f8e6f71SAmine Khaldi     sequence = NULL;
86892f8e6f71SAmine Khaldi     sequence_count = sequence_size = 0;
86902f8e6f71SAmine Khaldi }
86912f8e6f71SAmine Khaldi 
ok_sequence_(const struct externalui_message * expected,const char * context,BOOL todo,const char * file,int line)86922f8e6f71SAmine Khaldi static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
86932f8e6f71SAmine Khaldi                          const char *file, int line)
86942f8e6f71SAmine Khaldi {
86952f8e6f71SAmine Khaldi     static const struct externalui_message end_of_sequence = {0};
86962f8e6f71SAmine Khaldi     const struct externalui_message *actual;
86972f8e6f71SAmine Khaldi     int failcount = 0;
86982f8e6f71SAmine Khaldi     int i;
86992f8e6f71SAmine Khaldi 
87002f8e6f71SAmine Khaldi     add_message(&end_of_sequence);
87012f8e6f71SAmine Khaldi 
87022f8e6f71SAmine Khaldi     actual = sequence;
87032f8e6f71SAmine Khaldi 
87042f8e6f71SAmine Khaldi     while (expected->message && actual->message)
87052f8e6f71SAmine Khaldi     {
87062f8e6f71SAmine Khaldi         if (expected->message == actual->message)
87072f8e6f71SAmine Khaldi         {
8708f860a780SAmine Khaldi             if (expected->field_count < actual->field_count)
87092f8e6f71SAmine Khaldi             {
87102f8e6f71SAmine Khaldi                 todo_wine_if (todo)
87112f8e6f71SAmine Khaldi                     ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
87122f8e6f71SAmine Khaldi                                      context, expected->message, expected->field_count, actual->field_count);
87132f8e6f71SAmine Khaldi                 failcount++;
87142f8e6f71SAmine Khaldi             }
87152f8e6f71SAmine Khaldi 
87162f8e6f71SAmine Khaldi             for (i = 0; i <= actual->field_count; i++)
87172f8e6f71SAmine Khaldi             {
87182f8e6f71SAmine Khaldi                 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
87192f8e6f71SAmine Khaldi                 {
87202f8e6f71SAmine Khaldi                     todo_wine_if (todo)
87212f8e6f71SAmine Khaldi                         ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
87222f8e6f71SAmine Khaldi                                          context, expected->message, i, expected->field[i], actual->field[i]);
87232f8e6f71SAmine Khaldi                     failcount++;
87242f8e6f71SAmine Khaldi                 }
87252f8e6f71SAmine Khaldi             }
87262f8e6f71SAmine Khaldi 
87272f8e6f71SAmine Khaldi             expected++;
87282f8e6f71SAmine Khaldi             actual++;
87292f8e6f71SAmine Khaldi         }
8730f860a780SAmine Khaldi         else if (expected->optional)
8731f860a780SAmine Khaldi         {
8732f860a780SAmine Khaldi             expected++;
8733f860a780SAmine Khaldi         }
87342f8e6f71SAmine Khaldi         else
87352f8e6f71SAmine Khaldi         {
87362f8e6f71SAmine Khaldi             todo_wine_if (todo)
87372f8e6f71SAmine Khaldi                 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
87382f8e6f71SAmine Khaldi                                  context, expected->message, actual->message);
87392f8e6f71SAmine Khaldi             failcount++;
87402f8e6f71SAmine Khaldi             if (todo)
87412f8e6f71SAmine Khaldi                 goto done;
87422f8e6f71SAmine Khaldi             expected++;
87432f8e6f71SAmine Khaldi             actual++;
87442f8e6f71SAmine Khaldi         }
87452f8e6f71SAmine Khaldi     }
87462f8e6f71SAmine Khaldi 
87472f8e6f71SAmine Khaldi     if (expected->message || actual->message)
87482f8e6f71SAmine Khaldi     {
87492f8e6f71SAmine Khaldi         todo_wine_if (todo)
87502f8e6f71SAmine Khaldi             ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
87512f8e6f71SAmine Khaldi                              context, expected->message, actual->message);
87522f8e6f71SAmine Khaldi         failcount++;
87532f8e6f71SAmine Khaldi     }
87542f8e6f71SAmine Khaldi 
87552f8e6f71SAmine Khaldi     if(todo && !failcount) /* succeeded yet marked todo */
87562f8e6f71SAmine Khaldi     {
87572f8e6f71SAmine Khaldi         todo_wine
87582f8e6f71SAmine Khaldi             ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
87592f8e6f71SAmine Khaldi     }
87602f8e6f71SAmine Khaldi 
87612f8e6f71SAmine Khaldi done:
87622f8e6f71SAmine Khaldi     flush_sequence();
87632f8e6f71SAmine Khaldi }
87642f8e6f71SAmine Khaldi 
87652f8e6f71SAmine Khaldi #define ok_sequence(exp, contx, todo) \
87662f8e6f71SAmine Khaldi         ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
87672f8e6f71SAmine Khaldi 
8768f860a780SAmine Khaldi /* don't use PROGRESS, which is timing-dependent,
8769f860a780SAmine Khaldi  * or SHOWDIALOG, which due to a bug causes a hang on XP */
8770f860a780SAmine Khaldi static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE =
8771f860a780SAmine Khaldi     INSTALLLOGMODE_FATALEXIT |
8772f860a780SAmine Khaldi     INSTALLLOGMODE_ERROR |
8773f860a780SAmine Khaldi     INSTALLLOGMODE_WARNING |
8774f860a780SAmine Khaldi     INSTALLLOGMODE_USER |
8775f860a780SAmine Khaldi     INSTALLLOGMODE_INFO |
8776f860a780SAmine Khaldi     INSTALLLOGMODE_FILESINUSE |
8777f860a780SAmine Khaldi     INSTALLLOGMODE_RESOLVESOURCE |
8778f860a780SAmine Khaldi     INSTALLLOGMODE_OUTOFDISKSPACE |
8779f860a780SAmine Khaldi     INSTALLLOGMODE_ACTIONSTART |
8780f860a780SAmine Khaldi     INSTALLLOGMODE_ACTIONDATA |
8781f860a780SAmine Khaldi     INSTALLLOGMODE_COMMONDATA |
8782f860a780SAmine Khaldi     INSTALLLOGMODE_INITIALIZE |
8783f860a780SAmine Khaldi     INSTALLLOGMODE_TERMINATE |
8784f860a780SAmine Khaldi     INSTALLLOGMODE_RMFILESINUSE |
8785f860a780SAmine Khaldi     INSTALLLOGMODE_INSTALLSTART |
8786f860a780SAmine Khaldi     INSTALLLOGMODE_INSTALLEND;
8787f860a780SAmine Khaldi 
87882f8e6f71SAmine Khaldi static const struct externalui_message empty_sequence[] = {
87892f8e6f71SAmine Khaldi     {0}
87902f8e6f71SAmine Khaldi };
87912f8e6f71SAmine Khaldi 
87922f8e6f71SAmine Khaldi static const struct externalui_message openpackage_nonexistent_sequence[] = {
87932f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INITIALIZE, -1},
87942f8e6f71SAmine Khaldi     {INSTALLMESSAGE_TERMINATE, -1},
87952f8e6f71SAmine Khaldi     {0}
87962f8e6f71SAmine Khaldi };
87972f8e6f71SAmine Khaldi 
87982f8e6f71SAmine Khaldi static const struct externalui_message openpackage_sequence[] = {
87992f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INITIALIZE, -1},
88002f8e6f71SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
88012f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
88022f8e6f71SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
88032f8e6f71SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
88042f8e6f71SAmine Khaldi     {0}
88052f8e6f71SAmine Khaldi };
88062f8e6f71SAmine Khaldi 
88072f8e6f71SAmine Khaldi static const struct externalui_message processmessage_info_sequence[] = {
88082f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
88092f8e6f71SAmine Khaldi     {0}
88102f8e6f71SAmine Khaldi };
88112f8e6f71SAmine Khaldi 
88122f8e6f71SAmine Khaldi static const struct externalui_message processmessage_actionstart_sequence[] = {
88132f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
88142f8e6f71SAmine Khaldi     {0}
88152f8e6f71SAmine Khaldi };
88162f8e6f71SAmine Khaldi 
88172f8e6f71SAmine Khaldi static const struct externalui_message processmessage_actiondata_sequence[] = {
88182f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
88192f8e6f71SAmine Khaldi     {0}
88202f8e6f71SAmine Khaldi };
88212f8e6f71SAmine Khaldi 
88222f8e6f71SAmine Khaldi static const struct externalui_message processmessage_error_sequence[] = {
88232f8e6f71SAmine Khaldi     {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
88242f8e6f71SAmine Khaldi     {0}
88252f8e6f71SAmine Khaldi };
88262f8e6f71SAmine Khaldi 
88272f8e6f71SAmine Khaldi static const struct externalui_message processmessage_internal_error_sequence[] = {
88282f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]:  Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
88292f8e6f71SAmine Khaldi     {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
88302f8e6f71SAmine Khaldi     {0}
88312f8e6f71SAmine Khaldi };
88322f8e6f71SAmine Khaldi 
88332f8e6f71SAmine Khaldi static const struct externalui_message processmessage_error_format_sequence[] = {
88342f8e6f71SAmine Khaldi     {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
88352f8e6f71SAmine Khaldi     {0}
88362f8e6f71SAmine Khaldi };
88372f8e6f71SAmine Khaldi 
88382f8e6f71SAmine Khaldi static const struct externalui_message doaction_costinitialize_sequence[] = {
88392f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
88402f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
88412f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
88422f8e6f71SAmine Khaldi     {0}
88432f8e6f71SAmine Khaldi };
88442f8e6f71SAmine Khaldi 
88452f8e6f71SAmine Khaldi static const struct externalui_message doaction_custom_sequence[] = {
88462f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
88472f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
88482f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
88492f8e6f71SAmine Khaldi     {0}
88502f8e6f71SAmine Khaldi };
88512f8e6f71SAmine Khaldi 
88522f8e6f71SAmine Khaldi static const struct externalui_message doaction_custom_fullui_sequence[] = {
88532f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
88542f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
88552f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
88562f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
88572f8e6f71SAmine Khaldi     {0}
88582f8e6f71SAmine Khaldi };
88592f8e6f71SAmine Khaldi 
88602f8e6f71SAmine Khaldi static const struct externalui_message doaction_custom_cancel_sequence[] = {
88612f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
88622f8e6f71SAmine Khaldi     {0}
88632f8e6f71SAmine Khaldi };
88642f8e6f71SAmine Khaldi 
88652f8e6f71SAmine Khaldi static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
88662f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
88672f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
88682f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
88692f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]:  Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
88702f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
88712f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
88722f8e6f71SAmine Khaldi     {0}
88732f8e6f71SAmine Khaldi };
88742f8e6f71SAmine Khaldi 
88752f8e6f71SAmine Khaldi static const struct externalui_message doaction_dialog_sequence[] = {
88762f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
88772f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
88782f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
88792f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
88802f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
88812f8e6f71SAmine Khaldi     {0}
88822f8e6f71SAmine Khaldi };
88832f8e6f71SAmine Khaldi 
88842f8e6f71SAmine Khaldi static const struct externalui_message doaction_dialog_error_sequence[] = {
88852f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
88862f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
88872f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
88882f8e6f71SAmine Khaldi     {0}
88892f8e6f71SAmine Khaldi };
88902f8e6f71SAmine Khaldi 
88912f8e6f71SAmine Khaldi static const struct externalui_message doaction_dialog_3_sequence[] = {
88922f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
88932f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
88942f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
88952f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
88962f8e6f71SAmine Khaldi     {0}
88972f8e6f71SAmine Khaldi };
88982f8e6f71SAmine Khaldi 
88992f8e6f71SAmine Khaldi static const struct externalui_message doaction_dialog_12345_sequence[] = {
89002f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
89012f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
89022f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
89032f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
89042f8e6f71SAmine Khaldi     {0}
89052f8e6f71SAmine Khaldi };
89062f8e6f71SAmine Khaldi 
89072f8e6f71SAmine Khaldi static const struct externalui_message closehandle_sequence[] = {
89082f8e6f71SAmine Khaldi     {INSTALLMESSAGE_TERMINATE, -1},
89092f8e6f71SAmine Khaldi     {0}
89102f8e6f71SAmine Khaldi };
89112f8e6f71SAmine Khaldi 
externalui_message_string_callback(void * context,UINT message,LPCSTR string)89122f8e6f71SAmine Khaldi static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
89132f8e6f71SAmine Khaldi {
89142f8e6f71SAmine Khaldi     INT retval = context ? *((INT *)context) : 0;
89152f8e6f71SAmine Khaldi     struct externalui_message msg;
89162f8e6f71SAmine Khaldi 
89172f8e6f71SAmine Khaldi     msg.message = message;
89182f8e6f71SAmine Khaldi     msg.field_count = 0;
89192f8e6f71SAmine Khaldi     strcpy(msg.field[0], string);
89202f8e6f71SAmine Khaldi     add_message(&msg);
89212f8e6f71SAmine Khaldi 
89222f8e6f71SAmine Khaldi     return retval;
89232f8e6f71SAmine Khaldi }
89242f8e6f71SAmine Khaldi 
externalui_message_callback(void * context,UINT message,MSIHANDLE hrecord)89252f8e6f71SAmine Khaldi static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
89262f8e6f71SAmine Khaldi {
89272f8e6f71SAmine Khaldi     INT retval = context ? *((INT *)context) : 0;
89282f8e6f71SAmine Khaldi     struct externalui_message msg;
8929f860a780SAmine Khaldi     char buffer[256];
8930f860a780SAmine Khaldi     DWORD length;
8931f860a780SAmine Khaldi     UINT r;
89322f8e6f71SAmine Khaldi     int i;
89332f8e6f71SAmine Khaldi 
89342f8e6f71SAmine Khaldi     msg.message = message;
89352f8e6f71SAmine Khaldi     if (message == INSTALLMESSAGE_TERMINATE)
89362f8e6f71SAmine Khaldi     {
89372f8e6f71SAmine Khaldi         /* trying to access the record seems to hang on some versions of Windows */
89382f8e6f71SAmine Khaldi         msg.field_count = -1;
89392f8e6f71SAmine Khaldi         add_message(&msg);
89402f8e6f71SAmine Khaldi         return 1;
89412f8e6f71SAmine Khaldi     }
89422f8e6f71SAmine Khaldi     msg.field_count = MsiRecordGetFieldCount(hrecord);
89432f8e6f71SAmine Khaldi     for (i = 0; i <= msg.field_count; i++)
89442f8e6f71SAmine Khaldi     {
8945f860a780SAmine Khaldi         length = sizeof(buffer);
8946f860a780SAmine Khaldi         r = MsiRecordGetStringA(hrecord, i, buffer, &length);
8947f860a780SAmine Khaldi         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
89482f8e6f71SAmine Khaldi         memcpy(msg.field[i], buffer, min(100, length+1));
89492f8e6f71SAmine Khaldi     }
89502f8e6f71SAmine Khaldi 
8951f860a780SAmine Khaldi     /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
8952f860a780SAmine Khaldi     if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
8953f860a780SAmine Khaldi         return retval;
8954f860a780SAmine Khaldi 
89552f8e6f71SAmine Khaldi     add_message(&msg);
89562f8e6f71SAmine Khaldi 
89572f8e6f71SAmine Khaldi     return retval;
89582f8e6f71SAmine Khaldi }
89592f8e6f71SAmine Khaldi 
test_externalui_message(void)89602f8e6f71SAmine Khaldi static void test_externalui_message(void)
89612f8e6f71SAmine Khaldi {
89622f8e6f71SAmine Khaldi     /* test that events trigger the correct sequence of messages */
89632f8e6f71SAmine Khaldi 
89642f8e6f71SAmine Khaldi     INSTALLUI_HANDLER_RECORD prev;
89652f8e6f71SAmine Khaldi     MSIHANDLE hdb, hpkg, hrecord;
89662f8e6f71SAmine Khaldi     INT retval = 1;
89672f8e6f71SAmine Khaldi     UINT r;
89682f8e6f71SAmine Khaldi 
89692f8e6f71SAmine Khaldi     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
89702f8e6f71SAmine Khaldi 
89712f8e6f71SAmine Khaldi     MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval);
8972f860a780SAmine Khaldi     r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev);
89732f8e6f71SAmine Khaldi 
89742f8e6f71SAmine Khaldi     flush_sequence();
89752f8e6f71SAmine Khaldi 
89762f8e6f71SAmine Khaldi     CoInitialize(NULL);
89772f8e6f71SAmine Khaldi 
89782f8e6f71SAmine Khaldi     hdb = create_package_db();
89792f8e6f71SAmine Khaldi     ok(hdb, "failed to create database\n");
89802f8e6f71SAmine Khaldi 
8981*f4be6dc3SMikhail     create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
89822f8e6f71SAmine Khaldi     r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
89832f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
89842f8e6f71SAmine Khaldi 
8985*f4be6dc3SMikhail     r = run_query(hdb, 0, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
89862f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
8987*f4be6dc3SMikhail     r = run_query(hdb, 0, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
89882f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
89892f8e6f71SAmine Khaldi 
8990f860a780SAmine Khaldi     create_actiontext_table(hdb);
8991f860a780SAmine Khaldi     add_actiontext_entry(hdb, "'custom', 'description', 'template'");
8992f860a780SAmine Khaldi     add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
89932f8e6f71SAmine Khaldi 
89942f8e6f71SAmine Khaldi     r = MsiOpenPackageA(NULL, &hpkg);
89952f8e6f71SAmine Khaldi     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
89962f8e6f71SAmine Khaldi     ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
89972f8e6f71SAmine Khaldi 
89982f8e6f71SAmine Khaldi     r = MsiOpenPackageA("nonexistent", &hpkg);
89992f8e6f71SAmine Khaldi     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
90002f8e6f71SAmine Khaldi     ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
90012f8e6f71SAmine Khaldi 
90022f8e6f71SAmine Khaldi     r = package_from_db(hdb, &hpkg);
90032f8e6f71SAmine Khaldi     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
90042f8e6f71SAmine Khaldi     {
90052f8e6f71SAmine Khaldi         skip("Not enough rights to perform tests\n");
90062f8e6f71SAmine Khaldi         DeleteFileA(msifile);
90072f8e6f71SAmine Khaldi         return;
90082f8e6f71SAmine Khaldi     }
90092f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
90102f8e6f71SAmine Khaldi     ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
90112f8e6f71SAmine Khaldi 
90122f8e6f71SAmine Khaldi     /* Test MsiProcessMessage */
90132f8e6f71SAmine Khaldi     hrecord = MsiCreateRecord(3);
90142f8e6f71SAmine Khaldi     ok(hrecord, "failed to create record\n");
90152f8e6f71SAmine Khaldi 
90162f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 0, "zero");
90172f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 1, "one");
90182f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 2, "two");
90192f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 3, "three");
90202f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
90212f8e6f71SAmine Khaldi     ok(r == 1, "Expected 1, got %d\n", r);
90222f8e6f71SAmine Khaldi     ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
90232f8e6f71SAmine Khaldi 
90242f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 1, "name");
90252f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 2, "description");
90262f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 3, "template");
90272f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord);
90282f8e6f71SAmine Khaldi     ok(r == 1, "Expected 1, got %d\n", r);
90292f8e6f71SAmine Khaldi     ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
90302f8e6f71SAmine Khaldi 
90312f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 0, "apple");
90322f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 1, "cherry");
90332f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 2, "banana");
90342f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 3, "guava");
90352f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord);
90362f8e6f71SAmine Khaldi     ok(r == 1, "Expected 1, got %d\n", r);
90372f8e6f71SAmine Khaldi     ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
90382f8e6f71SAmine Khaldi 
90392f8e6f71SAmine Khaldi     /* non-internal error */
90402f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 0, NULL);
90412f8e6f71SAmine Khaldi     MsiRecordSetInteger(hrecord, 1, 1311);
90422f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
90432f8e6f71SAmine Khaldi     ok(r == 1, "Expected 1, got %d\n", r);
90442f8e6f71SAmine Khaldi     ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
90452f8e6f71SAmine Khaldi 
90462f8e6f71SAmine Khaldi     /* internal error */
90472f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 0, NULL);
90482f8e6f71SAmine Khaldi     MsiRecordSetInteger(hrecord, 1, 2726);
90492f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
90502f8e6f71SAmine Khaldi     ok(r == 0, "Expected 0, got %d\n", r);
90512f8e6f71SAmine Khaldi     ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
90522f8e6f71SAmine Khaldi 
90532f8e6f71SAmine Khaldi     /* with format field */
90542f8e6f71SAmine Khaldi     MsiRecordSetStringA(hrecord, 0, "starfruit");
90552f8e6f71SAmine Khaldi     r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
90562f8e6f71SAmine Khaldi     ok(r == 1, "Expected 1, got %d\n", r);
90572f8e6f71SAmine Khaldi     ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
90582f8e6f71SAmine Khaldi 
90592f8e6f71SAmine Khaldi     /* Test a standard action */
90602f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "CostInitialize");
90612f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
90622f8e6f71SAmine Khaldi     ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
90632f8e6f71SAmine Khaldi 
90642f8e6f71SAmine Khaldi     /* Test a custom action */
90652f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "custom");
90662f8e6f71SAmine Khaldi     ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
90672f8e6f71SAmine Khaldi     ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
90682f8e6f71SAmine Khaldi 
90692f8e6f71SAmine Khaldi     /* close the package */
90702f8e6f71SAmine Khaldi     MsiCloseHandle(hpkg);
90712f8e6f71SAmine Khaldi     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
90722f8e6f71SAmine Khaldi 
90732f8e6f71SAmine Khaldi     /* Test dialogs */
90742f8e6f71SAmine Khaldi     hdb = create_package_db();
90752f8e6f71SAmine Khaldi     ok(hdb, "failed to create database\n");
90762f8e6f71SAmine Khaldi 
90772f8e6f71SAmine Khaldi     r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
90782f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
90792f8e6f71SAmine Khaldi 
9080f860a780SAmine Khaldi     create_dialog_table(hdb);
9081f860a780SAmine Khaldi     add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
90822f8e6f71SAmine Khaldi 
9083f860a780SAmine Khaldi     create_control_table(hdb);
9084f860a780SAmine Khaldi     add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
90852f8e6f71SAmine Khaldi 
90862f8e6f71SAmine Khaldi     r = package_from_db(hdb, &hpkg);
90872f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
90882f8e6f71SAmine Khaldi     ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
90892f8e6f71SAmine Khaldi 
90902f8e6f71SAmine Khaldi     /* Test a custom action */
90912f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "custom");
90922f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
90932f8e6f71SAmine Khaldi     ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
90942f8e6f71SAmine Khaldi 
90952f8e6f71SAmine Khaldi     retval = 2;
90962f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "custom");
90972f8e6f71SAmine Khaldi     ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
90982f8e6f71SAmine Khaldi     ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
90992f8e6f71SAmine Khaldi 
91002f8e6f71SAmine Khaldi     retval = 0;
91012f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "custom");
91022f8e6f71SAmine Khaldi     ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
91032f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
91042f8e6f71SAmine Khaldi 
91052f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "dialog");
91062f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
91072f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
91082f8e6f71SAmine Khaldi 
91092f8e6f71SAmine Khaldi     retval = -1;
91102f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "error");
91112f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
91122f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
91132f8e6f71SAmine Khaldi 
91142f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "error");
91152f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
91162f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
91172f8e6f71SAmine Khaldi 
91182f8e6f71SAmine Khaldi     retval = -2;
91192f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "custom");
91202f8e6f71SAmine Khaldi     ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
91212f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
91222f8e6f71SAmine Khaldi 
91232f8e6f71SAmine Khaldi     retval = 3;
91242f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "dialog");
91252f8e6f71SAmine Khaldi     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
91262f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
91272f8e6f71SAmine Khaldi 
91282f8e6f71SAmine Khaldi     retval = 12345;
91292f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "dialog");
91302f8e6f71SAmine Khaldi     ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
91312f8e6f71SAmine Khaldi     ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
91322f8e6f71SAmine Khaldi 
91332f8e6f71SAmine Khaldi     MsiCloseHandle(hpkg);
91342f8e6f71SAmine Khaldi     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
91352f8e6f71SAmine Khaldi 
91362f8e6f71SAmine Khaldi     MsiCloseHandle(hrecord);
91372f8e6f71SAmine Khaldi     CoUninitialize();
91382f8e6f71SAmine Khaldi     DeleteFileA(msifile);
91392f8e6f71SAmine Khaldi     DeleteFileA("forcecodepage.idt");
91402f8e6f71SAmine Khaldi }
91412f8e6f71SAmine Khaldi 
91422f8e6f71SAmine Khaldi static const struct externalui_message controlevent_spawn_sequence[] = {
91432f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
91442f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
91452f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
91462f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
91472f8e6f71SAmine Khaldi 
91482f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
91492f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
91502f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
91512f8e6f71SAmine Khaldi 
91522f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
91532f8e6f71SAmine Khaldi 
91542f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
91552f8e6f71SAmine Khaldi     {0}
91562f8e6f71SAmine Khaldi };
91572f8e6f71SAmine Khaldi 
91582f8e6f71SAmine Khaldi static const struct externalui_message controlevent_spawn2_sequence[] = {
91592f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
91602f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
91612f8e6f71SAmine Khaldi     {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
91622f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
91632f8e6f71SAmine Khaldi 
91642f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
91652f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
91662f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
91672f8e6f71SAmine Khaldi 
91682f8e6f71SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
91692f8e6f71SAmine Khaldi 
91702f8e6f71SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
91712f8e6f71SAmine Khaldi     {0}
91722f8e6f71SAmine Khaldi };
91732f8e6f71SAmine Khaldi 
test_controlevent(void)91742f8e6f71SAmine Khaldi static void test_controlevent(void)
91752f8e6f71SAmine Khaldi {
91762f8e6f71SAmine Khaldi     INSTALLUI_HANDLER_RECORD prev;
91772f8e6f71SAmine Khaldi     MSIHANDLE hdb, hpkg;
91782f8e6f71SAmine Khaldi     UINT r;
91792f8e6f71SAmine Khaldi 
91802f8e6f71SAmine Khaldi     if (!winetest_interactive)
91812f8e6f71SAmine Khaldi     {
91822f8e6f71SAmine Khaldi         skip("interactive ControlEvent tests\n");
91832f8e6f71SAmine Khaldi         return;
91842f8e6f71SAmine Khaldi     }
91852f8e6f71SAmine Khaldi 
91862f8e6f71SAmine Khaldi     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
91872f8e6f71SAmine Khaldi 
91882f8e6f71SAmine Khaldi     MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9189f860a780SAmine Khaldi     r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
91902f8e6f71SAmine Khaldi 
91912f8e6f71SAmine Khaldi     flush_sequence();
91922f8e6f71SAmine Khaldi 
91932f8e6f71SAmine Khaldi     CoInitialize(NULL);
91942f8e6f71SAmine Khaldi 
91952f8e6f71SAmine Khaldi     hdb = create_package_db();
91962f8e6f71SAmine Khaldi     ok(hdb, "failed to create database\n");
91972f8e6f71SAmine Khaldi 
9198*f4be6dc3SMikhail     create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
91992f8e6f71SAmine Khaldi     r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
92002f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
92012f8e6f71SAmine Khaldi 
9202f860a780SAmine Khaldi     create_dialog_table(hdb);
9203f860a780SAmine Khaldi     add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9204f860a780SAmine Khaldi     add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9205f860a780SAmine Khaldi     add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9206f860a780SAmine Khaldi     add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
92072f8e6f71SAmine Khaldi 
9208f860a780SAmine Khaldi     create_control_table(hdb);
9209f860a780SAmine Khaldi     add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9210f860a780SAmine Khaldi     add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9211f860a780SAmine Khaldi     add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9212f860a780SAmine Khaldi     add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
92132f8e6f71SAmine Khaldi 
9214f860a780SAmine Khaldi     create_controlevent_table(hdb);
9215f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9216f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
92172f8e6f71SAmine Khaldi 
9218f860a780SAmine Khaldi     create_custom_action_table(hdb);
9219f860a780SAmine Khaldi     add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
92202f8e6f71SAmine Khaldi 
92212f8e6f71SAmine Khaldi     /* SpawnDialog and EndDialog should trigger after all other events */
9222f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9223f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
92242f8e6f71SAmine Khaldi 
92252f8e6f71SAmine Khaldi     /* Multiple dialog events cause only the last one to be triggered */
9226f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9227f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9228f860a780SAmine Khaldi     add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
92292f8e6f71SAmine Khaldi 
92302f8e6f71SAmine Khaldi     r = package_from_db(hdb, &hpkg);
92312f8e6f71SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
92322f8e6f71SAmine Khaldi     ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
92332f8e6f71SAmine Khaldi 
92342f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "spawn");
92352f8e6f71SAmine Khaldi     ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
92362f8e6f71SAmine Khaldi     ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
92372f8e6f71SAmine Khaldi 
92382f8e6f71SAmine Khaldi     r = MsiDoActionA(hpkg, "spawn2");
92392f8e6f71SAmine Khaldi     ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
92402f8e6f71SAmine Khaldi     ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
92412f8e6f71SAmine Khaldi 
92422f8e6f71SAmine Khaldi     MsiCloseHandle(hpkg);
92432f8e6f71SAmine Khaldi     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
92442f8e6f71SAmine Khaldi 
92452f8e6f71SAmine Khaldi     CoUninitialize();
92462f8e6f71SAmine Khaldi     DeleteFileA(msifile);
92472f8e6f71SAmine Khaldi     DeleteFileA("forcecodepage.idt");
92482f8e6f71SAmine Khaldi }
92492f8e6f71SAmine Khaldi 
9250f860a780SAmine Khaldi static const struct externalui_message toplevel_install_sequence[] = {
9251f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9252f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9253f860a780SAmine Khaldi 
9254f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9255f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9256f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9257f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9258f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9259f860a780SAmine Khaldi 
9260f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9261f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9262f860a780SAmine Khaldi     {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9263f860a780SAmine Khaldi 
9264f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9265f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9266f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9267f860a780SAmine Khaldi 
9268f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9269f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9270f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9271f860a780SAmine Khaldi 
9272f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9273f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9274f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9275f860a780SAmine Khaldi 
9276f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9277f860a780SAmine Khaldi     {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9278f860a780SAmine Khaldi 
9279f860a780SAmine Khaldi     /* property dump */
9280f860a780SAmine Khaldi 
9281f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9282f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9283f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9284f860a780SAmine Khaldi     {0}
9285f860a780SAmine Khaldi };
9286f860a780SAmine Khaldi 
9287f860a780SAmine Khaldi static const struct externalui_message toplevel_install_ui_sequence[] = {
9288f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9289f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9290f860a780SAmine Khaldi 
9291f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9292f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9293f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9294f860a780SAmine Khaldi 
9295f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9296f860a780SAmine Khaldi     {0}
9297f860a780SAmine Khaldi };
9298f860a780SAmine Khaldi 
9299f860a780SAmine Khaldi static const struct externalui_message toplevel_executeaction_install_sequence[] = {
9300f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9301f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9302f860a780SAmine Khaldi 
9303f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9304f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9305f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9306f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9307f860a780SAmine Khaldi 
9308f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9309f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9310f860a780SAmine Khaldi     {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9311f860a780SAmine Khaldi 
9312f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9313f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9314f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9315f860a780SAmine Khaldi 
9316f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9317f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9318f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9319f860a780SAmine Khaldi 
9320f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9321f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9322f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9323f860a780SAmine Khaldi 
9324f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9325f860a780SAmine Khaldi     {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9326f860a780SAmine Khaldi 
9327f860a780SAmine Khaldi     /* property dump */
9328f860a780SAmine Khaldi 
9329f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9330f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9331f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9332f860a780SAmine Khaldi     {0}
9333f860a780SAmine Khaldi };
9334f860a780SAmine Khaldi 
9335f860a780SAmine Khaldi static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = {
9336f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9337f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9338f860a780SAmine Khaldi 
9339f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9340f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9341f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9342f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9343f860a780SAmine Khaldi 
9344f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9345f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9346f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9347f860a780SAmine Khaldi 
9348f860a780SAmine Khaldi     /* property dump */
9349f860a780SAmine Khaldi 
9350f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9351f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9352f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9353f860a780SAmine Khaldi     {0}
9354f860a780SAmine Khaldi };
9355f860a780SAmine Khaldi 
9356f860a780SAmine Khaldi static const struct externalui_message toplevel_msiinstallproduct_sequence[] = {
9357f860a780SAmine Khaldi     {INSTALLMESSAGE_INITIALIZE, -1},
9358f860a780SAmine Khaldi 
9359f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9360f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9361f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9362f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9363f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9364f860a780SAmine Khaldi 
9365f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9366f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9367f860a780SAmine Khaldi 
9368f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9369f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9370f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9371f860a780SAmine Khaldi 
9372f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9373f860a780SAmine Khaldi 
9374f860a780SAmine Khaldi     /* property dump */
9375f860a780SAmine Khaldi 
9376f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9377f860a780SAmine Khaldi     {INSTALLMESSAGE_TERMINATE, -1},
9378f860a780SAmine Khaldi     {0}
9379f860a780SAmine Khaldi };
9380f860a780SAmine Khaldi 
9381f860a780SAmine Khaldi static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = {
9382f860a780SAmine Khaldi     {INSTALLMESSAGE_INITIALIZE, -1},
9383f860a780SAmine Khaldi 
9384f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9385f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9386f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9387f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9388f860a780SAmine Khaldi     {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9389f860a780SAmine Khaldi 
9390f860a780SAmine Khaldi     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9391f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9392f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9393f860a780SAmine Khaldi 
9394f860a780SAmine Khaldi     /* property dump */
9395f860a780SAmine Khaldi 
9396f860a780SAmine Khaldi     {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9397f860a780SAmine Khaldi     {INSTALLMESSAGE_TERMINATE, -1},
9398f860a780SAmine Khaldi     {0}
9399f860a780SAmine Khaldi };
9400f860a780SAmine Khaldi 
9401f860a780SAmine Khaldi /* tests involving top-level actions: INSTALL, ExecuteAction */
test_top_level_action(void)9402f860a780SAmine Khaldi static void test_top_level_action(void)
9403f860a780SAmine Khaldi {
9404f860a780SAmine Khaldi     INSTALLUI_HANDLER_RECORD prev;
9405f860a780SAmine Khaldi     MSIHANDLE hdb, hpkg;
9406f860a780SAmine Khaldi     UINT r;
9407f860a780SAmine Khaldi     char msifile_absolute[MAX_PATH];
9408f860a780SAmine Khaldi 
9409f860a780SAmine Khaldi     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9410f860a780SAmine Khaldi 
9411f860a780SAmine Khaldi     MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9412f860a780SAmine Khaldi     r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev);
9413f860a780SAmine Khaldi 
9414f860a780SAmine Khaldi     flush_sequence();
9415f860a780SAmine Khaldi 
9416f860a780SAmine Khaldi     CoInitialize(NULL);
9417f860a780SAmine Khaldi 
9418f860a780SAmine Khaldi     hdb = create_package_db();
9419f860a780SAmine Khaldi     ok(hdb, "failed to create database\n");
9420f860a780SAmine Khaldi 
9421*f4be6dc3SMikhail     create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") -1 );
9422f860a780SAmine Khaldi     r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9423f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9424f860a780SAmine Khaldi 
9425f860a780SAmine Khaldi     create_property_table(hdb);
9426f860a780SAmine Khaldi     add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9427f860a780SAmine Khaldi 
9428f860a780SAmine Khaldi     create_install_execute_sequence_table(hdb);
9429f860a780SAmine Khaldi     add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9430f860a780SAmine Khaldi     add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9431f860a780SAmine Khaldi     add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9432f860a780SAmine Khaldi 
9433f860a780SAmine Khaldi     create_install_ui_sequence_table(hdb);
9434f860a780SAmine Khaldi     add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9435f860a780SAmine Khaldi 
9436f860a780SAmine Khaldi     MsiDatabaseCommit(hdb);
9437f860a780SAmine Khaldi 
9438f860a780SAmine Khaldi     /* for some reason we have to open the package from file using an absolute path */
9439f860a780SAmine Khaldi     MsiCloseHandle(hdb);
9440f860a780SAmine Khaldi     GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9441f860a780SAmine Khaldi     r = MsiOpenPackageA(msifile_absolute, &hpkg);
9442f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9443f860a780SAmine Khaldi     ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9444f860a780SAmine Khaldi 
9445f860a780SAmine Khaldi     /* test INSTALL */
9446f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "INSTALL");
9447f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9448f860a780SAmine Khaldi     ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9449f860a780SAmine Khaldi 
9450f860a780SAmine Khaldi     /* test INSTALL with reduced+ UI */
9451f860a780SAmine Khaldi     /* for some reason we need to re-open the package to change the internal UI */
9452f860a780SAmine Khaldi     MsiCloseHandle(hpkg);
9453f860a780SAmine Khaldi     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9454f860a780SAmine Khaldi     MsiSetInternalUI(INSTALLUILEVEL_REDUCED, NULL);
9455f860a780SAmine Khaldi     r = MsiOpenPackageA(msifile_absolute, &hpkg);
9456f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9457f860a780SAmine Khaldi     ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9458f860a780SAmine Khaldi 
9459f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "INSTALL");
9460f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9461f860a780SAmine Khaldi     ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9462f860a780SAmine Khaldi 
9463f860a780SAmine Khaldi     /* test ExecuteAction with EXECUTEACTION property unset */
9464f860a780SAmine Khaldi     MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9465f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "ExecuteAction");
9466f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9467f860a780SAmine Khaldi     ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9468f860a780SAmine Khaldi 
9469f860a780SAmine Khaldi     /* test ExecuteAction with EXECUTEACTION property set */
9470f860a780SAmine Khaldi     MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9471f860a780SAmine Khaldi     r = MsiDoActionA(hpkg, "ExecuteAction");
9472f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9473f860a780SAmine Khaldi     ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9474f860a780SAmine Khaldi 
9475f860a780SAmine Khaldi     MsiCloseHandle(hpkg);
9476f860a780SAmine Khaldi     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9477f860a780SAmine Khaldi 
9478f860a780SAmine Khaldi     /* test MsiInstallProduct() */
9479f860a780SAmine Khaldi     r = MsiInstallProductA(msifile_absolute, NULL);
9480f860a780SAmine Khaldi     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9481f860a780SAmine Khaldi     ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9482f860a780SAmine Khaldi 
9483f860a780SAmine Khaldi     r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9484f860a780SAmine Khaldi     todo_wine
9485f860a780SAmine Khaldi     ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9486f860a780SAmine Khaldi     ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9487f860a780SAmine Khaldi 
9488f860a780SAmine Khaldi     CoUninitialize();
9489f860a780SAmine Khaldi     DeleteFileA(msifile);
9490f860a780SAmine Khaldi     DeleteFileA("forcecodepage.idt");
9491f860a780SAmine Khaldi }
9492f860a780SAmine Khaldi 
START_TEST(package)9493c2c66affSColin Finck START_TEST(package)
9494c2c66affSColin Finck {
94952b92436dSwinesync     char temp_path[MAX_PATH], prev_path[MAX_PATH];
94962b92436dSwinesync     DWORD len;
9497c2c66affSColin Finck 
9498*f4be6dc3SMikhail     if (!is_process_elevated()) restart_as_admin_elevated();
9499c2c66affSColin Finck 
9500*f4be6dc3SMikhail     IsWow64Process(GetCurrentProcess(), &is_wow64);
9501c2c66affSColin Finck 
95022b92436dSwinesync     GetCurrentDirectoryA(MAX_PATH, prev_path);
95032b92436dSwinesync     GetTempPathA(MAX_PATH, temp_path);
95042b92436dSwinesync     SetCurrentDirectoryA(temp_path);
95052b92436dSwinesync 
95062b92436dSwinesync     lstrcpyA(CURR_DIR, temp_path);
95072b92436dSwinesync     len = lstrlenA(CURR_DIR);
95082b92436dSwinesync 
95092b92436dSwinesync     if (len && (CURR_DIR[len - 1] == '\\'))
95102b92436dSwinesync         CURR_DIR[len - 1] = 0;
9511c2c66affSColin Finck 
9512c2c66affSColin Finck     test_createpackage();
9513c2c66affSColin Finck     test_doaction();
9514c2c66affSColin Finck     test_gettargetpath_bad();
9515c2c66affSColin Finck     test_settargetpath();
9516c2c66affSColin Finck     test_props();
9517c2c66affSColin Finck     test_property_table();
9518c2c66affSColin Finck     test_condition();
9519c2c66affSColin Finck     test_msipackage();
9520c2c66affSColin Finck     test_formatrecord2();
9521f860a780SAmine Khaldi     test_formatrecord_tables();
9522c2c66affSColin Finck     test_states();
9523c2c66affSColin Finck     test_removefiles();
9524c2c66affSColin Finck     test_appsearch();
9525c2c66affSColin Finck     test_appsearch_complocator();
9526c2c66affSColin Finck     test_appsearch_reglocator();
9527c2c66affSColin Finck     test_appsearch_inilocator();
9528c2c66affSColin Finck     test_appsearch_drlocator();
9529c2c66affSColin Finck     test_featureparents();
9530c2c66affSColin Finck     test_installprops();
9531c2c66affSColin Finck     test_launchconditions();
9532c2c66affSColin Finck     test_ccpsearch();
9533c2c66affSColin Finck     test_complocator();
9534c2c66affSColin Finck     test_MsiGetSourcePath();
9535c2c66affSColin Finck     test_shortlongsource();
9536c2c66affSColin Finck     test_sourcedir();
9537c2c66affSColin Finck     test_access();
9538c2c66affSColin Finck     test_emptypackage();
9539c2c66affSColin Finck     test_MsiGetProductProperty();
9540c2c66affSColin Finck     test_MsiSetProperty();
9541c2c66affSColin Finck     test_MsiApplyMultiplePatches();
9542c2c66affSColin Finck     test_MsiApplyPatch();
9543818a84ddSwinesync     test_costs();
9544c2c66affSColin Finck     test_MsiDatabaseCommit();
95452f8e6f71SAmine Khaldi     test_externalui();
95462f8e6f71SAmine Khaldi     test_externalui_message();
95472f8e6f71SAmine Khaldi     test_controlevent();
9548f860a780SAmine Khaldi     test_top_level_action();
9549c2c66affSColin Finck 
95502b92436dSwinesync     SetCurrentDirectoryA(prev_path);
9551c2c66affSColin Finck }
9552