c00ed61c18a88d9ec90787fb306fdf92a5d956d8
[reactos.git] / modules / rostests / winetests / msi / package.c
1 /*
2 * tests for Microsoft Installer functionality
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2005 Aric Stewart for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #define COBJMACROS
23
24 #include <assert.h>
25 #include <stdio.h>
26 #include <windows.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <msiquery.h>
30 #include <srrestoreptapi.h>
31 #include <shlobj.h>
32
33 #include "wine/test.h"
34
35 static BOOL is_wow64;
36 static const char msifile[] = "winetest-package.msi";
37 static const WCHAR msifileW[] =
38 {'w','i','n','e','t','e','s','t','-','p','a','c','k','a','g','e','.','m','s','i',0};
39 static char CURR_DIR[MAX_PATH];
40
41 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
42 static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
43
44 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL);
45 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
46 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
47 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
48 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
49 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
50 static void (WINAPI *pGetSystemInfo)(LPSYSTEM_INFO);
51 static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
52 static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR, UINT);
53
54 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
55 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
56
57 static void init_functionpointers(void)
58 {
59 HMODULE hmsi = GetModuleHandleA("msi.dll");
60 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
61 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
62 HMODULE hshell32 = GetModuleHandleA("shell32.dll");
63 HMODULE hsrclient;
64
65 #define GET_PROC(mod, func) \
66 p ## func = (void*)GetProcAddress(mod, #func);
67
68 GET_PROC(hmsi, MsiGetComponentPathExA);
69 GET_PROC(hshell32, SHGetFolderPathA);
70
71 GET_PROC(hadvapi32, CheckTokenMembership);
72 GET_PROC(hadvapi32, ConvertSidToStringSidA);
73 GET_PROC(hadvapi32, OpenProcessToken);
74 GET_PROC(hadvapi32, RegDeleteKeyExA)
75 GET_PROC(hadvapi32, RegDeleteKeyExW)
76 GET_PROC(hkernel32, IsWow64Process)
77 GET_PROC(hkernel32, GetNativeSystemInfo)
78 GET_PROC(hkernel32, GetSystemInfo)
79 GET_PROC(hkernel32, GetSystemWow64DirectoryA)
80
81 hsrclient = LoadLibraryA("srclient.dll");
82 GET_PROC(hsrclient, SRRemoveRestorePoint);
83 GET_PROC(hsrclient, SRSetRestorePointA);
84 #undef GET_PROC
85 }
86
87 static BOOL is_process_limited(void)
88 {
89 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
90 PSID Group = NULL;
91 BOOL IsInGroup;
92 HANDLE token;
93
94 if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
95
96 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
97 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
98 !pCheckTokenMembership(NULL, Group, &IsInGroup))
99 {
100 trace("Could not check if the current user is an administrator\n");
101 FreeSid(Group);
102 return FALSE;
103 }
104 FreeSid(Group);
105
106 if (!IsInGroup)
107 {
108 if (!AllocateAndInitializeSid(&NtAuthority, 2,
109 SECURITY_BUILTIN_DOMAIN_RID,
110 DOMAIN_ALIAS_RID_POWER_USERS,
111 0, 0, 0, 0, 0, 0, &Group) ||
112 !pCheckTokenMembership(NULL, Group, &IsInGroup))
113 {
114 trace("Could not check if the current user is a power user\n");
115 return FALSE;
116 }
117 if (!IsInGroup)
118 {
119 /* Only administrators and power users can be powerful */
120 return TRUE;
121 }
122 }
123
124 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
125 {
126 BOOL ret;
127 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
128 DWORD size;
129
130 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
131 CloseHandle(token);
132 return (ret && type == TokenElevationTypeLimited);
133 }
134 return FALSE;
135 }
136
137 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
138 {
139 if (pRegDeleteKeyExA)
140 return pRegDeleteKeyExA( key, subkey, access, 0 );
141 return RegDeleteKeyA( key, subkey );
142 }
143
144 static char *get_user_sid(void)
145 {
146 HANDLE token;
147 DWORD size = 0;
148 TOKEN_USER *user;
149 char *usersid = NULL;
150
151 if (!pConvertSidToStringSidA)
152 {
153 win_skip("ConvertSidToStringSidA is not available\n");
154 return NULL;
155 }
156 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
157 GetTokenInformation(token, TokenUser, NULL, size, &size);
158
159 user = HeapAlloc(GetProcessHeap(), 0, size);
160 GetTokenInformation(token, TokenUser, user, size, &size);
161 pConvertSidToStringSidA(user->User.Sid, &usersid);
162 HeapFree(GetProcessHeap(), 0, user);
163
164 CloseHandle(token);
165 return usersid;
166 }
167
168 /* RegDeleteTreeW from dlls/advapi32/registry.c */
169 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
170 {
171 LONG ret;
172 DWORD dwMaxSubkeyLen, dwMaxValueLen;
173 DWORD dwMaxLen, dwSize;
174 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
175 HKEY hSubKey = hKey;
176
177 if(lpszSubKey)
178 {
179 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
180 if (ret) return ret;
181 }
182
183 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
184 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
185 if (ret) goto cleanup;
186
187 dwMaxSubkeyLen++;
188 dwMaxValueLen++;
189 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
190 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
191 {
192 /* Name too big: alloc a buffer for it */
193 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
194 {
195 ret = ERROR_NOT_ENOUGH_MEMORY;
196 goto cleanup;
197 }
198 }
199
200 /* Recursively delete all the subkeys */
201 while (TRUE)
202 {
203 dwSize = dwMaxLen;
204 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
205 NULL, NULL, NULL)) break;
206
207 ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
208 if (ret) goto cleanup;
209 }
210
211 if (lpszSubKey)
212 {
213 if (pRegDeleteKeyExW)
214 ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
215 else
216 ret = RegDeleteKeyW(hKey, lpszSubKey);
217 }
218 else
219 while (TRUE)
220 {
221 dwSize = dwMaxLen;
222 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
223 NULL, NULL, NULL, NULL)) break;
224
225 ret = RegDeleteValueW(hKey, lpszName);
226 if (ret) goto cleanup;
227 }
228
229 cleanup:
230 if (lpszName != szNameBuf)
231 HeapFree(GetProcessHeap(), 0, lpszName);
232 if(lpszSubKey)
233 RegCloseKey(hSubKey);
234 return ret;
235 }
236
237 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
238 {
239 DWORD i,n=1;
240 GUID guid;
241
242 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
243 return FALSE;
244
245 for(i=0; i<8; i++)
246 out[7-i] = in[n++];
247 n++;
248 for(i=0; i<4; i++)
249 out[11-i] = in[n++];
250 n++;
251 for(i=0; i<4; i++)
252 out[15-i] = in[n++];
253 n++;
254 for(i=0; i<2; i++)
255 {
256 out[17+i*2] = in[n++];
257 out[16+i*2] = in[n++];
258 }
259 n++;
260 for( ; i<8; i++)
261 {
262 out[17+i*2] = in[n++];
263 out[16+i*2] = in[n++];
264 }
265 out[32]=0;
266 return TRUE;
267 }
268
269 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
270 {
271 WCHAR guidW[MAX_PATH];
272 WCHAR squashedW[MAX_PATH];
273 GUID guid;
274 HRESULT hr;
275 int size;
276
277 hr = CoCreateGuid(&guid);
278 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
279
280 size = StringFromGUID2(&guid, guidW, MAX_PATH);
281 ok(size == 39, "Expected 39, got %d\n", hr);
282
283 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
284 squash_guid(guidW, squashedW);
285 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
286 }
287
288 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
289 LPCSTR guid, LPSTR usersid, BOOL dir)
290 {
291 WCHAR guidW[MAX_PATH];
292 WCHAR squashedW[MAX_PATH];
293 CHAR squashed[MAX_PATH];
294 CHAR comppath[MAX_PATH];
295 CHAR prodpath[MAX_PATH];
296 CHAR path[MAX_PATH];
297 LPCSTR prod = NULL;
298 HKEY hkey;
299 REGSAM access = KEY_ALL_ACCESS;
300
301 if (is_wow64)
302 access |= KEY_WOW64_64KEY;
303
304 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
305 squash_guid(guidW, squashedW);
306 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
307
308 if (context == MSIINSTALLCONTEXT_MACHINE)
309 {
310 prod = "3D0DAE300FACA1300AD792060BCDAA92";
311 sprintf(comppath,
312 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
313 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
314 lstrcpyA(prodpath,
315 "SOFTWARE\\Classes\\Installer\\"
316 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
317 }
318 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
319 {
320 prod = "7D2F387510109040002000060BECB6AB";
321 sprintf(comppath,
322 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
323 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
324 sprintf(prodpath,
325 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
326 "Installer\\%s\\Installer\\Products\\"
327 "7D2F387510109040002000060BECB6AB", usersid);
328 }
329 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
330 {
331 prod = "7D2F387510109040002000060BECB6AB";
332 sprintf(comppath,
333 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
334 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
335 sprintf(prodpath,
336 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
337 "Installer\\Managed\\%s\\Installer\\Products\\"
338 "7D2F387510109040002000060BECB6AB", usersid);
339 }
340
341 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
342
343 lstrcpyA(path, CURR_DIR);
344 lstrcatA(path, "\\");
345 if (!dir) lstrcatA(path, filename);
346
347 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
348 RegCloseKey(hkey);
349
350 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
351 RegCloseKey(hkey);
352 }
353
354 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
355 {
356 WCHAR guidW[MAX_PATH];
357 WCHAR squashedW[MAX_PATH];
358 WCHAR substrW[MAX_PATH];
359 CHAR squashed[MAX_PATH];
360 CHAR comppath[MAX_PATH];
361 CHAR prodpath[MAX_PATH];
362 REGSAM access = KEY_ALL_ACCESS;
363
364 if (is_wow64)
365 access |= KEY_WOW64_64KEY;
366
367 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
368 squash_guid(guidW, squashedW);
369 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
370
371 if (context == MSIINSTALLCONTEXT_MACHINE)
372 {
373 sprintf(comppath,
374 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
375 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
376 lstrcpyA(prodpath,
377 "SOFTWARE\\Classes\\Installer\\"
378 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
379 }
380 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
381 {
382 sprintf(comppath,
383 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
384 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
385 sprintf(prodpath,
386 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
387 "Installer\\%s\\Installer\\Products\\"
388 "7D2F387510109040002000060BECB6AB", usersid);
389 }
390 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
391 {
392 sprintf(comppath,
393 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
394 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
395 sprintf(prodpath,
396 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
397 "Installer\\Managed\\%s\\Installer\\Products\\"
398 "7D2F387510109040002000060BECB6AB", usersid);
399 }
400
401 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
402 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
403
404 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
405 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
406 }
407
408 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
409 {
410 MSIHANDLE hview = 0;
411 UINT r, ret;
412
413 /* open a select query */
414 r = MsiDatabaseOpenViewA(hdb, query, &hview);
415 if (r != ERROR_SUCCESS)
416 return r;
417 r = MsiViewExecute(hview, 0);
418 if (r != ERROR_SUCCESS)
419 return r;
420 ret = MsiViewFetch(hview, phrec);
421 r = MsiViewClose(hview);
422 if (r != ERROR_SUCCESS)
423 return r;
424 r = MsiCloseHandle(hview);
425 if (r != ERROR_SUCCESS)
426 return r;
427 return ret;
428 }
429
430 static UINT run_query( MSIHANDLE hdb, const char *query )
431 {
432 MSIHANDLE hview = 0;
433 UINT r;
434
435 r = MsiDatabaseOpenViewA(hdb, query, &hview);
436 if( r != ERROR_SUCCESS )
437 return r;
438
439 r = MsiViewExecute(hview, 0);
440 if( r == ERROR_SUCCESS )
441 r = MsiViewClose(hview);
442 MsiCloseHandle(hview);
443 return r;
444 }
445
446 static UINT create_component_table( MSIHANDLE hdb )
447 {
448 return run_query( hdb,
449 "CREATE TABLE `Component` ( "
450 "`Component` CHAR(72) NOT NULL, "
451 "`ComponentId` CHAR(38), "
452 "`Directory_` CHAR(72) NOT NULL, "
453 "`Attributes` SHORT NOT NULL, "
454 "`Condition` CHAR(255), "
455 "`KeyPath` CHAR(72) "
456 "PRIMARY KEY `Component`)" );
457 }
458
459 static UINT create_feature_table( MSIHANDLE hdb )
460 {
461 return run_query( hdb,
462 "CREATE TABLE `Feature` ( "
463 "`Feature` CHAR(38) NOT NULL, "
464 "`Feature_Parent` CHAR(38), "
465 "`Title` CHAR(64), "
466 "`Description` CHAR(255), "
467 "`Display` SHORT NOT NULL, "
468 "`Level` SHORT NOT NULL, "
469 "`Directory_` CHAR(72), "
470 "`Attributes` SHORT NOT NULL "
471 "PRIMARY KEY `Feature`)" );
472 }
473
474 static UINT create_feature_components_table( MSIHANDLE hdb )
475 {
476 return run_query( hdb,
477 "CREATE TABLE `FeatureComponents` ( "
478 "`Feature_` CHAR(38) NOT NULL, "
479 "`Component_` CHAR(72) NOT NULL "
480 "PRIMARY KEY `Feature_`, `Component_` )" );
481 }
482
483 static UINT create_file_table( MSIHANDLE hdb )
484 {
485 return run_query( hdb,
486 "CREATE TABLE `File` ("
487 "`File` CHAR(72) NOT NULL, "
488 "`Component_` CHAR(72) NOT NULL, "
489 "`FileName` CHAR(255) NOT NULL, "
490 "`FileSize` LONG NOT NULL, "
491 "`Version` CHAR(72), "
492 "`Language` CHAR(20), "
493 "`Attributes` SHORT, "
494 "`Sequence` SHORT NOT NULL "
495 "PRIMARY KEY `File`)" );
496 }
497
498 static UINT create_remove_file_table( MSIHANDLE hdb )
499 {
500 return run_query( hdb,
501 "CREATE TABLE `RemoveFile` ("
502 "`FileKey` CHAR(72) NOT NULL, "
503 "`Component_` CHAR(72) NOT NULL, "
504 "`FileName` CHAR(255) LOCALIZABLE, "
505 "`DirProperty` CHAR(72) NOT NULL, "
506 "`InstallMode` SHORT NOT NULL "
507 "PRIMARY KEY `FileKey`)" );
508 }
509
510 static UINT create_appsearch_table( MSIHANDLE hdb )
511 {
512 return run_query( hdb,
513 "CREATE TABLE `AppSearch` ("
514 "`Property` CHAR(72) NOT NULL, "
515 "`Signature_` CHAR(72) NOT NULL "
516 "PRIMARY KEY `Property`, `Signature_`)" );
517 }
518
519 static UINT create_reglocator_table( MSIHANDLE hdb )
520 {
521 return run_query( hdb,
522 "CREATE TABLE `RegLocator` ("
523 "`Signature_` CHAR(72) NOT NULL, "
524 "`Root` SHORT NOT NULL, "
525 "`Key` CHAR(255) NOT NULL, "
526 "`Name` CHAR(255), "
527 "`Type` SHORT "
528 "PRIMARY KEY `Signature_`)" );
529 }
530
531 static UINT create_signature_table( MSIHANDLE hdb )
532 {
533 return run_query( hdb,
534 "CREATE TABLE `Signature` ("
535 "`Signature` CHAR(72) NOT NULL, "
536 "`FileName` CHAR(255) NOT NULL, "
537 "`MinVersion` CHAR(20), "
538 "`MaxVersion` CHAR(20), "
539 "`MinSize` LONG, "
540 "`MaxSize` LONG, "
541 "`MinDate` LONG, "
542 "`MaxDate` LONG, "
543 "`Languages` CHAR(255) "
544 "PRIMARY KEY `Signature`)" );
545 }
546
547 static UINT create_launchcondition_table( MSIHANDLE hdb )
548 {
549 return run_query( hdb,
550 "CREATE TABLE `LaunchCondition` ("
551 "`Condition` CHAR(255) NOT NULL, "
552 "`Description` CHAR(255) NOT NULL "
553 "PRIMARY KEY `Condition`)" );
554 }
555
556 static UINT create_property_table( MSIHANDLE hdb )
557 {
558 return run_query( hdb,
559 "CREATE TABLE `Property` ("
560 "`Property` CHAR(72) NOT NULL, "
561 "`Value` CHAR(0) "
562 "PRIMARY KEY `Property`)" );
563 }
564
565 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
566 {
567 return run_query( hdb,
568 "CREATE TABLE `InstallExecuteSequence` ("
569 "`Action` CHAR(72) NOT NULL, "
570 "`Condition` CHAR(255), "
571 "`Sequence` SHORT "
572 "PRIMARY KEY `Action`)" );
573 }
574
575 static UINT create_media_table( MSIHANDLE hdb )
576 {
577 return run_query( hdb,
578 "CREATE TABLE `Media` ("
579 "`DiskId` SHORT NOT NULL, "
580 "`LastSequence` SHORT NOT NULL, "
581 "`DiskPrompt` CHAR(64), "
582 "`Cabinet` CHAR(255), "
583 "`VolumeLabel` CHAR(32), "
584 "`Source` CHAR(72) "
585 "PRIMARY KEY `DiskId`)" );
586 }
587
588 static UINT create_ccpsearch_table( MSIHANDLE hdb )
589 {
590 return run_query( hdb,
591 "CREATE TABLE `CCPSearch` ("
592 "`Signature_` CHAR(72) NOT NULL "
593 "PRIMARY KEY `Signature_`)" );
594 }
595
596 static UINT create_drlocator_table( MSIHANDLE hdb )
597 {
598 return run_query( hdb,
599 "CREATE TABLE `DrLocator` ("
600 "`Signature_` CHAR(72) NOT NULL, "
601 "`Parent` CHAR(72), "
602 "`Path` CHAR(255), "
603 "`Depth` SHORT "
604 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
605 }
606
607 static UINT create_complocator_table( MSIHANDLE hdb )
608 {
609 return run_query( hdb,
610 "CREATE TABLE `CompLocator` ("
611 "`Signature_` CHAR(72) NOT NULL, "
612 "`ComponentId` CHAR(38) NOT NULL, "
613 "`Type` SHORT "
614 "PRIMARY KEY `Signature_`)" );
615 }
616
617 static UINT create_inilocator_table( MSIHANDLE hdb )
618 {
619 return run_query( hdb,
620 "CREATE TABLE `IniLocator` ("
621 "`Signature_` CHAR(72) NOT NULL, "
622 "`FileName` CHAR(255) NOT NULL, "
623 "`Section` CHAR(96)NOT NULL, "
624 "`Key` CHAR(128)NOT NULL, "
625 "`Field` SHORT, "
626 "`Type` SHORT "
627 "PRIMARY KEY `Signature_`)" );
628 }
629
630 static UINT create_custom_action_table( MSIHANDLE hdb )
631 {
632 return run_query( hdb,
633 "CREATE TABLE `CustomAction` ("
634 "`Action` CHAR(72) NOT NULL, "
635 "`Type` SHORT NOT NULL, "
636 "`Source` CHAR(75), "
637 "`Target` CHAR(255) "
638 "PRIMARY KEY `Action`)" );
639 }
640
641 static UINT create_dialog_table( MSIHANDLE hdb )
642 {
643 return run_query(hdb,
644 "CREATE TABLE `Dialog` ("
645 "`Dialog` CHAR(72) NOT NULL, "
646 "`HCentering` SHORT NOT NULL, "
647 "`VCentering` SHORT NOT NULL, "
648 "`Width` SHORT NOT NULL, "
649 "`Height` SHORT NOT NULL, "
650 "`Attributes` LONG, "
651 "`Title` CHAR(128) LOCALIZABLE, "
652 "`Control_First` CHAR(50) NOT NULL, "
653 "`Control_Default` CHAR(50), "
654 "`Control_Cancel` CHAR(50) "
655 "PRIMARY KEY `Dialog`)");
656 }
657
658 static UINT create_control_table( MSIHANDLE hdb )
659 {
660 return run_query(hdb,
661 "CREATE TABLE `Control` ("
662 "`Dialog_` CHAR(72) NOT NULL, "
663 "`Control` CHAR(50) NOT NULL, "
664 "`Type` CHAR(20) NOT NULL, "
665 "`X` SHORT NOT NULL, "
666 "`Y` SHORT NOT NULL, "
667 "`Width` SHORT NOT NULL, "
668 "`Height` SHORT NOT NULL, "
669 "`Attributes` LONG, "
670 "`Property` CHAR(50), "
671 "`Text` CHAR(0) LOCALIZABLE, "
672 "`Control_Next` CHAR(50), "
673 "`Help` CHAR(255) LOCALIZABLE "
674 "PRIMARY KEY `Dialog_`, `Control`)");
675 }
676
677 static UINT create_controlevent_table( MSIHANDLE hdb )
678 {
679 return run_query(hdb,
680 "CREATE TABLE `ControlEvent` ("
681 "`Dialog_` CHAR(72) NOT NULL, "
682 "`Control_` CHAR(50) NOT NULL, "
683 "`Event` CHAR(50) NOT NULL, "
684 "`Argument` CHAR(255) NOT NULL, "
685 "`Condition` CHAR(255), "
686 "`Ordering` SHORT "
687 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
688 }
689
690 static UINT create_actiontext_table( MSIHANDLE hdb )
691 {
692 return run_query(hdb,
693 "CREATE TABLE `ActionText` ("
694 "`Action` CHAR(72) NOT NULL, "
695 "`Description` CHAR(64) LOCALIZABLE, "
696 "`Template` CHAR(128) LOCALIZABLE "
697 "PRIMARY KEY `Action`)");
698 }
699
700 #define make_add_entry(type, qtext) \
701 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
702 { \
703 char insert[] = qtext; \
704 char *query; \
705 UINT sz, r; \
706 sz = strlen(values) + sizeof insert; \
707 query = HeapAlloc(GetProcessHeap(),0,sz); \
708 sprintf(query,insert,values); \
709 r = run_query( hdb, query ); \
710 HeapFree(GetProcessHeap(), 0, query); \
711 return r; \
712 }
713
714 make_add_entry(component,
715 "INSERT INTO `Component` "
716 "(`Component`, `ComponentId`, `Directory_`, "
717 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
718
719 make_add_entry(directory,
720 "INSERT INTO `Directory` "
721 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
722
723 make_add_entry(feature,
724 "INSERT INTO `Feature` "
725 "(`Feature`, `Feature_Parent`, `Title`, `Description`, "
726 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
727
728 make_add_entry(feature_components,
729 "INSERT INTO `FeatureComponents` "
730 "(`Feature_`, `Component_`) VALUES( %s )")
731
732 make_add_entry(file,
733 "INSERT INTO `File` "
734 "(`File`, `Component_`, `FileName`, `FileSize`, "
735 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
736
737 make_add_entry(appsearch,
738 "INSERT INTO `AppSearch` "
739 "(`Property`, `Signature_`) VALUES( %s )")
740
741 make_add_entry(signature,
742 "INSERT INTO `Signature` "
743 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
744 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) "
745 "VALUES( %s )")
746
747 make_add_entry(launchcondition,
748 "INSERT INTO `LaunchCondition` "
749 "(`Condition`, `Description`) VALUES( %s )")
750
751 make_add_entry(property,
752 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
753
754 make_add_entry(install_execute_sequence,
755 "INSERT INTO `InstallExecuteSequence` "
756 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
757
758 make_add_entry(media,
759 "INSERT INTO `Media` "
760 "(`DiskId`, `LastSequence`, `DiskPrompt`, "
761 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
762
763 make_add_entry(ccpsearch,
764 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
765
766 make_add_entry(drlocator,
767 "INSERT INTO `DrLocator` "
768 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
769
770 make_add_entry(complocator,
771 "INSERT INTO `CompLocator` "
772 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
773
774 make_add_entry(inilocator,
775 "INSERT INTO `IniLocator` "
776 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
777 "VALUES( %s )")
778
779 make_add_entry(custom_action,
780 "INSERT INTO `CustomAction` "
781 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
782
783 make_add_entry(dialog,
784 "INSERT INTO `Dialog` "
785 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
786
787 make_add_entry(control,
788 "INSERT INTO `Control` "
789 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
790
791 make_add_entry(controlevent,
792 "INSERT INTO `ControlEvent` "
793 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
794
795 make_add_entry(actiontext,
796 "INSERT INTO `ActionText` "
797 "(`Action`, `Description`, `Template`) VALUES( %s )");
798
799 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
800 const char *name, UINT type )
801 {
802 const char insert[] =
803 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
804 "VALUES( '%s', %u, '%s', '%s', %u )";
805 char *query;
806 UINT sz, r;
807
808 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
809 query = HeapAlloc( GetProcessHeap(), 0, sz );
810 sprintf( query, insert, sig, root, path, name, type );
811 r = run_query( hdb, query );
812 HeapFree( GetProcessHeap(), 0, query );
813 return r;
814 }
815
816 static UINT set_summary_info(MSIHANDLE hdb)
817 {
818 UINT res;
819 MSIHANDLE suminfo;
820
821 /* build summary info */
822 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
823 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
824
825 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL,
826 "Installation Database");
827 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
828
829 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL,
830 "Installation Database");
831 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
832
833 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL,
834 "Wine Hackers");
835 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
836
837 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL,
838 ";1033");
839 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
840
841 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL,
842 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
843 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
844
845 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
846 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
847
848 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
849 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
850
851 res = MsiSummaryInfoPersist(suminfo);
852 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
853
854 res = MsiCloseHandle( suminfo);
855 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
856
857 return res;
858 }
859
860
861 static MSIHANDLE create_package_db(void)
862 {
863 MSIHANDLE hdb = 0;
864 UINT res;
865
866 DeleteFileA(msifile);
867
868 /* create an empty database */
869 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb );
870 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
871 if( res != ERROR_SUCCESS )
872 return hdb;
873
874 res = MsiDatabaseCommit( hdb );
875 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
876
877 res = set_summary_info(hdb);
878 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
879
880 res = run_query( hdb,
881 "CREATE TABLE `Directory` ( "
882 "`Directory` CHAR(255) NOT NULL, "
883 "`Directory_Parent` CHAR(255), "
884 "`DefaultDir` CHAR(255) NOT NULL "
885 "PRIMARY KEY `Directory`)" );
886 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
887
888 return hdb;
889 }
890
891 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
892 {
893 UINT res;
894 CHAR szPackage[12];
895 MSIHANDLE hPackage;
896
897 sprintf(szPackage, "#%u", hdb);
898 res = MsiOpenPackageA(szPackage, &hPackage);
899 if (res != ERROR_SUCCESS)
900 {
901 MsiCloseHandle(hdb);
902 return res;
903 }
904
905 res = MsiCloseHandle(hdb);
906 if (res != ERROR_SUCCESS)
907 {
908 MsiCloseHandle(hPackage);
909 return res;
910 }
911
912 *handle = hPackage;
913 return ERROR_SUCCESS;
914 }
915
916 static void create_file_data(LPCSTR name, LPCSTR data)
917 {
918 HANDLE file;
919 DWORD written;
920
921 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
922 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
923 if (file == INVALID_HANDLE_VALUE)
924 return;
925
926 WriteFile(file, data, strlen(data), &written, NULL);
927 WriteFile(file, "\n", strlen("\n"), &written, NULL);
928
929 CloseHandle(file);
930 }
931
932 static void create_test_file(const CHAR *name)
933 {
934 create_file_data(name, name);
935 }
936
937 typedef struct _tagVS_VERSIONINFO
938 {
939 WORD wLength;
940 WORD wValueLength;
941 WORD wType;
942 WCHAR szKey[1];
943 WORD wPadding1[1];
944 VS_FIXEDFILEINFO Value;
945 WORD wPadding2[1];
946 WORD wChildren[1];
947 } VS_VERSIONINFO;
948
949 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
950 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
951
952 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
953 {
954 VS_VERSIONINFO *pVerInfo;
955 VS_FIXEDFILEINFO *pFixedInfo;
956 LPBYTE buffer, ofs;
957 CHAR path[MAX_PATH];
958 DWORD handle, size;
959 HANDLE resource;
960 BOOL ret = FALSE;
961
962 GetSystemDirectoryA(path, MAX_PATH);
963 /* Some dlls can't be updated on Vista/W2K8 */
964 lstrcatA(path, "\\version.dll");
965
966 CopyFileA(path, name, FALSE);
967
968 size = GetFileVersionInfoSizeA(path, &handle);
969 buffer = HeapAlloc(GetProcessHeap(), 0, size);
970
971 GetFileVersionInfoA(path, 0, size, buffer);
972
973 pVerInfo = (VS_VERSIONINFO *)buffer;
974 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
975 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
976
977 pFixedInfo->dwFileVersionMS = ms;
978 pFixedInfo->dwFileVersionLS = ls;
979 pFixedInfo->dwProductVersionMS = ms;
980 pFixedInfo->dwProductVersionLS = ls;
981
982 resource = BeginUpdateResourceA(name, FALSE);
983 if (!resource)
984 goto done;
985
986 if (!UpdateResourceA(resource, (LPCSTR)RT_VERSION, (LPCSTR)MAKEINTRESOURCE(VS_VERSION_INFO),
987 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
988 goto done;
989
990 if (!EndUpdateResourceA(resource, FALSE))
991 goto done;
992
993 ret = TRUE;
994
995 done:
996 HeapFree(GetProcessHeap(), 0, buffer);
997 return ret;
998 }
999
1000 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
1001 {
1002 RESTOREPOINTINFOA spec;
1003
1004 spec.dwEventType = event_type;
1005 spec.dwRestorePtType = APPLICATION_INSTALL;
1006 spec.llSequenceNumber = status->llSequenceNumber;
1007 lstrcpyA(spec.szDescription, "msitest restore point");
1008
1009 return pSRSetRestorePointA(&spec, status);
1010 }
1011
1012 static void remove_restore_point(DWORD seq_number)
1013 {
1014 DWORD res;
1015
1016 res = pSRRemoveRestorePoint(seq_number);
1017 if (res != ERROR_SUCCESS)
1018 trace("Failed to remove the restore point : %08x\n", res);
1019 }
1020
1021 static BOOL is_root(const char *path)
1022 {
1023 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
1024 }
1025
1026 static void test_createpackage(void)
1027 {
1028 MSIHANDLE hPackage = 0;
1029 UINT res;
1030
1031 res = package_from_db(create_package_db(), &hPackage);
1032 if (res == ERROR_INSTALL_PACKAGE_REJECTED)
1033 {
1034 skip("Not enough rights to perform tests\n");
1035 DeleteFileA(msifile);
1036 return;
1037 }
1038 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
1039
1040 res = MsiCloseHandle( hPackage);
1041 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
1042 DeleteFileA(msifile);
1043 }
1044
1045 static void test_doaction( void )
1046 {
1047 MSIHANDLE hpkg;
1048 UINT r;
1049
1050 r = MsiDoActionA( -1, NULL );
1051 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1052
1053 r = package_from_db(create_package_db(), &hpkg);
1054 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1055 {
1056 skip("Not enough rights to perform tests\n");
1057 DeleteFileA(msifile);
1058 return;
1059 }
1060 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1061
1062 r = MsiDoActionA(hpkg, NULL);
1063 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1064
1065 r = MsiDoActionA(0, "boo");
1066 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1067
1068 r = MsiDoActionA(hpkg, "boo");
1069 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
1070
1071 MsiCloseHandle( hpkg );
1072 DeleteFileA(msifile);
1073 }
1074
1075 static void test_gettargetpath_bad(void)
1076 {
1077 static const WCHAR boo[] = {'b','o','o',0};
1078 static const WCHAR empty[] = {0};
1079 char buffer[0x80];
1080 WCHAR bufferW[0x80];
1081 MSIHANDLE hpkg;
1082 DWORD sz;
1083 UINT r;
1084
1085 r = package_from_db(create_package_db(), &hpkg);
1086 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1087 {
1088 skip("Not enough rights to perform tests\n");
1089 DeleteFileA(msifile);
1090 return;
1091 }
1092 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1093
1094 r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1095 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1096
1097 r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1098 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1099
1100 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1101 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1102
1103 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1104 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1105
1106 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1107 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1108
1109 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1110 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1111
1112 sz = 0;
1113 r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1114 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1115
1116 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1117 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1118
1119 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1120 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1121
1122 r = MsiGetTargetPathW( 0, boo, NULL, NULL );
1123 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1124
1125 r = MsiGetTargetPathW( 0, boo, NULL, NULL );
1126 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1127
1128 r = MsiGetTargetPathW( hpkg, boo, NULL, NULL );
1129 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1130
1131 r = MsiGetTargetPathW( hpkg, boo, bufferW, NULL );
1132 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1133
1134 sz = 0;
1135 r = MsiGetTargetPathW( hpkg, empty, bufferW, &sz );
1136 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1137
1138 MsiCloseHandle( hpkg );
1139 DeleteFileA(msifile);
1140 }
1141
1142 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1143 {
1144 UINT r;
1145 DWORD size;
1146 MSIHANDLE rec;
1147
1148 rec = MsiCreateRecord( 1 );
1149 ok(rec, "MsiCreate record failed\n");
1150
1151 r = MsiRecordSetStringA( rec, 0, file );
1152 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1153
1154 size = MAX_PATH;
1155 r = MsiFormatRecordA( hpkg, rec, buff, &size );
1156 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1157
1158 MsiCloseHandle( rec );
1159 }
1160
1161 static void test_settargetpath(void)
1162 {
1163 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH];
1164 DWORD sz;
1165 MSIHANDLE hpkg;
1166 UINT r;
1167 MSIHANDLE hdb;
1168
1169 hdb = create_package_db();
1170 ok ( hdb, "failed to create package database\n" );
1171
1172 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1173 ok( r == S_OK, "failed to add directory entry: %d\n" , r );
1174
1175 r = create_component_table( hdb );
1176 ok( r == S_OK, "cannot create Component table: %d\n", r );
1177
1178 r = add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1179 ok( r == S_OK, "cannot add dummy component: %d\n", r );
1180
1181 r = add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1182 ok( r == S_OK, "cannot add test component: %d\n", r );
1183
1184 r = create_feature_table( hdb );
1185 ok( r == S_OK, "cannot create Feature table: %d\n", r );
1186
1187 r = add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1188 ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r );
1189
1190 r = create_feature_components_table( hdb );
1191 ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
1192
1193 r = add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1194 ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1195
1196 r = add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1197 ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1198
1199 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1200 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1201
1202 r = create_file_table( hdb );
1203 ok( r == S_OK, "cannot create File table: %d\n", r );
1204
1205 r = add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1206 ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1207
1208 r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1209 ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1210
1211 r = package_from_db( hdb, &hpkg );
1212 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1213 {
1214 skip("Not enough rights to perform tests\n");
1215 DeleteFileA(msifile);
1216 return;
1217 }
1218 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1219
1220 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1221
1222 r = MsiDoActionA( hpkg, "CostInitialize");
1223 ok( r == ERROR_SUCCESS, "cost init failed\n");
1224
1225 r = MsiDoActionA( hpkg, "FileCost");
1226 ok( r == ERROR_SUCCESS, "file cost failed\n");
1227
1228 r = MsiDoActionA( hpkg, "CostFinalize");
1229 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1230
1231 buffer[0] = 0;
1232 sz = sizeof(buffer);
1233 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1234 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1235 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1236
1237 r = MsiSetTargetPathA( 0, NULL, NULL );
1238 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1239
1240 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1241 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1242
1243 r = MsiSetTargetPathA( hpkg, "boo", NULL );
1244 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1245
1246 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1247 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1248
1249 sz = sizeof tempdir - 1;
1250 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1251 sprintf( file, "%srootfile.txt", tempdir );
1252 buffer[0] = 0;
1253 query_file_path( hpkg, "[#RootFile]", buffer );
1254 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1255 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1256
1257 GetTempFileNameA( tempdir, "_wt", 0, buffer );
1258 sprintf( tempdir, "%s\\subdir", buffer );
1259
1260 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1261 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1262 "MsiSetTargetPath on file returned %d\n", r );
1263
1264 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1265 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1266 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1267
1268 DeleteFileA( buffer );
1269
1270 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1271 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1272
1273 r = GetFileAttributesA( buffer );
1274 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1275
1276 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1277 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1278
1279 buffer[0] = 0;
1280 sz = sizeof buffer - 1;
1281 lstrcatA( tempdir, "\\" );
1282 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1283 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1284 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1285
1286 sprintf( file, "%srootfile.txt", tempdir );
1287 query_file_path( hpkg, "[#RootFile]", buffer );
1288 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1289
1290 buffer[0] = 0;
1291 sz = sizeof(buffer);
1292 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1293 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1294 lstrcatA( tempdir, "TestParent\\" );
1295 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1296
1297 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1298 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1299
1300 buffer[0] = 0;
1301 sz = sizeof(buffer);
1302 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1303 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1304 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1305 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1306
1307 buffer[0] = 0;
1308 query_file_path( hpkg, "[#TestFile]", buffer );
1309 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1310 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1311
1312 buffer[0] = 0;
1313 sz = sizeof buffer - 1;
1314 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1315 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1316 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1317
1318 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1319 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1320
1321 buffer[0] = 0;
1322 sz = sizeof buffer - 1;
1323 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1324 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1325 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1326
1327 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " );
1328 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1329
1330 buffer[0] = 0;
1331 sz = sizeof buffer - 1;
1332 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1333 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1334 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1335
1336 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1337 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1338
1339 buffer[0] = 0;
1340 sz = sizeof buffer - 1;
1341 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1342 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1343 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1344
1345 MsiCloseHandle( hpkg );
1346 }
1347
1348 static void test_condition(void)
1349 {
1350 static const WCHAR cond1[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0};
1351 static const WCHAR cond2[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0};
1352 static const WCHAR cond3[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0};
1353 static const WCHAR cond4[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0};
1354 MSICONDITION r;
1355 MSIHANDLE hpkg;
1356
1357 r = package_from_db(create_package_db(), &hpkg);
1358 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1359 {
1360 skip("Not enough rights to perform tests\n");
1361 DeleteFileA(msifile);
1362 return;
1363 }
1364 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1365
1366 r = MsiEvaluateConditionA(0, NULL);
1367 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1368
1369 r = MsiEvaluateConditionA(hpkg, NULL);
1370 ok( r == MSICONDITION_NONE, "wrong return val\n");
1371
1372 r = MsiEvaluateConditionA(hpkg, "");
1373 ok( r == MSICONDITION_NONE, "wrong return val\n");
1374
1375 r = MsiEvaluateConditionA(hpkg, "1");
1376 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1377
1378 r = MsiEvaluateConditionA(hpkg, "0");
1379 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1380
1381 r = MsiEvaluateConditionA(hpkg, "-1");
1382 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1383
1384 r = MsiEvaluateConditionA(hpkg, "0 = 0");
1385 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1386
1387 r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1388 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1389
1390 r = MsiEvaluateConditionA(hpkg, "0 = 1");
1391 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1392
1393 r = MsiEvaluateConditionA(hpkg, "0 > 1");
1394 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1395
1396 r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1397 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1398
1399 r = MsiEvaluateConditionA(hpkg, "1 > 1");
1400 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1401
1402 r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1403 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1404
1405 r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1406 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1407
1408 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1409 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1410
1411 r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1412 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1413
1414 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1415 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1416
1417 r = MsiEvaluateConditionA(hpkg, "0 < 1");
1418 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1419
1420 r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1421 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1422
1423 r = MsiEvaluateConditionA(hpkg, "1 < 1");
1424 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1425
1426 r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1427 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1428
1429 r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1430 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1431
1432 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1433 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1434
1435 r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1436 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1437
1438 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1439 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1440
1441 r = MsiEvaluateConditionA(hpkg, "0 >=");
1442 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1443
1444 r = MsiEvaluateConditionA(hpkg, " ");
1445 ok( r == MSICONDITION_NONE, "wrong return val\n");
1446
1447 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1448 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1449
1450 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1451 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1452
1453 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1454 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1455
1456 r = MsiEvaluateConditionA(hpkg, "not 0");
1457 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1458
1459 r = MsiEvaluateConditionA(hpkg, "not LicView");
1460 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1461
1462 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1463 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1464
1465 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1466 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1467
1468 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1469 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1470
1471 r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1472 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1473
1474 r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1475 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1476
1477 r = MsiEvaluateConditionA(hpkg, "\"0\"");
1478 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1479
1480 r = MsiEvaluateConditionA(hpkg, "1 and 2");
1481 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1482
1483 r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1484 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1485
1486 r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1487 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1488
1489 r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1490 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1491
1492 r = MsiEvaluateConditionA(hpkg, "(0)");
1493 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1494
1495 r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1496 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1497
1498 r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1499 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1500
1501 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1502 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1503
1504 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1505 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1506
1507 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1508 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1509
1510 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1511 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1512
1513 r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1514 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1515
1516 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1517 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1518
1519 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1520 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1521
1522 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1523 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1524
1525 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1526 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1527
1528 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1529 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1530
1531 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1532 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1533
1534 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1535 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1536
1537 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1538 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1539
1540 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1541 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1542
1543 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1544 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1545
1546 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1547 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1548
1549 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1550 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1551
1552 r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1553 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1554
1555 r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1556 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1557
1558 r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1559 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1560
1561 r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1562 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1563
1564 r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1565 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1566
1567 r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1568 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1569
1570 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1571 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1572
1573 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1574 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1575
1576 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1577 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1578
1579 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1580 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1581
1582 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1583 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1584
1585 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1586 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1587
1588 MsiSetPropertyA(hpkg, "mm", "5" );
1589
1590 r = MsiEvaluateConditionA(hpkg, "mm = 5");
1591 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1592
1593 r = MsiEvaluateConditionA(hpkg, "mm < 6");
1594 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1595
1596 r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1598
1599 r = MsiEvaluateConditionA(hpkg, "mm > 4");
1600 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1601
1602 r = MsiEvaluateConditionA(hpkg, "mm < 12");
1603 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1604
1605 r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1606 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1607
1608 r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1609 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1610
1611 r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1612 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1613
1614 r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1615 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1616
1617 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1618 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1619
1620 r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1621 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1622
1623 r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1624 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1625
1626 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1627 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1628
1629 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1630 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1631
1632 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1633 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1634
1635 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1636 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1637
1638 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1639 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1640
1641 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1642 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1643
1644 r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1645 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1646
1647 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1648 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1649
1650 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1651 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1652
1653 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1654 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1655
1656 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1657 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1658
1659 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1660 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1661
1662 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1663 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1664
1665 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1666 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1667
1668 r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1669 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1670
1671 r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1672 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1673
1674 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1675 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1676
1677 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1678 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1679
1680 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1681 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1682
1683 MsiSetPropertyA(hpkg, "bandalmael", "0" );
1684 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1685 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1686
1687 MsiSetPropertyA(hpkg, "bandalmael", "" );
1688 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1689 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1690
1691 MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1692 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1693 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1694
1695 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1696 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1697 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1698
1699 MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1700 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1701 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1702
1703 MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1704 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1705 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1706
1707 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1708 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1709 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1710
1711 MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1712 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1713 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1714
1715 MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1716 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1717 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1718
1719 MsiSetPropertyA(hpkg, "bandalmael", "-" );
1720 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1721 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1722
1723 MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1724 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1725 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1726
1727 MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1728 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1729 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1730 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1731 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1732
1733 MsiSetPropertyA(hpkg, "one", "hi");
1734 MsiSetPropertyA(hpkg, "two", "hithere");
1735 r = MsiEvaluateConditionA(hpkg, "one >< two");
1736 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1737
1738 MsiSetPropertyA(hpkg, "one", "hithere");
1739 MsiSetPropertyA(hpkg, "two", "hi");
1740 r = MsiEvaluateConditionA(hpkg, "one >< two");
1741 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1742
1743 MsiSetPropertyA(hpkg, "one", "hello");
1744 MsiSetPropertyA(hpkg, "two", "hi");
1745 r = MsiEvaluateConditionA(hpkg, "one >< two");
1746 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1747
1748 MsiSetPropertyA(hpkg, "one", "hellohithere");
1749 MsiSetPropertyA(hpkg, "two", "hi");
1750 r = MsiEvaluateConditionA(hpkg, "one >< two");
1751 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1752
1753 MsiSetPropertyA(hpkg, "one", "");
1754 MsiSetPropertyA(hpkg, "two", "hi");
1755 r = MsiEvaluateConditionA(hpkg, "one >< two");
1756 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1757
1758 MsiSetPropertyA(hpkg, "one", "hi");
1759 MsiSetPropertyA(hpkg, "two", "");
1760 r = MsiEvaluateConditionA(hpkg, "one >< two");
1761 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1762
1763 MsiSetPropertyA(hpkg, "one", "");
1764 MsiSetPropertyA(hpkg, "two", "");
1765 r = MsiEvaluateConditionA(hpkg, "one >< two");
1766 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1767
1768 MsiSetPropertyA(hpkg, "one", "1234");
1769 MsiSetPropertyA(hpkg, "two", "1");
1770 r = MsiEvaluateConditionA(hpkg, "one >< two");
1771 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1772
1773 MsiSetPropertyA(hpkg, "one", "one 1234");
1774 MsiSetPropertyA(hpkg, "two", "1");
1775 r = MsiEvaluateConditionA(hpkg, "one >< two");
1776 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1777
1778 MsiSetPropertyA(hpkg, "one", "hithere");
1779 MsiSetPropertyA(hpkg, "two", "hi");
1780 r = MsiEvaluateConditionA(hpkg, "one << two");
1781 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1782
1783 MsiSetPropertyA(hpkg, "one", "hi");
1784 MsiSetPropertyA(hpkg, "two", "hithere");
1785 r = MsiEvaluateConditionA(hpkg, "one << two");
1786 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1787
1788 MsiSetPropertyA(hpkg, "one", "hi");
1789 MsiSetPropertyA(hpkg, "two", "hi");
1790 r = MsiEvaluateConditionA(hpkg, "one << two");
1791 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1792
1793 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1794 MsiSetPropertyA(hpkg, "two", "hi");
1795 r = MsiEvaluateConditionA(hpkg, "one << two");
1796 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1797
1798 MsiSetPropertyA(hpkg, "one", "");
1799 MsiSetPropertyA(hpkg, "two", "hi");
1800 r = MsiEvaluateConditionA(hpkg, "one << two");
1801 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1802
1803 MsiSetPropertyA(hpkg, "one", "hithere");
1804 MsiSetPropertyA(hpkg, "two", "");
1805 r = MsiEvaluateConditionA(hpkg, "one << two");
1806 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1807
1808 MsiSetPropertyA(hpkg, "one", "");
1809 MsiSetPropertyA(hpkg, "two", "");
1810 r = MsiEvaluateConditionA(hpkg, "one << two");
1811 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1812
1813 MsiSetPropertyA(hpkg, "one", "1234");
1814 MsiSetPropertyA(hpkg, "two", "1");
1815 r = MsiEvaluateConditionA(hpkg, "one << two");
1816 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1817
1818 MsiSetPropertyA(hpkg, "one", "1234 one");
1819 MsiSetPropertyA(hpkg, "two", "1");
1820 r = MsiEvaluateConditionA(hpkg, "one << two");
1821 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1822
1823 MsiSetPropertyA(hpkg, "one", "hithere");
1824 MsiSetPropertyA(hpkg, "two", "there");
1825 r = MsiEvaluateConditionA(hpkg, "one >> two");
1826 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1827
1828 MsiSetPropertyA(hpkg, "one", "hithere");
1829 MsiSetPropertyA(hpkg, "two", "hi");
1830 r = MsiEvaluateConditionA(hpkg, "one >> two");
1831 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1832
1833 MsiSetPropertyA(hpkg, "one", "there");
1834 MsiSetPropertyA(hpkg, "two", "hithere");
1835 r = MsiEvaluateConditionA(hpkg, "one >> two");
1836 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1837
1838 MsiSetPropertyA(hpkg, "one", "there");
1839 MsiSetPropertyA(hpkg, "two", "there");
1840 r = MsiEvaluateConditionA(hpkg, "one >> two");
1841 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1842
1843 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1844 MsiSetPropertyA(hpkg, "two", "hi");
1845 r = MsiEvaluateConditionA(hpkg, "one >> two");
1846 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1847
1848 MsiSetPropertyA(hpkg, "one", "");
1849 MsiSetPropertyA(hpkg, "two", "there");
1850 r = MsiEvaluateConditionA(hpkg, "one >> two");
1851 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1852
1853 MsiSetPropertyA(hpkg, "one", "there");
1854 MsiSetPropertyA(hpkg, "two", "");
1855 r = MsiEvaluateConditionA(hpkg, "one >> two");
1856 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1857
1858 MsiSetPropertyA(hpkg, "one", "");
1859 MsiSetPropertyA(hpkg, "two", "");
1860 r = MsiEvaluateConditionA(hpkg, "one >> two");
1861 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1862
1863 MsiSetPropertyA(hpkg, "one", "1234");
1864 MsiSetPropertyA(hpkg, "two", "4");
1865 r = MsiEvaluateConditionA(hpkg, "one >> two");
1866 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1867
1868 MsiSetPropertyA(hpkg, "one", "one 1234");
1869 MsiSetPropertyA(hpkg, "two", "4");
1870 r = MsiEvaluateConditionA(hpkg, "one >> two");
1871 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1872
1873 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1874
1875 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1876 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1877
1878 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1879 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1880
1881 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1882 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1883
1884 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1885 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1886
1887 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1888 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1889
1890 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1891 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1892
1893 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1894 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1895
1896 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1897 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1898
1899 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1900 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1901
1902 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1903 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1904
1905 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1906 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1907
1908 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1909 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1910
1911 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1912 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1913
1914 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1915 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1916
1917 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1918 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1919
1920 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1921 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1922
1923 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1924 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1925
1926 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1927 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1928
1929 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1930 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1931
1932 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1933 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1934
1935 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1936 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1937
1938 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1939 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1940
1941 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1942 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1943
1944 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1945 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1946
1947 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1948 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1949
1950 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1951 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1952
1953 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1954 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1955
1956 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1957 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1958
1959 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1960 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1961
1962 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1963 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1964
1965 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
1966 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1967
1968 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
1969 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1970
1971 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
1972 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1973
1974 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
1975 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1976
1977 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
1978 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1979
1980 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
1981 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1982
1983 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
1984 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1985
1986 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
1987 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1988 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1989
1990 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
1991 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1992
1993 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
1994 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1995
1996 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1997 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1998
1999 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
2000 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2001
2002 MsiSetPropertyA(hpkg, "one", "1");
2003 r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
2004 ok( r == MSICONDITION_FALSE, "wrong return val\n");
2005
2006 MsiSetPropertyA(hpkg, "X", "5.0");
2007
2008 r = MsiEvaluateConditionA(hpkg, "X != \"\"");
2009 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2010
2011 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
2012 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2013
2014 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
2015 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2016
2017 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
2018 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2019
2020 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
2021 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2022
2023 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2024 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2025
2026 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2027 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2028
2029 /* feature doesn't exist */
2030 r = MsiEvaluateConditionA(hpkg, "&nofeature");
2031 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2032
2033 MsiSetPropertyA(hpkg, "A", "2");
2034 MsiSetPropertyA(hpkg, "X", "50");
2035
2036 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2037 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2038
2039 r = MsiEvaluateConditionA(hpkg, "A <= X");
2040 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2041
2042 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2043 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2044
2045 MsiSetPropertyA(hpkg, "X", "50val");
2046
2047 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2048 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2049
2050 r = MsiEvaluateConditionA(hpkg, "A <= X");
2051 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2052
2053 MsiSetPropertyA(hpkg, "A", "7");
2054 MsiSetPropertyA(hpkg, "X", "50");
2055
2056 r = MsiEvaluateConditionA(hpkg, "7 <= X");
2057 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2058
2059 r = MsiEvaluateConditionA(hpkg, "A <= X");
2060 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2061
2062 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2063 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2064
2065 MsiSetPropertyA(hpkg, "X", "50val");
2066
2067 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2068 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2069
2070 r = MsiEvaluateConditionA(hpkg, "A <= X");
2071 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2072
2073 r = MsiEvaluateConditionW(hpkg, cond1);
2074 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2075 "wrong return val (%d)\n", r);
2076
2077 r = MsiEvaluateConditionW(hpkg, cond2);
2078 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2079 "wrong return val (%d)\n", r);
2080
2081 r = MsiEvaluateConditionW(hpkg, cond3);
2082 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
2083 "wrong return val (%d)\n", r);
2084
2085 r = MsiEvaluateConditionW(hpkg, cond4);
2086 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
2087 "wrong return val (%d)\n", r);
2088
2089 MsiCloseHandle( hpkg );
2090 DeleteFileA(msifile);
2091 }
2092
2093 static BOOL check_prop_empty( MSIHANDLE hpkg, const char * prop)
2094 {
2095 UINT r;
2096 DWORD sz;
2097 char buffer[2];
2098
2099 sz = sizeof buffer;
2100 strcpy(buffer,"x");
2101 r = MsiGetPropertyA( hpkg, prop, buffer, &sz );
2102 return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
2103 }
2104
2105 static void test_props(void)
2106 {
2107 MSIHANDLE hpkg, hdb;
2108 UINT r;
2109 DWORD sz;
2110 char buffer[0x100];
2111
2112 hdb = create_package_db();
2113 r = run_query( hdb,
2114 "CREATE TABLE `Property` ( "
2115 "`Property` CHAR(255) NOT NULL, "
2116 "`Value` CHAR(255) "
2117 "PRIMARY KEY `Property`)" );
2118 ok( r == ERROR_SUCCESS , "Failed\n" );
2119
2120 r = run_query(hdb,
2121 "INSERT INTO `Property` "
2122 "(`Property`, `Value`) "
2123 "VALUES( 'MetadataCompName', 'Photoshop.dll' )");
2124 ok( r == ERROR_SUCCESS , "Failed\n" );
2125
2126 r = package_from_db( hdb, &hpkg );
2127 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2128 {
2129 skip("Not enough rights to perform tests\n");
2130 DeleteFileA(msifile);
2131 return;
2132 }
2133 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2134
2135 /* test invalid values */
2136 r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2137 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2138
2139 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2140 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2141
2142 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2143 ok( r == ERROR_SUCCESS, "wrong return val\n");
2144
2145 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2146 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2147
2148 /* test retrieving an empty/nonexistent property */
2149 sz = sizeof buffer;
2150 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2151 ok( r == ERROR_SUCCESS, "wrong return val\n");
2152 ok( sz == 0, "wrong size returned\n");
2153
2154 check_prop_empty( hpkg, "boo");
2155 sz = 0;
2156 strcpy(buffer,"x");
2157 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2158 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2159 ok( !strcmp(buffer,"x"), "buffer was changed\n");
2160 ok( sz == 0, "wrong size returned\n");
2161
2162 sz = 1;
2163 strcpy(buffer,"x");
2164 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2165 ok( r == ERROR_SUCCESS, "wrong return val\n");
2166 ok( buffer[0] == 0, "buffer was not changed\n");
2167 ok( sz == 0, "wrong size returned\n");
2168
2169 /* set the property to something */
2170 r = MsiSetPropertyA( 0, NULL, NULL );
2171 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
2172
2173 r = MsiSetPropertyA( hpkg, NULL, NULL );
2174 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2175
2176 r = MsiSetPropertyA( hpkg, "", NULL );
2177 ok( r == ERROR_SUCCESS, "wrong return val\n");
2178
2179 /* try set and get some illegal property identifiers */
2180 r = MsiSetPropertyA( hpkg, "", "asdf" );
2181 ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
2182
2183 r = MsiSetPropertyA( hpkg, "=", "asdf" );
2184 ok( r == ERROR_SUCCESS, "wrong return val\n");
2185
2186 r = MsiSetPropertyA( hpkg, " ", "asdf" );
2187 ok( r == ERROR_SUCCESS, "wrong return val\n");
2188
2189 r = MsiSetPropertyA( hpkg, "'", "asdf" );
2190 ok( r == ERROR_SUCCESS, "wrong return val\n");
2191
2192 sz = sizeof buffer;
2193 buffer[0]=0;
2194 r = MsiGetPropertyA( hpkg, "'", buffer, &sz );
2195 ok( r == ERROR_SUCCESS, "wrong return val\n");
2196 ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
2197
2198 /* set empty values */
2199 r = MsiSetPropertyA( hpkg, "boo", NULL );
2200 ok( r == ERROR_SUCCESS, "wrong return val\n");
2201 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2202
2203 r = MsiSetPropertyA( hpkg, "boo", "" );
2204 ok( r == ERROR_SUCCESS, "wrong return val\n");
2205 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2206
2207 /* set a non-empty value */
2208 r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2209 ok( r == ERROR_SUCCESS, "wrong return val\n");
2210
2211 sz = 1;
2212 strcpy(buffer,"x");
2213 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2214 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2215 ok( buffer[0] == 0, "buffer was not changed\n");
2216 ok( sz == 3, "wrong size returned\n");
2217
2218 sz = 4;
2219 strcpy(buffer,"x");
2220 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2221 ok( r == ERROR_SUCCESS, "wrong return val\n");
2222 ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
2223 ok( sz == 3, "wrong size returned\n");
2224
2225 sz = 3;
2226 strcpy(buffer,"x");
2227 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2228 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2229 ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
2230 ok( sz == 3, "wrong size returned\n");
2231
2232 r = MsiSetPropertyA(hpkg, "SourceDir", "foo");
2233 ok( r == ERROR_SUCCESS, "wrong return val\n");
2234
2235 sz = 4;
2236 r = MsiGetPropertyA(hpkg, "SOURCEDIR", buffer, &sz);
2237 ok( r == ERROR_SUCCESS, "wrong return val\n");
2238 ok( !strcmp(buffer,""), "buffer wrong\n");
2239 ok( sz == 0, "wrong size returned\n");
2240
2241 sz = 4;
2242 r = MsiGetPropertyA(hpkg, "SOMERANDOMNAME", buffer, &sz);
2243 ok( r == ERROR_SUCCESS, "wrong return val\n");
2244 ok( !strcmp(buffer,""), "buffer wrong\n");
2245 ok( sz == 0, "wrong size returned\n");
2246
2247 sz = 4;
2248 r = MsiGetPropertyA(hpkg, "SourceDir", buffer, &sz);
2249 ok( r == ERROR_SUCCESS, "wrong return val\n");
2250 ok( !strcmp(buffer,"foo"), "buffer wrong\n");
2251 ok( sz == 3, "wrong size returned\n");
2252
2253 r = MsiSetPropertyA(hpkg, "MetadataCompName", "Photoshop.dll");
2254 ok( r == ERROR_SUCCESS, "wrong return val\n");
2255
2256 sz = 0;
2257 r = MsiGetPropertyA(hpkg, "MetadataCompName", NULL, &sz );
2258 ok( r == ERROR_SUCCESS, "return wrong\n");
2259 ok( sz == 13, "size wrong (%d)\n", sz);
2260
2261 sz = 13;
2262 r = MsiGetPropertyA(hpkg, "MetadataCompName", buffer, &sz );
2263 ok( r == ERROR_MORE_DATA, "return wrong\n");
2264 ok( !strcmp(buffer,"Photoshop.dl"), "buffer wrong\n");
2265
2266 r = MsiSetPropertyA(hpkg, "property", "value");
2267 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2268
2269 sz = 6;
2270 r = MsiGetPropertyA(hpkg, "property", buffer, &sz);
2271 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2272 ok( !strcmp(buffer, "value"), "Expected value, got %s\n", buffer);
2273
2274 r = MsiSetPropertyA(hpkg, "property", NULL);
2275 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2276
2277 sz = 6;
2278 r = MsiGetPropertyA(hpkg, "property", buffer, &sz);
2279 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2280 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2281
2282 MsiCloseHandle( hpkg );
2283 DeleteFileA(msifile);
2284 }
2285
2286 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
2287 {
2288 MSIHANDLE hview, hrec;
2289 BOOL found = FALSE;
2290 CHAR buffer[MAX_PATH];
2291 DWORD sz;
2292 UINT r;
2293
2294 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2295 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2296 r = MsiViewExecute(hview, 0);
2297 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2298
2299 if (len < 0) len = lstrlenA(val);
2300
2301 while (r == ERROR_SUCCESS && !found)
2302 {
2303 r = MsiViewFetch(hview, &hrec);
2304 if (r != ERROR_SUCCESS) break;
2305
2306 sz = MAX_PATH;
2307 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2308 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2309 {
2310 sz = MAX_PATH;
2311 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2312 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2313 {
2314 ok(sz == len, "wrong size %u\n", sz);
2315 found = TRUE;
2316 }
2317 }
2318
2319 MsiCloseHandle(hrec);
2320 }
2321 MsiViewClose(hview);
2322 MsiCloseHandle(hview);
2323 return found;
2324 }
2325
2326 static void test_property_table(void)
2327 {
2328 const char *query;
2329 UINT r;
2330 MSIHANDLE hpkg, hdb, hrec;
2331 char buffer[MAX_PATH], package[10];
2332 DWORD sz;
2333 BOOL found;
2334
2335 hdb = create_package_db();
2336 ok( hdb, "failed to create package\n");
2337
2338 r = package_from_db(hdb, &hpkg);
2339 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2340 {
2341 skip("Not enough rights to perform tests\n");
2342 DeleteFileA(msifile);
2343 return;
2344 }
2345 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2346
2347 MsiCloseHandle(hdb);
2348
2349 hdb = MsiGetActiveDatabase(hpkg);
2350
2351 query = "CREATE TABLE `_Property` ( "
2352 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2353 r = run_query(hdb, query);
2354 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2355
2356 MsiCloseHandle(hdb);
2357 MsiCloseHandle(hpkg);
2358 DeleteFileA(msifile);
2359
2360 hdb = create_package_db();
2361 ok( hdb, "failed to create package\n");
2362
2363 query = "CREATE TABLE `_Property` ( "
2364 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2365 r = run_query(hdb, query);
2366 ok(r == ERROR_SUCCESS, "failed to create table\n");
2367
2368 query = "ALTER `_Property` ADD `foo` INTEGER";
2369 r = run_query(hdb, query);
2370 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2371
2372 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2373 r = run_query(hdb, query);
2374 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2375
2376 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2377 r = run_query(hdb, query);
2378 ok(r == ERROR_SUCCESS, "failed to add column\n");
2379
2380 sprintf(package, "#%i", hdb);
2381 r = MsiOpenPackageA(package, &hpkg);
2382 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2383 if (r == ERROR_SUCCESS)
2384 MsiCloseHandle(hpkg);
2385
2386 r = MsiCloseHandle(hdb);
2387 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2388
2389 hdb = create_package_db();
2390 ok (hdb, "failed to create package database\n");
2391
2392 r = create_property_table(hdb);
2393 ok(r == ERROR_SUCCESS, "cannot create Property table: %d\n", r);
2394
2395 r = add_property_entry(hdb, "'prop', 'val'");
2396 ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2397
2398 r = create_custom_action_table(hdb);
2399 ok(r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
2400
2401 r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2402 ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2403
2404 r = package_from_db(hdb, &hpkg);
2405 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2406
2407 MsiCloseHandle(hdb);
2408
2409 sz = MAX_PATH;
2410 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2412 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2413
2414 hdb = MsiGetActiveDatabase(hpkg);
2415
2416 found = find_prop_in_property(hdb, "prop", "val", -1);
2417 ok(found, "prop should be in the _Property table\n");
2418
2419 r = add_property_entry(hdb, "'dantes', 'mercedes'");
2420 ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2421
2422 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2423 r = do_query(hdb, query, &hrec);
2424 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2425
2426 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2427 ok(found == FALSE, "dantes should not be in the _Property table\n");
2428
2429 sz = MAX_PATH;
2430 lstrcpyA(buffer, "aaa");
2431 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2433 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2434
2435 r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2437
2438 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2439 ok(found == TRUE, "dantes should be in the _Property table\n");
2440
2441 r = MsiDoActionA( hpkg, "EmbedNull" );
2442 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2443
2444 sz = MAX_PATH;
2445 memset( buffer, 'a', sizeof(buffer) );
2446 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2447 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2448 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2449 ok( sz == sizeof("\0np") - 1, "got %u\n", sz );
2450
2451 found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2452 ok(found == TRUE, "prop2 should be in the _Property table\n");
2453
2454 MsiCloseHandle(hdb);
2455 MsiCloseHandle(hpkg);
2456 DeleteFileA(msifile);
2457 }
2458
2459 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2460 {
2461 MSIHANDLE htab = 0;
2462 UINT res;
2463
2464 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2465 if( res == ERROR_SUCCESS )
2466 {
2467 UINT r;
2468
2469 r = MsiViewExecute( htab, hrec );
2470 if( r != ERROR_SUCCESS )
2471 {
2472 res = r;
2473 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2474 }
2475
2476 r = MsiViewClose( htab );
2477 if( r != ERROR_SUCCESS )
2478 res = r;
2479
2480 r = MsiCloseHandle( htab );
2481 if( r != ERROR_SUCCESS )
2482 res = r;
2483 }
2484 return res;
2485 }
2486
2487 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2488 {
2489 return try_query_param( hdb, szQuery, 0 );
2490 }
2491
2492 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2493 {
2494 MSIHANDLE summary;
2495 UINT r;
2496
2497 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2499
2500 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2502
2503 r = MsiSummaryInfoPersist(summary);
2504 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2505
2506 MsiCloseHandle(summary);
2507 }
2508
2509 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2510 {
2511 MSIHANDLE summary;
2512 UINT r;
2513
2514 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2515 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2516
2517 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2518 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2519
2520 r = MsiSummaryInfoPersist(summary);
2521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2522
2523 MsiCloseHandle(summary);
2524 }
2525
2526 static void test_msipackage(void)
2527 {
2528 MSIHANDLE hdb = 0, hpack = 100;
2529 UINT r;
2530 const char *query;
2531 char name[10];
2532
2533 /* NULL szPackagePath */
2534 r = MsiOpenPackageA(NULL, &hpack);
2535 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2536
2537 /* empty szPackagePath */
2538 r = MsiOpenPackageA("", &hpack);
2539 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2540 {
2541 skip("Not enough rights to perform tests\n");
2542 return;
2543 }
2544 todo_wine
2545 {
2546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2547 }
2548
2549 if (r == ERROR_SUCCESS)
2550 MsiCloseHandle(hpack);
2551
2552 /* nonexistent szPackagePath */
2553 r = MsiOpenPackageA("nonexistent", &hpack);
2554 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2555
2556 /* NULL hProduct */
2557 r = MsiOpenPackageA(msifile, NULL);
2558 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2559
2560 name[0]='#';
2561 name[1]=0;
2562 r = MsiOpenPackageA(name, &hpack);
2563 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2564
2565 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2567
2568 /* database exists, but is empty */
2569 sprintf(name, "#%d", hdb);
2570 r = MsiOpenPackageA(name, &hpack);
2571 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2572 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2573
2574 query = "CREATE TABLE `Property` ( "
2575 "`Property` CHAR(72), `Value` CHAR(0) "
2576 "PRIMARY KEY `Property`)";
2577 r = try_query(hdb, query);
2578 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2579
2580 query = "CREATE TABLE `InstallExecuteSequence` ("
2581 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2582 "PRIMARY KEY `Action`)";
2583 r = try_query(hdb, query);
2584 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2585
2586 /* a few key tables exist */
2587 sprintf(name, "#%d", hdb);
2588 r = MsiOpenPackageA(name, &hpack);
2589 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2590 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2591
2592 MsiCloseHandle(hdb);
2593 DeleteFileA(msifile);
2594
2595 /* start with a clean database to show what constitutes a valid package */
2596 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
2597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2598
2599 sprintf(name, "#%d", hdb);
2600
2601 /* The following summary information props must exist:
2602 * - PID_REVNUMBER
2603 * - PID_PAGECOUNT
2604 */
2605
2606 set_summary_dword(hdb, PID_PAGECOUNT, 100);
2607 r = MsiOpenPackageA(name, &hpack);
2608 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2609 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2610
2611 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2612 r = MsiOpenPackageA(name, &hpack);
2613 ok(r == ERROR_SUCCESS,
2614 "Expected ERROR_SUCCESS, got %d\n", r);
2615
2616 MsiCloseHandle(hpack);
2617 MsiCloseHandle(hdb);
2618 DeleteFileA(msifile);
2619 }
2620
2621 static void test_formatrecord2(void)
2622 {
2623 MSIHANDLE hpkg, hrec ;
2624 char buffer[0x100];
2625 DWORD sz;
2626 UINT r;
2627
2628 r = package_from_db(create_package_db(), &hpkg);
2629 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2630 {
2631 skip("Not enough rights to perform tests\n");
2632 DeleteFileA(msifile);
2633 return;
2634 }
2635 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2636
2637 r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2638 ok( r == ERROR_SUCCESS, "set property failed\n");
2639
2640 hrec = MsiCreateRecord(2);
2641 ok(hrec, "create record failed\n");
2642
2643 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2644 ok( r == ERROR_SUCCESS, "format record failed\n");
2645
2646 buffer[0] = 0;
2647 sz = sizeof buffer;
2648 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2649 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2650
2651 r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2652 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2653 r = MsiRecordSetStringA(hrec, 1, "hoo");
2654 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2655 sz = sizeof buffer;
2656 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2657 ok( sz == 3, "size wrong\n");
2658 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2659 ok( r == ERROR_SUCCESS, "format failed\n");
2660
2661 r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2662 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2663 sz = sizeof buffer;
2664 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2665 ok( sz == 3, "size wrong\n");
2666 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2667 ok( r == ERROR_SUCCESS, "format failed\n");
2668
2669 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2670 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2671 r = MsiRecordSetStringA(hrec, 1, "hoo");
2672 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2673 sz = sizeof buffer;
2674 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2675 ok( sz == 3, "size wrong\n");
2676 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2677 ok( r == ERROR_SUCCESS, "format failed\n");
2678
2679 r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2680 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2681 sz = sizeof buffer;
2682 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2683 ok( sz == 1, "size wrong\n");
2684 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2685 ok( r == ERROR_SUCCESS, "format failed\n");
2686
2687 SetEnvironmentVariableA("FOO", "BAR");
2688 r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2689 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2690 sz = sizeof buffer;
2691 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2692 ok( sz == 3, "size wrong\n");
2693 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2694 ok( r == ERROR_SUCCESS, "format failed\n");
2695
2696 r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2697 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2698 r = MsiRecordSetStringA(hrec, 1, "%FOO");
2699 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2700 sz = sizeof buffer;
2701 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2702 ok( sz == 3, "size wrong\n");
2703 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2704 ok( r == ERROR_SUCCESS, "format failed\n");
2705
2706 MsiCloseHandle( hrec );
2707 MsiCloseHandle( hpkg );
2708 DeleteFileA(msifile);
2709 }
2710
2711 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
2712 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2713 {
2714 UINT r;
2715 INSTALLSTATE state = 0xdeadbee;
2716 INSTALLSTATE action = 0xdeadbee;
2717
2718 r = MsiGetFeatureStateA( package, feature, &state, &action );
2719 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2720 if (r == ERROR_SUCCESS)
2721 {
2722 ok( state == expected_state, "%u: expected state %d got %d\n",
2723 line, expected_state, state );
2724 todo_wine_if (todo)
2725 ok( action == expected_action, "%u: expected action %d got %d\n",
2726 line, expected_action, action );
2727 }
2728 else
2729 {
2730 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
2731 todo_wine_if (todo)
2732 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2733
2734 }
2735 }
2736
2737 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
2738 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
2739 {
2740 UINT r;
2741 INSTALLSTATE state = 0xdeadbee;
2742 INSTALLSTATE action = 0xdeadbee;
2743
2744 r = MsiGetComponentStateA( package, component, &state, &action );
2745 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2746 if (r == ERROR_SUCCESS)
2747 {
2748 ok( state == expected_state, "%u: expected state %d got %d\n",
2749 line, expected_state, state );
2750 todo_wine_if (todo)
2751 ok( action == expected_action, "%u: expected action %d got %d\n",
2752 line, expected_action, action );
2753 }
2754 else
2755 {
2756 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2757 line, state );
2758 todo_wine_if (todo)
2759 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2760 line, action );
2761 }
2762 }
2763
2764 static void test_states(void)
2765 {
2766 static const char msifile2[] = "winetest2-package.msi";
2767 static const char msifile3[] = "winetest3-package.msi";
2768 static const char msifile4[] = "winetest4-package.msi";
2769 static const WCHAR msifile2W[] =
2770 {'w','i','n','e','t','e','s','t','2','-','p','a','c','k','a','g','e','.','m','s','i',0};
2771 static const WCHAR msifile3W[] =
2772 {'w','i','n','e','t','e','s','t','3','-','p','a','c','k','a','g','e','.','m','s','i',0};
2773 static const WCHAR msifile4W[] =
2774 {'w','i','n','e','t','e','s','t','4','-','p','a','c','k','a','g','e','.','m','s','i',0};
2775 INSTALLSTATE state;
2776 MSIHANDLE hpkg;
2777 UINT r;
2778 MSIHANDLE hdb;
2779
2780 if (is_process_limited())
2781 {
2782 skip("process is limited\n");
2783 return;
2784 }
2785
2786 hdb = create_package_db();
2787 ok ( hdb, "failed to create package database\n" );
2788
2789 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2790 ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
2791
2792 r = create_property_table( hdb );
2793 ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r );
2794
2795 r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2796 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2797
2798 r = add_property_entry( hdb, "'ProductLanguage', '1033'" );
2799 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2800
2801 r = add_property_entry( hdb, "'ProductName', 'MSITEST'" );
2802 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2803
2804 r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
2805 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2806
2807 r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
2808 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2809
2810 r = create_install_execute_sequence_table( hdb );
2811 ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r );
2812
2813 r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
2814 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2815
2816 r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
2817 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2818
2819 r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
2820 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2821
2822 r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
2823 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2824
2825 r = add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
2826 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2827
2828 r = add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
2829 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2830
2831 r = add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
2832 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2833
2834 r = add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
2835 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2836
2837 r = add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
2838 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2839
2840 r = add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
2841 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2842
2843 r = add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
2844 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2845
2846 r = create_media_table( hdb );
2847 ok( r == ERROR_SUCCESS, "cannot create media table: %d\n", r );
2848
2849 r = add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
2850 ok( r == ERROR_SUCCESS, "cannot add media entry: %d\n", r );
2851
2852 r = create_feature_table( hdb );
2853 ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
2854
2855 r = create_component_table( hdb );
2856 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
2857
2858 /* msidbFeatureAttributesFavorLocal */
2859 r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2860 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2861
2862 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2863 r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
2864 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2865
2866 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2867 r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
2868 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2869
2870 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2871 r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
2872 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2873
2874 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
2875 r = add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
2876 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2877
2878 /* msidbFeatureAttributesFavorSource */
2879 r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
2880 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2881
2882 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2883 r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
2884 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2885
2886 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2887 r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
2888 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2889
2890 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2891 r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
2892 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2893
2894 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
2895 r = add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
2896 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2897
2898 /* msidbFeatureAttributesFavorSource */
2899 r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
2900 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2901
2902 /* msidbFeatureAttributesFavorLocal */
2903 r = add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
2904 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2905
2906 /* disabled */
2907 r = add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
2908 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2909
2910 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2911 r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
2912 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2913
2914 /* no feature parent:msidbComponentAttributesLocalOnly */
2915 r = add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
2916 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2917
2918 /* msidbFeatureAttributesFavorLocal:removed */
2919 r = add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
2920 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2921
2922 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
2923 r = add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
2924 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2925
2926 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
2927 r = add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
2928 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2929
2930 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
2931 r = add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
2932 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2933
2934 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
2935 r = add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
2936 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2937
2938 /* msidbFeatureAttributesFavorSource:removed */
2939 r = add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
2940 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2941
2942 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
2943 r = add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
2944 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2945
2946 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
2947 r = add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
2948 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2949
2950 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
2951 r = add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
2952 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2953
2954 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
2955 r = add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
2956 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2957
2958 /* msidbFeatureAttributesFavorLocal */
2959 r = add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
2960 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2961
2962 r = add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
2963 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2964
2965 /* msidbFeatureAttributesFavorSource */
2966 r = add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
2967 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2968
2969 r = add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
2970 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2971
2972 /* msidbFeatureAttributesFavorAdvertise */
2973 r = add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
2974 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2975
2976 r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
2977 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2978
2979 /* msidbFeatureAttributesUIDisallowAbsent */
2980 r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
2981 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2982
2983 r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
2984 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2985
2986 /* high install level */
2987 r = add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
2988 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2989
2990 r = add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
2991 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2992
2993 /* msidbFeatureAttributesFollowParent */
2994 r = add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
2995 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2996
2997 r = create_feature_components_table( hdb );
2998 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
2999
3000 r = add_feature_components_entry( hdb, "'one', 'alpha'" );
3001 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3002
3003 r = add_feature_components_entry( hdb, "'one', 'beta'" );
3004 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3005
3006 r = add_feature_components_entry( hdb, "'one', 'gamma'" );
3007 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3008
3009 r = add_feature_components_entry( hdb, "'one', 'theta'" );
3010 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3011
3012 r = add_feature_components_entry( hdb, "'two', 'delta'" );
3013 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3014
3015 r = add_feature_components_entry( hdb, "'two', 'epsilon'" );
3016 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3017
3018 r = add_feature_components_entry( hdb, "'two', 'zeta'" );
3019 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3020
3021 r = add_feature_components_entry( hdb, "'two', 'iota'" );
3022 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3023
3024 r = add_feature_components_entry( hdb, "'three', 'eta'" );
3025 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3026
3027 r = add_feature_components_entry( hdb, "'four', 'eta'" );
3028 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3029
3030 r = add_feature_components_entry( hdb, "'five', 'eta'" );
3031 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3032
3033 r = add_feature_components_entry( hdb, "'six', 'lambda'" );
3034 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3035
3036 r = add_feature_components_entry( hdb, "'six', 'mu'" );
3037 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3038
3039 r = add_feature_components_entry( hdb, "'six', 'nu'" );
3040 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3041
3042 r = add_feature_components_entry( hdb, "'six', 'xi'" );
3043 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3044
3045 r = add_feature_components_entry( hdb, "'seven', 'omicron'" );
3046 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3047
3048 r = add_feature_components_entry( hdb, "'seven', 'pi'" );
3049 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3050
3051 r = add_feature_components_entry( hdb, "'seven', 'rho'" );
3052 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3053
3054 r = add_feature_components_entry( hdb, "'seven', 'sigma'" );
3055 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3056
3057 r = add_feature_components_entry( hdb, "'eight', 'tau'" );
3058 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3059
3060 r = add_feature_components_entry( hdb, "'nine', 'phi'" );
3061 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3062
3063 r = add_feature_components_entry( hdb, "'ten', 'chi'" );
3064 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3065
3066 r = add_feature_components_entry( hdb, "'eleven', 'psi'" );
3067 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3068
3069 r = add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3070 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3071
3072 r = add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3073 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3074
3075 r = create_file_table( hdb );
3076 ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
3077
3078 r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3079 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3080
3081 r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3082 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3083
3084 r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3085 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3086
3087 r = add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3088 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3089
3090 r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3091 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3092
3093 r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3094 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3095
3096 r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3097 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3098
3099 r = add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3100 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3101
3102 /* compressed file */
3103 r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3104 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3105
3106 r = add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3107 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3108
3109 r = add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3110 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3111
3112 r = add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3113 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3114
3115 r = add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3116 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3117
3118 r = add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3119 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3120
3121 r = add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3122 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3123
3124 r = add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3125 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3126
3127 r = add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3128 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3129
3130 r = add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3131 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3132
3133 r = add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3134 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3135
3136 r = add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3137 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3138
3139 r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3140 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3141
3142 r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3143 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3144
3145 r = add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3146 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3147
3148 MsiDatabaseCommit(hdb);
3149
3150 /* these properties must not be in the saved msi file */
3151 r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3152 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3153
3154 r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3155 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3156
3157 r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
3158 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3159
3160 r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3161 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3162
3163 r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3164 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3165
3166 r = package_from_db( hdb, &hpkg );
3167 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3168 {
3169 skip("Not enough rights to perform tests\n");
3170 DeleteFileA(msifile);
3171 return;
3172 }
3173 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3174
3175 MsiCloseHandle(hdb);
3176
3177 CopyFileA(msifile, msifile2, FALSE);
3178 CopyFileA(msifile, msifile3, FALSE);
3179 CopyFileA(msifile, msifile4, FALSE);
3180
3181 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3182 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3183
3184 r = MsiDoActionA( hpkg, "CostInitialize");
3185 ok( r == ERROR_SUCCESS, "cost init failed\n");
3186
3187 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3188 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3189
3190 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3191
3192 r = MsiDoActionA( hpkg, "FileCost");
3193 ok( r == ERROR_SUCCESS, "file cost failed\n");
3194
3195 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3196 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3197
3198 r = MsiDoActionA( hpkg, "CostFinalize");
3199 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3200
3201 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3202 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3203 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3204 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3205 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3206 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3207 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3208 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3209 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3210 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3211 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3212 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3213 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3214
3215 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3216 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3217 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3218 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3219 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3220 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3221 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
3222 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3223 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
3224 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3225 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3226 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3227 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3228 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3229 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3230 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3231 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3232 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3233 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3234 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3235 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3236 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3237 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3238
3239 MsiCloseHandle( hpkg );
3240
3241 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3242
3243 /* publish the features and components */
3244 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246
3247 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
3248 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3249
3250 /* these properties must not be in the saved msi file */
3251 r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3252 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3253
3254 r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3255 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3256
3257 r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
3258 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3259
3260 r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3261 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3262
3263 r = package_from_db( hdb, &hpkg );
3264 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3265
3266 MsiCloseHandle(hdb);
3267
3268 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3269 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3270
3271 r = MsiDoActionA( hpkg, "CostInitialize");
3272 ok( r == ERROR_SUCCESS, "cost init failed\n");
3273
3274 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3275 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3276
3277 r = MsiDoActionA( hpkg, "FileCost");
3278 ok( r == ERROR_SUCCESS, "file cost failed\n");
3279
3280 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3281 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3282
3283 r = MsiDoActionA( hpkg, "CostFinalize");
3284 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3285
3286 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3287 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3288 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3289 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3290 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3291 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3292 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3293 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3294 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3295 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3296 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3297 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3298 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3299
3300 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3301 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3302 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3303 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3304 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3305 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3306 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3307 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3308 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3309 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3310 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3311 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3312 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3313 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3314 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3315 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3316 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3317 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3318 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3319 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3320 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3321 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3322 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3323
3324 MsiCloseHandle(hpkg);
3325
3326 /* uninstall the product */
3327 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3329
3330 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3331 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3332 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3333 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3334
3335 /* all features installed locally */
3336 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338
3339 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3340 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3341 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3342 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3343
3344 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_DIRECT, &hdb);
3345 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3346
3347 /* these properties must not be in the saved msi file */
3348 r = add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3349 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3350
3351 r = package_from_db( hdb, &hpkg );
3352 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3353
3354 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3355 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3356
3357 r = MsiDoActionA( hpkg, "CostInitialize");
3358 ok( r == ERROR_SUCCESS, "cost init failed\n");
3359
3360 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3361 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3362
3363 r = MsiDoActionA( hpkg, "CostFinalize");
3364 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3365
3366 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3367 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3368 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3369 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3370 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3371 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3372 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, FALSE );
3373 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3374 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3375 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, TRUE );
3376 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3377 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3378 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3379
3380 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3381 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3382 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3383 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3384 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3385 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3386 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3387 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3388 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3389 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3390 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3391 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3392 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3393 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3394 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3395 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3396 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3397 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3398 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3399 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3400 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3401 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3402 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3403
3404 MsiCloseHandle(hpkg);
3405
3406 /* uninstall the product */
3407 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3409
3410 /* all features installed from source */
3411 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3413
3414 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3415 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3416 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3417 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3418
3419 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3420 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3421
3422 /* this property must not be in the saved msi file */
3423 r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3424 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3425
3426 r = package_from_db( hdb, &hpkg );
3427 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3428
3429 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3430 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3431
3432 r = MsiDoActionA( hpkg, "CostInitialize");
3433 ok( r == ERROR_SUCCESS, "cost init failed\n");
3434
3435 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3436 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3437
3438 r = MsiDoActionA( hpkg, "FileCost");
3439 ok( r == ERROR_SUCCESS, "file cost failed\n");
3440
3441 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3442 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3443
3444 r = MsiDoActionA( hpkg, "CostFinalize");
3445 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3446
3447 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3448 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3449 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3450 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3451 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3452 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3453 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3454 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3455 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3456 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3457 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3458 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3459 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3460
3461 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3462 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3463 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3464 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3465 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3466 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3467 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3468 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3469 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3470 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3471 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3472 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3473 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3474 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3475 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3476 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3477 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3478 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3479 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3480 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3481 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3482 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3483 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE );
3484
3485 MsiCloseHandle(hpkg);
3486
3487 /* reinstall the product */
3488 r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3489 ok(r == ERROR_SUCCESS || broken(r == ERROR_INSTALL_FAILURE) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r);
3490
3491 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3492 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3493 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3494 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3495
3496 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3497 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3498
3499 /* this property must not be in the saved msi file */
3500 r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3501 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3502
3503 r = package_from_db( hdb, &hpkg );
3504 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3505
3506 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3507 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3508
3509 r = MsiDoActionA( hpkg, "CostInitialize");
3510 ok( r == ERROR_SUCCESS, "cost init failed\n");
3511
3512 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3513 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3514
3515 r = MsiDoActionA( hpkg, "FileCost");
3516 ok( r == ERROR_SUCCESS, "file cost failed\n");
3517
3518 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3519 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
3520
3521 r = MsiDoActionA( hpkg, "CostFinalize");
3522 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3523
3524 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3525 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3526 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3527 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3528 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3529 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3530 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3531 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3532 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3533 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, FALSE );
3534 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, TRUE );
3535 test_feature_states( __LINE__, hpkg, "twelve", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3536 test_feature_states( __LINE__, hpkg, "thirteen", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_UNKNOWN, FALSE );
3537
3538 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3539 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3540 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3541 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3542 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3543 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3544 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3545 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3546 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3547 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
3548 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3549 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3550 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3551 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3552 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3553 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3554 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3555 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
3556 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3557 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3558 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3559 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
3560 test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE );
3561
3562 MsiCloseHandle(hpkg);
3563
3564 /* uninstall the product */
3565 r = MsiInstallProductA(msifile4, "REMOVE=ALL");
3566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3567
3568 DeleteFileA(msifile);
3569 DeleteFileA(msifile2);
3570 DeleteFileA(msifile3);
3571 DeleteFileA(msifile4);
3572 }
3573
3574 static void test_getproperty(void)
3575 {
3576 MSIHANDLE hPackage = 0;
3577 char prop[100];
3578 static CHAR empty[] = "";
3579 DWORD size;
3580 UINT r;
3581
3582 r = package_from_db(create_package_db(), &hPackage);
3583 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3584 {
3585 skip("Not enough rights to perform tests\n");
3586 DeleteFileA(msifile);
3587 return;
3588 }
3589 ok( r == ERROR_SUCCESS, "Failed to create package %u\n", r );
3590
3591 /* set the property */
3592 r = MsiSetPropertyA(hPackage, "Name", "Value");
3593 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3594
3595 /* retrieve the size, NULL pointer */
3596 size = 0;
3597 r = MsiGetPropertyA(hPackage, "Name", NULL, &size);
3598 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3599 ok( size == 5, "Expected 5, got %d\n", size);
3600
3601 /* retrieve the size, empty string */
3602 size = 0;
3603 r = MsiGetPropertyA(hPackage, "Name", empty, &size);
3604 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3605 ok( size == 5, "Expected 5, got %d\n", size);
3606
3607 /* don't change size */
3608 r = MsiGetPropertyA(hPackage, "Name", prop, &size);
3609 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3610 ok( size == 5, "Expected 5, got %d\n", size);
3611 ok( !lstrcmpA(prop, "Valu"), "Expected Valu, got %s\n", prop);
3612
3613 /* increase the size by 1 */
3614 size++;
3615 r = MsiGetPropertyA(hPackage, "Name", prop, &size);
3616 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3617 ok( size == 5, "Expected 5, got %d\n", size);
3618 ok( !lstrcmpA(prop, "Value"), "Expected Value, got %s\n", prop);
3619
3620 r = MsiCloseHandle( hPackage);
3621 ok( r == ERROR_SUCCESS , "Failed to close package\n" );
3622 DeleteFileA(msifile);
3623 }
3624
3625 static void test_removefiles(void)
3626 {
3627 MSIHANDLE hpkg;
3628 UINT r;
3629 MSIHANDLE hdb;
3630 INSTALLSTATE installed, action;
3631
3632 hdb = create_package_db();
3633 ok ( hdb, "failed to create package database\n" );
3634
3635 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3636 ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
3637
3638 r = create_feature_table( hdb );
3639 ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
3640
3641 r = create_component_table( hdb );
3642 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
3643
3644 r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3645 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
3646
3647 r = add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3648 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3649
3650 r = add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3651 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3652
3653 r = add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3654 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3655
3656 r = add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3657 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3658
3659 r = add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3660 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3661
3662 r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3663 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3664
3665 r = add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3666 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3667
3668 r = create_feature_components_table( hdb );
3669 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
3670
3671 r = add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3672 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3673
3674 r = add_feature_components_entry( hdb, "'one', 'helium'" );
3675 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3676
3677 r = add_feature_components_entry( hdb, "'one', 'lithium'" );
3678 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3679
3680 r = add_feature_components_entry( hdb, "'one', 'beryllium'" );
3681 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3682
3683 r = add_feature_components_entry( hdb, "'one', 'boron'" );
3684 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3685
3686 r = add_feature_components_entry( hdb, "'one', 'carbon'" );
3687 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3688
3689 r = add_feature_components_entry( hdb, "'one', 'oxygen'" );
3690 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3691
3692 r = create_file_table( hdb );
3693 ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
3694
3695 r = add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3696 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3697
3698 r = add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3699 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3700
3701 r = add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3702 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3703
3704 r = add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3705 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3706
3707 r = add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3708 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3709
3710 r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3711 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3712
3713 r = add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3714 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
3715
3716 r = create_remove_file_table( hdb );
3717 ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r);
3718
3719 r = package_from_db( hdb, &hpkg );
3720 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3721 {
3722 skip("Not enough rights to perform tests\n");
3723 DeleteFileA(msifile);
3724 return;
3725 }
3726 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3727
3728 MsiCloseHandle( hdb );
3729
3730 create_test_file( "hydrogen.txt" );
3731 create_test_file( "helium.txt" );
3732 create_test_file( "lithium.txt" );
3733 create_test_file( "beryllium.txt" );
3734 create_test_file( "boron.txt" );
3735 create_test_file( "carbon.txt" );
3736 create_test_file( "oxygen.txt" );
3737
3738 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3739 ok( r == ERROR_SUCCESS, "set property failed\n");
3740
3741 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3742
3743 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3744 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3745
3746 r = MsiDoActionA( hpkg, "CostInitialize");
3747 ok( r == ERROR_SUCCESS, "cost init failed\n");
3748
3749 r = MsiDoActionA( hpkg, "FileCost");
3750 ok( r == ERROR_SUCCESS, "file cost failed\n");
3751
3752 installed = action = 0xdeadbeef;
3753 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3754 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3755 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3756 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3757
3758 r = MsiDoActionA( hpkg, "CostFinalize");
3759 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3760
3761 r = MsiDoActionA( hpkg, "InstallValidate");
3762 ok( r == ERROR_SUCCESS, "install validate failed\n");
3763
3764 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3765 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3766
3767 installed = action = 0xdeadbeef;
3768 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3769 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3770 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3771 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3772
3773 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3774 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3775
3776 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3777 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3778
3779 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3780 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3781
3782 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3783 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3784
3785 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3786 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3787
3788 installed = action = 0xdeadbeef;
3789 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3790 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3791 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3792 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3793
3794 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3795 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3796
3797 installed = action = 0xdeadbeef;
3798 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3799 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3800 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3801 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3802
3803 r = MsiDoActionA( hpkg, "RemoveFiles");
3804 ok( r == ERROR_SUCCESS, "remove files failed\n");
3805
3806 installed = action = 0xdeadbeef;
3807 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3808 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3809 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3810 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3811
3812 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3813 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
3814 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
3815 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
3816 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
3817 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
3818 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
3819
3820 MsiCloseHandle( hpkg );
3821 DeleteFileA(msifile);
3822 }
3823
3824 static void test_appsearch(void)
3825 {
3826 MSIHANDLE hpkg;
3827 UINT r;
3828 MSIHANDLE hdb;
3829 CHAR prop[MAX_PATH];
3830 DWORD size;
3831 HKEY hkey;
3832 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
3833
3834 hdb = create_package_db();
3835 ok ( hdb, "failed to create package database\n" );
3836
3837 r = create_appsearch_table( hdb );
3838 ok( r == ERROR_SUCCESS, "cannot create AppSearch table: %d\n", r );
3839
3840 r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
3841 ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
3842
3843 r = add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
3844 ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
3845
3846 r = add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
3847 ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
3848
3849 r = create_reglocator_table( hdb );
3850 ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3851
3852 r = add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
3853 ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3854
3855 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
3856 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3857 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
3858 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3859 RegCloseKey(hkey);
3860 r = add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", 1 );
3861 ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3862
3863 r = create_drlocator_table( hdb );
3864 ok( r == ERROR_SUCCESS, "cannot create DrLocator table: %d\n", r );
3865
3866 r = add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
3867 ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
3868
3869 r = create_signature_table( hdb );
3870 ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
3871
3872 r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
3873 ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
3874
3875 r = add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3876 ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
3877
3878 r = add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3879 ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
3880
3881 r = package_from_db( hdb, &hpkg );
3882 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3883 {
3884 skip("Not enough rights to perform tests\n");
3885 DeleteFileA(msifile);
3886 return;
3887 }
3888 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3889 MsiCloseHandle( hdb );
3890 if (r != ERROR_SUCCESS)
3891 goto done;
3892
3893 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3894
3895 r = MsiDoActionA( hpkg, "AppSearch" );
3896 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
3897
3898 size = sizeof(prop);
3899 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
3900 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3901 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3902
3903 size = sizeof(prop);
3904 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
3905 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3906
3907 size = sizeof(prop);
3908 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
3909 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3910 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3911
3912 done:
3913 MsiCloseHandle( hpkg );
3914 DeleteFileA(msifile);
3915 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3916 }
3917
3918 static void test_appsearch_complocator(void)
3919 {
3920 MSIHANDLE hpkg, hdb;
3921 char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH];
3922 LPSTR usersid;
3923 DWORD size;
3924 UINT r;
3925
3926 if (!(usersid = get_user_sid()))
3927 return;
3928
3929 if (is_process_limited())
3930 {
3931 skip("process is limited\n");
3932 return;
3933 }
3934
3935 create_test_file("FileName1");
3936 create_test_file("FileName4");
3937 set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE,
3938 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
3939
3940 create_test_file("FileName2");
3941 set_component_path("FileName2", MSIINSTALLCONTEXT_USERUNMANAGED,
3942 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
3943
3944 create_test_file("FileName3");
3945 set_component_path("FileName3", MSIINSTALLCONTEXT_USERMANAGED,
3946 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
3947
3948 create_test_file("FileName5");
3949 set_component_path("FileName5", MSIINSTALLCONTEXT_MACHINE,
3950 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
3951
3952 create_test_file("FileName6");
3953 set_component_path("FileName6", MSIINSTALLCONTEXT_MACHINE,
3954 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
3955
3956 create_test_file("FileName7");
3957 set_component_path("FileName7", MSIINSTALLCONTEXT_MACHINE,
3958 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
3959
3960 /* dir is FALSE, but we're pretending it's a directory */
3961 set_component_path("IDontExist\\", MSIINSTALLCONTEXT_MACHINE,
3962 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
3963
3964 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
3965 set_component_path("FileName8.dll", MSIINSTALLCONTEXT_MACHINE,
3966 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
3967
3968 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
3969 set_component_path("FileName9.dll", MSIINSTALLCONTEXT_MACHINE,
3970 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
3971
3972 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
3973 set_component_path("FileName10.dll", MSIINSTALLCONTEXT_MACHINE,
3974 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
3975
3976 hdb = create_package_db();
3977 ok(hdb, "Expected a valid database handle\n");
3978
3979 r = create_appsearch_table(hdb);
3980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3981
3982 r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
3983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3984
3985 r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
3986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3987
3988 r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
3989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3990
3991 r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
3992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3993
3994 r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
3995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3996
3997 r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
3998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999
4000 r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4002
4003 r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4005
4006 r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4008
4009 r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4011
4012 r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4014
4015 r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4017
4018 r = create_complocator_table(hdb);
4019 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4020
4021 /* published component, machine, file, signature, misdbLocatorTypeFile */
4022 r = add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4024
4025 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4026 r = add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4028
4029 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4030 r = add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4031 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4032
4033 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4034 r = add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4036
4037 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4038 r = add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4040
4041 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4042 r = add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044
4045 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4046 r = add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4048
4049 /* unpublished component, no signature, misdbLocatorTypeDir */
4050 r = add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4052
4053 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4054 r = add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4056
4057 /* published component, signature w/ ver, misdbLocatorTypeFile */
4058 r = add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4060
4061 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4062 r = add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4064
4065 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4066 r = add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4068
4069 r = create_signature_table(hdb);
4070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4071
4072 r = add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4074
4075 r = add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4077
4078 r = add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4080
4081 r = add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4083
4084 r = add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4086
4087 r = add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4089
4090 r = add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4091 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4092
4093 r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4094 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4095
4096 r = package_from_db(hdb, &hpkg);
4097 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4098 {
4099 skip("Not enough rights to perform tests\n");
4100 goto error;
4101 }
4102 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4103
4104 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4106
4107 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4108
4109 r = MsiDoActionA(hpkg, "AppSearch");
4110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4111
4112 strcpy(expected, CURR_DIR);
4113 if (is_root(CURR_DIR)) expected[2] = 0;
4114
4115 size = MAX_PATH;
4116 sprintf(path, "%s\\FileName1", expected);
4117 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4119 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4120
4121 size = MAX_PATH;
4122 sprintf(path, "%s\\FileName2", expected);
4123 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4125 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4126
4127 size = MAX_PATH;
4128 sprintf(path, "%s\\FileName3", expected);
4129 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4131 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4132
4133 size = MAX_PATH;
4134 sprintf(path, "%s\\FileName4", expected);
4135 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4137 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4138
4139 size = MAX_PATH;
4140 sprintf(path, "%s\\FileName5", expected);
4141 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4143 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4144
4145 size = MAX_PATH;
4146 sprintf(path, "%s\\", expected);
4147 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4148 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4149 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4150
4151 size = MAX_PATH;
4152 sprintf(path, "%s\\", expected);
4153 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4155 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4156
4157 size = MAX_PATH;
4158 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4160 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4161
4162 size = MAX_PATH;
4163 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4165 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4166
4167 size = MAX_PATH;
4168 sprintf(path, "%s\\FileName8.dll", expected);
4169 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4171 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4172
4173 size = MAX_PATH;
4174 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4176 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4177
4178 size = MAX_PATH;
4179 sprintf(path, "%s\\FileName10.dll", expected);
4180 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4182 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4183
4184 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4185 MSIINSTALLCONTEXT_MACHINE, NULL);
4186 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4187 MSIINSTALLCONTEXT_USERUNMANAGED, usersid);
4188 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4189 MSIINSTALLCONTEXT_USERMANAGED, usersid);
4190 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4191 MSIINSTALLCONTEXT_MACHINE, NULL);
4192 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4193 MSIINSTALLCONTEXT_MACHINE, NULL);
4194 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4195 MSIINSTALLCONTEXT_MACHINE, NULL);
4196 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4197 MSIINSTALLCONTEXT_MACHINE, NULL);
4198 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4199 MSIINSTALLCONTEXT_MACHINE, NULL);
4200 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4201 MSIINSTALLCONTEXT_MACHINE, NULL);
4202 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4203 MSIINSTALLCONTEXT_MACHINE, NULL);
4204
4205 MsiCloseHandle(hpkg);
4206
4207 error:
4208 DeleteFileA("FileName1");
4209 DeleteFileA("FileName2");
4210 DeleteFileA("FileName3");
4211 DeleteFileA("FileName4");
4212 DeleteFileA("FileName5");
4213 DeleteFileA("FileName6");
4214 DeleteFileA("FileName7");
4215 DeleteFileA("FileName8.dll");
4216 DeleteFileA("FileName9.dll");
4217 DeleteFileA("FileName10.dll");
4218 DeleteFileA(msifile);
4219 LocalFree(usersid);
4220 }
4221
4222 static void test_appsearch_reglocator(void)
4223 {
4224 MSIHANDLE hpkg, hdb;
4225 char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH];
4226 DWORD binary[2], size, val;
4227 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4228 HKEY hklm, classes, hkcu, users;
4229 LPSTR pathdata, pathvar, ptr;
4230 LPCSTR str;
4231 LONG res;
4232 UINT r, type = 0;
4233 SYSTEM_INFO si;
4234
4235 version = TRUE;
4236 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4237 version = FALSE;
4238
4239 DeleteFileA("test.dll");
4240
4241 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4242 if (res == ERROR_ACCESS_DENIED)
4243 {
4244 skip("Not enough rights to perform tests\n");
4245 return;
4246 }
4247 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4248
4249 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4250 (const BYTE *)"regszdata", 10);
4251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4252
4253 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4255
4256 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4257 (const BYTE *)"regszdata", 10);
4258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4259
4260 users = 0;
4261 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4262 ok(res == ERROR_SUCCESS ||
4263 broken(res == ERROR_INVALID_PARAMETER),
4264 "Expected ERROR_SUCCESS, got %d\n", res);
4265
4266 if (res == ERROR_SUCCESS)
4267 {
4268 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4269 (const BYTE *)"regszdata", 10);
4270 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4271 }
4272
4273 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4275
4276 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4277 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4278
4279 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4280 (const BYTE *)"regszdata", 10);
4281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4282
4283 val = 42;
4284 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4285 (const BYTE *)&val, sizeof(DWORD));
4286 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4287
4288 val = -42;
4289 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4290 (const BYTE *)&val, sizeof(DWORD));
4291 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4292
4293 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4294 (const BYTE *)"%PATH%", 7);
4295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4296
4297 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4298 (const BYTE *)"my%NOVAR%", 10);
4299 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4300
4301 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4302 (const BYTE *)"one\0two\0", 9);
4303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4304
4305 binary[0] = 0x1234abcd;
4306 binary[1] = 0x567890ef;
4307 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4308 (const BYTE *)binary, sizeof(binary));
4309 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4310
4311 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4312 (const BYTE *)"#regszdata", 11);
4313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4314
4315 strcpy(expected, CURR_DIR);
4316 if (is_root(CURR_DIR)) expected[2] = 0;
4317
4318 create_test_file("FileName1");
4319 sprintf(path, "%s\\FileName1", expected);
4320 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4321 (const BYTE *)path, lstrlenA(path) + 1);
4322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4323
4324 sprintf(path, "%s\\FileName2", expected);
4325 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4326 (const BYTE *)path, lstrlenA(path) + 1);
4327 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4328
4329 lstrcpyA(path, expected);
4330 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4331 (const BYTE *)path, lstrlenA(path) + 1);
4332 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4333
4334 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4335 (const BYTE *)"", 1);
4336 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4337
4338 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4339 sprintf(path, "%s\\FileName3.dll", expected);
4340 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4341 (const BYTE *)path, lstrlenA(path) + 1);
4342 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4343
4344 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4345 sprintf(path, "%s\\FileName4.dll", expected);
4346 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4347 (const BYTE *)path, lstrlenA(path) + 1);
4348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4349
4350 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4351 sprintf(path, "%s\\FileName5.dll", expected);
4352 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4353 (const BYTE *)path, lstrlenA(path) + 1);
4354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4355
4356 sprintf(path, "\"%s\\FileName1\" -option", expected);
4357 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4358 (const BYTE *)path, lstrlenA(path) + 1);
4359 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4360
4361 space = strchr(expected, ' ') != NULL;
4362 sprintf(path, "%s\\FileName1 -option", expected);
4363 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4364 (const BYTE *)path, lstrlenA(path) + 1);
4365 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
4366
4367 hdb = create_package_db();
4368 ok(hdb, "Expected a valid database handle\n");
4369
4370 r = create_appsearch_table(hdb);
4371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4372
4373 r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4375
4376 r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4378
4379 r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4381
4382 r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4384
4385 r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4387
4388 r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4390
4391 r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4393
4394 r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4396
4397 r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4399
4400 r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4402
4403 r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4405
4406 r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4408
4409 r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4411
4412 r = add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4414
4415 r = add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4417
4418 r = add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4420
4421 r = add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4423
4424 r = add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4426
4427 r = add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4429
4430 r = add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4432
4433 r = add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4435
4436 r = add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4438
4439 r = add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4441
4442 r = add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4444
4445 r = add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4447
4448 r = add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4450
4451 r = add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4453
4454 r = add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4456
4457 r = add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4459
4460 r = add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4462
4463 r = create_reglocator_table(hdb);
4464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4465
4466 type = msidbLocatorTypeRawValue;
4467 if (is_64bit)
4468 type |= msidbLocatorType64bit;
4469
4470 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4471 r = add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4473
4474 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4475 r = add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4477
4478 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4479 r = add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4481
4482 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4483 r = add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4485
4486 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4487 r = add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4489
4490 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4491 r = add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4492 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4493
4494 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4495 r = add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4497
4498 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4499 r = add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4500 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4501
4502 type = msidbLocatorTypeFileName;
4503 if (is_64bit)
4504 type |= msidbLocatorType64bit;
4505
4506 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4507 r = add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4509
4510 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4511 r = add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4513
4514 /* HKLM, msidbLocatorTypeFileName, no signature */
4515 r = add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4517
4518 type = msidbLocatorTypeDirectory;
4519 if (is_64bit)
4520 type |= msidbLocatorType64bit;
4521
4522 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4523 r = add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4525
4526 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4527 r = add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4529
4530 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4531 r = add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4533
4534 type = msidbLocatorTypeRawValue;
4535 if (is_64bit)
4536 type |= msidbLocatorType64bit;
4537
4538 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4539 r = add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4541
4542 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4543 r = add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4545
4546 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4547 r = add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4549
4550 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4551 r = add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4553
4554 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4555 r = add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4557
4558 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4559 r = add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4561
4562 type = msidbLocatorTypeFileName;
4563 if (is_64bit)
4564 type |= msidbLocatorType64bit;
4565
4566 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4567 r = add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569
4570 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4571 r = add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4573
4574 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4575 r = add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4577
4578 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4579 r = add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4581
4582 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4583 r = add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4585
4586 type = msidbLocatorTypeDirectory;
4587 if (is_64bit)
4588 type |= msidbLocatorType64bit;
4589
4590 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4591 r = add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4593
4594 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4595 r = add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4597
4598 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4599 r = add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4601
4602 type = msidbLocatorTypeFileName;
4603 if (is_64bit)
4604 type |= msidbLocatorType64bit;
4605
4606 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4607 r = add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4609
4610 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4611 r = add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4612 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4613
4614 r = create_signature_table(hdb);
4615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4616
4617 str = "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''";
4618 r = add_signature_entry(hdb, str);
4619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4620
4621 str = "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''";
4622 r = add_signature_entry(hdb, str);
4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4624
4625 str = "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''";
4626 r = add_signature_entry(hdb, str);
4627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4628
4629 str = "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4630 r = add_signature_entry(hdb, str);
4631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4632
4633 str = "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4634 r = add_signature_entry(hdb, str);
4635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4636
4637 str = "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
4638 r = add_signature_entry(hdb, str);
4639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4640
4641 if (!is_root(CURR_DIR))
4642 {
4643 ptr = strrchr(expected, '\\') + 1;
4644 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4645 r = add_signature_entry(hdb, path);
4646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4647 }
4648 str = "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''";
4649 r = add_signature_entry(hdb, str);
4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4651
4652 str = "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''";
4653 r = add_signature_entry(hdb, str);
4654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4655
4656 str = "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''";
4657 r = add_signature_entry(hdb, str);
4658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4659
4660 r = package_from_db(hdb, &hpkg);
4661 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4662
4663 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4664
4665 r = MsiDoActionA(hpkg, "AppSearch");
4666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4667
4668 size = MAX_PATH;
4669 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4671 ok(!lstrcmpA(prop, "regszdata"),
4672 "Expected \"regszdata\", got \"%s\"\n", prop);
4673
4674 size = MAX_PATH;
4675 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4677 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4678
4679 size = MAX_PATH;
4680 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4682 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4683
4684 memset(&si, 0, sizeof(si));
4685 if (pGetNativeSystemInfo) pGetNativeSystemInfo(&si);
4686
4687 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4688 {
4689 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4690 pathvar = HeapAlloc(GetProcessHeap(), 0, size);
4691 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4692
4693 size = 0;
4694 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696
4697 pathdata = HeapAlloc(GetProcessHeap(), 0, ++size);
4698 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4700 ok(!lstrcmpA(pathdata, pathvar),
4701 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4702
4703 HeapFree(GetProcessHeap(), 0, pathvar);
4704 HeapFree(GetProcessHeap(), 0, pathdata);
4705 }
4706
4707 size = MAX_PATH;
4708 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4710 ok(!lstrcmpA(prop,
4711 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4712
4713 size = MAX_PATH;
4714 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4716 todo_wine
4717 {
4718 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4719 "Expected \"\\0one\\0two\\0\\0\"\n");
4720 }
4721
4722 size = MAX_PATH;
4723 lstrcpyA(path, "#xCDAB3412EF907856");
4724 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4726 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4727
4728 size = MAX_PATH;
4729 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4731 ok(!lstrcmpA(prop, "##regszdata"),
4732 "Expected \"##regszdata\", got \"%s\"\n", prop);
4733
4734 size = MAX_PATH;
4735 sprintf(path, "%s\\FileName1", expected);
4736 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4738 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4739
4740 size = MAX_PATH;
4741 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4744
4745 size = MAX_PATH;
4746 sprintf(path, "%s\\", expected);
4747 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4750
4751 size = MAX_PATH;
4752 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4754 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4755
4756 size = MAX_PATH;
4757 sprintf(path, "%s\\", expected);
4758 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4759 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4760 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4761
4762 size = MAX_PATH;
4763 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4765 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4766
4767 size = MAX_PATH;
4768 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4770 ok(!lstrcmpA(prop, "regszdata"),
4771 "Expected \"regszdata\", got \"%s\"\n", prop);
4772
4773 size = MAX_PATH;
4774 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776 ok(!lstrcmpA(prop, "regszdata"),
4777 "Expected \"regszdata\", got \"%s\"\n", prop);
4778
4779 if (users)
4780 {
4781 size = MAX_PATH;
4782 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4784 ok(!lstrcmpA(prop, "regszdata"),
4785 "Expected \"regszdata\", got \"%s\"\n", prop);
4786 }
4787
4788 size = MAX_PATH;
4789 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4791 ok(!lstrcmpA(prop, "defvalue"),
4792 "Expected \"defvalue\", got \"%s\"\n", prop);
4793
4794 size = MAX_PATH;
4795 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4797 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4798
4799 size = MAX_PATH;
4800 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4802 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4803
4804 if (version)
4805 {
4806 size = MAX_PATH;
4807 sprintf(path, "%s\\FileName3.dll", expected);
4808 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4810 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4811
4812 size = MAX_PATH;
4813 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4815 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4816
4817 size = MAX_PATH;
4818 sprintf(path, "%s\\FileName5.dll", expected);
4819 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4821 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4822 }
4823
4824 if (!is_root(CURR_DIR))
4825 {
4826 size = MAX_PATH;
4827 lstrcpyA(path, expected);
4828 ptr = strrchr(path, '\\') + 1;
4829 *ptr = '\0';
4830 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4832 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4833 }
4834 size = MAX_PATH;
4835 sprintf(path, "%s\\", expected);
4836 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4837 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4838 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4839
4840 size = MAX_PATH;
4841 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4843 if (is_root(CURR_DIR))
4844 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4845 else
4846 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4847
4848 size = MAX_PATH;
4849 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4851 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4852
4853 size = MAX_PATH;
4854 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4856 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4857
4858 size = MAX_PATH;
4859 sprintf(path, "%s\\FileName1", expected);
4860 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4862 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4863
4864 size = MAX_PATH;
4865 sprintf(path, "%s\\FileName1", expected);
4866 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4868 if (space)
4869 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4870 else
4871 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4872
4873 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4874 RegDeleteValueA(hklm, "Value1");
4875 RegDeleteValueA(hklm, "Value2");
4876 RegDeleteValueA(hklm, "Value3");
4877 RegDeleteValueA(hklm, "Value4");
4878 RegDeleteValueA(hklm, "Value5");
4879 RegDeleteValueA(hklm, "Value6");
4880 RegDeleteValueA(hklm, "Value7");
4881 RegDeleteValueA(hklm, "Value8");
4882 RegDeleteValueA(hklm, "Value9");
4883 RegDeleteValueA(hklm, "Value10");
4884 RegDeleteValueA(hklm, "Value11");
4885 RegDeleteValueA(hklm, "Value12");
4886 RegDeleteValueA(hklm, "Value13");
4887 RegDeleteValueA(hklm, "Value14");
4888 RegDeleteValueA(hklm, "Value15");
4889 RegDeleteValueA(hklm, "Value16");
4890 RegDeleteValueA(hklm, "Value17");
4891 RegDeleteKeyA(hklm, "");
4892 RegCloseKey(hklm);
4893
4894 RegDeleteValueA(classes, "Value1");
4895 RegDeleteKeyA(classes, "");
4896 RegCloseKey(classes);
4897
4898 RegDeleteValueA(hkcu, "Value1");
4899 RegDeleteKeyA(hkcu, "");
4900 RegCloseKey(hkcu);
4901
4902 RegDeleteValueA(users, "Value1");
4903 RegDeleteKeyA(users, "");
4904 RegCloseKey(users);
4905
4906 DeleteFileA("FileName1");
4907 DeleteFileA("FileName3.dll");
4908 DeleteFileA("FileName4.dll");
4909 DeleteFileA("FileName5.dll");
4910 MsiCloseHandle(hpkg);
4911 DeleteFileA(msifile);
4912 }
4913
4914 static void delete_win_ini(LPCSTR file)
4915 {
4916 CHAR path[MAX_PATH];
4917
4918 GetWindowsDirectoryA(path, MAX_PATH);
4919 lstrcatA(path, "\\");
4920 lstrcatA(path, file);
4921
4922 DeleteFileA(path);
4923 }
4924
4925 static void test_appsearch_inilocator(void)
4926 {
4927 MSIHANDLE hpkg, hdb;
4928 char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH];
4929 BOOL version;
4930 LPCSTR str;
4931 LPSTR ptr;
4932 DWORD size;
4933 UINT r;
4934
4935 version = TRUE;
4936 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4937 version = FALSE;
4938
4939 DeleteFileA("test.dll");
4940
4941 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4942
4943 strcpy(expected, CURR_DIR);
4944 if (is_root(CURR_DIR)) expected[2] = 0;
4945
4946 create_test_file("FileName1");
4947 sprintf(path, "%s\\FileName1", expected);
4948 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4949
4950 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4951
4952 sprintf(path, "%s\\IDontExist", expected);
4953 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4954
4955 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4956 sprintf(path, "%s\\FileName2.dll", expected);
4957 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4958
4959 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4960 sprintf(path, "%s\\FileName3.dll", expected);
4961 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4962
4963 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4964 sprintf(path, "%s\\FileName4.dll", expected);
4965 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4966
4967 hdb = create_package_db();
4968 ok(hdb, "Expected a valid database handle\n");
4969
4970 r = create_appsearch_table(hdb);
4971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4972
4973 r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4975
4976 r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4978
4979 r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4981
4982 r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4984
4985 r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4987
4988 r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4990
4991 r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4993
4994 r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4996
4997 r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4999
5000 r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5002
5003 r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5005
5006 r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
5007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5008
5009 r = create_inilocator_table(hdb);
5010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5011
5012 /* msidbLocatorTypeRawValue, field 1 */
5013 str = "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2";
5014 r = add_inilocator_entry(hdb, str);
5015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5016
5017 /* msidbLocatorTypeRawValue, field 2 */
5018 str = "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2";
5019 r = add_inilocator_entry(hdb, str);
5020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5021
5022 /* msidbLocatorTypeRawValue, entire field */
5023 str = "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2";
5024 r = add_inilocator_entry(hdb, str);
5025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5026
5027 /* msidbLocatorTypeFile */
5028 str = "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1";
5029 r = add_inilocator_entry(hdb, str);
5030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5031
5032 /* msidbLocatorTypeDirectory, file */
5033 str = "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0";
5034 r = add_inilocator_entry(hdb, str);
5035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5036
5037 /* msidbLocatorTypeDirectory, directory */
5038 str = "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0";
5039 r = add_inilocator_entry(hdb, str);
5040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5041
5042 /* msidbLocatorTypeFile, file, no signature */
5043 str = "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1";
5044 r = add_inilocator_entry(hdb, str);
5045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5046
5047 /* msidbLocatorTypeFile, dir, no signature */
5048 str = "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1";
5049 r = add_inilocator_entry(hdb, str);
5050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5051
5052 /* msidbLocatorTypeFile, file does not exist */
5053 str = "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1";
5054 r = add_inilocator_entry(hdb, str);
5055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5056
5057 /* msidbLocatorTypeFile, signature with version */
5058 str = "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1";
5059 r = add_inilocator_entry(hdb, str);
5060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5061
5062 /* msidbLocatorTypeFile, signature with version, ver > max */
5063 str = "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1";
5064 r = add_inilocator_entry(hdb, str);
5065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5066
5067 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
5068 str = "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1";
5069 r = add_inilocator_entry(hdb, str);
5070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5071
5072 r = create_signature_table(hdb);
5073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5074
5075 r = add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
5076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5077
5078 r = add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
5079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5080
5081 r = add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5083
5084 r = add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086
5087 r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5089
5090 r = package_from_db(hdb, &hpkg);
5091 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5092 {
5093 skip("Not enough rights to perform tests\n");
5094 goto error;
5095 }
5096 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5097
5098 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5099
5100 r = MsiDoActionA(hpkg, "AppSearch");
5101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5102
5103 size = MAX_PATH;
5104 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5106 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
5107
5108 size = MAX_PATH;
5109 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5111 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
5112
5113 size = MAX_PATH;
5114 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5116 ok(!lstrcmpA(prop, "keydata,field2"),
5117 "Expected \"keydata,field2\", got \"%s\"\n", prop);
5118
5119 size = MAX_PATH;
5120 sprintf(path, "%s\\FileName1", expected);
5121 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5123 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5124
5125 size = MAX_PATH;
5126 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5128 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5129
5130 size = MAX_PATH;
5131 sprintf(path, "%s\\", expected);
5132 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5134 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5135
5136 size = MAX_PATH;
5137 sprintf(path, "%s\\", expected);
5138 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5140 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5141
5142 if (!is_root(CURR_DIR))
5143 {
5144 size = MAX_PATH;
5145 lstrcpyA(path, expected);
5146 ptr = strrchr(path, '\\');
5147 *(ptr + 1) = 0;
5148 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5150 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5151 }
5152 size = MAX_PATH;
5153 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5155 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5156
5157 if (version)
5158 {
5159 size = MAX_PATH;
5160 sprintf(path, "%s\\FileName2.dll", expected);
5161 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5162 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5163 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5164
5165 size = MAX_PATH;
5166 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5168 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5169
5170 size = MAX_PATH;
5171 sprintf(path, "%s\\FileName4.dll", expected);
5172 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
5173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5174 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5175 }
5176
5177 MsiCloseHandle(hpkg);
5178
5179 error:
5180 delete_win_ini("IniFile.ini");
5181 DeleteFileA("FileName1");
5182 DeleteFileA("FileName2.dll");
5183 DeleteFileA("FileName3.dll");
5184 DeleteFileA("FileName4.dll");
5185 DeleteFileA(msifile);
5186 }
5187
5188 /*
5189 * MSI AppSearch action on DrLocator table always returns absolute paths.
5190 * If a relative path was set, it returns the first absolute path that
5191 * matches or an empty string if it didn't find anything.
5192 * This helper function replicates this behaviour.
5193 */
5194 static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5195 {
5196 int i, size;
5197 DWORD attr, drives;
5198
5199 size = lstrlenA(relative);
5200 drives = GetLogicalDrives();
5201 lstrcpyA(absolute, "A:\\");
5202 for (i = 0; i < 26; absolute[0] = '\0', i++)
5203 {
5204 if (!(drives & (1 << i)))
5205 continue;
5206
5207 absolute[0] = 'A' + i;
5208 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5209 continue;
5210
5211 lstrcpynA(absolute + 3, relative, size + 1);
5212 attr = GetFileAttributesA(absolute);
5213 if (attr != INVALID_FILE_ATTRIBUTES &&
5214 (attr & FILE_ATTRIBUTE_DIRECTORY))
5215 {
5216 if (absolute[3 + size - 1] != '\\')
5217 lstrcatA(absolute, "\\");
5218 break;
5219 }
5220 absolute[3] = '\0';
5221 }
5222 }
5223
5224 static void test_appsearch_drlocator(void)
5225 {
5226 MSIHANDLE hpkg, hdb;
5227 char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH];
5228 BOOL version;
5229 LPCSTR str;
5230 DWORD size;
5231 UINT r;
5232
5233 version = TRUE;
5234 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5235 version = FALSE;
5236
5237 DeleteFileA("test.dll");
5238
5239 create_test_file("FileName1");
5240 CreateDirectoryA("one", NULL);
5241 CreateDirectoryA("one\\two", NULL);
5242 CreateDirectoryA("one\\two\\three", NULL);
5243 create_test_file("one\\two\\three\\FileName2");
5244 CreateDirectoryA("another", NULL);
5245 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5246 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5247 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5248
5249 hdb = create_package_db();
5250 ok(hdb, "Expected a valid database handle\n");
5251
5252 r = create_appsearch_table(hdb);
5253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5254
5255 r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5257
5258 r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5260
5261 r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5263
5264 r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5266
5267 r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5269
5270 r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5272
5273 r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5275
5276 r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5278
5279 r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5281
5282 r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5284
5285 r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5287
5288 r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5290
5291 r = create_drlocator_table(hdb);
5292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5293
5294 strcpy(expected, CURR_DIR);
5295 if (is_root(CURR_DIR)) expected[2] = 0;
5296
5297 /* no parent, full path, depth 0, signature */
5298 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5299 r = add_drlocator_entry(hdb, path);
5300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5301
5302 /* no parent, full path, depth 0, no signature */
5303 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5304 r = add_drlocator_entry(hdb, path);
5305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5306
5307 /* no parent, relative path, depth 0, no signature */
5308 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5309 r = add_drlocator_entry(hdb, path);
5310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5311
5312 /* no parent, full path, depth 2, signature */
5313 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5314 r = add_drlocator_entry(hdb, path);
5315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5316
5317 /* no parent, full path, depth 3, signature */
5318 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5319 r = add_drlocator_entry(hdb, path);
5320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5321
5322 /* no parent, full path, depth 1, signature is dir */
5323 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5324 r = add_drlocator_entry(hdb, path);
5325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5326
5327 /* parent is in DrLocator, relative path, depth 0, signature */
5328 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5329 r = add_drlocator_entry(hdb, path);
5330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5331
5332 /* no parent, full path, depth 0, signature w/ version */
5333 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5334 r = add_drlocator_entry(hdb, path);
5335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5336
5337 /* no parent, full path, depth 0, signature w/ version, ver > max */
5338 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5339 r = add_drlocator_entry(hdb, path);
5340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5341
5342 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5343 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5344 r = add_drlocator_entry(hdb, path);
5345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5346
5347 /* no parent, relative empty path, depth 0, no signature */
5348 sprintf(path, "'NewSignature11', '', '', 0");
5349 r = add_drlocator_entry(hdb, path);
5350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5351
5352 r = create_reglocator_table(hdb);
5353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5354
5355 /* parent */
5356 r = add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5358
5359 /* parent is in RegLocator, no path, depth 0, no signature */
5360 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5361 r = add_drlocator_entry(hdb, path);
5362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5363
5364 r = create_signature_table(hdb);
5365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5366
5367 str = "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''";
5368 r = add_signature_entry(hdb, str);
5369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5370
5371 str = "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''";
5372 r = add_signature_entry(hdb, str);
5373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5374
5375 str = "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''";
5376 r = add_signature_entry(hdb, str);
5377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5378
5379 str = "'NewSignature6', 'another', '', '', '', '', '', '', ''";
5380 r = add_signature_entry(hdb, str);
5381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5382
5383 str = "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''";
5384 r = add_signature_entry(hdb, str);
5385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5386
5387 str = "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5388 r = add_signature_entry(hdb, str);
5389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5390
5391 str = "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5392 r = add_signature_entry(hdb, str);
5393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5394
5395 str = "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''";
5396 r = add_signature_entry(hdb, str);
5397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5398
5399 r = package_from_db(hdb, &hpkg);
5400 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5401 {
5402 skip("Not enough rights to perform tests\n");
5403 goto error;
5404 }
5405 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5406
5407 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5408
5409 r = MsiDoActionA(hpkg, "AppSearch");
5410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5411
5412 size = MAX_PATH;
5413 sprintf(path, "%s\\FileName1", expected);
5414 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5416 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5417
5418 size = MAX_PATH;
5419 sprintf(path, "%s\\", expected);
5420 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5422 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5423
5424 size = MAX_PATH;
5425 search_absolute_directory(path, expected + 3);
5426 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5428 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5429
5430 size = MAX_PATH;
5431 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5433 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5434
5435 size = MAX_PATH;
5436 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5437 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5439 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5440
5441 size = MAX_PATH;
5442 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5444 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5445
5446 size = MAX_PATH;
5447 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5448 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5450 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5451
5452 if (version)
5453 {
5454 size = MAX_PATH;
5455 sprintf(path, "%s\\FileName3.dll", expected);
5456 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5458 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5459
5460 size = MAX_PATH;
5461 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5463 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5464
5465 size = MAX_PATH;
5466 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5467 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5468 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5469 }
5470
5471 size = MAX_PATH;
5472 search_absolute_directory(path, "");
5473 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5475 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5476
5477 size = MAX_PATH;
5478 strcpy(path, "c:\\");
5479 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5481 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5482
5483 MsiCloseHandle(hpkg);
5484
5485 error:
5486 DeleteFileA("FileName1");
5487 DeleteFileA("FileName3.dll");
5488 DeleteFileA("FileName4.dll");
5489 DeleteFileA("FileName5.dll");
5490 DeleteFileA("one\\two\\three\\FileName2");
5491 RemoveDirectoryA("one\\two\\three");
5492 RemoveDirectoryA("one\\two");
5493 RemoveDirectoryA("one");
5494 RemoveDirectoryA("another");
5495 DeleteFileA(msifile);
5496 }
5497
5498 static void test_featureparents(void)
5499 {
5500 MSIHANDLE hpkg;
5501 UINT r;
5502 MSIHANDLE hdb;
5503
5504 hdb = create_package_db();
5505 ok ( hdb, "failed to create package database\n" );
5506
5507 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
5508 ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
5509
5510 r = create_feature_table( hdb );
5511 ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
5512
5513 r = create_component_table( hdb );
5514 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
5515
5516 r = create_feature_components_table( hdb );
5517 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
5518
5519 r = create_file_table( hdb );
5520 ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
5521
5522 /* msidbFeatureAttributesFavorLocal */
5523 r = add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5524 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5525
5526 /* msidbFeatureAttributesFavorSource */
5527 r = add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5528 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5529
5530 /* msidbFeatureAttributesFavorLocal */
5531 r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5532 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5533
5534 /* msidbFeatureAttributesUIDisallowAbsent */
5535 r = add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5536 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5537
5538 /* disabled because of install level */
5539 r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5540 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5541
5542 /* child feature of disabled feature */
5543 r = add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5544 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
5545
5546 /* component of disabled feature (install level) */
5547 r = add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5548 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5549
5550 /* component of disabled child feature (install level) */
5551 r = add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5552 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5553
5554 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5555 r = add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5556 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5557
5558 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5559 r = add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5560 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5561
5562 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5563 r = add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5564 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5565
5566 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5567 r = add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5568 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5569
5570 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5571 r = add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5572 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5573
5574 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5575 r = add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5576 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5577
5578 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5579 r = add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5580 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5581
5582 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5583 r = add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5584 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
5585
5586 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5587 r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5588 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5589
5590 r = add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5591 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5592
5593 r = add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5594 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5595
5596 r = add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5597 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5598
5599 r = add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5600 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5601
5602 r = add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5603 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5604
5605 r = add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5606 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5607
5608 r = add_feature_components_entry( hdb, "'orion', 'leo'" );
5609 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5610
5611 r = add_feature_components_entry( hdb, "'orion', 'virgo'" );
5612 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5613
5614 r = add_feature_components_entry( hdb, "'orion', 'libra'" );
5615 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5616
5617 r = add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5618 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5619
5620 r = add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5621 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5622
5623 r = add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5624 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5625
5626 r = add_feature_components_entry( hdb, "'orion', 'canis'" );
5627 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5628
5629 r = add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5630 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5631
5632 r = add_feature_components_entry( hdb, "'orion', 'lepus'" );
5633 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5634
5635 r = add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5636 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5637
5638 r = add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5639 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
5640
5641 r = add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5642 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5643
5644 r = add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5645 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5646
5647 r = add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5648 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5649
5650 r = add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5651 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5652
5653 r = add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5654 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5655
5656 r = add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5657 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5658
5659 r = add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5660 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5661
5662 r = add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5663 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5664
5665 r = add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5666 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5667
5668 r = add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5669 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5670
5671 r = add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5672 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
5673
5674 r = package_from_db( hdb, &hpkg );
5675 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5676 {
5677 skip("Not enough rights to perform tests\n");
5678 DeleteFileA(msifile);
5679 return;
5680 }
5681 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5682
5683 MsiCloseHandle( hdb );
5684
5685 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5686
5687 r = MsiDoActionA( hpkg, "CostInitialize");
5688 ok( r == ERROR_SUCCESS, "cost init failed\n");
5689
5690 r = MsiDoActionA( hpkg, "FileCost");
5691 ok( r == ERROR_SUCCESS, "file cost failed\n");
5692
5693 r = MsiDoActionA( hpkg, "CostFinalize");
5694 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5695
5696 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5697 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5698 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5699 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5700 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5701 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5702
5703 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5704 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5705 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5706 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5707 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5708 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5709 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5710 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5711 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5712 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5713 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5714
5715 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5716 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5717
5718 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5719 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5720
5721 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5722 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5723
5724 test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, FALSE );
5725 test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, FALSE );
5726 test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5727 test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, FALSE );
5728 test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5729 test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE );
5730
5731 test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5732 test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5733 test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5734 test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, FALSE );
5735 test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5736 test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, FALSE );
5737 test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5738 test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5739 test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5740 test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5741 test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE );
5742
5743 MsiCloseHandle(hpkg);
5744 DeleteFileA(msifile);
5745 }
5746
5747 static void test_installprops(void)
5748 {
5749 MSIHANDLE hpkg, hdb;
5750 CHAR path[MAX_PATH], buf[MAX_PATH];
5751 DWORD size, type;
5752 LANGID langid;
5753 HKEY hkey1, hkey2;
5754 int res;
5755 UINT r;
5756 REGSAM access = KEY_ALL_ACCESS;
5757 SYSTEM_INFO si;
5758 INSTALLUILEVEL uilevel;
5759
5760 if (is_wow64)
5761 access |= KEY_WOW64_64KEY;
5762
5763 lstrcpyA(path, CURR_DIR);
5764 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5765 lstrcatA(path, msifile);
5766
5767 uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
5768
5769 hdb = create_package_db();
5770 ok( hdb, "failed to create database\n");
5771
5772 r = package_from_db(hdb, &hpkg);
5773 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5774 {
5775 skip("Not enough rights to perform tests\n");
5776 MsiSetInternalUI(uilevel, NULL);
5777 DeleteFileA(msifile);
5778 return;
5779 }
5780 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5781
5782 MsiCloseHandle(hdb);
5783
5784 buf[0] = 0;
5785 size = MAX_PATH;
5786 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5787 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5788 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5789
5790 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5791
5792 buf[0] = 0;
5793 size = MAX_PATH;
5794 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5795 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5796 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5797
5798 buf[0] = 0;
5799 size = MAX_PATH;
5800 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5801 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5802 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5803
5804 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5805 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5806
5807 size = MAX_PATH;
5808 type = REG_SZ;
5809 *path = '\0';
5810 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5811 {
5812 size = MAX_PATH;
5813 type = REG_SZ;
5814 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5815 }
5816
5817 buf[0] = 0;
5818 size = MAX_PATH;
5819 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5820 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5821 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5822
5823 size = MAX_PATH;
5824 type = REG_SZ;
5825 *path = '\0';
5826 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5827 {
5828 size = MAX_PATH;
5829 type = REG_SZ;
5830 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5831 }
5832
5833 if (*path)
5834 {
5835 buf[0] = 0;
5836 size = MAX_PATH;
5837 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5838 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5839 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5840 }
5841
5842 buf[0] = 0;
5843 size = MAX_PATH;
5844 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5845 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5846 trace("VersionDatabase = %s\n", buf);
5847
5848 buf[0] = 0;
5849 size = MAX_PATH;
5850 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5851 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5852 trace("VersionMsi = %s\n", buf);
5853
5854 buf[0] = 0;
5855 size = MAX_PATH;
5856 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5857 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5858 trace("Date = %s\n", buf);
5859
5860 buf[0] = 0;
5861 size = MAX_PATH;
5862 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5863 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5864 trace("Time = %s\n", buf);
5865
5866 buf[0] = 0;
5867 size = MAX_PATH;
5868 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5869 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5870 trace("PackageCode = %s\n", buf);
5871
5872 buf[0] = 0;
5873 size = MAX_PATH;
5874 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5875 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5876 trace("ComputerName = %s\n", buf);
5877
5878 langid = GetUserDefaultLangID();
5879 sprintf(path, "%d", langid);
5880
5881 buf[0] = 0;
5882 size = MAX_PATH;
5883 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5884 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5885 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5886
5887 res = GetSystemMetrics(SM_CXSCREEN);
5888 buf[0] = 0;
5889 size = MAX_PATH;
5890 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5891 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5892 ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
5893
5894 res = GetSystemMetrics(SM_CYSCREEN);
5895 buf[0] = 0;
5896 size = MAX_PATH;
5897 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5898 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5899 ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
5900
5901 if (pGetSystemInfo && pSHGetFolderPathA)
5902 {
5903 pGetSystemInfo(&si);
5904 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5905 {
5906 buf[0] = 0;
5907 size = MAX_PATH;
5908 r = MsiGetPropertyA(hpkg, "Intel", buf, &size);
5909 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5910 ok(buf[0], "property not set\n");
5911
5912 buf[0] = 0;
5913 size = MAX_PATH;
5914 r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size);
5915 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5916 ok(buf[0], "property not set\n");
5917
5918 buf[0] = 0;
5919 size = MAX_PATH;
5920 r = MsiGetPropertyA(hpkg, "Msix64", buf, &size);
5921 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5922 ok(buf[0], "property not set\n");
5923
5924 buf[0] = 0;
5925 size = MAX_PATH;
5926 r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size);
5927 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5928 GetSystemDirectoryA(path, MAX_PATH);
5929 if (size) buf[size - 1] = 0;
5930 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5931
5932 buf[0] = 0;
5933 size = MAX_PATH;
5934 r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size);
5935 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5936 pGetSystemWow64DirectoryA(path, MAX_PATH);
5937 if (size) buf[size - 1] = 0;
5938 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5939
5940 buf[0] = 0;
5941 size = MAX_PATH;
5942 r = MsiGetPropertyA(hpkg, "ProgramFiles64Folder", buf, &size);
5943 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5944 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
5945 if (size) buf[size - 1] = 0;
5946 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5947
5948 buf[0] = 0;
5949 size = MAX_PATH;
5950 r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size);
5951 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5952 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
5953 if (size) buf[size - 1] = 0;
5954 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5955
5956 buf[0] = 0;
5957 size = MAX_PATH;
5958 r = MsiGetPropertyA(hpkg, "CommonFiles64Folder", buf, &size);
5959 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5960 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
5961 if (size) buf[size - 1] = 0;
5962 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5963
5964 buf[0] = 0;
5965 size = MAX_PATH;
5966 r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size);
5967 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5968 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
5969 if (size) buf[size - 1] = 0;
5970 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
5971
5972 buf[0] = 0;
5973 size = MAX_PATH;
5974 r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size);
5975 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5976 ok(buf[0], "property not set\n");
5977 }
5978 else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5979 {
5980 if (!is_wow64)
5981 {
5982 buf[0] = 0;
5983 size = MAX_PATH;
5984 r = MsiGetPropertyA(hpkg, "Intel", buf, &size);
5985 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5986 ok(buf[0], "property not set\n");
5987
5988 buf[0] = 0;
5989 size = MAX_PATH;
5990 r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size);
5991 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5992 ok(!buf[0], "property set\n");
5993
5994 buf[0] = 0;
5995 size = MAX_PATH;
5996 r = MsiGetPropertyA(hpkg, "Msix64", buf, &size);
5997 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5998 ok(!buf[0], "property set\n");
5999
6000 buf[0] = 0;
6001 size = MAX_PATH;
6002 r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size);
6003 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6004 ok(!buf[0], "property set\n");
6005
6006 buf[0] = 0;
6007 size = MAX_PATH;
6008 r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size);
6009 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6010 GetSystemDirectoryA(path, MAX_PATH);
6011 if (size) buf[size - 1] = 0;
6012 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6013
6014 buf[0] = 0;
6015 size = MAX_PATH;
6016 r = MsiGetPropertyA(hpkg, "ProgramFiles64Folder", buf, &size);
6017 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6018 ok(!buf[0], "property set\n");
6019
6020 buf[0] = 0;
6021 size = MAX_PATH;
6022 r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size);
6023 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6024 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
6025 if (size) buf[size - 1] = 0;
6026 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6027
6028 buf[0] = 0;
6029 size = MAX_PATH;
6030 r = MsiGetPropertyA(hpkg, "CommonFiles64Folder", buf, &size);
6031 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6032 ok(!buf[0], "property set\n");
6033
6034 buf[0] = 0;
6035 size = MAX_PATH;
6036 r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size);
6037 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6038 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
6039 if (size) buf[size - 1] = 0;
6040 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6041
6042 buf[0] = 0;
6043 size = MAX_PATH;
6044 r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size);
6045 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6046 ok(!buf[0], "property set\n");
6047 }
6048 else
6049 {
6050 buf[0] = 0;
6051 size = MAX_PATH;
6052 r = MsiGetPropertyA(hpkg, "Intel", buf, &size);
6053 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6054 ok(buf[0], "property not set\n");
6055
6056 buf[0] = 0;
6057 size = MAX_PATH;
6058 r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size);
6059 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6060 ok(buf[0], "property not set\n");
6061
6062 buf[0] = 0;
6063 size = MAX_PATH;
6064 r = MsiGetPropertyA(hpkg, "Msix64", buf, &size);
6065 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6066 ok(buf[0], "property not set\n");
6067
6068 buf[0] = 0;
6069 size = MAX_PATH;
6070 r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size);
6071 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6072 GetSystemDirectoryA(path, MAX_PATH);
6073 if (size) buf[size - 1] = 0;
6074 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6075
6076 buf[0] = 0;
6077 size = MAX_PATH;
6078 r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size);
6079 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6080 pGetSystemWow64DirectoryA(path, MAX_PATH);
6081 if (size) buf[size - 1] = 0;
6082 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6083
6084 buf[0] = 0;
6085 size = MAX_PATH;
6086 r = MsiGetPropertyA(hpkg, "ProgramFilesFolder64", buf, &size);
6087 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6088 ok(!buf[0], "property set\n");
6089
6090 buf[0] = 0;
6091 size = MAX_PATH;
6092 r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size);
6093 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6094 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
6095 if (size) buf[size - 1] = 0;
6096 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6097
6098 buf[0] = 0;
6099 size = MAX_PATH;
6100 r = MsiGetPropertyA(hpkg, "CommonFilesFolder64", buf, &size);
6101 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6102 ok(!buf[0], "property set\n");
6103
6104 buf[0] = 0;
6105 size = MAX_PATH;
6106 r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size);
6107 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6108 pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
6109 if (size) buf[size - 1] = 0;
6110 ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
6111
6112 buf[0] = 0;
6113 size = MAX_PATH;
6114 r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size);
6115 ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
6116 ok(buf[0], "property not set\n");
6117 }
6118 }
6119 }
6120
6121 CloseHandle(hkey1);
6122 CloseHandle(hkey2);
6123 MsiCloseHandle(hpkg);
6124 DeleteFileA(msifile);
6125 MsiSetInternalUI(uilevel, NULL);
6126 }
6127
6128 static void test_launchconditions(void)
6129 {
6130 MSIHANDLE hpkg;
6131 MSIHANDLE hdb;
6132 UINT r;
6133
6134 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6135
6136 hdb = create_package_db();
6137 ok( hdb, "failed to create package database\n" );
6138
6139 r = create_launchcondition_table( hdb );
6140 ok( r == ERROR_SUCCESS, "cannot create LaunchCondition table: %d\n", r );
6141
6142 r = add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
6143 ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r );
6144
6145 /* invalid condition */
6146 r = add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
6147 ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r );
6148
6149 r = package_from_db( hdb, &hpkg );
6150 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6151 {
6152 skip("Not enough rights to perform tests\n");
6153 DeleteFileA(msifile);
6154 return;
6155 }
6156 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
6157
6158 MsiCloseHandle( hdb );
6159
6160 r = MsiSetPropertyA( hpkg, "X", "1" );
6161 ok( r == ERROR_SUCCESS, "failed to set property\n" );
6162
6163 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6164
6165 /* invalid conditions are ignored */
6166 r = MsiDoActionA( hpkg, "LaunchConditions" );
6167 ok( r == ERROR_SUCCESS, "cost init failed\n" );
6168
6169 /* verify LaunchConditions still does some verification */
6170 r = MsiSetPropertyA( hpkg, "X", "2" );
6171 ok( r == ERROR_SUCCESS, "failed to set property\n" );
6172
6173 r = MsiDoActionA( hpkg, "LaunchConditions" );
6174 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
6175
6176 MsiCloseHandle( hpkg );
6177 DeleteFileA( msifile );
6178 }
6179
6180 static void test_ccpsearch(void)
6181 {
6182 MSIHANDLE hdb, hpkg;
6183 CHAR prop[MAX_PATH];
6184 DWORD size = MAX_PATH;
6185 UINT r;
6186
6187 hdb = create_package_db();
6188 ok(hdb, "failed to create package database\n");
6189
6190 r = create_ccpsearch_table(hdb);
6191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192
6193 r = add_ccpsearch_entry(hdb, "'CCP_random'");
6194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195
6196 r = add_ccpsearch_entry(hdb, "'RMCCP_random'");
6197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6198
6199 r = create_reglocator_table(hdb);
6200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6201
6202 r = add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
6203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6204
6205 r = create_drlocator_table(hdb);
6206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6207
6208 r = add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
6209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6210
6211 r = create_signature_table(hdb);
6212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6213
6214 r = package_from_db(hdb, &hpkg);
6215 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6216 {
6217 skip("Not enough rights to perform tests\n");
6218 DeleteFileA(msifile);
6219 return;
6220 }
6221 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6222
6223 MsiCloseHandle(hdb);
6224
6225 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6226
6227 r = MsiDoActionA(hpkg, "CCPSearch");
6228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6229
6230 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
6231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6232 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
6233
6234 MsiCloseHandle(hpkg);
6235 DeleteFileA(msifile);
6236 }
6237
6238 static void test_complocator(void)
6239 {
6240 MSIHANDLE hdb, hpkg;
6241 UINT r;
6242 CHAR prop[MAX_PATH];
6243 CHAR expected[MAX_PATH];
6244 DWORD size = MAX_PATH;
6245
6246 hdb = create_package_db();
6247 ok(hdb, "failed to create package database\n");
6248
6249 r = create_appsearch_table(hdb);
6250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6251
6252 r = add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
6253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6254
6255 r = add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
6256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6257
6258 r = add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
6259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6260
6261 r = add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
6262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6263
6264 r = add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
6265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6266
6267 r = add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
6268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6269
6270 r = add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
6271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6272
6273 r = add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
6274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6275
6276 r = add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
6277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6278
6279 r = add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
6280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6281
6282 r = add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
6283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6284
6285 r = add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
6286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6287
6288 r = add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
6289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6290
6291 r = add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
6292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6293
6294 r = add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
6295 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6296
6297 r = add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
6298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6299
6300 r = create_complocator_table(hdb);
6301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6302
6303 r = add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
6304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6305
6306 r = add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
6307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6308
6309 r = add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
6310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6311
6312 r = add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
6313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6314
6315 r = add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
6316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6317
6318 r = add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
6319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6320
6321 r = add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
6322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6323
6324 r = add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
6325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6326
6327 r = add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
6328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6329
6330 r = add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
6331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6332
6333 r = add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
6334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6335
6336 r = add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
6337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6338
6339 r = add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
6340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6341
6342 r = add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
6343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6344
6345 r = add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
6346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6347
6348 r = add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6350
6351 r = create_signature_table(hdb);
6352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6353
6354 r = add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
6355 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6356
6357 r = add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
6358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6359
6360 r = add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
6361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6362
6363 r = add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
6364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6365
6366 r = add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
6367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6368
6369 r = add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
6370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6371
6372 r = add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
6373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6374
6375 r = add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
6376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6377
6378 r = package_from_db(hdb, &hpkg);
6379 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6380 {
6381 skip("Not enough rights to perform tests\n");
6382 DeleteFileA(msifile);
6383 return;
6384 }
6385 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6386
6387 MsiCloseHandle(hdb);
6388
6389 create_test_file("abelisaurus");
6390 create_test_file("bactrosaurus");
6391 create_test_file("camelotia");
6392 create_test_file("diclonius");
6393 create_test_file("echinodon");
6394 create_test_file("falcarius");
6395 create_test_file("gallimimus");
6396 create_test_file("hagryphus");
6397 CreateDirectoryA("iguanodon", NULL);
6398 CreateDirectoryA("jobaria", NULL);
6399 CreateDirectoryA("kakuru", NULL);
6400 CreateDirectoryA("labocania", NULL);
6401 CreateDirectoryA("megaraptor", NULL);
6402 CreateDirectoryA("neosodon", NULL);
6403 CreateDirectoryA("olorotitan", NULL);
6404 CreateDirectoryA("pantydraco", NULL);
6405
6406 set_component_path("abelisaurus", MSIINSTALLCONTEXT_MACHINE,
6407 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
6408 set_component_path("bactrosaurus", MSIINSTALLCONTEXT_MACHINE,
6409 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
6410 set_component_path("echinodon", MSIINSTALLCONTEXT_MACHINE,
6411 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
6412 set_component_path("falcarius", MSIINSTALLCONTEXT_MACHINE,
6413 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
6414 set_component_path("iguanodon", MSIINSTALLCONTEXT_MACHINE,
6415 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
6416 set_component_path("jobaria", MSIINSTALLCONTEXT_MACHINE,
6417 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
6418 set_component_path("megaraptor", MSIINSTALLCONTEXT_MACHINE,
6419 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
6420 set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
6421 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
6422
6423 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6424
6425 r = MsiDoActionA(hpkg, "AppSearch");
6426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6427
6428 size = MAX_PATH;
6429 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
6430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6431
6432 lstrcpyA(expected, CURR_DIR);
6433 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6434 lstrcatA(expected, "abelisaurus");
6435 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6436 "Expected %s or empty string, got %s\n", expected, prop);
6437
6438 size = MAX_PATH;
6439 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
6440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6441 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6442
6443 size = MAX_PATH;
6444 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
6445 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6446 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6447
6448 size = MAX_PATH;
6449 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
6450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6452
6453 size = MAX_PATH;
6454 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
6455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6456
6457 lstrcpyA(expected, CURR_DIR);
6458 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6459 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6460 "Expected %s or empty string, got %s\n", expected, prop);
6461
6462 size = MAX_PATH;
6463 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
6464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6465 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6466
6467 size = MAX_PATH;
6468 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
6469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6470 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6471
6472 size = MAX_PATH;
6473 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
6474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6476
6477 size = MAX_PATH;
6478 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
6479 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6480 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6481
6482 size = MAX_PATH;
6483 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
6484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6486
6487 size = MAX_PATH;
6488 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
6489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6490 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6491
6492 size = MAX_PATH;
6493 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
6494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6495 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6496
6497 size = MAX_PATH;
6498 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6500
6501 lstrcpyA(expected, CURR_DIR);
6502 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6503 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6504 "Expected %s or empty string, got %s\n", expected, prop);
6505
6506 size = MAX_PATH;
6507 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
6508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6509
6510 lstrcpyA(expected, CURR_DIR);
6511 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6512 lstrcatA(expected, "neosodon\\");
6513 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6514 "Expected %s or empty string, got %s\n", expected, prop);
6515
6516 size = MAX_PATH;
6517 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6518 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6519 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6520
6521 size = MAX_PATH;
6522 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6524 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6525
6526 MsiCloseHandle(hpkg);
6527 DeleteFileA("abelisaurus");
6528 DeleteFileA("bactrosaurus");
6529 DeleteFileA("camelotia");
6530 DeleteFileA("diclonius");
6531 DeleteFileA("echinodon");
6532 DeleteFileA("falcarius");
6533 DeleteFileA("gallimimus");
6534 DeleteFileA("hagryphus");
6535 RemoveDirectoryA("iguanodon");
6536 RemoveDirectoryA("jobaria");
6537 RemoveDirectoryA("kakuru");
6538 RemoveDirectoryA("labocania");
6539 RemoveDirectoryA("megaraptor");
6540 RemoveDirectoryA("neosodon");
6541 RemoveDirectoryA("olorotitan");
6542 RemoveDirectoryA("pantydraco");
6543 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6544 MSIINSTALLCONTEXT_MACHINE, NULL);
6545 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6546 MSIINSTALLCONTEXT_MACHINE, NULL);
6547 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6548 MSIINSTALLCONTEXT_MACHINE, NULL);
6549 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6550 MSIINSTALLCONTEXT_MACHINE, NULL);
6551 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6552 MSIINSTALLCONTEXT_MACHINE, NULL);
6553 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6554 MSIINSTALLCONTEXT_MACHINE, NULL);
6555 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6556 MSIINSTALLCONTEXT_MACHINE, NULL);
6557 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6558 MSIINSTALLCONTEXT_MACHINE, NULL);
6559 DeleteFileA(msifile);
6560 }
6561
6562 static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
6563 {
6564 MSIHANDLE summary;
6565 UINT r;
6566
6567 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6569
6570 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6572
6573 r = MsiSummaryInfoPersist(summary);
6574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6575
6576 MsiCloseHandle(summary);
6577 }
6578
6579 static void test_MsiGetSourcePath(void)
6580 {
6581 MSIHANDLE hdb, hpkg;
6582 CHAR path[MAX_PATH];
6583 CHAR cwd[MAX_PATH];
6584 CHAR subsrc[MAX_PATH];
6585 CHAR sub2[MAX_PATH];
6586 DWORD size;
6587 UINT r;
6588
6589 lstrcpyA(cwd, CURR_DIR);
6590 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6591
6592 lstrcpyA(subsrc, cwd);
6593 lstrcatA(subsrc, "subsource");
6594 lstrcatA(subsrc, "\\");
6595
6596 lstrcpyA(sub2, subsrc);
6597 lstrcatA(sub2, "sub2");
6598 lstrcatA(sub2, "\\");
6599
6600 /* uncompressed source */
6601
6602 hdb = create_package_db();
6603 ok( hdb, "failed to create database\n");
6604
6605 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
6606
6607 r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6608 ok(r == S_OK, "failed\n");
6609
6610 r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6611 ok(r == S_OK, "failed\n");
6612
6613 r = add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6614 ok(r == S_OK, "failed\n");
6615
6616 r = MsiDatabaseCommit(hdb);
6617 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6618
6619 r = package_from_db(hdb, &hpkg);
6620 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6621 {
6622 skip("Not enough rights to perform tests\n");
6623 DeleteFileA(msifile);
6624 return;
6625 }
6626 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6627
6628 MsiCloseHandle(hdb);
6629
6630 /* invalid database handle */
6631 size = MAX_PATH;
6632 lstrcpyA(path, "kiwi");
6633 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6634 ok(r == ERROR_INVALID_HANDLE,
6635 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6636 ok(!lstrcmpA(path, "kiwi"),
6637 "Expected path to be unchanged, got \"%s\"\n", path);
6638 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6639
6640 /* NULL szFolder */
6641 size = MAX_PATH;
6642 lstrcpyA(path, "kiwi");
6643 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6644 ok(r == ERROR_INVALID_PARAMETER,
6645 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6646 ok(!lstrcmpA(path, "kiwi"),
6647 "Expected path to be unchanged, got \"%s\"\n", path);
6648 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6649
6650 /* empty szFolder */
6651 size = MAX_PATH;
6652 lstrcpyA(path, "kiwi");
6653 r = MsiGetSourcePathA(hpkg, "", path, &size);
6654 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6655 ok(!lstrcmpA(path, "kiwi"),
6656 "Expected path to be unchanged, got \"%s\"\n", path);
6657 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6658
6659 /* try TARGETDIR */
6660 size = MAX_PATH;
6661 lstrcpyA(path, "kiwi");
6662 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6663 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6664 ok(!lstrcmpA(path, "kiwi"),
6665 "Expected path to be unchanged, got \"%s\"\n", path);
6666 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6667
6668 size = MAX_PATH;
6669 lstrcpyA(path, "kiwi");
6670 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6672 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6673 ok(size == 0, "Expected 0, got %d\n", size);
6674
6675 size = MAX_PATH;
6676 lstrcpyA(path, "kiwi");
6677 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6679 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6680 ok(size == 0, "Expected 0, got %d\n", size);
6681
6682 /* try SourceDir */
6683 size = MAX_PATH;
6684 lstrcpyA(path, "kiwi");
6685 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6686 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6687 ok(!lstrcmpA(path, "kiwi"),
6688 "Expected path to be unchanged, got \"%s\"\n", path);
6689 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6690
6691 /* try SOURCEDIR */
6692 size = MAX_PATH;
6693 lstrcpyA(path, "kiwi");
6694 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6695 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6696 ok(!lstrcmpA(path, "kiwi"),
6697 "Expected path to be unchanged, got \"%s\"\n", path);
6698 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6699
6700 /* source path does not exist, but the property exists */
6701 size = MAX_PATH;
6702 lstrcpyA(path, "kiwi");
6703 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6705 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6706 ok(size == 0, "Expected 0, got %d\n", size);
6707
6708 size = MAX_PATH;
6709 lstrcpyA(path, "kiwi");
6710 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6712 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6713 ok(size == 0, "Expected 0, got %d\n", size);
6714
6715 /* try SubDir */
6716 size = MAX_PATH;
6717 lstrcpyA(path, "kiwi");
6718 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6719 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6720 ok(!lstrcmpA(path, "kiwi"),
6721 "Expected path to be unchanged, got \"%s\"\n", path);
6722 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6723
6724 /* try SubDir2 */
6725 size = MAX_PATH;
6726 lstrcpyA(path, "kiwi");
6727 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6728 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6729 ok(!lstrcmpA(path, "kiwi"),
6730 "Expected path to be unchanged, got \"%s\"\n", path);
6731 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6732
6733 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6734
6735 r = MsiDoActionA(hpkg, "CostInitialize");
6736 ok(r == ERROR_SUCCESS, "cost init failed\n");
6737
6738 /* try TARGETDIR after CostInitialize */
6739 size = MAX_PATH;
6740 lstrcpyA(path, "kiwi");
6741 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6743 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6744 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6745
6746 /* try SourceDir after CostInitialize */
6747 size = MAX_PATH;
6748 lstrcpyA(path, "kiwi");
6749 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6751 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6752 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6753
6754 /* try SOURCEDIR after CostInitialize */
6755 size = MAX_PATH;
6756 lstrcpyA(path, "kiwi");
6757 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6758 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6759 ok(!lstrcmpA(path, "kiwi"),
6760 "Expected path to be unchanged, got \"%s\"\n", path);
6761 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6762
6763 /* source path does not exist, but the property exists */
6764 size = MAX_PATH;
6765 lstrcpyA(path, "kiwi");
6766 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6768 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6769 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6770
6771 size = MAX_PATH;
6772 lstrcpyA(path, "kiwi");
6773 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6775 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6776 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6777
6778 /* try SubDir after CostInitialize */
6779 size = MAX_PATH;
6780 lstrcpyA(path, "kiwi");
6781 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6783 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6784 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6785
6786 /* try SubDir2 after CostInitialize */
6787 size = MAX_PATH;
6788 lstrcpyA(path, "kiwi");
6789 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6791 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6792 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6793
6794 r = MsiDoActionA(hpkg, "ResolveSource");
6795 ok(r == ERROR_SUCCESS, "file cost failed\n");
6796
6797 /* try TARGETDIR after ResolveSource */
6798 size = MAX_PATH;
6799 lstrcpyA(path, "kiwi");
6800 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6802 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6803 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6804
6805 /* try SourceDir after ResolveSource */
6806 size = MAX_PATH;
6807 lstrcpyA(path, "kiwi");
6808 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6810 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6811 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6812
6813 /* try SOURCEDIR after ResolveSource */
6814 size = MAX_PATH;
6815 lstrcpyA(path, "kiwi");
6816 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6817 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6818 ok(!lstrcmpA(path, "kiwi"),
6819 "Expected path to be unchanged, got \"%s\"\n", path);
6820 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6821
6822 /* source path does not exist, but the property exists */
6823 size = MAX_PATH;
6824 lstrcpyA(path, "kiwi");
6825 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6827 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6828 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6829
6830 size = MAX_PATH;
6831 lstrcpyA(path, "kiwi");
6832 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6834 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6835 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6836
6837 /* try SubDir after ResolveSource */
6838 size = MAX_PATH;
6839 lstrcpyA(path, "kiwi");
6840 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6842 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6843 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6844
6845 /* try SubDir2 after ResolveSource */
6846 size = MAX_PATH;
6847 lstrcpyA(path, "kiwi");
6848 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6850 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6851 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6852
6853 r = MsiDoActionA(hpkg, "FileCost");
6854 ok(r == ERROR_SUCCESS, "file cost failed\n");
6855
6856 /* try TARGETDIR after FileCost */
6857 size = MAX_PATH;
6858 lstrcpyA(path, "kiwi");
6859 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6861 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6862 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6863
6864 /* try SourceDir after FileCost */
6865 size = MAX_PATH;
6866 lstrcpyA(path, "kiwi");
6867 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6869 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6870 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6871
6872 /* try SOURCEDIR after FileCost */
6873 size = MAX_PATH;
6874 lstrcpyA(path, "kiwi");
6875 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6876 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6877 ok(!lstrcmpA(path, "kiwi"),
6878 "Expected path to be unchanged, got \"%s\"\n", path);
6879 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6880
6881 /* source path does not exist, but the property exists */
6882 size = MAX_PATH;
6883 lstrcpyA(path, "kiwi");
6884 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6886 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6887 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6888
6889 size = MAX_PATH;
6890 lstrcpyA(path, "kiwi");
6891 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6892 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6893 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6894 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6895
6896 /* try SubDir after FileCost */
6897 size = MAX_PATH;
6898 lstrcpyA(path, "kiwi");
6899 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6901 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6902 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6903
6904 /* try SubDir2 after FileCost */
6905 size = MAX_PATH;
6906 lstrcpyA(path, "kiwi");
6907 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6909 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6910 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6911
6912 r = MsiDoActionA(hpkg, "CostFinalize");
6913 ok(r == ERROR_SUCCESS, "file cost failed\n");
6914
6915 /* try TARGETDIR after CostFinalize */
6916 size = MAX_PATH;
6917 lstrcpyA(path, "kiwi");
6918 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6919 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6920 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6921 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6922
6923 /* try SourceDir after CostFinalize */
6924 size = MAX_PATH;
6925 lstrcpyA(path, "kiwi");
6926 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6928 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6929 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6930
6931 /* try SOURCEDIR after CostFinalize */
6932 size = MAX_PATH;
6933 lstrcpyA(path, "kiwi");
6934 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6935 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6936 ok(!lstrcmpA(path, "kiwi"),
6937 "Expected path to be unchanged, got \"%s\"\n", path);
6938 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6939
6940 /* source path does not exist, but the property exists */
6941 size = MAX_PATH;
6942 lstrcpyA(path, "kiwi");
6943 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6946 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6947
6948 size = MAX_PATH;
6949 lstrcpyA(path, "kiwi");
6950 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6951 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6952 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6953 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6954
6955 /* try SubDir after CostFinalize */
6956 size = MAX_PATH;
6957 lstrcpyA(path, "kiwi");
6958 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6960 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6961 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
6962
6963 /* try SubDir2 after CostFinalize */
6964 size = MAX_PATH;
6965 lstrcpyA(path, "kiwi");
6966 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6968 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6969 ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size);
6970
6971 /* nonexistent directory */
6972 size = MAX_PATH;
6973 lstrcpyA(path, "kiwi");
6974 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6975 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6976 ok(!lstrcmpA(path, "kiwi"),
6977 "Expected path to be unchanged, got \"%s\"\n", path);
6978 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
6979
6980 /* NULL szPathBuf */
6981 size = MAX_PATH;
6982 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6984 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
6985
6986 /* NULL pcchPathBuf */
6987 lstrcpyA(path, "kiwi");
6988 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6989 ok(r == ERROR_INVALID_PARAMETER,
6990 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6991 ok(!lstrcmpA(path, "kiwi"),
6992 "Expected path to be unchanged, got \"%s\"\n", path);
6993
6994 /* pcchPathBuf is 0 */
6995 size = 0;
6996 lstrcpyA(path, "kiwi");
6997 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6998 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6999 ok(!lstrcmpA(path, "kiwi"),
7000 "Expected path to be unchanged, got \"%s\"\n", path);
7001 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7002
7003 /* pcchPathBuf does not have room for NULL terminator */
7004 size = lstrlenA(cwd);
7005 lstrcpyA(path, "kiwi");
7006 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7007 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7008 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
7009 "Expected path with no backslash, got \"%s\"\n", path);
7010 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7011
7012 /* pcchPathBuf has room for NULL terminator */
7013 size = lstrlenA(cwd) + 1;
7014 lstrcpyA(path, "kiwi");
7015 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7017 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7018 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7019
7020 /* remove property */
7021 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
7022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7023
7024 /* try SourceDir again */
7025 size = MAX_PATH;
7026 lstrcpyA(path, "kiwi");
7027 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7029 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7030 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7031
7032 /* set property to a valid directory */
7033 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
7034 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7035
7036 /* try SOURCEDIR again */
7037 size = MAX_PATH;
7038 lstrcpyA(path, "kiwi");
7039 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7040 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7041 ok(!lstrcmpA(path, "kiwi"),
7042 "Expected path to be unchanged, got \"%s\"\n", path);
7043 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7044
7045 MsiCloseHandle(hpkg);
7046
7047 /* compressed source */
7048
7049 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
7050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7051
7052 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
7053
7054 r = package_from_db(hdb, &hpkg);
7055 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7056
7057 /* try TARGETDIR */
7058 size = MAX_PATH;
7059 lstrcpyA(path, "kiwi");
7060 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
7061 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7062 ok(!lstrcmpA(path, "kiwi"),
7063 "Expected path to be unchanged, got \"%s\"\n", path);
7064 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7065
7066 /* try SourceDir */
7067 size = MAX_PATH;
7068 lstrcpyA(path, "kiwi");
7069 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7070 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7071 ok(!lstrcmpA(path, "kiwi"),
7072 "Expected path to be unchanged, got \"%s\"\n", path);
7073 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7074
7075 /* try SOURCEDIR */
7076 size = MAX_PATH;
7077 lstrcpyA(path, "kiwi");
7078 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7079 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7080 ok(!lstrcmpA(path, "kiwi"),
7081 "Expected path to be unchanged, got \"%s\"\n", path);
7082 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7083
7084 /* source path nor the property exist */
7085 size = MAX_PATH;
7086 lstrcpyA(path, "kiwi");
7087 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7089 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7090 ok(size == 0, "Expected 0, got %d\n", size);
7091
7092 size = MAX_PATH;
7093 lstrcpyA(path, "kiwi");
7094 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7096 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7097 ok(size == 0, "Expected 0, got %d\n", size);
7098
7099 /* try SubDir */
7100 size = MAX_PATH;
7101 lstrcpyA(path, "kiwi");
7102 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7103 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7104 ok(!lstrcmpA(path, "kiwi"),
7105 "Expected path to be unchanged, got \"%s\"\n", path);
7106 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7107
7108 /* try SubDir2 */
7109 size = MAX_PATH;
7110 lstrcpyA(path, "kiwi");
7111 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7112 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7113 ok(!lstrcmpA(path, "kiwi"),
7114 "Expected path to be unchanged, got \"%s\"\n", path);
7115 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7116
7117 r = MsiDoActionA(hpkg, "CostInitialize");
7118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7119
7120 /* try TARGETDIR after CostInitialize */
7121 size = MAX_PATH;
7122 lstrcpyA(path, "kiwi");
7123 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
7124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7125 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7126 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7127
7128 /* try SourceDir after CostInitialize */
7129 size = MAX_PATH;
7130 lstrcpyA(path, "kiwi");
7131 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7133 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7134 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7135
7136 /* try SOURCEDIR after CostInitialize */
7137 size = MAX_PATH;
7138 lstrcpyA(path, "kiwi");
7139 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7140 todo_wine
7141 {
7142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7143 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7144 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7145 }
7146
7147 /* source path does not exist, but the property exists */
7148 size = MAX_PATH;
7149 lstrcpyA(path, "kiwi");
7150 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7152 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7153 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7154
7155 size = MAX_PATH;
7156 lstrcpyA(path, "kiwi");
7157 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7159 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7160 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7161
7162 /* try SubDir after CostInitialize */
7163 size = MAX_PATH;
7164 lstrcpyA(path, "kiwi");
7165 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7167 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7168 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7169
7170 /* try SubDir2 after CostInitialize */
7171 size = MAX_PATH;
7172 lstrcpyA(path, "kiwi");
7173 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7175 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7176 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7177
7178 r = MsiDoActionA(hpkg, "ResolveSource");
7179 ok(r == ERROR_SUCCESS, "file cost failed\n");
7180
7181 /* try TARGETDIR after ResolveSource */
7182 size = MAX_PATH;
7183 lstrcpyA(path, "kiwi");
7184 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
7185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7186 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7187 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7188
7189 /* try SourceDir after ResolveSource */
7190 size = MAX_PATH;
7191 lstrcpyA(path, "kiwi");
7192 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7194 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7195 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7196
7197 /* try SOURCEDIR after ResolveSource */
7198 size = MAX_PATH;
7199 lstrcpyA(path, "kiwi");
7200 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7201 todo_wine
7202 {
7203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7204 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7205 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7206 }
7207
7208 /* source path and the property exist */
7209 size = MAX_PATH;
7210 lstrcpyA(path, "kiwi");
7211 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7213 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7214 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7215
7216 size = MAX_PATH;
7217 lstrcpyA(path, "kiwi");
7218 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7220 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7221 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7222
7223 /* try SubDir after ResolveSource */
7224 size = MAX_PATH;
7225 lstrcpyA(path, "kiwi");
7226 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7228 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7229 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7230
7231 /* try SubDir2 after ResolveSource */
7232 size = MAX_PATH;
7233 lstrcpyA(path, "kiwi");
7234 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7235 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7236 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7237 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7238
7239 r = MsiDoActionA(hpkg, "FileCost");
7240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7241
7242 /* try TARGETDIR after CostFinalize */
7243 size = MAX_PATH;
7244 lstrcpyA(path, "kiwi");
7245 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
7246 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7247 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7248 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7249
7250 /* try SourceDir after CostFinalize */
7251 size = MAX_PATH;
7252 lstrcpyA(path, "kiwi");
7253 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7255 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7256 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7257
7258 /* try SOURCEDIR after CostFinalize */
7259 size = MAX_PATH;
7260 lstrcpyA(path, "kiwi");
7261 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7262 todo_wine
7263 {
7264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7265 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7266 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7267 }
7268
7269 /* source path and the property exist */
7270 size = MAX_PATH;
7271 lstrcpyA(path, "kiwi");
7272 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7274 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7275 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7276
7277 size = MAX_PATH;
7278 lstrcpyA(path, "kiwi");
7279 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7281 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7282 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7283
7284 /* try SubDir after CostFinalize */
7285 size = MAX_PATH;
7286 lstrcpyA(path, "kiwi");
7287 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7289 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7290 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7291
7292 /* try SubDir2 after CostFinalize */
7293 size = MAX_PATH;
7294 lstrcpyA(path, "kiwi");
7295 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7297 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7298 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7299
7300 r = MsiDoActionA(hpkg, "CostFinalize");
7301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7302
7303 /* try TARGETDIR after CostFinalize */
7304 size = MAX_PATH;
7305 lstrcpyA(path, "kiwi");
7306 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
7307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7308 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7309 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7310
7311 /* try SourceDir after CostFinalize */
7312 size = MAX_PATH;
7313 lstrcpyA(path, "kiwi");
7314 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7316 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7317 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7318
7319 /* try SOURCEDIR after CostFinalize */
7320 size = MAX_PATH;
7321 lstrcpyA(path, "kiwi");
7322 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7323 todo_wine
7324 {
7325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7326 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7327 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7328 }
7329
7330 /* source path and the property exist */
7331 size = MAX_PATH;
7332 lstrcpyA(path, "kiwi");
7333 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7335 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7336 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7337
7338 size = MAX_PATH;
7339 lstrcpyA(path, "kiwi");
7340 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7342 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7343 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7344
7345 /* try SubDir after CostFinalize */
7346 size = MAX_PATH;
7347 lstrcpyA(path, "kiwi");
7348 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7350 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7351 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7352
7353 /* try SubDir2 after CostFinalize */
7354 size = MAX_PATH;
7355 lstrcpyA(path, "kiwi");
7356 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7358 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7359 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7360
7361 MsiCloseHandle(hpkg);
7362 DeleteFileA(msifile);
7363 }
7364
7365 static void test_shortlongsource(void)
7366 {
7367 MSIHANDLE hdb, hpkg;
7368 CHAR path[MAX_PATH];
7369 CHAR cwd[MAX_PATH];
7370 CHAR subsrc[MAX_PATH];
7371 DWORD size;
7372 UINT r;
7373
7374 lstrcpyA(cwd, CURR_DIR);
7375 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7376
7377 lstrcpyA(subsrc, cwd);
7378 lstrcatA(subsrc, "long");
7379 lstrcatA(subsrc, "\\");
7380
7381 /* long file names */
7382
7383 hdb = create_package_db();
7384 ok( hdb, "failed to create database\n");
7385
7386 set_suminfo_prop(hdb, PID_WORDCOUNT, 0);
7387
7388 r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7389 ok(r == S_OK, "failed\n");
7390
7391 r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
7392 ok(r == S_OK, "failed\n");
7393
7394 /* CostInitialize:short */
7395 r = add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
7396 ok(r == S_OK, "failed\n");
7397
7398 /* CostInitialize:long */
7399 r = add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
7400 ok(r == S_OK, "failed\n");
7401
7402 /* FileCost:short */
7403 r = add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
7404 ok(r == S_OK, "failed\n");
7405
7406 /* FileCost:long */
7407 r = add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
7408 ok(r == S_OK, "failed\n");
7409
7410 /* CostFinalize:short */
7411 r = add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
7412 ok(r == S_OK, "failed\n");
7413
7414 /* CostFinalize:long */
7415 r = add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
7416 ok(r == S_OK, "failed\n");
7417
7418 MsiDatabaseCommit(hdb);
7419
7420 r = package_from_db(hdb, &hpkg);
7421 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7422 {
7423 skip("Not enough rights to perform tests\n");
7424 DeleteFileA(msifile);
7425 return;
7426 }
7427 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7428
7429 MsiCloseHandle(hdb);
7430
7431 CreateDirectoryA("one", NULL);
7432 CreateDirectoryA("four", NULL);
7433
7434 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7435
7436 r = MsiDoActionA(hpkg, "CostInitialize");
7437 ok(r == ERROR_SUCCESS, "file cost failed\n");
7438
7439 CreateDirectoryA("five", NULL);
7440 CreateDirectoryA("eight", NULL);
7441
7442 r = MsiDoActionA(hpkg, "FileCost");
7443 ok(r == ERROR_SUCCESS, "file cost failed\n");
7444
7445 CreateDirectoryA("nine", NULL);
7446 CreateDirectoryA("twelve", NULL);
7447
7448 r = MsiDoActionA(hpkg, "CostFinalize");
7449 ok(r == ERROR_SUCCESS, "file cost failed\n");
7450
7451 /* neither short nor long source directories exist */
7452 size = MAX_PATH;
7453 lstrcpyA(path, "kiwi");
7454 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7456 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7457 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7458
7459 CreateDirectoryA("short", NULL);
7460
7461 /* short source directory exists */
7462 size = MAX_PATH;
7463 lstrcpyA(path, "kiwi");
7464 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7466 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7467 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7468
7469 CreateDirectoryA("long", NULL);
7470
7471 /* both short and long source directories exist */
7472 size = MAX_PATH;
7473 lstrcpyA(path, "kiwi");
7474 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7475 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7476 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7477 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7478
7479 lstrcpyA(subsrc, cwd);
7480 lstrcatA(subsrc, "two");
7481 lstrcatA(subsrc, "\\");
7482
7483 /* short dir exists before CostInitialize */
7484 size = MAX_PATH;
7485 lstrcpyA(path, "kiwi");
7486 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7488 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7489 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7490
7491 lstrcpyA(subsrc, cwd);
7492 lstrcatA(subsrc, "four");
7493 lstrcatA(subsrc, "\\");
7494
7495 /* long dir exists before CostInitialize */
7496 size = MAX_PATH;
7497 lstrcpyA(path, "kiwi");
7498 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7500 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7501 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7502
7503 lstrcpyA(subsrc, cwd);
7504 lstrcatA(subsrc, "six");
7505 lstrcatA(subsrc, "\\");
7506
7507 /* short dir exists before FileCost */
7508 size = MAX_PATH;
7509 lstrcpyA(path, "kiwi");
7510 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7512 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7513 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7514
7515 lstrcpyA(subsrc, cwd);
7516 lstrcatA(subsrc, "eight");
7517 lstrcatA(subsrc, "\\");
7518
7519 /* long dir exists before FileCost */
7520 size = MAX_PATH;
7521 lstrcpyA(path, "kiwi");
7522 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7524 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7525 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7526
7527 lstrcpyA(subsrc, cwd);
7528 lstrcatA(subsrc, "ten");
7529 lstrcatA(subsrc, "\\");
7530
7531 /* short dir exists before CostFinalize */
7532 size = MAX_PATH;
7533 lstrcpyA(path, "kiwi");
7534 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7536 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7537 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7538
7539 lstrcpyA(subsrc, cwd);
7540 lstrcatA(subsrc, "twelve");
7541 lstrcatA(subsrc, "\\");
7542
7543 /* long dir exists before CostFinalize */
7544 size = MAX_PATH;
7545 lstrcpyA(path, "kiwi");
7546 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7548 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7549 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7550
7551 MsiCloseHandle(hpkg);
7552 RemoveDirectoryA("short");
7553 RemoveDirectoryA("long");
7554 RemoveDirectoryA("one");
7555 RemoveDirectoryA("four");
7556 RemoveDirectoryA("five");
7557 RemoveDirectoryA("eight");
7558 RemoveDirectoryA("nine");
7559 RemoveDirectoryA("twelve");
7560
7561 /* short file names */
7562
7563 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb);
7564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7565
7566 set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
7567
7568 r = package_from_db(hdb, &hpkg);
7569 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7570
7571 MsiCloseHandle(hdb);
7572
7573 CreateDirectoryA("one", NULL);
7574 CreateDirectoryA("four", NULL);
7575
7576 r = MsiDoActionA(hpkg, "CostInitialize");
7577 ok(r == ERROR_SUCCESS, "file cost failed\n");
7578
7579 CreateDirectoryA("five", NULL);
7580 CreateDirectoryA("eight", NULL);
7581
7582 r = MsiDoActionA(hpkg, "FileCost");
7583 ok(r == ERROR_SUCCESS, "file cost failed\n");
7584
7585 CreateDirectoryA("nine", NULL);
7586 CreateDirectoryA("twelve", NULL);
7587
7588 r = MsiDoActionA(hpkg, "CostFinalize");
7589 ok(r == ERROR_SUCCESS, "file cost failed\n");
7590
7591 lstrcpyA(subsrc, cwd);
7592 lstrcatA(subsrc, "short");
7593 lstrcatA(subsrc, "\\");
7594
7595 /* neither short nor long source directories exist */
7596 size = MAX_PATH;
7597 lstrcpyA(path, "kiwi");
7598 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7600 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7601 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7602
7603 CreateDirectoryA("short", NULL);
7604
7605 /* short source directory exists */
7606 size = MAX_PATH;
7607 lstrcpyA(path, "kiwi");
7608 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7610 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7611 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7612
7613 CreateDirectoryA("long", NULL);
7614
7615 /* both short and long source directories exist */
7616 size = MAX_PATH;
7617 lstrcpyA(path, "kiwi");
7618 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7620 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7621 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7622
7623 lstrcpyA(subsrc, cwd);
7624 lstrcatA(subsrc, "one");
7625 lstrcatA(subsrc, "\\");
7626
7627 /* short dir exists before CostInitialize */
7628 size = MAX_PATH;
7629 lstrcpyA(path, "kiwi");
7630 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7632 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7633 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7634
7635 lstrcpyA(subsrc, cwd);
7636 lstrcatA(subsrc, "three");
7637 lstrcatA(subsrc, "\\");
7638
7639 /* long dir exists before CostInitialize */
7640 size = MAX_PATH;
7641 lstrcpyA(path, "kiwi");
7642 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7644 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7645 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7646
7647 lstrcpyA(subsrc, cwd);
7648 lstrcatA(subsrc, "five");
7649 lstrcatA(subsrc, "\\");
7650
7651 /* short dir exists before FileCost */
7652 size = MAX_PATH;
7653 lstrcpyA(path, "kiwi");
7654 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7656 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7657 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7658
7659 lstrcpyA(subsrc, cwd);
7660 lstrcatA(subsrc, "seven");
7661 lstrcatA(subsrc, "\\");
7662
7663 /* long dir exists before FileCost */
7664 size = MAX_PATH;
7665 lstrcpyA(path, "kiwi");
7666 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7668 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7669 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7670
7671 lstrcpyA(subsrc, cwd);
7672 lstrcatA(subsrc, "nine");
7673 lstrcatA(subsrc, "\\");
7674
7675 /* short dir exists before CostFinalize */
7676 size = MAX_PATH;
7677 lstrcpyA(path, "kiwi");
7678 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7680 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7681 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7682
7683 lstrcpyA(subsrc, cwd);
7684 lstrcatA(subsrc, "eleven");
7685 lstrcatA(subsrc, "\\");
7686
7687 /* long dir exists before CostFinalize */
7688 size = MAX_PATH;
7689 lstrcpyA(path, "kiwi");
7690 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7692 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7693 ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size);
7694
7695 MsiCloseHandle(hpkg);
7696 RemoveDirectoryA("short");
7697 RemoveDirectoryA("long");
7698 RemoveDirectoryA("one");
7699 RemoveDirectoryA("four");
7700 RemoveDirectoryA("five");
7701 RemoveDirectoryA("eight");
7702 RemoveDirectoryA("nine");
7703 RemoveDirectoryA("twelve");
7704 DeleteFileA(msifile);
7705 }
7706
7707 static void test_sourcedir(void)
7708 {
7709 MSIHANDLE hdb, hpkg;
7710 CHAR package[12];
7711 CHAR path[MAX_PATH];
7712 CHAR cwd[MAX_PATH];
7713 CHAR subsrc[MAX_PATH];
7714 DWORD size;
7715 UINT r;
7716
7717 lstrcpyA(cwd, CURR_DIR);
7718 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7719
7720 lstrcpyA(subsrc, cwd);
7721 lstrcatA(subsrc, "long");
7722 lstrcatA(subsrc, "\\");
7723
7724 hdb = create_package_db();
7725 ok( hdb, "failed to create database\n");
7726
7727 r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7728 ok(r == S_OK, "failed\n");
7729
7730 sprintf(package, "#%u", hdb);
7731 r = MsiOpenPackageA(package, &hpkg);
7732 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7733 {
7734 skip("Not enough rights to perform tests\n");
7735 goto error;
7736 }
7737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7738
7739 /* properties only */
7740
7741 /* SourceDir prop */
7742 size = MAX_PATH;
7743 lstrcpyA(path, "kiwi");
7744 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7746 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7747 ok(size == 0, "Expected 0, got %d\n", size);
7748
7749 /* SOURCEDIR prop */
7750 size = MAX_PATH;
7751 lstrcpyA(path, "kiwi");
7752 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7754 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7755 ok(size == 0, "Expected 0, got %d\n", size);
7756
7757 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7758
7759 r = MsiDoActionA(hpkg, "CostInitialize");
7760 ok(r == ERROR_SUCCESS, "file cost failed\n");
7761
7762 /* SourceDir after CostInitialize */
7763 size = MAX_PATH;
7764 lstrcpyA(path, "kiwi");
7765 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7767 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7768 ok(size == 0, "Expected 0, got %d\n", size);
7769
7770 /* SOURCEDIR after CostInitialize */
7771 size = MAX_PATH;
7772 lstrcpyA(path, "kiwi");
7773 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7775 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7776 ok(size == 0, "Expected 0, got %d\n", size);
7777
7778 r = MsiDoActionA(hpkg, "FileCost");
7779 ok(r == ERROR_SUCCESS, "file cost failed\n");
7780
7781 /* SourceDir after FileCost */
7782 size = MAX_PATH;
7783 lstrcpyA(path, "kiwi");
7784 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7786 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7787 ok(size == 0, "Expected 0, got %d\n", size);
7788
7789 /* SOURCEDIR after FileCost */
7790 size = MAX_PATH;
7791 lstrcpyA(path, "kiwi");
7792 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7794 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7795 ok(size == 0, "Expected 0, got %d\n", size);
7796
7797 r = MsiDoActionA(hpkg, "CostFinalize");
7798 ok(r == ERROR_SUCCESS, "file cost failed\n");
7799
7800 /* SourceDir after CostFinalize */
7801 size = MAX_PATH;
7802 lstrcpyA(path, "kiwi");
7803 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7805 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7806 ok(size == 0, "Expected 0, got %d\n", size);
7807
7808 /* SOURCEDIR after CostFinalize */
7809 size = MAX_PATH;
7810 lstrcpyA(path, "kiwi");
7811 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7813 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7814 ok(size == 0, "Expected 0, got %d\n", size);
7815
7816 size = MAX_PATH;
7817 lstrcpyA(path, "kiwi");
7818 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7819 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7820 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7821 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
7822
7823 /* SOURCEDIR after calling MsiGetSourcePath */
7824 size = MAX_PATH;
7825 lstrcpyA(path, "kiwi");
7826 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7828 todo_wine {
7829 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7830 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7831 }
7832
7833 r = MsiDoActionA(hpkg, "ResolveSource");
7834 ok(r == ERROR_SUCCESS, "file cost failed\n");
7835
7836 /* SourceDir after ResolveSource */
7837 size = MAX_PATH;
7838 lstrcpyA(path, "kiwi");
7839 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7840 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7841 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7842 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7843
7844 /* SOURCEDIR after ResolveSource */
7845 size = MAX_PATH;
7846 lstrcpyA(path, "kiwi");
7847 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7849 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7850 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7851
7852 /* random casing */
7853 size = MAX_PATH;
7854 lstrcpyA(path, "kiwi");
7855 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7857 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7858 ok(size == 0, "Expected 0, got %d\n", size);
7859
7860 MsiCloseHandle(hpkg);
7861
7862 /* reset the package state */
7863 sprintf(package, "#%i", hdb);
7864 r = MsiOpenPackageA(package, &hpkg);
7865 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7866
7867 /* test how MsiGetSourcePath affects the properties */
7868
7869 /* SourceDir prop */
7870 size = MAX_PATH;
7871 lstrcpyA(path, "kiwi");
7872 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7873 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7874 todo_wine
7875 {
7876 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7877 ok(size == 0, "Expected 0, got %d\n", size);
7878 }
7879
7880 size = MAX_PATH;
7881 lstrcpyA(path, "kiwi");
7882 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7883 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7884 ok(!lstrcmpA(path, "kiwi"),
7885 "Expected path to be unchanged, got \"%s\"\n", path);
7886 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7887
7888 /* SourceDir after MsiGetSourcePath */
7889 size = MAX_PATH;
7890 lstrcpyA(path, "kiwi");
7891 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7892 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7893 todo_wine
7894 {
7895 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7896 ok(size == 0, "Expected 0, got %d\n", size);
7897 }
7898
7899 /* SOURCEDIR prop */
7900 size = MAX_PATH;
7901 lstrcpyA(path, "kiwi");
7902 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7904 todo_wine
7905 {
7906 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7907 ok(size == 0, "Expected 0, got %d\n", size);
7908 }
7909
7910 size = MAX_PATH;
7911 lstrcpyA(path, "kiwi");
7912 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7913 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7914 ok(!lstrcmpA(path, "kiwi"),
7915 "Expected path to be unchanged, got \"%s\"\n", path);
7916 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7917
7918 /* SOURCEDIR prop after MsiGetSourcePath */
7919 size = MAX_PATH;
7920 lstrcpyA(path, "kiwi");
7921 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7922 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7923 todo_wine
7924 {
7925 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7926 ok(size == 0, "Expected 0, got %d\n", size);
7927 }
7928
7929 r = MsiDoActionA(hpkg, "CostInitialize");
7930 ok(r == ERROR_SUCCESS, "file cost failed\n");
7931
7932 /* SourceDir after CostInitialize */
7933 size = MAX_PATH;
7934 lstrcpyA(path, "kiwi");
7935 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7937 todo_wine
7938 {
7939 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7940 ok(size == 0, "Expected 0, got %d\n", size);
7941 }
7942
7943 size = MAX_PATH;
7944 lstrcpyA(path, "kiwi");
7945 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7947 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7948 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7949
7950 /* SourceDir after MsiGetSourcePath */
7951 size = MAX_PATH;
7952 lstrcpyA(path, "kiwi");
7953 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7955 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7956 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7957
7958 /* SOURCEDIR after CostInitialize */
7959 size = MAX_PATH;
7960 lstrcpyA(path, "kiwi");
7961 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7963 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7964 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7965
7966 /* SOURCEDIR source path still does not exist */
7967 size = MAX_PATH;
7968 lstrcpyA(path, "kiwi");
7969 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7970 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7971 ok(!lstrcmpA(path, "kiwi"),
7972 "Expected path to be unchanged, got \"%s\"\n", path);
7973 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7974
7975 r = MsiDoActionA(hpkg, "FileCost");
7976 ok(r == ERROR_SUCCESS, "file cost failed\n");
7977
7978 /* SourceDir after FileCost */
7979 size = MAX_PATH;
7980 lstrcpyA(path, "kiwi");
7981 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7983 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7984 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7985
7986 /* SOURCEDIR after FileCost */
7987 size = MAX_PATH;
7988 lstrcpyA(path, "kiwi");
7989 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7991 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7992 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
7993
7994 /* SOURCEDIR source path still does not exist */
7995 size = MAX_PATH;
7996 lstrcpyA(path, "kiwi");
7997 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7998 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7999 ok(!lstrcmpA(path, "kiwi"),
8000 "Expected path to be unchanged, got \"%s\"\n", path);
8001 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8002
8003 r = MsiDoActionA(hpkg, "CostFinalize");
8004 ok(r == ERROR_SUCCESS, "file cost failed\n");
8005
8006 /* SourceDir after CostFinalize */
8007 size = MAX_PATH;
8008 lstrcpyA(path, "kiwi");
8009 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
8010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8011 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
8012 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
8013
8014 /* SOURCEDIR after CostFinalize */
8015 size = MAX_PATH;
8016 lstrcpyA(path, "kiwi");
8017 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
8018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8019 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
8020 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
8021
8022 /* SOURCEDIR source path still does not exist */
8023 size = MAX_PATH;
8024 lstrcpyA(path, "kiwi");
8025 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
8026 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
8027 ok(!lstrcmpA(path, "kiwi"),
8028 "Expected path to be unchanged, got \"%s\"\n", path);
8029 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8030
8031 r = MsiDoActionA(hpkg, "ResolveSource");
8032 ok(r == ERROR_SUCCESS, "file cost failed\n");
8033
8034 /* SourceDir after ResolveSource */
8035 size = MAX_PATH;
8036 lstrcpyA(path, "kiwi");
8037 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
8038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8039 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
8040 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
8041
8042 /* SOURCEDIR after ResolveSource */
8043 size = MAX_PATH;
8044 lstrcpyA(path, "kiwi");
8045 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
8046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8047 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
8048 ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
8049
8050 /* SOURCEDIR source path still does not exist */
8051 size = MAX_PATH;
8052 lstrcpyA(path, "kiwi");
8053 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
8054 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
8055 ok(!lstrcmpA(path, "kiwi"),
8056 "Expected path to be unchanged, got \"%s\"\n", path);
8057 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8058
8059 MsiCloseHandle(hpkg);
8060
8061 error:
8062 MsiCloseHandle(hdb);
8063 DeleteFileA(msifile);
8064 }
8065
8066 struct access_res
8067 {
8068 BOOL gothandle;
8069 DWORD lasterr;
8070 BOOL ignore;
8071 };
8072
8073 static const struct access_res create[16] =
8074 {
8075 { TRUE, ERROR_SUCCESS, TRUE },
8076 { TRUE, ERROR_SUCCESS, TRUE },
8077 { TRUE, ERROR_SUCCESS, FALSE },
8078 { TRUE, ERROR_SUCCESS, FALSE },
8079 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8080 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8081 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8082 { TRUE, ERROR_SUCCESS, FALSE },
8083 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8084 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8085 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8086 { TRUE, ERROR_SUCCESS, TRUE },
8087 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8088 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8089 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8090 { TRUE, ERROR_SUCCESS, TRUE }
8091 };
8092
8093 static const struct access_res create_commit[16] =
8094 {
8095 { TRUE, ERROR_SUCCESS, TRUE },
8096 { TRUE, ERROR_SUCCESS, TRUE },
8097 { TRUE, ERROR_SUCCESS, FALSE },
8098 { TRUE, ERROR_SUCCESS, FALSE },
8099 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8100 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8101 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8102 { TRUE, ERROR_SUCCESS, FALSE },
8103 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8104 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8105 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8106 { TRUE, ERROR_SUCCESS, TRUE },
8107 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8108 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8109 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
8110 { TRUE, ERROR_SUCCESS, TRUE }
8111 };
8112
8113 static const struct access_res create_close[16] =
8114 {
8115 { TRUE, ERROR_SUCCESS, FALSE },
8116 { TRUE, ERROR_SUCCESS, FALSE },
8117 { TRUE, ERROR_SUCCESS, FALSE },
8118 { TRUE, ERROR_SUCCESS, FALSE },
8119 { TRUE, ERROR_SUCCESS, FALSE },
8120 { TRUE, ERROR_SUCCESS, FALSE },
8121 { TRUE, ERROR_SUCCESS, FALSE },
8122 { TRUE, ERROR_SUCCESS, FALSE },
8123 { TRUE, ERROR_SUCCESS, FALSE },
8124 { TRUE, ERROR_SUCCESS, FALSE },
8125 { TRUE, ERROR_SUCCESS, FALSE },
8126 { TRUE, ERROR_SUCCESS, FALSE },
8127 { TRUE, ERROR_SUCCESS, FALSE },
8128 { TRUE, ERROR_SUCCESS, FALSE },
8129 { TRUE, ERROR_SUCCESS, FALSE },
8130 { TRUE, ERROR_SUCCESS }
8131 };
8132
8133 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
8134 {
8135 DWORD access = 0, share = 0;
8136 DWORD lasterr;
8137 HANDLE hfile;
8138 int i, j, idx = 0;
8139
8140 for (i = 0; i < 4; i++)
8141 {
8142 if (i == 0) access = 0;
8143 if (i == 1) access = GENERIC_READ;
8144 if (i == 2) access = GENERIC_WRITE;
8145 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
8146
8147 for (j = 0; j < 4; j++)
8148 {
8149 if (ares[idx].ignore)
8150 continue;
8151
8152 if (j == 0) share = 0;
8153 if (j == 1) share = FILE_SHARE_READ;
8154 if (j == 2) share = FILE_SHARE_WRITE;
8155 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
8156
8157 SetLastError(0xdeadbeef);
8158 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
8159 FILE_ATTRIBUTE_NORMAL, 0);
8160 lasterr = GetLastError();
8161
8162 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
8163 "(%d, handle, %d): Expected %d, got %d\n",
8164 line, idx, ares[idx].gothandle,
8165 (hfile != INVALID_HANDLE_VALUE));
8166
8167 ok(lasterr == ares[idx].lasterr, "(%d, lasterr, %d): Expected %d, got %d\n",
8168 line, idx, ares[idx].lasterr, lasterr);
8169
8170 CloseHandle(hfile);
8171 idx++;
8172 }
8173 }
8174 }
8175
8176 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
8177
8178 static void test_access(void)
8179 {
8180 MSIHANDLE hdb;
8181 UINT r;
8182
8183 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
8184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8185
8186 test_file_access(msifile, create);
8187
8188 r = MsiDatabaseCommit(hdb);
8189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8190
8191 test_file_access(msifile, create_commit);
8192 MsiCloseHandle(hdb);
8193
8194 test_file_access(msifile, create_close);
8195 DeleteFileA(msifile);
8196
8197 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
8198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8199
8200 test_file_access(msifile, create);
8201
8202 r = MsiDatabaseCommit(hdb);
8203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8204
8205 test_file_access(msifile, create_commit);
8206 MsiCloseHandle(hdb);
8207
8208 test_file_access(msifile, create_close);
8209 DeleteFileA(msifile);
8210 }
8211
8212 static void test_emptypackage(void)
8213 {
8214 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
8215 MSIHANDLE hview = 0, hrec = 0;
8216 MSICONDITION condition;
8217 CHAR buffer[MAX_PATH];
8218 DWORD size;
8219 UINT r;
8220
8221 r = MsiOpenPackageA("", &hpkg);
8222 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8223 {
8224 skip("Not enough rights to perform tests\n");
8225 return;
8226 }
8227 todo_wine
8228 {
8229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8230 }
8231
8232 hdb = MsiGetActiveDatabase(hpkg);
8233 todo_wine
8234 {
8235 ok(hdb != 0, "Expected a valid database handle\n");
8236 }
8237
8238 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
8239 todo_wine
8240 {
8241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8242 }
8243 r = MsiViewExecute(hview, 0);
8244 todo_wine
8245 {
8246 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8247 }
8248
8249 r = MsiViewFetch(hview, &hrec);
8250 todo_wine
8251 {
8252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8253 }
8254
8255 buffer[0] = 0;
8256 size = MAX_PATH;
8257 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
8258 todo_wine
8259 {
8260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8261 ok(!lstrcmpA(buffer, "_Property"),
8262 "Expected \"_Property\", got \"%s\"\n", buffer);
8263 }
8264
8265 MsiCloseHandle(hrec);
8266
8267 r = MsiViewFetch(hview, &hrec);
8268 todo_wine
8269 {
8270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8271 }
8272
8273 size = MAX_PATH;
8274 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
8275 todo_wine
8276 {
8277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278 ok(!lstrcmpA(buffer, "#_FolderCache"),
8279 "Expected \"_Property\", got \"%s\"\n", buffer);
8280 }
8281
8282 MsiCloseHandle(hrec);
8283 MsiViewClose(hview);
8284 MsiCloseHandle(hview);
8285
8286 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
8287 todo_wine
8288 {
8289 ok(condition == MSICONDITION_FALSE,
8290 "Expected MSICONDITION_FALSE, got %d\n", condition);
8291 }
8292
8293 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
8294 todo_wine
8295 {
8296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8297 }
8298 r = MsiViewExecute(hview, 0);
8299 todo_wine
8300 {
8301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8302 }
8303
8304 /* _Property table is not empty */
8305 r = MsiViewFetch(hview, &hrec);
8306 todo_wine
8307 {
8308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8309 }
8310
8311 MsiCloseHandle(hrec);
8312 MsiViewClose(hview);
8313 MsiCloseHandle(hview);
8314
8315 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
8316 todo_wine
8317 {
8318 ok(condition == MSICONDITION_FALSE,
8319 "Expected MSICONDITION_FALSE, got %d\n", condition);
8320 }
8321
8322 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
8323 todo_wine
8324 {
8325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8326 }
8327 r = MsiViewExecute(hview, 0);
8328 todo_wine
8329 {
8330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8331 }
8332
8333 /* #_FolderCache is not empty */
8334 r = MsiViewFetch(hview, &hrec);
8335 todo_wine
8336 {
8337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8338 }
8339
8340 MsiCloseHandle(hrec);
8341 MsiViewClose(hview);
8342 MsiCloseHandle(hview);
8343
8344 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
8345 todo_wine
8346 {
8347 ok(r == ERROR_BAD_QUERY_SYNTAX,
8348 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8349 }
8350
8351 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
8352 todo_wine
8353 {
8354 ok(r == ERROR_BAD_QUERY_SYNTAX,
8355 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8356 }
8357
8358 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
8359 todo_wine
8360 {
8361 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
8362 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
8363 }
8364
8365 MsiCloseHandle(hsuminfo);
8366
8367 r = MsiDatabaseCommit(hdb);
8368 todo_wine
8369 {
8370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8371 }
8372
8373 MsiCloseHandle(hdb);
8374 MsiCloseHandle(hpkg);
8375 }
8376
8377 static void test_MsiGetProductProperty(void)
8378 {
8379 static const WCHAR prodcode_propW[] = {'P','r','o','d','u','c','t','C','o','d','e',0};
8380 static const WCHAR nonexistentW[] = {'I','D','o','n','t','E','x','i','s','t',0};
8381 static const WCHAR newpropW[] = {'N','e','w','P','r','o','p','e','r','t','y',0};
8382 static const WCHAR appleW[] = {'a','p','p','l','e',0};
8383 static const WCHAR emptyW[] = {0};
8384 WCHAR valW[MAX_PATH];
8385 MSIHANDLE hprod, hdb;
8386 CHAR val[MAX_PATH];
8387 CHAR path[MAX_PATH];
8388 CHAR query[MAX_PATH];
8389 CHAR keypath[MAX_PATH*2];
8390 CHAR prodcode[MAX_PATH];
8391 WCHAR prodcodeW[MAX_PATH];
8392 CHAR prod_squashed[MAX_PATH];
8393 WCHAR prod_squashedW[MAX_PATH];
8394 HKEY prodkey, userkey, props;
8395 DWORD size;
8396 LONG res;
8397 UINT r;
8398 REGSAM access = KEY_ALL_ACCESS;
8399
8400 GetCurrentDirectoryA(MAX_PATH, path);
8401 lstrcatA(path, "\\");
8402
8403 create_test_guid(prodcode, prod_squashed);
8404 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
8405 squash_guid(prodcodeW, prod_squashedW);
8406
8407 if (is_wow64)
8408 access |= KEY_WOW64_64KEY;
8409
8410 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
8411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8412
8413 r = MsiDatabaseCommit(hdb);
8414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8415
8416 r = set_summary_info(hdb);
8417 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8418
8419 r = run_query(hdb,
8420 "CREATE TABLE `Directory` ( "
8421 "`Directory` CHAR(255) NOT NULL, "
8422 "`Directory_Parent` CHAR(255), "
8423 "`DefaultDir` CHAR(255) NOT NULL "
8424 "PRIMARY KEY `Directory`)");
8425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8426
8427 r = run_query(hdb,
8428 "CREATE TABLE `Property` ( "
8429 "`Property` CHAR(72) NOT NULL, "
8430 "`Value` CHAR(255) "
8431 "PRIMARY KEY `Property`)");
8432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8433
8434 sprintf(query, "INSERT INTO `Property` "
8435 "(`Property`, `Value`) "
8436 "VALUES( 'ProductCode', '%s' )", prodcode);
8437 r = run_query(hdb, query);
8438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8439
8440 r = MsiDatabaseCommit(hdb);
8441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8442
8443 MsiCloseHandle(hdb);
8444
8445 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8446 lstrcatA(keypath, prod_squashed);
8447
8448 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8449 if (res == ERROR_ACCESS_DENIED)
8450 {
8451 skip("Not enough rights to perform tests\n");
8452 DeleteFileA(msifile);
8453 return;
8454 }
8455 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8456
8457 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8458 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8459 lstrcatA(keypath, prod_squashed);
8460
8461 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8462 if (res == ERROR_ACCESS_DENIED)
8463 {
8464 skip("Not enough rights to perform tests\n");
8465 RegDeleteKeyA(prodkey, "");
8466 RegCloseKey(prodkey);
8467 return;
8468 }
8469 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8470
8471 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8472 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8473
8474 lstrcpyA(val, path);
8475 lstrcatA(val, "\\");
8476 lstrcatA(val, msifile);
8477 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8478 (const BYTE *)val, lstrlenA(val) + 1);
8479 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8480
8481 hprod = 0xdeadbeef;
8482 r = MsiOpenProductA(prodcode, &hprod);
8483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8484 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8485
8486 /* hProduct is invalid */
8487 size = MAX_PATH;
8488 lstrcpyA(val, "apple");
8489 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
8490 ok(r == ERROR_INVALID_HANDLE,
8491 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8492 ok(!lstrcmpA(val, "apple"),
8493 "Expected val to be unchanged, got \"%s\"\n", val);
8494 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8495
8496 size = MAX_PATH;
8497 lstrcpyW(valW, appleW);
8498 r = MsiGetProductPropertyW(0xdeadbeef, prodcode_propW, valW, &size);
8499 ok(r == ERROR_INVALID_HANDLE,
8500 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8501 ok(!lstrcmpW(valW, appleW),
8502 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8503 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8504
8505 /* szProperty is NULL */
8506 size = MAX_PATH;
8507 lstrcpyA(val, "apple");
8508 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
8509 ok(r == ERROR_INVALID_PARAMETER,
8510 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8511 ok(!lstrcmpA(val, "apple"),
8512 "Expected val to be unchanged, got \"%s\"\n", val);
8513 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8514
8515 size = MAX_PATH;
8516 lstrcpyW(valW, appleW);
8517 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
8518 ok(r == ERROR_INVALID_PARAMETER,
8519 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8520 ok(!lstrcmpW(valW, appleW),
8521 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8522 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8523
8524 /* szProperty is empty */
8525 size = MAX_PATH;
8526 lstrcpyA(val, "apple");
8527 r = MsiGetProductPropertyA(hprod, "", val, &size);
8528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8529 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8530 ok(size == 0, "Expected 0, got %d\n", size);
8531
8532 size = MAX_PATH;
8533 lstrcpyW(valW, appleW);
8534 r = MsiGetProductPropertyW(hprod, emptyW, valW, &size);
8535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8536 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8537 ok(size == 0, "Expected 0, got %d\n", size);
8538
8539 /* get the property */
8540 size = MAX_PATH;
8541 lstrcpyA(val, "apple");
8542 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8544 ok(!lstrcmpA(val, prodcode),
8545 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8546 ok(size == lstrlenA(prodcode),
8547 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8548
8549 size = MAX_PATH;
8550 lstrcpyW(valW, appleW);
8551 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size);
8552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8553 ok(!lstrcmpW(valW, prodcodeW),
8554 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8555 ok(size == lstrlenW(prodcodeW),
8556 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8557
8558 /* lpValueBuf is NULL */
8559 size = MAX_PATH;
8560 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8562 ok(size == lstrlenA(prodcode),
8563 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8564
8565 size = MAX_PATH;
8566 r = MsiGetProductPropertyW(hprod, prodcode_propW, NULL, &size);
8567 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8568 ok(size == lstrlenW(prodcodeW),
8569 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8570
8571 /* pcchValueBuf is NULL */
8572 lstrcpyA(val, "apple");
8573 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8574 ok(r == ERROR_INVALID_PARAMETER,
8575 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8576 ok(!lstrcmpA(val, "apple"),
8577 "Expected val to be unchanged, got \"%s\"\n", val);
8578 ok(size == lstrlenA(prodcode),
8579 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8580
8581 lstrcpyW(valW, appleW);
8582 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, NULL);
8583 ok(r == ERROR_INVALID_PARAMETER,
8584 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8585 ok(!lstrcmpW(valW, appleW),
8586 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8587 ok(size == lstrlenW(prodcodeW),
8588 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8589
8590 /* pcchValueBuf is too small */
8591 size = 4;
8592 lstrcpyA(val, "apple");
8593 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8594 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8595 ok(!strncmp(val, prodcode, 3),
8596 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8597 ok(size == lstrlenA(prodcode),
8598 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8599
8600 size = 4;
8601 lstrcpyW(valW, appleW);
8602 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size);
8603 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8604 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8605 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8606 ok(size == lstrlenW(prodcodeW),
8607 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8608
8609 /* pcchValueBuf does not leave room for NULL terminator */
8610 size = lstrlenA(prodcode);
8611 lstrcpyA(val, "apple");
8612 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8613 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8614 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8615 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8616 ok(size == lstrlenA(prodcode),
8617 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8618
8619 size = lstrlenW(prodcodeW);
8620 lstrcpyW(valW, appleW);
8621 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size);
8622 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8623 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8624 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8625 ok(size == lstrlenW(prodcodeW),
8626 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8627
8628 /* pcchValueBuf has enough room for NULL terminator */
8629 size = lstrlenA(prodcode) + 1;
8630 lstrcpyA(val, "apple");
8631 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8633 ok(!lstrcmpA(val, prodcode),
8634 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8635 ok(size == lstrlenA(prodcode),
8636 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8637
8638 size = lstrlenW(prodcodeW) + 1;
8639 lstrcpyW(valW, appleW);
8640 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size);
8641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8642 ok(!lstrcmpW(valW, prodcodeW),
8643 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8644 ok(size == lstrlenW(prodcodeW),
8645 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8646
8647 /* nonexistent property */
8648 size = MAX_PATH;
8649 lstrcpyA(val, "apple");
8650 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8652 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8653 ok(size == 0, "Expected 0, got %d\n", size);
8654
8655 size = MAX_PATH;
8656 lstrcpyW(valW, appleW);
8657 r = MsiGetProductPropertyW(hprod, nonexistentW, valW, &size);
8658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8659 ok(!lstrcmpW(valW, emptyW), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8660 ok(size == 0, "Expected 0, got %d\n", size);
8661
8662 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8664
8665 /* non-product property set */
8666 size = MAX_PATH;
8667 lstrcpyA(val, "apple");
8668 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8670 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8671 ok(size == 0, "Expected 0, got %d\n", size);
8672
8673 size = MAX_PATH;
8674 lstrcpyW(valW, appleW);
8675 r = MsiGetProductPropertyW(hprod, newpropW, valW, &size);
8676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8677 ok(!lstrcmpW(valW, emptyW), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8678 ok(size == 0, "Expected 0, got %d\n", size);
8679
8680 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8682
8683 /* non-product property that is also a product property set */
8684 size = MAX_PATH;
8685 lstrcpyA(val, "apple");
8686 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8688 ok(!lstrcmpA(val, prodcode),
8689 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8690 ok(size == lstrlenA(prodcode),
8691 "Expected %d, got %d\n", lstrlenA(prodcode), size);
8692
8693 size = MAX_PATH;
8694 lstrcpyW(valW, appleW);
8695 r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size);
8696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8697 ok(!lstrcmpW(valW, prodcodeW),
8698 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8699 ok(size == lstrlenW(prodcodeW),
8700 "Expected %d, got %d\n", lstrlenW(prodcodeW), size);
8701
8702 MsiCloseHandle(hprod);
8703
8704 RegDeleteValueA(props, "LocalPackage");
8705 delete_key(props, "", access);
8706 RegCloseKey(props);
8707 delete_key(userkey, "", access);
8708 RegCloseKey(userkey);
8709 delete_key(prodkey, "", access);
8710 RegCloseKey(prodkey);
8711 DeleteFileA(msifile);
8712 }
8713
8714 static void test_MsiSetProperty(void)
8715 {
8716 MSIHANDLE hpkg, hdb, hrec;
8717 CHAR buf[MAX_PATH];
8718 LPCSTR query;
8719 DWORD size;
8720 UINT r;
8721
8722 r = package_from_db(create_package_db(), &hpkg);
8723 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8724 {
8725 skip("Not enough rights to perform tests\n");
8726 DeleteFileA(msifile);
8727 return;
8728 }
8729 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8730
8731 /* invalid hInstall */
8732 r = MsiSetPropertyA(0, "Prop", "Val");
8733 ok(r == ERROR_INVALID_HANDLE,
8734 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8735
8736 /* invalid hInstall */
8737 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8738 ok(r == ERROR_INVALID_HANDLE,
8739 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8740
8741 /* szName is NULL */
8742 r = MsiSetPropertyA(hpkg, NULL, "Val");
8743 ok(r == ERROR_INVALID_PARAMETER,
8744 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8745
8746 /* both szName and szValue are NULL */
8747 r = MsiSetPropertyA(hpkg, NULL, NULL);
8748 ok(r == ERROR_INVALID_PARAMETER,
8749 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8750
8751 /* szName is empty */
8752 r = MsiSetPropertyA(hpkg, "", "Val");
8753 ok(r == ERROR_FUNCTION_FAILED,
8754 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8755
8756 /* szName is empty and szValue is NULL */
8757 r = MsiSetPropertyA(hpkg, "", NULL);
8758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8759
8760 /* set a property */
8761 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8763
8764 /* get the property */
8765 size = MAX_PATH;
8766 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8768 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8769 ok(size == 3, "Expected 3, got %d\n", size);
8770
8771 /* update the property */
8772 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8774
8775 /* get the property */
8776 size = MAX_PATH;
8777 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8778 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8779 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8780 ok(size == 4, "Expected 4, got %d\n", size);
8781
8782 hdb = MsiGetActiveDatabase(hpkg);
8783 ok(hdb != 0, "Expected a valid database handle\n");
8784
8785 /* set prop is not in the _Property table */
8786 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8787 r = do_query(hdb, query, &hrec);
8788 ok(r == ERROR_BAD_QUERY_SYNTAX,
8789 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8790
8791 /* set prop is not in the Property table */
8792 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8793 r = do_query(hdb, query, &hrec);
8794 ok(r == ERROR_BAD_QUERY_SYNTAX,
8795 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8796
8797 MsiCloseHandle(hdb);
8798
8799 /* szValue is an empty string */
8800 r = MsiSetPropertyA(hpkg, "Prop", "");
8801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8802
8803 /* try to get the property */
8804 size = MAX_PATH;
8805 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8807 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8808 ok(size == 0, "Expected 0, got %d\n", size);
8809
8810 /* reset the property */
8811 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8813
8814 /* delete the property */
8815 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8817
8818 /* try to get the property */
8819 size = MAX_PATH;
8820 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8821 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8822 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8823 ok(size == 0, "Expected 0, got %d\n", size);
8824
8825 MsiCloseHandle(hpkg);
8826 DeleteFileA(msifile);
8827 }
8828
8829 static void test_MsiApplyMultiplePatches(void)
8830 {
8831 UINT r, type = GetDriveTypeW(NULL);
8832
8833 r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
8834 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8835
8836 r = MsiApplyMultiplePatchesA("", NULL, NULL);
8837 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8838
8839 r = MsiApplyMultiplePatchesA(";", NULL, NULL);
8840 if (type == DRIVE_FIXED)
8841 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8842 else
8843 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8844
8845 r = MsiApplyMultiplePatchesA(" ;", NULL, NULL);
8846 if (type == DRIVE_FIXED)
8847 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8848 else
8849 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8850
8851 r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
8852 if (type == DRIVE_FIXED)
8853 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8854 else
8855 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8856
8857 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8858 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8859
8860 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8861 if (type == DRIVE_FIXED)
8862 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8863 else
8864 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8865
8866 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8867 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8868
8869 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8870 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8871 }
8872
8873 static void test_MsiApplyPatch(void)
8874 {
8875 UINT r;
8876
8877 r = MsiApplyPatchA(NULL, NULL, INSTALLTYPE_DEFAULT, NULL);
8878 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8879
8880 r = MsiApplyPatchA("", NULL, INSTALLTYPE_DEFAULT, NULL);
8881 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8882 }
8883
8884 static void test_MsiEnumComponentCosts(void)
8885 {
8886 MSIHANDLE hdb, hpkg;
8887 char package[12], drive[3];
8888 DWORD len;
8889 UINT r;
8890 int cost, temp;
8891
8892 hdb = create_package_db();
8893 ok( hdb, "failed to create database\n" );
8894
8895 r = create_property_table( hdb );
8896 ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r );
8897
8898 r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8899 ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
8900
8901 r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8902 ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
8903
8904 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8905 ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r );
8906
8907 r = create_media_table( hdb );
8908 ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r );
8909
8910 r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8911 ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r );
8912
8913 r = create_file_table( hdb );
8914 ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r );
8915
8916 r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8917 ok( r == ERROR_SUCCESS, "cannot add file %u\n", r );
8918
8919 r = create_component_table( hdb );
8920 ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r );
8921
8922 r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8923 ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
8924
8925 r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8926 ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
8927
8928 r = create_feature_table( hdb );
8929 ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r );
8930
8931 r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8932 ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
8933
8934 r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8935 ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
8936
8937 r = create_feature_components_table( hdb );
8938 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r );
8939
8940 r = add_feature_components_entry( hdb, "'one', 'one'" );
8941 ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
8942
8943 r = add_feature_components_entry( hdb, "'two', 'two'" );
8944 ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
8945
8946 r = create_install_execute_sequence_table( hdb );
8947 ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r );
8948
8949 r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8950 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8951
8952 r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8953 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8954
8955 r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8956 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8957
8958 r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8959 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
8960
8961 MsiDatabaseCommit( hdb );
8962
8963 sprintf( package, "#%u", hdb );
8964 r = MsiOpenPackageA( package, &hpkg );
8965 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8966 {
8967 skip("Not enough rights to perform tests\n");
8968 goto error;
8969 }
8970 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8971
8972 r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8973 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8974
8975 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8976 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8977
8978 r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8979 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8980
8981 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8982 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8983
8984 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
8985 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8986
8987 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8988 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8989
8990 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
8991 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8992
8993 len = sizeof(drive);
8994 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8995 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8996
8997 len = sizeof(drive);
8998 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8999 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
9000
9001 len = sizeof(drive);
9002 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9003 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
9004
9005 len = sizeof(drive);
9006 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
9007 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
9008
9009 MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
9010
9011 r = MsiDoActionA( hpkg, "CostInitialize" );
9012 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
9013
9014 r = MsiDoActionA( hpkg, "FileCost" );
9015 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
9016
9017 len = sizeof(drive);
9018 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9019 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
9020
9021 r = MsiDoActionA( hpkg, "CostFinalize" );
9022 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
9023
9024 /* contrary to what msdn says InstallValidate must be called too */
9025 len = sizeof(drive);
9026 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9027 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
9028
9029 r = MsiDoActionA( hpkg, "InstallValidate" );
9030 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
9031
9032 len = 0;
9033 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9034 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
9035
9036 len = 0;
9037 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9038 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
9039 ok( len == 2, "expected len == 2, got %u\n", len );
9040
9041 len = 2;
9042 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9043 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
9044 ok( len == 2, "expected len == 2, got %u\n", len );
9045
9046 len = 2;
9047 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
9048 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
9049 ok( len == 2, "expected len == 2, got %u\n", len );
9050
9051 /* install state doesn't seem to matter */
9052 len = sizeof(drive);
9053 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
9054 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9055
9056 len = sizeof(drive);
9057 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
9058 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9059
9060 len = sizeof(drive);
9061 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
9062 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9063
9064 len = sizeof(drive);
9065 drive[0] = 0;
9066 cost = temp = 0xdead;
9067 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9068 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9069 ok( len == 2, "expected len == 2, got %u\n", len );
9070 ok( drive[0], "expected a drive\n" );
9071 ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
9072 ok( !temp, "expected temp == 0, got %d\n", temp );
9073
9074 len = sizeof(drive);
9075 drive[0] = 0;
9076 cost = temp = 0xdead;
9077 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9078 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9079 ok( len == 2, "expected len == 2, got %u\n", len );
9080 ok( drive[0], "expected a drive\n" );
9081 ok( !cost, "expected cost == 0, got %d\n", cost );
9082 ok( !temp, "expected temp == 0, got %d\n", temp );
9083
9084 len = sizeof(drive);
9085 drive[0] = 0;
9086 cost = temp = 0xdead;
9087 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
9088 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
9089 ok( len == 2, "expected len == 2, got %u\n", len );
9090 ok( drive[0], "expected a drive\n" );
9091 ok( !cost, "expected cost == 0, got %d\n", cost );
9092 ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
9093
9094 /* increased index */
9095 len = sizeof(drive);
9096 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
9097 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
9098
9099 len = sizeof(drive);
9100 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
9101 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
9102
9103 MsiCloseHandle( hpkg );
9104 error:
9105 MsiCloseHandle( hdb );
9106 DeleteFileA( msifile );
9107 }
9108
9109 static void test_MsiDatabaseCommit(void)
9110 {
9111 UINT r;
9112 MSIHANDLE hdb, hpkg = 0;
9113 char buf[32], package[12];
9114 DWORD sz;
9115
9116 hdb = create_package_db();
9117 ok( hdb, "failed to create database\n" );
9118
9119 r = create_property_table( hdb );
9120 ok( r == ERROR_SUCCESS, "can't create Property table %u\n", r );
9121
9122 sprintf( package, "#%u", hdb );
9123 r = MsiOpenPackageA( package, &hpkg );
9124 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9125 {
9126 skip("Not enough rights to perform tests\n");
9127 goto error;
9128 }
9129 ok( r == ERROR_SUCCESS, "got %u\n", r );
9130
9131 r = MsiSetPropertyA( hpkg, "PROP", "value" );
9132 ok( r == ERROR_SUCCESS, "got %u\n", r );
9133
9134 buf[0] = 0;
9135 sz = sizeof(buf);
9136 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
9137 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
9138 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
9139
9140 r = MsiDatabaseCommit( hdb );
9141 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
9142
9143 buf[0] = 0;
9144 sz = sizeof(buf);
9145 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
9146 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
9147 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
9148
9149 MsiCloseHandle( hpkg );
9150 error:
9151 MsiCloseHandle( hdb );
9152 DeleteFileA( msifile );
9153 }
9154
9155 static int externalui_ran;
9156
9157 static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
9158 {
9159 externalui_ran = 1;
9160 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
9161 return 0;
9162 }
9163
9164 static int externalui_record_ran;
9165
9166 static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
9167 {
9168 INT retval = context ? *((INT *)context) : 0;
9169 UINT r;
9170 externalui_record_ran = 1;
9171 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
9172 r = MsiRecordGetFieldCount(hrecord);
9173 ok(r == 1, "expected 1, got %u\n", r);
9174 r = MsiRecordGetInteger(hrecord, 1);
9175 ok(r == 12345, "expected 12345, got %u\n", r);
9176 return retval;
9177 }
9178
9179 static void test_externalui(void)
9180 {
9181 /* test that external UI handlers work correctly */
9182
9183 INSTALLUI_HANDLERA prev;
9184 INSTALLUI_HANDLER_RECORD prev_record;
9185 MSIHANDLE hpkg, hrecord;
9186 UINT r;
9187 INT retval = 0;
9188
9189 prev = MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
9190
9191 r = package_from_db(create_package_db(), &hpkg);
9192 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9193 {
9194 skip("Not enough rights to perform tests\n");
9195 DeleteFileA(msifile);
9196 return;
9197 }
9198 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
9199
9200 hrecord = MsiCreateRecord(1);
9201 ok(hrecord, "Expected a valid record\n");
9202 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
9203 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
9204 r = MsiRecordSetInteger(hrecord, 1, 12345);
9205 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
9206
9207 externalui_ran = 0;
9208 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9209 ok(r == 0, "expected 0, got %u\n", r);
9210 ok(externalui_ran == 1, "external UI callback did not run\n");
9211
9212 prev = MsiSetExternalUIA(prev, 0, NULL);
9213 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
9214 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_USER, &retval, &prev_record);
9215 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
9216
9217 externalui_ran = externalui_record_ran = 0;
9218 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9219 ok(r == 0, "expected 0, got %u\n", r);
9220 ok(externalui_ran == 0, "external UI callback should not have run\n");
9221 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
9222
9223 MsiSetExternalUIA(externalui_callback, INSTALLLOGMODE_USER, NULL);
9224
9225 externalui_ran = externalui_record_ran = 0;
9226 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9227 ok(r == 0, "expected 0, got %u\n", r);
9228 ok(externalui_ran == 1, "external UI callback did not run\n");
9229 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
9230
9231 retval = 1;
9232 externalui_ran = externalui_record_ran = 0;
9233 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9234 ok(r == 1, "expected 1, got %u\n", r);
9235 ok(externalui_ran == 0, "external UI callback should not have run\n");
9236 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
9237
9238 /* filter and context should be kept separately */
9239 r = MsiSetExternalUIRecord(externalui_record_callback, INSTALLLOGMODE_ERROR, &retval, &prev_record);
9240 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
9241
9242 externalui_ran = externalui_record_ran = 0;
9243 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9244 ok(r == 0, "expected 0, got %u\n", r);
9245 ok(externalui_ran == 1, "external UI callback did not run\n");
9246 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
9247
9248 MsiCloseHandle(hpkg);
9249 DeleteFileA(msifile);
9250 }
9251
9252 struct externalui_message {
9253 UINT message;
9254 int field_count;
9255 char field[4][100];
9256 int match[4]; /* should we test for a match */
9257 int optional;
9258 };
9259
9260 static struct externalui_message *sequence;
9261 static int sequence_count, sequence_size;
9262
9263 static void add_message(const struct externalui_message *msg)
9264 {
9265 if (!sequence)
9266 {
9267 sequence_size = 10;
9268 sequence = HeapAlloc(GetProcessHeap(), 0, sequence_size * sizeof(*sequence));
9269 }
9270 if (sequence_count == sequence_size)
9271 {
9272 sequence_size *= 2;
9273 sequence = HeapReAlloc(GetProcessHeap(), 0, sequence, sequence_size * sizeof(*sequence));
9274 }
9275
9276 assert(sequence);
9277
9278 sequence[sequence_count++] = *msg;
9279 }
9280
9281 static void flush_sequence(void)
9282 {
9283 HeapFree(GetProcessHeap(), 0, sequence);
9284 sequence = NULL;
9285 sequence_count = sequence_size = 0;
9286 }
9287
9288 static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
9289 const char *file, int line)
9290 {
9291 static const struct externalui_message end_of_sequence = {0};
9292 const struct externalui_message *actual;
9293 int failcount = 0;
9294 int i;
9295
9296 add_message(&end_of_sequence);
9297
9298 actual = sequence;
9299
9300 while (expected->message && actual->message)
9301 {
9302 if (expected->message == actual->message)
9303 {
9304 if (expected->field_count != actual->field_count)
9305 {
9306 todo_wine_if (todo)
9307 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
9308 context, expected->message, expected->field_count, actual->field_count);
9309 failcount++;
9310 }
9311
9312 for (i = 0; i <= actual->field_count; i++)
9313 {
9314 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
9315 {
9316 todo_wine_if (todo)
9317 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
9318 context, expected->message, i, expected->field[i], actual->field[i]);
9319 failcount++;
9320 }
9321 }
9322
9323 expected++;
9324 actual++;
9325 }
9326 else
9327 {
9328 todo_wine_if (todo)
9329 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
9330 context, expected->message, actual->message);
9331 failcount++;
9332 if (todo)
9333 goto done;
9334 expected++;
9335 actual++;
9336 }
9337 }
9338
9339 if (expected->message || actual->message)
9340 {
9341 todo_wine_if (todo)
9342 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
9343 context, expected->message, actual->message);
9344 failcount++;
9345 }
9346
9347 if(todo && !failcount) /* succeeded yet marked todo */
9348 {
9349 todo_wine
9350 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
9351 }
9352
9353 done:
9354 flush_sequence();
9355 }
9356
9357 #define ok_sequence(exp, contx, todo) \
9358 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
9359
9360 static const struct externalui_message empty_sequence[] = {
9361 {0}
9362 };
9363
9364 static const struct externalui_message openpackage_nonexistent_sequence[] = {
9365 {INSTALLMESSAGE_INITIALIZE, -1},
9366 {INSTALLMESSAGE_TERMINATE, -1},
9367 {0}
9368 };
9369
9370 static const struct externalui_message openpackage_sequence[] = {
9371 {INSTALLMESSAGE_INITIALIZE, -1},
9372 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9373 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9374 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9375 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9376 {0}
9377 };
9378
9379 static const struct externalui_message processmessage_info_sequence[] = {
9380 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
9381 {0}
9382 };
9383
9384 static const struct externalui_message processmessage_actionstart_sequence[] = {
9385 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
9386 {0}
9387 };
9388
9389 static const struct externalui_message processmessage_actiondata_sequence[] = {
9390 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
9391 {0}
9392 };
9393
9394 static const struct externalui_message processmessage_error_sequence[] = {
9395 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
9396 {0}
9397 };
9398
9399 static const struct externalui_message processmessage_internal_error_sequence[] = {
9400 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
9401 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
9402 {0}
9403 };
9404
9405 static const struct externalui_message processmessage_error_format_sequence[] = {
9406 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
9407 {0}
9408 };
9409
9410 static const struct externalui_message doaction_costinitialize_sequence[] = {
9411 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
9412 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9413 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9414 {0}
9415 };
9416
9417 static const struct externalui_message doaction_custom_sequence[] = {
9418 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
9419 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9420 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
9421 {0}
9422 };
9423
9424 static const struct externalui_message doaction_custom_fullui_sequence[] = {
9425 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9426 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9427 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
9428 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9429 {0}
9430 };
9431
9432 static const struct externalui_message doaction_custom_cancel_sequence[] = {
9433 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9434 {0}
9435 };
9436
9437 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
9438 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9439 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9440 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
9441 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
9442 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
9443 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
9444 {0}
9445 };
9446
9447 static const struct externalui_message doaction_dialog_sequence[] = {
9448 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9449 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9450 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9451 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
9452 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
9453 {0}
9454 };
9455
9456 static const struct externalui_message doaction_dialog_error_sequence[] = {
9457 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
9458 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
9459 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
9460 {0}
9461 };
9462
9463 static const struct externalui_message doaction_dialog_3_sequence[] = {
9464 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9465 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9466 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9467 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9468 {0}
9469 };
9470
9471 static const struct externalui_message doaction_dialog_12345_sequence[] = {
9472 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9473 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9474 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9475 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
9476 {0}
9477 };
9478
9479 static const struct externalui_message closehandle_sequence[] = {
9480 {INSTALLMESSAGE_TERMINATE, -1},
9481 {0}
9482 };
9483
9484 static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
9485 {
9486 INT retval = context ? *((INT *)context) : 0;
9487 struct externalui_message msg;
9488
9489 msg.message = message;
9490 msg.field_count = 0;
9491 strcpy(msg.field[0], string);
9492 add_message(&msg);
9493
9494 return retval;
9495 }
9496
9497 static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
9498 {
9499 INT retval = context ? *((INT *)context) : 0;
9500 struct externalui_message msg;
9501 char buffer[100];
9502 DWORD length = 100;
9503 int i;
9504
9505 msg.message = message;
9506 if (message == INSTALLMESSAGE_TERMINATE)
9507 {
9508 /* trying to access the record seems to hang on some versions of Windows */
9509 msg.field_count = -1;
9510 add_message(&msg);
9511 return 1;
9512 }
9513 msg.field_count = MsiRecordGetFieldCount(hrecord);
9514 for (i = 0; i <= msg.field_count; i++)
9515 {
9516 length = 100;
9517 MsiRecordGetStringA(hrecord, i, buffer, &length);
9518 memcpy(msg.field[i], buffer, min(100, length+1));
9519 }
9520
9521 add_message(&msg);
9522
9523 return retval;
9524 }
9525
9526 static void test_externalui_message(void)
9527 {
9528 /* test that events trigger the correct sequence of messages */
9529
9530 INSTALLUI_HANDLER_RECORD prev;
9531 MSIHANDLE hdb, hpkg, hrecord;
9532 INT retval = 1;
9533 UINT r;
9534
9535 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9536
9537 /* processing SHOWDIALOG with a record handler causes a crash on XP */
9538 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval);
9539 r = MsiSetExternalUIRecord(externalui_message_callback, 0xffffffff ^ INSTALLLOGMODE_PROGRESS ^ INSTALLLOGMODE_SHOWDIALOG, &retval, &prev);
9540
9541 flush_sequence();
9542
9543 CoInitialize(NULL);
9544
9545 hdb = create_package_db();
9546 ok(hdb, "failed to create database\n");
9547
9548 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9549 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9551
9552 r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9553 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
9554 r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9555 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
9556
9557 r = create_actiontext_table(hdb);
9558 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
9559 r = add_actiontext_entry(hdb, "'custom', 'description', 'template'");
9560 ok(r == ERROR_SUCCESS, "Failed to insert into ActionText table: %u\n", r);
9561 r = add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
9562 ok(r == ERROR_SUCCESS, "Failed to insert into ActionText table: %u\n", r);
9563
9564 r = MsiOpenPackageA(NULL, &hpkg);
9565 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9566 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
9567
9568 r = MsiOpenPackageA("nonexistent", &hpkg);
9569 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9570 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9571
9572 r = package_from_db(hdb, &hpkg);
9573 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
9574 {
9575 skip("Not enough rights to perform tests\n");
9576 DeleteFileA(msifile);
9577 return;
9578 }
9579 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9580 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9581
9582 /* Test MsiProcessMessage */
9583 hrecord = MsiCreateRecord(3);
9584 ok(hrecord, "failed to create record\n");
9585
9586 MsiRecordSetStringA(hrecord, 0, "zero");
9587 MsiRecordSetStringA(hrecord, 1, "one");
9588 MsiRecordSetStringA(hrecord, 2, "two");
9589 MsiRecordSetStringA(hrecord, 3, "three");
9590 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9591 ok(r == 1, "Expected 1, got %d\n", r);
9592 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9593
9594 MsiRecordSetStringA(hrecord, 1, "name");
9595 MsiRecordSetStringA(hrecord, 2, "description");
9596 MsiRecordSetStringA(hrecord, 3, "template");
9597 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONSTART, hrecord);
9598 ok(r == 1, "Expected 1, got %d\n", r);
9599 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9600
9601 MsiRecordSetStringA(hrecord, 0, "apple");
9602 MsiRecordSetStringA(hrecord, 1, "cherry");
9603 MsiRecordSetStringA(hrecord, 2, "banana");
9604 MsiRecordSetStringA(hrecord, 3, "guava");
9605 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_ACTIONDATA, hrecord);
9606 ok(r == 1, "Expected 1, got %d\n", r);
9607 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9608
9609 /* non-internal error */
9610 MsiRecordSetStringA(hrecord, 0, NULL);
9611 MsiRecordSetInteger(hrecord, 1, 1311);
9612 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9613 ok(r == 1, "Expected 1, got %d\n", r);
9614 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9615
9616 /* internal error */
9617 MsiRecordSetStringA(hrecord, 0, NULL);
9618 MsiRecordSetInteger(hrecord, 1, 2726);
9619 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9620 ok(r == 0, "Expected 0, got %d\n", r);
9621 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9622
9623 /* with format field */
9624 MsiRecordSetStringA(hrecord, 0, "starfruit");
9625 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9626 ok(r == 1, "Expected 1, got %d\n", r);
9627 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9628
9629 /* Test a standard action */
9630 r = MsiDoActionA(hpkg, "CostInitialize");
9631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9632 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9633
9634 /* Test a custom action */
9635 r = MsiDoActionA(hpkg, "custom");
9636 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9637 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9638
9639 /* close the package */
9640 MsiCloseHandle(hpkg);
9641 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9642
9643 /* Test dialogs */
9644 hdb = create_package_db();
9645 ok(hdb, "failed to create database\n");
9646
9647 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9649
9650 r = create_dialog_table(hdb);
9651 ok(r == ERROR_SUCCESS, "failed to create dialog table %u\n", r);
9652 r = add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9653 ok(r == ERROR_SUCCESS, "failed to insert into dialog table %u\n", r);
9654
9655 r = create_control_table(hdb);
9656 ok(r == ERROR_SUCCESS, "failed to create control table %u\n", r);
9657 r = add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9658 ok(r == ERROR_SUCCESS, "failed to insert into control table %u\n", r);
9659
9660 r = package_from_db(hdb, &hpkg);
9661 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9662 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9663
9664 /* Test a custom action */
9665 r = MsiDoActionA(hpkg, "custom");
9666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9667 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9668
9669 retval = 2;
9670 r = MsiDoActionA(hpkg, "custom");
9671 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9672 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9673
9674 retval = 0;
9675 r = MsiDoActionA(hpkg, "custom");
9676 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9677 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9678
9679 r = MsiDoActionA(hpkg, "dialog");
9680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9681 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9682
9683 retval = -1;
9684 r = MsiDoActionA(hpkg, "error");
9685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9686 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9687
9688 r = MsiDoActionA(hpkg, "error");
9689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9690 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9691
9692 retval = -2;
9693 r = MsiDoActionA(hpkg, "custom");
9694 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9695 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9696
9697 retval = 3;
9698 r = MsiDoActionA(hpkg, "dialog");
9699 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9700 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9701
9702 retval = 12345;
9703 r = MsiDoActionA(hpkg, "dialog");
9704 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9705 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9706
9707 MsiCloseHandle(hpkg);
9708 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9709
9710 MsiCloseHandle(hrecord);
9711 CoUninitialize();
9712 DeleteFileA(msifile);
9713 DeleteFileA("forcecodepage.idt");
9714 }
9715
9716 static const struct externalui_message controlevent_spawn_sequence[] = {
9717 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9718 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9719 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9720 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9721
9722 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9723 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9724 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9725
9726 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9727
9728 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9729 {0}
9730 };
9731
9732 static const struct externalui_message controlevent_spawn2_sequence[] = {
9733 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9734 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9735 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9736 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9737
9738 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9739 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9740 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9741
9742 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9743
9744 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9745 {0}
9746 };
9747
9748 static void test_controlevent(void)
9749 {
9750 INSTALLUI_HANDLER_RECORD prev;
9751 MSIHANDLE hdb, hpkg;
9752 UINT r;
9753
9754 if (!winetest_interactive)
9755 {
9756 skip("interactive ControlEvent tests\n");
9757 return;
9758 }
9759
9760 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
9761
9762 /* processing SHOWDIALOG with a record handler causes a crash on XP */
9763 MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL);
9764 r = MsiSetExternalUIRecord(externalui_message_callback, 0xffffffff ^ INSTALLLOGMODE_PROGRESS ^ INSTALLLOGMODE_SHOWDIALOG, NULL, &prev);
9765
9766 flush_sequence();
9767
9768 CoInitialize(NULL);
9769
9770 hdb = create_package_db();
9771 ok(hdb, "failed to create database\n");
9772
9773 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9774 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9776
9777 r = create_dialog_table(hdb);
9778 ok(r == ERROR_SUCCESS, "failed to create Dialog table: %u\n", r);
9779 r = add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9780 ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r);
9781 r = add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9782 ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r);
9783 r = add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9784 ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r);
9785 r = add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9786 ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r);
9787
9788 r = create_control_table(hdb);
9789 ok(r == ERROR_SUCCESS, "failed to create Control table: %u\n", r);
9790 r = add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9791 ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r);
9792 r = add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9793 ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r);
9794 r = add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9795 ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r);
9796 r = add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9797 ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r);
9798
9799 r = create_controlevent_table(hdb);
9800 ok(r == ERROR_SUCCESS, "failed to create ControlEvent table: %u\n", r);
9801 r = add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9802 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9803 r = add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9804 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9805
9806 r = create_custom_action_table(hdb);
9807 ok(r == ERROR_SUCCESS, "failed to create CustomAction table: %u\n", r);
9808 r = add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9809 ok(r == ERROR_SUCCESS, "failed to insert into CustomAction table: %u\n", r);
9810
9811 /* SpawnDialog and EndDialog should trigger after all other events */
9812 r = add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9813 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9814 r = add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9815 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9816
9817 /* Multiple dialog events cause only the last one to be triggered */
9818 r = add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9819 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9820 r = add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9821 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9822 r = add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9823 ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r);
9824
9825 r = package_from_db(hdb, &hpkg);
9826 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9827 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9828
9829 r = MsiDoActionA(hpkg, "spawn");
9830 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9831 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9832
9833 r = MsiDoActionA(hpkg, "spawn2");
9834 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9835 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9836
9837 MsiCloseHandle(hpkg);
9838 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9839
9840 CoUninitialize();
9841 DeleteFileA(msifile);
9842 DeleteFileA("forcecodepage.idt");
9843 }
9844
9845 START_TEST(package)
9846 {
9847 STATEMGRSTATUS status;
9848 BOOL ret = FALSE;
9849
9850 init_functionpointers();
9851
9852 if (pIsWow64Process)
9853 pIsWow64Process(GetCurrentProcess(), &is_wow64);
9854
9855 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
9856
9857 /* Create a restore point ourselves so we circumvent the multitude of restore points
9858 * that would have been created by all the installation and removal tests.
9859 *
9860 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
9861 * creation of restore points.
9862 */
9863 if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
9864 {
9865 memset(&status, 0, sizeof(status));
9866 ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9867 }
9868
9869 test_createpackage();
9870 test_doaction();
9871 test_gettargetpath_bad();
9872 test_settargetpath();
9873 test_props();
9874 test_property_table();
9875 test_condition();
9876 test_msipackage();
9877 test_formatrecord2();
9878 test_states();
9879 test_getproperty();
9880 test_removefiles();
9881 test_appsearch();
9882 test_appsearch_complocator();
9883 test_appsearch_reglocator();
9884 test_appsearch_inilocator();
9885 test_appsearch_drlocator();
9886 test_featureparents();
9887 test_installprops();
9888 test_launchconditions();
9889 test_ccpsearch();
9890 test_complocator();
9891 test_MsiGetSourcePath();
9892 test_shortlongsource();
9893 test_sourcedir();
9894 test_access();
9895 test_emptypackage();
9896 test_MsiGetProductProperty();
9897 test_MsiSetProperty();
9898 test_MsiApplyMultiplePatches();
9899 test_MsiApplyPatch();
9900 test_MsiEnumComponentCosts();
9901 test_MsiDatabaseCommit();
9902 test_externalui();
9903 test_externalui_message();
9904 test_controlevent();
9905
9906 if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
9907 {
9908 ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9909 if (ret)
9910 remove_restore_point(status.llSequenceNumber);
9911 }
9912 }