92a0f9a13a0727147764d5985e790916c87b77ca
[reactos.git] / 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 <stdio.h>
25 #include <windows.h>
26 #include <msidefs.h>
27 #include <msi.h>
28 #include <msiquery.h>
29 #include <srrestoreptapi.h>
30 #include <shlobj.h>
31
32 #include "wine/test.h"
33
34 static BOOL is_wow64;
35 static const char msifile[] = "winetest-package.msi";
36 static char CURR_DIR[MAX_PATH];
37
38 static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR);
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
40 static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
41
42 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
43 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
44 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
45 static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
46 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
47 static void (WINAPI *pGetSystemInfo)(LPSYSTEM_INFO);
48 static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
49 static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR, UINT);
50
51 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
52 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
53
54 static void init_functionpointers(void)
55 {
56 HMODULE hmsi = GetModuleHandleA("msi.dll");
57 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
58 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
59 HMODULE hshell32 = GetModuleHandleA("shell32.dll");
60 HMODULE hsrclient;
61
62 #define GET_PROC(mod, func) \
63 p ## func = (void*)GetProcAddress(mod, #func);
64
65 GET_PROC(hmsi, MsiApplyMultiplePatchesA);
66 GET_PROC(hmsi, MsiGetComponentPathExA);
67 GET_PROC(hshell32, SHGetFolderPathA);
68
69 GET_PROC(hadvapi32, ConvertSidToStringSidA);
70 GET_PROC(hadvapi32, OpenProcessToken);
71 GET_PROC(hadvapi32, RegDeleteKeyExA)
72 GET_PROC(hadvapi32, RegDeleteKeyExW)
73 GET_PROC(hkernel32, IsWow64Process)
74 GET_PROC(hkernel32, GetNativeSystemInfo)
75 GET_PROC(hkernel32, GetSystemInfo)
76 GET_PROC(hkernel32, GetSystemWow64DirectoryA)
77
78 hsrclient = LoadLibraryA("srclient.dll");
79 GET_PROC(hsrclient, SRRemoveRestorePoint);
80 GET_PROC(hsrclient, SRSetRestorePointA);
81 #undef GET_PROC
82 }
83
84 static BOOL is_process_limited(void)
85 {
86 HANDLE token;
87
88 if (!pOpenProcessToken) return FALSE;
89
90 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
91 {
92 BOOL ret;
93 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
94 DWORD size;
95
96 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
97 CloseHandle(token);
98 return (ret && type == TokenElevationTypeLimited);
99 }
100 return FALSE;
101 }
102
103 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
104 {
105 if (pRegDeleteKeyExA)
106 return pRegDeleteKeyExA( key, subkey, access, 0 );
107 return RegDeleteKeyA( key, subkey );
108 }
109
110 static char *get_user_sid(void)
111 {
112 HANDLE token;
113 DWORD size = 0;
114 TOKEN_USER *user;
115 char *usersid = NULL;
116
117 if (!pConvertSidToStringSidA)
118 {
119 win_skip("ConvertSidToStringSidA is not available\n");
120 return NULL;
121 }
122 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
123 GetTokenInformation(token, TokenUser, NULL, size, &size);
124
125 user = HeapAlloc(GetProcessHeap(), 0, size);
126 GetTokenInformation(token, TokenUser, user, size, &size);
127 pConvertSidToStringSidA(user->User.Sid, &usersid);
128 HeapFree(GetProcessHeap(), 0, user);
129
130 CloseHandle(token);
131 return usersid;
132 }
133
134 /* RegDeleteTreeW from dlls/advapi32/registry.c */
135 static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
136 {
137 LONG ret;
138 DWORD dwMaxSubkeyLen, dwMaxValueLen;
139 DWORD dwMaxLen, dwSize;
140 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
141 HKEY hSubKey = hKey;
142
143 if(lpszSubKey)
144 {
145 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
146 if (ret) return ret;
147 }
148
149 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
150 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
151 if (ret) goto cleanup;
152
153 dwMaxSubkeyLen++;
154 dwMaxValueLen++;
155 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
156 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
157 {
158 /* Name too big: alloc a buffer for it */
159 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
160 {
161 ret = ERROR_NOT_ENOUGH_MEMORY;
162 goto cleanup;
163 }
164 }
165
166 /* Recursively delete all the subkeys */
167 while (TRUE)
168 {
169 dwSize = dwMaxLen;
170 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
171 NULL, NULL, NULL)) break;
172
173 ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
174 if (ret) goto cleanup;
175 }
176
177 if (lpszSubKey)
178 {
179 if (pRegDeleteKeyExW)
180 ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
181 else
182 ret = RegDeleteKeyW(hKey, lpszSubKey);
183 }
184 else
185 while (TRUE)
186 {
187 dwSize = dwMaxLen;
188 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
189 NULL, NULL, NULL, NULL)) break;
190
191 ret = RegDeleteValueW(hKey, lpszName);
192 if (ret) goto cleanup;
193 }
194
195 cleanup:
196 if (lpszName != szNameBuf)
197 HeapFree(GetProcessHeap(), 0, lpszName);
198 if(lpszSubKey)
199 RegCloseKey(hSubKey);
200 return ret;
201 }
202
203 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
204 {
205 DWORD i,n=1;
206 GUID guid;
207
208 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
209 return FALSE;
210
211 for(i=0; i<8; i++)
212 out[7-i] = in[n++];
213 n++;
214 for(i=0; i<4; i++)
215 out[11-i] = in[n++];
216 n++;
217 for(i=0; i<4; i++)
218 out[15-i] = in[n++];
219 n++;
220 for(i=0; i<2; i++)
221 {
222 out[17+i*2] = in[n++];
223 out[16+i*2] = in[n++];
224 }
225 n++;
226 for( ; i<8; i++)
227 {
228 out[17+i*2] = in[n++];
229 out[16+i*2] = in[n++];
230 }
231 out[32]=0;
232 return TRUE;
233 }
234
235 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
236 {
237 WCHAR guidW[MAX_PATH];
238 WCHAR squashedW[MAX_PATH];
239 GUID guid;
240 HRESULT hr;
241 int size;
242
243 hr = CoCreateGuid(&guid);
244 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
245
246 size = StringFromGUID2(&guid, guidW, MAX_PATH);
247 ok(size == 39, "Expected 39, got %d\n", hr);
248
249 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
250 squash_guid(guidW, squashedW);
251 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
252 }
253
254 static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
255 LPCSTR guid, LPSTR usersid, BOOL dir)
256 {
257 WCHAR guidW[MAX_PATH];
258 WCHAR squashedW[MAX_PATH];
259 CHAR squashed[MAX_PATH];
260 CHAR comppath[MAX_PATH];
261 CHAR prodpath[MAX_PATH];
262 CHAR path[MAX_PATH];
263 LPCSTR prod = NULL;
264 HKEY hkey;
265 REGSAM access = KEY_ALL_ACCESS;
266
267 if (is_wow64)
268 access |= KEY_WOW64_64KEY;
269
270 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
271 squash_guid(guidW, squashedW);
272 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
273
274 if (context == MSIINSTALLCONTEXT_MACHINE)
275 {
276 prod = "3D0DAE300FACA1300AD792060BCDAA92";
277 sprintf(comppath,
278 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
279 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
280 lstrcpyA(prodpath,
281 "SOFTWARE\\Classes\\Installer\\"
282 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
283 }
284 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
285 {
286 prod = "7D2F387510109040002000060BECB6AB";
287 sprintf(comppath,
288 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
289 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
290 sprintf(prodpath,
291 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
292 "Installer\\%s\\Installer\\Products\\"
293 "7D2F387510109040002000060BECB6AB", usersid);
294 }
295 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
296 {
297 prod = "7D2F387510109040002000060BECB6AB";
298 sprintf(comppath,
299 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
300 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
301 sprintf(prodpath,
302 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
303 "Installer\\Managed\\%s\\Installer\\Products\\"
304 "7D2F387510109040002000060BECB6AB", usersid);
305 }
306
307 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
308
309 lstrcpyA(path, CURR_DIR);
310 lstrcatA(path, "\\");
311 if (!dir) lstrcatA(path, filename);
312
313 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
314 RegCloseKey(hkey);
315
316 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
317 RegCloseKey(hkey);
318 }
319
320 static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
321 {
322 WCHAR guidW[MAX_PATH];
323 WCHAR squashedW[MAX_PATH];
324 WCHAR substrW[MAX_PATH];
325 CHAR squashed[MAX_PATH];
326 CHAR comppath[MAX_PATH];
327 CHAR prodpath[MAX_PATH];
328 REGSAM access = KEY_ALL_ACCESS;
329
330 if (is_wow64)
331 access |= KEY_WOW64_64KEY;
332
333 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
334 squash_guid(guidW, squashedW);
335 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
336
337 if (context == MSIINSTALLCONTEXT_MACHINE)
338 {
339 sprintf(comppath,
340 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
341 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
342 lstrcpyA(prodpath,
343 "SOFTWARE\\Classes\\Installer\\"
344 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
345 }
346 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
347 {
348 sprintf(comppath,
349 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
350 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
351 sprintf(prodpath,
352 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
353 "Installer\\%s\\Installer\\Products\\"
354 "7D2F387510109040002000060BECB6AB", usersid);
355 }
356 else if (context == MSIINSTALLCONTEXT_USERMANAGED)
357 {
358 sprintf(comppath,
359 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
360 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
361 sprintf(prodpath,
362 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
363 "Installer\\Managed\\%s\\Installer\\Products\\"
364 "7D2F387510109040002000060BECB6AB", usersid);
365 }
366
367 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
368 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
369
370 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
371 package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
372 }
373
374 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
375 {
376 MSIHANDLE hview = 0;
377 UINT r, ret;
378
379 /* open a select query */
380 r = MsiDatabaseOpenView(hdb, query, &hview);
381 if (r != ERROR_SUCCESS)
382 return r;
383 r = MsiViewExecute(hview, 0);
384 if (r != ERROR_SUCCESS)
385 return r;
386 ret = MsiViewFetch(hview, phrec);
387 r = MsiViewClose(hview);
388 if (r != ERROR_SUCCESS)
389 return r;
390 r = MsiCloseHandle(hview);
391 if (r != ERROR_SUCCESS)
392 return r;
393 return ret;
394 }
395
396 static UINT run_query( MSIHANDLE hdb, const char *query )
397 {
398 MSIHANDLE hview = 0;
399 UINT r;
400
401 r = MsiDatabaseOpenView(hdb, query, &hview);
402 if( r != ERROR_SUCCESS )
403 return r;
404
405 r = MsiViewExecute(hview, 0);
406 if( r == ERROR_SUCCESS )
407 r = MsiViewClose(hview);
408 MsiCloseHandle(hview);
409 return r;
410 }
411
412 static UINT create_component_table( MSIHANDLE hdb )
413 {
414 return run_query( hdb,
415 "CREATE TABLE `Component` ( "
416 "`Component` CHAR(72) NOT NULL, "
417 "`ComponentId` CHAR(38), "
418 "`Directory_` CHAR(72) NOT NULL, "
419 "`Attributes` SHORT NOT NULL, "
420 "`Condition` CHAR(255), "
421 "`KeyPath` CHAR(72) "
422 "PRIMARY KEY `Component`)" );
423 }
424
425 static UINT create_feature_table( MSIHANDLE hdb )
426 {
427 return run_query( hdb,
428 "CREATE TABLE `Feature` ( "
429 "`Feature` CHAR(38) NOT NULL, "
430 "`Feature_Parent` CHAR(38), "
431 "`Title` CHAR(64), "
432 "`Description` CHAR(255), "
433 "`Display` SHORT NOT NULL, "
434 "`Level` SHORT NOT NULL, "
435 "`Directory_` CHAR(72), "
436 "`Attributes` SHORT NOT NULL "
437 "PRIMARY KEY `Feature`)" );
438 }
439
440 static UINT create_feature_components_table( MSIHANDLE hdb )
441 {
442 return run_query( hdb,
443 "CREATE TABLE `FeatureComponents` ( "
444 "`Feature_` CHAR(38) NOT NULL, "
445 "`Component_` CHAR(72) NOT NULL "
446 "PRIMARY KEY `Feature_`, `Component_` )" );
447 }
448
449 static UINT create_file_table( MSIHANDLE hdb )
450 {
451 return run_query( hdb,
452 "CREATE TABLE `File` ("
453 "`File` CHAR(72) NOT NULL, "
454 "`Component_` CHAR(72) NOT NULL, "
455 "`FileName` CHAR(255) NOT NULL, "
456 "`FileSize` LONG NOT NULL, "
457 "`Version` CHAR(72), "
458 "`Language` CHAR(20), "
459 "`Attributes` SHORT, "
460 "`Sequence` SHORT NOT NULL "
461 "PRIMARY KEY `File`)" );
462 }
463
464 static UINT create_remove_file_table( MSIHANDLE hdb )
465 {
466 return run_query( hdb,
467 "CREATE TABLE `RemoveFile` ("
468 "`FileKey` CHAR(72) NOT NULL, "
469 "`Component_` CHAR(72) NOT NULL, "
470 "`FileName` CHAR(255) LOCALIZABLE, "
471 "`DirProperty` CHAR(72) NOT NULL, "
472 "`InstallMode` SHORT NOT NULL "
473 "PRIMARY KEY `FileKey`)" );
474 }
475
476 static UINT create_appsearch_table( MSIHANDLE hdb )
477 {
478 return run_query( hdb,
479 "CREATE TABLE `AppSearch` ("
480 "`Property` CHAR(72) NOT NULL, "
481 "`Signature_` CHAR(72) NOT NULL "
482 "PRIMARY KEY `Property`, `Signature_`)" );
483 }
484
485 static UINT create_reglocator_table( MSIHANDLE hdb )
486 {
487 return run_query( hdb,
488 "CREATE TABLE `RegLocator` ("
489 "`Signature_` CHAR(72) NOT NULL, "
490 "`Root` SHORT NOT NULL, "
491 "`Key` CHAR(255) NOT NULL, "
492 "`Name` CHAR(255), "
493 "`Type` SHORT "
494 "PRIMARY KEY `Signature_`)" );
495 }
496
497 static UINT create_signature_table( MSIHANDLE hdb )
498 {
499 return run_query( hdb,
500 "CREATE TABLE `Signature` ("
501 "`Signature` CHAR(72) NOT NULL, "
502 "`FileName` CHAR(255) NOT NULL, "
503 "`MinVersion` CHAR(20), "
504 "`MaxVersion` CHAR(20), "
505 "`MinSize` LONG, "
506 "`MaxSize` LONG, "
507 "`MinDate` LONG, "
508 "`MaxDate` LONG, "
509 "`Languages` CHAR(255) "
510 "PRIMARY KEY `Signature`)" );
511 }
512
513 static UINT create_launchcondition_table( MSIHANDLE hdb )
514 {
515 return run_query( hdb,
516 "CREATE TABLE `LaunchCondition` ("
517 "`Condition` CHAR(255) NOT NULL, "
518 "`Description` CHAR(255) NOT NULL "
519 "PRIMARY KEY `Condition`)" );
520 }
521
522 static UINT create_property_table( MSIHANDLE hdb )
523 {
524 return run_query( hdb,
525 "CREATE TABLE `Property` ("
526 "`Property` CHAR(72) NOT NULL, "
527 "`Value` CHAR(0) "
528 "PRIMARY KEY `Property`)" );
529 }
530
531 static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
532 {
533 return run_query( hdb,
534 "CREATE TABLE `InstallExecuteSequence` ("
535 "`Action` CHAR(72) NOT NULL, "
536 "`Condition` CHAR(255), "
537 "`Sequence` SHORT "
538 "PRIMARY KEY `Action`)" );
539 }
540
541 static UINT create_media_table( MSIHANDLE hdb )
542 {
543 return run_query( hdb,
544 "CREATE TABLE `Media` ("
545 "`DiskId` SHORT NOT NULL, "
546 "`LastSequence` SHORT NOT NULL, "
547 "`DiskPrompt` CHAR(64), "
548 "`Cabinet` CHAR(255), "
549 "`VolumeLabel` CHAR(32), "
550 "`Source` CHAR(72) "
551 "PRIMARY KEY `DiskId`)" );
552 }
553
554 static UINT create_ccpsearch_table( MSIHANDLE hdb )
555 {
556 return run_query( hdb,
557 "CREATE TABLE `CCPSearch` ("
558 "`Signature_` CHAR(72) NOT NULL "
559 "PRIMARY KEY `Signature_`)" );
560 }
561
562 static UINT create_drlocator_table( MSIHANDLE hdb )
563 {
564 return run_query( hdb,
565 "CREATE TABLE `DrLocator` ("
566 "`Signature_` CHAR(72) NOT NULL, "
567 "`Parent` CHAR(72), "
568 "`Path` CHAR(255), "
569 "`Depth` SHORT "
570 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
571 }
572
573 static UINT create_complocator_table( MSIHANDLE hdb )
574 {
575 return run_query( hdb,
576 "CREATE TABLE `CompLocator` ("
577 "`Signature_` CHAR(72) NOT NULL, "
578 "`ComponentId` CHAR(38) NOT NULL, "
579 "`Type` SHORT "
580 "PRIMARY KEY `Signature_`)" );
581 }
582
583 static UINT create_inilocator_table( MSIHANDLE hdb )
584 {
585 return run_query( hdb,
586 "CREATE TABLE `IniLocator` ("
587 "`Signature_` CHAR(72) NOT NULL, "
588 "`FileName` CHAR(255) NOT NULL, "
589 "`Section` CHAR(96)NOT NULL, "
590 "`Key` CHAR(128)NOT NULL, "
591 "`Field` SHORT, "
592 "`Type` SHORT "
593 "PRIMARY KEY `Signature_`)" );
594 }
595
596 #define make_add_entry(type, qtext) \
597 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
598 { \
599 char insert[] = qtext; \
600 char *query; \
601 UINT sz, r; \
602 sz = strlen(values) + sizeof insert; \
603 query = HeapAlloc(GetProcessHeap(),0,sz); \
604 sprintf(query,insert,values); \
605 r = run_query( hdb, query ); \
606 HeapFree(GetProcessHeap(), 0, query); \
607 return r; \
608 }
609
610 make_add_entry(component,
611 "INSERT INTO `Component` "
612 "(`Component`, `ComponentId`, `Directory_`, "
613 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
614
615 make_add_entry(directory,
616 "INSERT INTO `Directory` "
617 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
618
619 make_add_entry(feature,
620 "INSERT INTO `Feature` "
621 "(`Feature`, `Feature_Parent`, `Title`, `Description`, "
622 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
623
624 make_add_entry(feature_components,
625 "INSERT INTO `FeatureComponents` "
626 "(`Feature_`, `Component_`) VALUES( %s )")
627
628 make_add_entry(file,
629 "INSERT INTO `File` "
630 "(`File`, `Component_`, `FileName`, `FileSize`, "
631 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
632
633 make_add_entry(appsearch,
634 "INSERT INTO `AppSearch` "
635 "(`Property`, `Signature_`) VALUES( %s )")
636
637 make_add_entry(signature,
638 "INSERT INTO `Signature` "
639 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
640 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) "
641 "VALUES( %s )")
642
643 make_add_entry(launchcondition,
644 "INSERT INTO `LaunchCondition` "
645 "(`Condition`, `Description`) VALUES( %s )")
646
647 make_add_entry(property,
648 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
649
650 make_add_entry(install_execute_sequence,
651 "INSERT INTO `InstallExecuteSequence` "
652 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
653
654 make_add_entry(media,
655 "INSERT INTO `Media` "
656 "(`DiskId`, `LastSequence`, `DiskPrompt`, "
657 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
658
659 make_add_entry(ccpsearch,
660 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
661
662 make_add_entry(drlocator,
663 "INSERT INTO `DrLocator` "
664 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
665
666 make_add_entry(complocator,
667 "INSERT INTO `CompLocator` "
668 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
669
670 make_add_entry(inilocator,
671 "INSERT INTO `IniLocator` "
672 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
673 "VALUES( %s )")
674
675 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
676 const char *name, UINT type )
677 {
678 const char insert[] =
679 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
680 "VALUES( '%s', %u, '%s', '%s', %u )";
681 char *query;
682 UINT sz, r;
683
684 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
685 query = HeapAlloc( GetProcessHeap(), 0, sz );
686 sprintf( query, insert, sig, root, path, name, type );
687 r = run_query( hdb, query );
688 HeapFree( GetProcessHeap(), 0, query );
689 return r;
690 }
691
692 static UINT set_summary_info(MSIHANDLE hdb)
693 {
694 UINT res;
695 MSIHANDLE suminfo;
696
697 /* build summary info */
698 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
699 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
700
701 res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
702 "Installation Database");
703 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
704
705 res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
706 "Installation Database");
707 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
708
709 res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
710 "Wine Hackers");
711 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
712
713 res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
714 ";1033");
715 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
716
717 res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
718 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
719 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
720
721 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
722 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
723
724 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
725 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
726
727 res = MsiSummaryInfoPersist(suminfo);
728 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
729
730 res = MsiCloseHandle( suminfo);
731 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
732
733 return res;
734 }
735
736
737 static MSIHANDLE create_package_db(void)
738 {
739 MSIHANDLE hdb = 0;
740 UINT res;
741
742 DeleteFile(msifile);
743
744 /* create an empty database */
745 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
746 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
747 if( res != ERROR_SUCCESS )
748 return hdb;
749
750 res = MsiDatabaseCommit( hdb );
751 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
752
753 res = set_summary_info(hdb);
754 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
755
756 res = run_query( hdb,
757 "CREATE TABLE `Directory` ( "
758 "`Directory` CHAR(255) NOT NULL, "
759 "`Directory_Parent` CHAR(255), "
760 "`DefaultDir` CHAR(255) NOT NULL "
761 "PRIMARY KEY `Directory`)" );
762 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
763
764 return hdb;
765 }
766
767 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
768 {
769 UINT res;
770 CHAR szPackage[12];
771 MSIHANDLE hPackage;
772
773 sprintf(szPackage, "#%u", hdb);
774 res = MsiOpenPackage(szPackage, &hPackage);
775 if (res != ERROR_SUCCESS)
776 {
777 MsiCloseHandle(hdb);
778 return res;
779 }
780
781 res = MsiCloseHandle(hdb);
782 if (res != ERROR_SUCCESS)
783 {
784 MsiCloseHandle(hPackage);
785 return res;
786 }
787
788 *handle = hPackage;
789 return ERROR_SUCCESS;
790 }
791
792 static void create_test_file(const CHAR *name)
793 {
794 HANDLE file;
795 DWORD written;
796
797 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
798 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
799 WriteFile(file, name, strlen(name), &written, NULL);
800 WriteFile(file, "\n", strlen("\n"), &written, NULL);
801 CloseHandle(file);
802 }
803
804 typedef struct _tagVS_VERSIONINFO
805 {
806 WORD wLength;
807 WORD wValueLength;
808 WORD wType;
809 WCHAR szKey[1];
810 WORD wPadding1[1];
811 VS_FIXEDFILEINFO Value;
812 WORD wPadding2[1];
813 WORD wChildren[1];
814 } VS_VERSIONINFO;
815
816 #define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
817 #define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
818
819 static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
820 {
821 VS_VERSIONINFO *pVerInfo;
822 VS_FIXEDFILEINFO *pFixedInfo;
823 LPBYTE buffer, ofs;
824 CHAR path[MAX_PATH];
825 DWORD handle, size;
826 HANDLE resource;
827 BOOL ret = FALSE;
828
829 GetSystemDirectory(path, MAX_PATH);
830 /* Some dlls can't be updated on Vista/W2K8 */
831 lstrcatA(path, "\\version.dll");
832
833 CopyFileA(path, name, FALSE);
834
835 size = GetFileVersionInfoSize(path, &handle);
836 buffer = HeapAlloc(GetProcessHeap(), 0, size);
837
838 GetFileVersionInfoA(path, 0, size, buffer);
839
840 pVerInfo = (VS_VERSIONINFO *)buffer;
841 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
842 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
843
844 pFixedInfo->dwFileVersionMS = ms;
845 pFixedInfo->dwFileVersionLS = ls;
846 pFixedInfo->dwProductVersionMS = ms;
847 pFixedInfo->dwProductVersionLS = ls;
848
849 resource = BeginUpdateResource(name, FALSE);
850 if (!resource)
851 goto done;
852
853 if (!UpdateResource(resource, RT_VERSION, MAKEINTRESOURCE(VS_VERSION_INFO),
854 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), buffer, size))
855 goto done;
856
857 if (!EndUpdateResource(resource, FALSE))
858 goto done;
859
860 ret = TRUE;
861
862 done:
863 HeapFree(GetProcessHeap(), 0, buffer);
864 return ret;
865 }
866
867 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
868 {
869 RESTOREPOINTINFOA spec;
870
871 spec.dwEventType = event_type;
872 spec.dwRestorePtType = APPLICATION_INSTALL;
873 spec.llSequenceNumber = status->llSequenceNumber;
874 lstrcpyA(spec.szDescription, "msitest restore point");
875
876 return pSRSetRestorePointA(&spec, status);
877 }
878
879 static void remove_restore_point(DWORD seq_number)
880 {
881 DWORD res;
882
883 res = pSRRemoveRestorePoint(seq_number);
884 if (res != ERROR_SUCCESS)
885 trace("Failed to remove the restore point : %08x\n", res);
886 }
887
888 static void test_createpackage(void)
889 {
890 MSIHANDLE hPackage = 0;
891 UINT res;
892
893 res = package_from_db(create_package_db(), &hPackage);
894 if (res == ERROR_INSTALL_PACKAGE_REJECTED)
895 {
896 skip("Not enough rights to perform tests\n");
897 DeleteFile(msifile);
898 return;
899 }
900 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
901
902 res = MsiCloseHandle( hPackage);
903 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
904 DeleteFile(msifile);
905 }
906
907 static void test_doaction( void )
908 {
909 MSIHANDLE hpkg;
910 UINT r;
911
912 r = MsiDoAction( -1, NULL );
913 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
914
915 r = package_from_db(create_package_db(), &hpkg);
916 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
917 {
918 skip("Not enough rights to perform tests\n");
919 DeleteFile(msifile);
920 return;
921 }
922 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
923
924 r = MsiDoAction(hpkg, NULL);
925 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
926
927 r = MsiDoAction(0, "boo");
928 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
929
930 r = MsiDoAction(hpkg, "boo");
931 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
932
933 MsiCloseHandle( hpkg );
934 DeleteFile(msifile);
935 }
936
937 static void test_gettargetpath_bad(void)
938 {
939 static const WCHAR boo[] = {'b','o','o',0};
940 static const WCHAR empty[] = {0};
941 char buffer[0x80];
942 WCHAR bufferW[0x80];
943 MSIHANDLE hpkg;
944 DWORD sz;
945 UINT r;
946
947 r = package_from_db(create_package_db(), &hpkg);
948 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
949 {
950 skip("Not enough rights to perform tests\n");
951 DeleteFile(msifile);
952 return;
953 }
954 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
955
956 r = MsiGetTargetPath( 0, NULL, NULL, NULL );
957 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
958
959 r = MsiGetTargetPath( 0, NULL, NULL, &sz );
960 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
961
962 r = MsiGetTargetPath( 0, "boo", NULL, NULL );
963 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
964
965 r = MsiGetTargetPath( 0, "boo", NULL, NULL );
966 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
967
968 r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
969 ok( r == ERROR_DIRECTORY, "wrong return val\n");
970
971 r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
972 ok( r == ERROR_DIRECTORY, "wrong return val\n");
973
974 sz = 0;
975 r = MsiGetTargetPath( hpkg, "", buffer, &sz );
976 ok( r == ERROR_DIRECTORY, "wrong return val\n");
977
978 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
979 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
980
981 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
982 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
983
984 r = MsiGetTargetPathW( 0, boo, NULL, NULL );
985 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
986
987 r = MsiGetTargetPathW( 0, boo, NULL, NULL );
988 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
989
990 r = MsiGetTargetPathW( hpkg, boo, NULL, NULL );
991 ok( r == ERROR_DIRECTORY, "wrong return val\n");
992
993 r = MsiGetTargetPathW( hpkg, boo, bufferW, NULL );
994 ok( r == ERROR_DIRECTORY, "wrong return val\n");
995
996 sz = 0;
997 r = MsiGetTargetPathW( hpkg, empty, bufferW, &sz );
998 ok( r == ERROR_DIRECTORY, "wrong return val\n");
999
1000 MsiCloseHandle( hpkg );
1001 DeleteFile(msifile);
1002 }
1003
1004 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
1005 {
1006 UINT r;
1007 DWORD size;
1008 MSIHANDLE rec;
1009
1010 rec = MsiCreateRecord( 1 );
1011 ok(rec, "MsiCreate record failed\n");
1012
1013 r = MsiRecordSetString( rec, 0, file );
1014 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1015
1016 size = MAX_PATH;
1017 r = MsiFormatRecord( hpkg, rec, buff, &size );
1018 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1019
1020 MsiCloseHandle( rec );
1021 }
1022
1023 static void test_settargetpath(void)
1024 {
1025 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH];
1026 DWORD sz;
1027 MSIHANDLE hpkg;
1028 UINT r;
1029 MSIHANDLE hdb;
1030
1031 hdb = create_package_db();
1032 ok ( hdb, "failed to create package database\n" );
1033
1034 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1035 ok( r == S_OK, "failed to add directory entry: %d\n" , r );
1036
1037 r = create_component_table( hdb );
1038 ok( r == S_OK, "cannot create Component table: %d\n", r );
1039
1040 r = add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1041 ok( r == S_OK, "cannot add dummy component: %d\n", r );
1042
1043 r = add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1044 ok( r == S_OK, "cannot add test component: %d\n", r );
1045
1046 r = create_feature_table( hdb );
1047 ok( r == S_OK, "cannot create Feature table: %d\n", r );
1048
1049 r = add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1050 ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r );
1051
1052 r = create_feature_components_table( hdb );
1053 ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
1054
1055 r = add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1056 ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1057
1058 r = add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1059 ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
1060
1061 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1062 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1063
1064 r = create_file_table( hdb );
1065 ok( r == S_OK, "cannot create File table: %d\n", r );
1066
1067 r = add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1068 ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1069
1070 r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1071 ok( r == S_OK, "cannot add file to the File table: %d\n", r );
1072
1073 r = package_from_db( hdb, &hpkg );
1074 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1075 {
1076 skip("Not enough rights to perform tests\n");
1077 DeleteFile(msifile);
1078 return;
1079 }
1080 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1081
1082 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1083
1084 r = MsiDoAction( hpkg, "CostInitialize");
1085 ok( r == ERROR_SUCCESS, "cost init failed\n");
1086
1087 r = MsiDoAction( hpkg, "FileCost");
1088 ok( r == ERROR_SUCCESS, "file cost failed\n");
1089
1090 r = MsiDoAction( hpkg, "CostFinalize");
1091 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1092
1093 r = MsiSetTargetPath( 0, NULL, NULL );
1094 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1095
1096 r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
1097 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1098
1099 r = MsiSetTargetPath( hpkg, "boo", NULL );
1100 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1101
1102 r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
1103 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1104
1105 sz = sizeof tempdir - 1;
1106 r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
1107 sprintf( file, "%srootfile.txt", tempdir );
1108 buffer[0] = 0;
1109 query_file_path( hpkg, "[#RootFile]", buffer );
1110 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1111 ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer );
1112
1113 GetTempFileName( tempdir, "_wt", 0, buffer );
1114 sprintf( tempdir, "%s\\subdir", buffer );
1115
1116 r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
1117 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1118 "MsiSetTargetPath on file returned %d\n", r );
1119
1120 r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
1121 ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
1122 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1123
1124 DeleteFile( buffer );
1125
1126 r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
1127 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1128
1129 r = GetFileAttributes( buffer );
1130 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1131
1132 r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
1133 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1134
1135 buffer[0] = 0;
1136 sz = sizeof buffer - 1;
1137 lstrcat( tempdir, "\\" );
1138 r = MsiGetTargetPath( hpkg, "TARGETDIR", buffer, &sz );
1139 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1140 ok( !lstrcmp(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1141
1142 sprintf( file, "%srootfile.txt", tempdir );
1143 query_file_path( hpkg, "[#RootFile]", buffer );
1144 ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer);
1145
1146 buffer[0] = 0;
1147 sz = sizeof(buffer);
1148 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1149 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1150 lstrcatA( tempdir, "TestParent\\" );
1151 ok( !lstrcmpi(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1152
1153 r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );
1154 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1155
1156 buffer[0] = 0;
1157 sz = sizeof(buffer);
1158 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1159 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1160 ok( lstrcmpi(buffer, "C:\\one\\two\\TestDir\\"),
1161 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1162
1163 buffer[0] = 0;
1164 query_file_path( hpkg, "[#TestFile]", buffer );
1165 ok( !lstrcmpi(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1166 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1167
1168 buffer[0] = 0;
1169 sz = sizeof buffer - 1;
1170 r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1171 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1172 ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1173
1174 r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two\\three" );
1175 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1176
1177 buffer[0] = 0;
1178 sz = sizeof buffer - 1;
1179 r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1180 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1181 ok( !lstrcmpi(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1182
1183 r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\one\\\\two " );
1184 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1185
1186 buffer[0] = 0;
1187 sz = sizeof buffer - 1;
1188 r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1189 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1190 ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1191
1192 r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1193 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1194
1195 buffer[0] = 0;
1196 sz = sizeof buffer - 1;
1197 r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
1198 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1199 ok( !lstrcmpi(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1200
1201 MsiCloseHandle( hpkg );
1202 }
1203
1204 static void test_condition(void)
1205 {
1206 static const WCHAR cond1[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0};
1207 static const WCHAR cond2[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0};
1208 static const WCHAR cond3[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0};
1209 static const WCHAR cond4[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0};
1210 MSICONDITION r;
1211 MSIHANDLE hpkg;
1212
1213 r = package_from_db(create_package_db(), &hpkg);
1214 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1215 {
1216 skip("Not enough rights to perform tests\n");
1217 DeleteFile(msifile);
1218 return;
1219 }
1220 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1221
1222 r = MsiEvaluateCondition(0, NULL);
1223 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1224
1225 r = MsiEvaluateCondition(hpkg, NULL);
1226 ok( r == MSICONDITION_NONE, "wrong return val\n");
1227
1228 r = MsiEvaluateCondition(hpkg, "");
1229 ok( r == MSICONDITION_NONE, "wrong return val\n");
1230
1231 r = MsiEvaluateCondition(hpkg, "1");
1232 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1233
1234 r = MsiEvaluateCondition(hpkg, "0");
1235 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1236
1237 r = MsiEvaluateCondition(hpkg, "-1");
1238 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1239
1240 r = MsiEvaluateCondition(hpkg, "0 = 0");
1241 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1242
1243 r = MsiEvaluateCondition(hpkg, "0 <> 0");
1244 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1245
1246 r = MsiEvaluateCondition(hpkg, "0 = 1");
1247 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1248
1249 r = MsiEvaluateCondition(hpkg, "0 > 1");
1250 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1251
1252 r = MsiEvaluateCondition(hpkg, "0 ~> 1");
1253 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1254
1255 r = MsiEvaluateCondition(hpkg, "1 > 1");
1256 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1257
1258 r = MsiEvaluateCondition(hpkg, "1 ~> 1");
1259 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1260
1261 r = MsiEvaluateCondition(hpkg, "0 >= 1");
1262 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1263
1264 r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
1265 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1266
1267 r = MsiEvaluateCondition(hpkg, "1 >= 1");
1268 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1269
1270 r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
1271 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1272
1273 r = MsiEvaluateCondition(hpkg, "0 < 1");
1274 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1275
1276 r = MsiEvaluateCondition(hpkg, "0 ~< 1");
1277 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1278
1279 r = MsiEvaluateCondition(hpkg, "1 < 1");
1280 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1281
1282 r = MsiEvaluateCondition(hpkg, "1 ~< 1");
1283 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1284
1285 r = MsiEvaluateCondition(hpkg, "0 <= 1");
1286 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1287
1288 r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
1289 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1290
1291 r = MsiEvaluateCondition(hpkg, "1 <= 1");
1292 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1293
1294 r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
1295 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1296
1297 r = MsiEvaluateCondition(hpkg, "0 >=");
1298 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1299
1300 r = MsiEvaluateCondition(hpkg, " ");
1301 ok( r == MSICONDITION_NONE, "wrong return val\n");
1302
1303 r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
1304 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1305
1306 r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
1307 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1308
1309 r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
1310 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1311
1312 r = MsiEvaluateCondition(hpkg, "not 0");
1313 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1314
1315 r = MsiEvaluateCondition(hpkg, "not LicView");
1316 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1317
1318 r = MsiEvaluateCondition(hpkg, "\"Testing\" ~<< \"Testing\"");
1319 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1320
1321 r = MsiEvaluateCondition(hpkg, "LicView ~<< \"Testing\"");
1322 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1323
1324 r = MsiEvaluateCondition(hpkg, "Not LicView ~<< \"Testing\"");
1325 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1326
1327 r = MsiEvaluateCondition(hpkg, "not \"A\"");
1328 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1329
1330 r = MsiEvaluateCondition(hpkg, "~not \"A\"");
1331 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1332
1333 r = MsiEvaluateCondition(hpkg, "\"0\"");
1334 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1335
1336 r = MsiEvaluateCondition(hpkg, "1 and 2");
1337 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1338
1339 r = MsiEvaluateCondition(hpkg, "not 0 and 3");
1340 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1341
1342 r = MsiEvaluateCondition(hpkg, "not 0 and 0");
1343 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1344
1345 r = MsiEvaluateCondition(hpkg, "not 0 or 1");
1346 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1347
1348 r = MsiEvaluateCondition(hpkg, "(0)");
1349 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1350
1351 r = MsiEvaluateCondition(hpkg, "(((((1))))))");
1352 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1353
1354 r = MsiEvaluateCondition(hpkg, "(((((1)))))");
1355 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1356
1357 r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
1358 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1359
1360 r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
1361 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1362
1363 r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
1364 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1365
1366 r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
1367 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1368
1369 r = MsiEvaluateCondition(hpkg, "0 < > 0");
1370 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1371
1372 r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
1373 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1374
1375 r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
1376 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1377
1378 r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
1379 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1380
1381 r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
1382 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1383
1384 r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
1385 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1386
1387 r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
1388 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1389
1390 r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
1391 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1392
1393 r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
1394 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1395
1396 r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
1397 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1398
1399 r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
1400 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1401
1402 r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
1403 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1404
1405 r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
1406 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1407
1408 r = MsiEvaluateCondition(hpkg, "1 XOR 1");
1409 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1410
1411 r = MsiEvaluateCondition(hpkg, "1 IMP 1");
1412 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1413
1414 r = MsiEvaluateCondition(hpkg, "1 IMP 0");
1415 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1416
1417 r = MsiEvaluateCondition(hpkg, "0 IMP 0");
1418 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1419
1420 r = MsiEvaluateCondition(hpkg, "0 EQV 0");
1421 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1422
1423 r = MsiEvaluateCondition(hpkg, "0 EQV 1");
1424 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1425
1426 r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
1427 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1428
1429 r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
1430 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1431
1432 r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
1433 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1434
1435 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
1436 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1437
1438 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
1439 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1440
1441 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
1442 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1443
1444 MsiSetProperty(hpkg, "mm", "5" );
1445
1446 r = MsiEvaluateCondition(hpkg, "mm = 5");
1447 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1448
1449 r = MsiEvaluateCondition(hpkg, "mm < 6");
1450 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1451
1452 r = MsiEvaluateCondition(hpkg, "mm <= 5");
1453 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1454
1455 r = MsiEvaluateCondition(hpkg, "mm > 4");
1456 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1457
1458 r = MsiEvaluateCondition(hpkg, "mm < 12");
1459 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1460
1461 r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
1462 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1463
1464 r = MsiEvaluateCondition(hpkg, "0 = \"\"");
1465 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1466
1467 r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
1468 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1469
1470 r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
1471 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1472
1473 r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
1474 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1475
1476 r = MsiEvaluateCondition(hpkg, "3 >< 1");
1477 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1478
1479 r = MsiEvaluateCondition(hpkg, "3 >< 4");
1480 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1481
1482 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
1483 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1484
1485 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
1486 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1487
1488 r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
1489 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1490
1491 r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
1492 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1493
1494 r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
1495 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1496
1497 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
1498 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1499
1500 r = MsiEvaluateCondition(hpkg, "_1 = _1");
1501 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1502
1503 r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
1504 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1505
1506 r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
1507 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1508
1509 r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1510 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1511
1512 r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
1513 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1514
1515 r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
1516 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1517
1518 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1519 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1520
1521 r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1522 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1523
1524 r = MsiEvaluateCondition(hpkg, "bandalmael<0");
1525 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1526
1527 r = MsiEvaluateCondition(hpkg, "bandalmael>0");
1528 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1529
1530 r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
1531 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1532
1533 r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
1534 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1535
1536 r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
1537 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1538
1539 MsiSetProperty(hpkg, "bandalmael", "0" );
1540 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1541 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1542
1543 MsiSetProperty(hpkg, "bandalmael", "" );
1544 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1545 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1546
1547 MsiSetProperty(hpkg, "bandalmael", "asdf" );
1548 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1549 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1550
1551 MsiSetProperty(hpkg, "bandalmael", "0asdf" );
1552 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1553 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1554
1555 MsiSetProperty(hpkg, "bandalmael", "0 " );
1556 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1557 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1558
1559 MsiSetProperty(hpkg, "bandalmael", "-0" );
1560 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1561 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1562
1563 MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
1564 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1565 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1566
1567 MsiSetProperty(hpkg, "bandalmael", "--0" );
1568 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1569 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1570
1571 MsiSetProperty(hpkg, "bandalmael", "0x00" );
1572 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1573 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1574
1575 MsiSetProperty(hpkg, "bandalmael", "-" );
1576 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1577 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1578
1579 MsiSetProperty(hpkg, "bandalmael", "+0" );
1580 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1581 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1582
1583 MsiSetProperty(hpkg, "bandalmael", "0.0" );
1584 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1585 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1586 r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1587 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1588
1589 MsiSetProperty(hpkg, "one", "hi");
1590 MsiSetProperty(hpkg, "two", "hithere");
1591 r = MsiEvaluateCondition(hpkg, "one >< two");
1592 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1593
1594 MsiSetProperty(hpkg, "one", "hithere");
1595 MsiSetProperty(hpkg, "two", "hi");
1596 r = MsiEvaluateCondition(hpkg, "one >< two");
1597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1598
1599 MsiSetProperty(hpkg, "one", "hello");
1600 MsiSetProperty(hpkg, "two", "hi");
1601 r = MsiEvaluateCondition(hpkg, "one >< two");
1602 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1603
1604 MsiSetProperty(hpkg, "one", "hellohithere");
1605 MsiSetProperty(hpkg, "two", "hi");
1606 r = MsiEvaluateCondition(hpkg, "one >< two");
1607 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1608
1609 MsiSetProperty(hpkg, "one", "");
1610 MsiSetProperty(hpkg, "two", "hi");
1611 r = MsiEvaluateCondition(hpkg, "one >< two");
1612 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1613
1614 MsiSetProperty(hpkg, "one", "hi");
1615 MsiSetProperty(hpkg, "two", "");
1616 r = MsiEvaluateCondition(hpkg, "one >< two");
1617 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1618
1619 MsiSetProperty(hpkg, "one", "");
1620 MsiSetProperty(hpkg, "two", "");
1621 r = MsiEvaluateCondition(hpkg, "one >< two");
1622 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1623
1624 MsiSetProperty(hpkg, "one", "1234");
1625 MsiSetProperty(hpkg, "two", "1");
1626 r = MsiEvaluateCondition(hpkg, "one >< two");
1627 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1628
1629 MsiSetProperty(hpkg, "one", "one 1234");
1630 MsiSetProperty(hpkg, "two", "1");
1631 r = MsiEvaluateCondition(hpkg, "one >< two");
1632 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1633
1634 MsiSetProperty(hpkg, "one", "hithere");
1635 MsiSetProperty(hpkg, "two", "hi");
1636 r = MsiEvaluateCondition(hpkg, "one << two");
1637 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1638
1639 MsiSetProperty(hpkg, "one", "hi");
1640 MsiSetProperty(hpkg, "two", "hithere");
1641 r = MsiEvaluateCondition(hpkg, "one << two");
1642 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1643
1644 MsiSetProperty(hpkg, "one", "hi");
1645 MsiSetProperty(hpkg, "two", "hi");
1646 r = MsiEvaluateCondition(hpkg, "one << two");
1647 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1648
1649 MsiSetProperty(hpkg, "one", "abcdhithere");
1650 MsiSetProperty(hpkg, "two", "hi");
1651 r = MsiEvaluateCondition(hpkg, "one << two");
1652 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1653
1654 MsiSetProperty(hpkg, "one", "");
1655 MsiSetProperty(hpkg, "two", "hi");
1656 r = MsiEvaluateCondition(hpkg, "one << two");
1657 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1658
1659 MsiSetProperty(hpkg, "one", "hithere");
1660 MsiSetProperty(hpkg, "two", "");
1661 r = MsiEvaluateCondition(hpkg, "one << two");
1662 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1663
1664 MsiSetProperty(hpkg, "one", "");
1665 MsiSetProperty(hpkg, "two", "");
1666 r = MsiEvaluateCondition(hpkg, "one << two");
1667 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1668
1669 MsiSetProperty(hpkg, "one", "1234");
1670 MsiSetProperty(hpkg, "two", "1");
1671 r = MsiEvaluateCondition(hpkg, "one << two");
1672 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1673
1674 MsiSetProperty(hpkg, "one", "1234 one");
1675 MsiSetProperty(hpkg, "two", "1");
1676 r = MsiEvaluateCondition(hpkg, "one << two");
1677 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1678
1679 MsiSetProperty(hpkg, "one", "hithere");
1680 MsiSetProperty(hpkg, "two", "there");
1681 r = MsiEvaluateCondition(hpkg, "one >> two");
1682 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1683
1684 MsiSetProperty(hpkg, "one", "hithere");
1685 MsiSetProperty(hpkg, "two", "hi");
1686 r = MsiEvaluateCondition(hpkg, "one >> two");
1687 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1688
1689 MsiSetProperty(hpkg, "one", "there");
1690 MsiSetProperty(hpkg, "two", "hithere");
1691 r = MsiEvaluateCondition(hpkg, "one >> two");
1692 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1693
1694 MsiSetProperty(hpkg, "one", "there");
1695 MsiSetProperty(hpkg, "two", "there");
1696 r = MsiEvaluateCondition(hpkg, "one >> two");
1697 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1698
1699 MsiSetProperty(hpkg, "one", "abcdhithere");
1700 MsiSetProperty(hpkg, "two", "hi");
1701 r = MsiEvaluateCondition(hpkg, "one >> two");
1702 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1703
1704 MsiSetProperty(hpkg, "one", "");
1705 MsiSetProperty(hpkg, "two", "there");
1706 r = MsiEvaluateCondition(hpkg, "one >> two");
1707 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1708
1709 MsiSetProperty(hpkg, "one", "there");
1710 MsiSetProperty(hpkg, "two", "");
1711 r = MsiEvaluateCondition(hpkg, "one >> two");
1712 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1713
1714 MsiSetProperty(hpkg, "one", "");
1715 MsiSetProperty(hpkg, "two", "");
1716 r = MsiEvaluateCondition(hpkg, "one >> two");
1717 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1718
1719 MsiSetProperty(hpkg, "one", "1234");
1720 MsiSetProperty(hpkg, "two", "4");
1721 r = MsiEvaluateCondition(hpkg, "one >> two");
1722 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1723
1724 MsiSetProperty(hpkg, "one", "one 1234");
1725 MsiSetProperty(hpkg, "two", "4");
1726 r = MsiEvaluateCondition(hpkg, "one >> two");
1727 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1728
1729 MsiSetProperty(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1730
1731 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1732 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1733
1734 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1735 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1736
1737 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1738 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1739
1740 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1741 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1742
1743 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1744 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1745
1746 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1747 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1748
1749 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1750 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1751
1752 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1753 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1754
1755 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1756 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1757
1758 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1759 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1760
1761 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1762 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1763
1764 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1765 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1766
1767 r = MsiEvaluateCondition(hpkg, "\"2\" < \"1.1");
1768 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1769
1770 r = MsiEvaluateCondition(hpkg, "\"2\" < \"1.1\"");
1771 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1772
1773 r = MsiEvaluateCondition(hpkg, "\"2\" < \"12.1\"");
1774 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1775
1776 r = MsiEvaluateCondition(hpkg, "\"02.1\" < \"2.11\"");
1777 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1778
1779 r = MsiEvaluateCondition(hpkg, "\"02.1.1\" < \"2.1\"");
1780 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1781
1782 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1783 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1784
1785 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1\"");
1786 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1787
1788 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"0\"");
1789 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1790
1791 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"-1\"");
1792 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1793
1794 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a\"");
1795 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1796
1797 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"!\"");
1798 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1799
1800 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"!\"");
1801 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1802
1803 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"/\"");
1804 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1805
1806 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \" \"");
1807 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1808
1809 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1810 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1811
1812 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1813 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1814
1815 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1816 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1817
1818 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1819 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1820
1821 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
1822 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1823
1824 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"{a}\"");
1825 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1826
1827 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"{a\"");
1828 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1829
1830 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"[a\"");
1831 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1832
1833 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a{\"");
1834 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1835
1836 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"a]\"");
1837 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1838
1839 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"A\"");
1840 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1841
1842 MsiSetProperty(hpkg, "MsiNetAssemblySupport", "1.1.4322");
1843 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1844 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1845
1846 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
1847 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1848
1849 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
1850 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1851
1852 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1853 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1854
1855 r = MsiEvaluateCondition(hpkg, "MsiNetAssemblySupport < \"1\"");
1856 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1857
1858 MsiSetProperty(hpkg, "one", "1");
1859 r = MsiEvaluateCondition(hpkg, "one < \"1\"");
1860 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1861
1862 MsiSetProperty(hpkg, "X", "5.0");
1863
1864 r = MsiEvaluateCondition(hpkg, "X != \"\"");
1865 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1866
1867 r = MsiEvaluateCondition(hpkg, "X =\"5.0\"");
1868 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1869
1870 r = MsiEvaluateCondition(hpkg, "X =\"5.1\"");
1871 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1872
1873 r = MsiEvaluateCondition(hpkg, "X =\"6.0\"");
1874 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1875
1876 r = MsiEvaluateCondition(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
1877 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1878
1879 r = MsiEvaluateCondition(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1880 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1881
1882 r = MsiEvaluateCondition(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
1883 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1884
1885 /* feature doesn't exist */
1886 r = MsiEvaluateCondition(hpkg, "&nofeature");
1887 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1888
1889 MsiSetProperty(hpkg, "A", "2");
1890 MsiSetProperty(hpkg, "X", "50");
1891
1892 r = MsiEvaluateCondition(hpkg, "2 <= X");
1893 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1894
1895 r = MsiEvaluateCondition(hpkg, "A <= X");
1896 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1897
1898 r = MsiEvaluateCondition(hpkg, "A <= 50");
1899 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1900
1901 MsiSetProperty(hpkg, "X", "50val");
1902
1903 r = MsiEvaluateCondition(hpkg, "2 <= X");
1904 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1905
1906 r = MsiEvaluateCondition(hpkg, "A <= X");
1907 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1908
1909 MsiSetProperty(hpkg, "A", "7");
1910 MsiSetProperty(hpkg, "X", "50");
1911
1912 r = MsiEvaluateCondition(hpkg, "7 <= X");
1913 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1914
1915 r = MsiEvaluateCondition(hpkg, "A <= X");
1916 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1917
1918 r = MsiEvaluateCondition(hpkg, "A <= 50");
1919 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1920
1921 MsiSetProperty(hpkg, "X", "50val");
1922
1923 r = MsiEvaluateCondition(hpkg, "2 <= X");
1924 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1925
1926 r = MsiEvaluateCondition(hpkg, "A <= X");
1927 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1928
1929 r = MsiEvaluateConditionW(hpkg, cond1);
1930 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
1931 "wrong return val (%d)\n", r);
1932
1933 r = MsiEvaluateConditionW(hpkg, cond2);
1934 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
1935 "wrong return val (%d)\n", r);
1936
1937 r = MsiEvaluateConditionW(hpkg, cond3);
1938 ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
1939 "wrong return val (%d)\n", r);
1940
1941 r = MsiEvaluateConditionW(hpkg, cond4);
1942 ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
1943 "wrong return val (%d)\n", r);
1944
1945 MsiCloseHandle( hpkg );
1946 DeleteFile(msifile);
1947 }
1948
1949 static BOOL check_prop_empty( MSIHANDLE hpkg, const char * prop)
1950 {
1951 UINT r;
1952 DWORD sz;
1953 char buffer[2];
1954
1955 sz = sizeof buffer;
1956 strcpy(buffer,"x");
1957 r = MsiGetProperty( hpkg, prop, buffer, &sz );
1958 return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
1959 }
1960
1961 static void test_props(void)
1962 {
1963 MSIHANDLE hpkg, hdb;
1964 UINT r;
1965 DWORD sz;
1966 char buffer[0x100];
1967
1968 hdb = create_package_db();
1969 r = run_query( hdb,
1970 "CREATE TABLE `Property` ( "
1971 "`Property` CHAR(255) NOT NULL, "
1972 "`Value` CHAR(255) "
1973 "PRIMARY KEY `Property`)" );
1974 ok( r == ERROR_SUCCESS , "Failed\n" );
1975
1976 r = run_query(hdb,
1977 "INSERT INTO `Property` "
1978 "(`Property`, `Value`) "
1979 "VALUES( 'MetadataCompName', 'Photoshop.dll' )");
1980 ok( r == ERROR_SUCCESS , "Failed\n" );
1981
1982 r = package_from_db( hdb, &hpkg );
1983 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1984 {
1985 skip("Not enough rights to perform tests\n");
1986 DeleteFile(msifile);
1987 return;
1988 }
1989 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1990
1991 /* test invalid values */
1992 r = MsiGetProperty( 0, NULL, NULL, NULL );
1993 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1994
1995 r = MsiGetProperty( hpkg, NULL, NULL, NULL );
1996 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1997
1998 r = MsiGetProperty( hpkg, "boo", NULL, NULL );
1999 ok( r == ERROR_SUCCESS, "wrong return val\n");
2000
2001 r = MsiGetProperty( hpkg, "boo", buffer, NULL );
2002 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2003
2004 /* test retrieving an empty/nonexistent property */
2005 sz = sizeof buffer;
2006 r = MsiGetProperty( hpkg, "boo", NULL, &sz );
2007 ok( r == ERROR_SUCCESS, "wrong return val\n");
2008 ok( sz == 0, "wrong size returned\n");
2009
2010 check_prop_empty( hpkg, "boo");
2011 sz = 0;
2012 strcpy(buffer,"x");
2013 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2014 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2015 ok( !strcmp(buffer,"x"), "buffer was changed\n");
2016 ok( sz == 0, "wrong size returned\n");
2017
2018 sz = 1;
2019 strcpy(buffer,"x");
2020 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2021 ok( r == ERROR_SUCCESS, "wrong return val\n");
2022 ok( buffer[0] == 0, "buffer was not changed\n");
2023 ok( sz == 0, "wrong size returned\n");
2024
2025 /* set the property to something */
2026 r = MsiSetProperty( 0, NULL, NULL );
2027 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
2028
2029 r = MsiSetProperty( hpkg, NULL, NULL );
2030 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
2031
2032 r = MsiSetProperty( hpkg, "", NULL );
2033 ok( r == ERROR_SUCCESS, "wrong return val\n");
2034
2035 /* try set and get some illegal property identifiers */
2036 r = MsiSetProperty( hpkg, "", "asdf" );
2037 ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
2038
2039 r = MsiSetProperty( hpkg, "=", "asdf" );
2040 ok( r == ERROR_SUCCESS, "wrong return val\n");
2041
2042 r = MsiSetProperty( hpkg, " ", "asdf" );
2043 ok( r == ERROR_SUCCESS, "wrong return val\n");
2044
2045 r = MsiSetProperty( hpkg, "'", "asdf" );
2046 ok( r == ERROR_SUCCESS, "wrong return val\n");
2047
2048 sz = sizeof buffer;
2049 buffer[0]=0;
2050 r = MsiGetProperty( hpkg, "'", buffer, &sz );
2051 ok( r == ERROR_SUCCESS, "wrong return val\n");
2052 ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
2053
2054 /* set empty values */
2055 r = MsiSetProperty( hpkg, "boo", NULL );
2056 ok( r == ERROR_SUCCESS, "wrong return val\n");
2057 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2058
2059 r = MsiSetProperty( hpkg, "boo", "" );
2060 ok( r == ERROR_SUCCESS, "wrong return val\n");
2061 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
2062
2063 /* set a non-empty value */
2064 r = MsiSetProperty( hpkg, "boo", "xyz" );
2065 ok( r == ERROR_SUCCESS, "wrong return val\n");
2066
2067 sz = 1;
2068 strcpy(buffer,"x");
2069 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2070 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2071 ok( buffer[0] == 0, "buffer was not changed\n");
2072 ok( sz == 3, "wrong size returned\n");
2073
2074 sz = 4;
2075 strcpy(buffer,"x");
2076 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2077 ok( r == ERROR_SUCCESS, "wrong return val\n");
2078 ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
2079 ok( sz == 3, "wrong size returned\n");
2080
2081 sz = 3;
2082 strcpy(buffer,"x");
2083 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
2084 ok( r == ERROR_MORE_DATA, "wrong return val\n");
2085 ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
2086 ok( sz == 3, "wrong size returned\n");
2087
2088 r = MsiSetProperty(hpkg, "SourceDir", "foo");
2089 ok( r == ERROR_SUCCESS, "wrong return val\n");
2090
2091 sz = 4;
2092 r = MsiGetProperty(hpkg, "SOURCEDIR", buffer, &sz);
2093 ok( r == ERROR_SUCCESS, "wrong return val\n");
2094 ok( !strcmp(buffer,""), "buffer wrong\n");
2095 ok( sz == 0, "wrong size returned\n");
2096
2097 sz = 4;
2098 r = MsiGetProperty(hpkg, "SOMERANDOMNAME", buffer, &sz);
2099 ok( r == ERROR_SUCCESS, "wrong return val\n");
2100 ok( !strcmp(buffer,""), "buffer wrong\n");
2101 ok( sz == 0, "wrong size returned\n");
2102
2103 sz = 4;
2104 r = MsiGetProperty(hpkg, "SourceDir", buffer, &sz);
2105 ok( r == ERROR_SUCCESS, "wrong return val\n");
2106 ok( !strcmp(buffer,"foo"), "buffer wrong\n");
2107 ok( sz == 3, "wrong size returned\n");
2108
2109 r = MsiSetProperty(hpkg, "MetadataCompName", "Photoshop.dll");
2110 ok( r == ERROR_SUCCESS, "wrong return val\n");
2111
2112 sz = 0;
2113 r = MsiGetProperty(hpkg, "MetadataCompName", NULL, &sz );
2114 ok( r == ERROR_SUCCESS, "return wrong\n");
2115 ok( sz == 13, "size wrong (%d)\n", sz);
2116
2117 sz = 13;
2118 r = MsiGetProperty(hpkg, "MetadataCompName", buffer, &sz );
2119 ok( r == ERROR_MORE_DATA, "return wrong\n");
2120 ok( !strcmp(buffer,"Photoshop.dl"), "buffer wrong\n");
2121
2122 r = MsiSetProperty(hpkg, "property", "value");
2123 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2124
2125 sz = 6;
2126 r = MsiGetProperty(hpkg, "property", buffer, &sz);
2127 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2128 ok( !strcmp(buffer, "value"), "Expected value, got %s\n", buffer);
2129
2130 r = MsiSetProperty(hpkg, "property", NULL);
2131 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2132
2133 sz = 6;
2134 r = MsiGetProperty(hpkg, "property", buffer, &sz);
2135 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2136 ok( !strlen(buffer), "Expected empty string, got %s\n", buffer);
2137
2138 MsiCloseHandle( hpkg );
2139 DeleteFile(msifile);
2140 }
2141
2142 static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val)
2143 {
2144 MSIHANDLE hview, hrec;
2145 BOOL found;
2146 CHAR buffer[MAX_PATH];
2147 DWORD sz;
2148 UINT r;
2149
2150 r = MsiDatabaseOpenView(hdb, "SELECT * FROM `_Property`", &hview);
2151 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2152 r = MsiViewExecute(hview, 0);
2153 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2154
2155 found = FALSE;
2156 while (r == ERROR_SUCCESS && !found)
2157 {
2158 r = MsiViewFetch(hview, &hrec);
2159 if (r != ERROR_SUCCESS) break;
2160
2161 sz = MAX_PATH;
2162 r = MsiRecordGetString(hrec, 1, buffer, &sz);
2163 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2164 {
2165 sz = MAX_PATH;
2166 r = MsiRecordGetString(hrec, 2, buffer, &sz);
2167 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, val))
2168 found = TRUE;
2169 }
2170
2171 MsiCloseHandle(hrec);
2172 }
2173
2174 MsiViewClose(hview);
2175 MsiCloseHandle(hview);
2176
2177 return found;
2178 }
2179
2180 static void test_property_table(void)
2181 {
2182 const char *query;
2183 UINT r;
2184 MSIHANDLE hpkg, hdb, hrec;
2185 char buffer[MAX_PATH], package[10];
2186 DWORD sz;
2187 BOOL found;
2188
2189 hdb = create_package_db();
2190 ok( hdb, "failed to create package\n");
2191
2192 r = package_from_db(hdb, &hpkg);
2193 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2194 {
2195 skip("Not enough rights to perform tests\n");
2196 DeleteFile(msifile);
2197 return;
2198 }
2199 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2200
2201 MsiCloseHandle(hdb);
2202
2203 hdb = MsiGetActiveDatabase(hpkg);
2204
2205 query = "CREATE TABLE `_Property` ( "
2206 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2207 r = run_query(hdb, query);
2208 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2209
2210 MsiCloseHandle(hdb);
2211 MsiCloseHandle(hpkg);
2212 DeleteFile(msifile);
2213
2214 hdb = create_package_db();
2215 ok( hdb, "failed to create package\n");
2216
2217 query = "CREATE TABLE `_Property` ( "
2218 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2219 r = run_query(hdb, query);
2220 ok(r == ERROR_SUCCESS, "failed to create table\n");
2221
2222 query = "ALTER `_Property` ADD `foo` INTEGER";
2223 r = run_query(hdb, query);
2224 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2225
2226 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2227 r = run_query(hdb, query);
2228 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2229
2230 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2231 r = run_query(hdb, query);
2232 ok(r == ERROR_SUCCESS, "failed to add column\n");
2233
2234 sprintf(package, "#%i", hdb);
2235 r = MsiOpenPackage(package, &hpkg);
2236 todo_wine ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2237 if (r == ERROR_SUCCESS)
2238 MsiCloseHandle(hpkg);
2239
2240 r = MsiCloseHandle(hdb);
2241 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2242
2243 hdb = create_package_db();
2244 ok (hdb, "failed to create package database\n");
2245
2246 r = create_property_table(hdb);
2247 ok(r == ERROR_SUCCESS, "cannot create Property table: %d\n", r);
2248
2249 r = add_property_entry(hdb, "'prop', 'val'");
2250 ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2251
2252 r = package_from_db(hdb, &hpkg);
2253 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2254
2255 MsiCloseHandle(hdb);
2256
2257 sz = MAX_PATH;
2258 r = MsiGetProperty(hpkg, "prop", buffer, &sz);
2259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2260 ok(!lstrcmp(buffer, "val"), "Expected val, got %s\n", buffer);
2261
2262 hdb = MsiGetActiveDatabase(hpkg);
2263
2264 found = find_prop_in_property(hdb, "prop", "val");
2265 ok(found, "prop should be in the _Property table\n");
2266
2267 r = add_property_entry(hdb, "'dantes', 'mercedes'");
2268 ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
2269
2270 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2271 r = do_query(hdb, query, &hrec);
2272 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2273
2274 found = find_prop_in_property(hdb, "dantes", "mercedes");
2275 ok(found == FALSE, "dantes should not be in the _Property table\n");
2276
2277 sz = MAX_PATH;
2278 lstrcpy(buffer, "aaa");
2279 r = MsiGetProperty(hpkg, "dantes", buffer, &sz);
2280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2281 ok(lstrlenA(buffer) == 0, "Expected empty string, got %s\n", buffer);
2282
2283 r = MsiSetProperty(hpkg, "dantes", "mercedes");
2284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2285
2286 found = find_prop_in_property(hdb, "dantes", "mercedes");
2287 ok(found == TRUE, "dantes should be in the _Property table\n");
2288
2289 MsiCloseHandle(hdb);
2290 MsiCloseHandle(hpkg);
2291 DeleteFile(msifile);
2292 }
2293
2294 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2295 {
2296 MSIHANDLE htab = 0;
2297 UINT res;
2298
2299 res = MsiDatabaseOpenView( hdb, szQuery, &htab );
2300 if( res == ERROR_SUCCESS )
2301 {
2302 UINT r;
2303
2304 r = MsiViewExecute( htab, hrec );
2305 if( r != ERROR_SUCCESS )
2306 {
2307 res = r;
2308 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2309 }
2310
2311 r = MsiViewClose( htab );
2312 if( r != ERROR_SUCCESS )
2313 res = r;
2314
2315 r = MsiCloseHandle( htab );
2316 if( r != ERROR_SUCCESS )
2317 res = r;
2318 }
2319 return res;
2320 }
2321
2322 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2323 {
2324 return try_query_param( hdb, szQuery, 0 );
2325 }
2326
2327 static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
2328 {
2329 MSIHANDLE summary;
2330 UINT r;
2331
2332 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2334
2335 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_LPSTR, 0, NULL, value);
2336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2337
2338 r = MsiSummaryInfoPersist(summary);
2339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2340
2341 MsiCloseHandle(summary);
2342 }
2343
2344 static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
2345 {
2346 MSIHANDLE summary;
2347 UINT r;
2348
2349 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2351
2352 r = MsiSummaryInfoSetPropertyA(summary, pid, VT_I4, value, NULL, NULL);
2353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2354
2355 r = MsiSummaryInfoPersist(summary);
2356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2357
2358 MsiCloseHandle(summary);
2359 }
2360
2361 static void test_msipackage(void)
2362 {
2363 MSIHANDLE hdb = 0, hpack = 100;
2364 UINT r;
2365 const char *query;
2366 char name[10];
2367
2368 /* NULL szPackagePath */
2369 r = MsiOpenPackage(NULL, &hpack);
2370 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2371
2372 /* empty szPackagePath */
2373 r = MsiOpenPackage("", &hpack);
2374 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2375 {
2376 skip("Not enough rights to perform tests\n");
2377 return;
2378 }
2379 todo_wine
2380 {
2381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2382 }
2383
2384 if (r == ERROR_SUCCESS)
2385 MsiCloseHandle(hpack);
2386
2387 /* nonexistent szPackagePath */
2388 r = MsiOpenPackage("nonexistent", &hpack);
2389 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2390
2391 /* NULL hProduct */
2392 r = MsiOpenPackage(msifile, NULL);
2393 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2394
2395 name[0]='#';
2396 name[1]=0;
2397 r = MsiOpenPackage(name, &hpack);
2398 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2399
2400 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2402
2403 /* database exists, but is emtpy */
2404 sprintf(name, "#%d", hdb);
2405 r = MsiOpenPackage(name, &hpack);
2406 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2407 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2408
2409 query = "CREATE TABLE `Property` ( "
2410 "`Property` CHAR(72), `Value` CHAR(0) "
2411 "PRIMARY KEY `Property`)";
2412 r = try_query(hdb, query);
2413 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2414
2415 query = "CREATE TABLE `InstallExecuteSequence` ("
2416 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2417 "PRIMARY KEY `Action`)";
2418 r = try_query(hdb, query);
2419 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2420
2421 /* a few key tables exist */
2422 sprintf(name, "#%d", hdb);
2423 r = MsiOpenPackage(name, &hpack);
2424 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2425 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2426
2427 MsiCloseHandle(hdb);
2428 DeleteFile(msifile);
2429
2430 /* start with a clean database to show what constitutes a valid package */
2431 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2433
2434 sprintf(name, "#%d", hdb);
2435
2436 /* The following summary information props must exist:
2437 * - PID_REVNUMBER
2438 * - PID_PAGECOUNT
2439 */
2440
2441 set_summary_dword(hdb, PID_PAGECOUNT, 100);
2442 r = MsiOpenPackage(name, &hpack);
2443 ok(r == ERROR_INSTALL_PACKAGE_INVALID,
2444 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2445
2446 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2447 r = MsiOpenPackage(name, &hpack);
2448 ok(r == ERROR_SUCCESS,
2449 "Expected ERROR_SUCCESS, got %d\n", r);
2450
2451 MsiCloseHandle(hpack);
2452 MsiCloseHandle(hdb);
2453 DeleteFile(msifile);
2454 }
2455
2456 static void test_formatrecord2(void)
2457 {
2458 MSIHANDLE hpkg, hrec ;
2459 char buffer[0x100];
2460 DWORD sz;
2461 UINT r;
2462
2463 r = package_from_db(create_package_db(), &hpkg);
2464 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2465 {
2466 skip("Not enough rights to perform tests\n");
2467 DeleteFile(msifile);
2468 return;
2469 }
2470 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2471
2472 r = MsiSetProperty(hpkg, "Manufacturer", " " );
2473 ok( r == ERROR_SUCCESS, "set property failed\n");
2474
2475 hrec = MsiCreateRecord(2);
2476 ok(hrec, "create record failed\n");
2477
2478 r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2479 ok( r == ERROR_SUCCESS, "format record failed\n");
2480
2481 buffer[0] = 0;
2482 sz = sizeof buffer;
2483 r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
2484 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2485
2486 r = MsiRecordSetString(hrec, 0, "[foo][1]");
2487 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2488 r = MsiRecordSetString(hrec, 1, "hoo");
2489 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2490 sz = sizeof buffer;
2491 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2492 ok( sz == 3, "size wrong\n");
2493 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2494 ok( r == ERROR_SUCCESS, "format failed\n");
2495
2496 r = MsiRecordSetString(hrec, 0, "x[~]x");
2497 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2498 sz = sizeof buffer;
2499 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2500 ok( sz == 3, "size wrong\n");
2501 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2502 ok( r == ERROR_SUCCESS, "format failed\n");
2503
2504 r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
2505 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2506 r = MsiRecordSetString(hrec, 1, "hoo");
2507 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2508 sz = sizeof buffer;
2509 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2510 ok( sz == 3, "size wrong\n");
2511 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2512 ok( r == ERROR_SUCCESS, "format failed\n");
2513
2514 r = MsiRecordSetString(hrec, 0, "[\\[]");
2515 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2516 sz = sizeof buffer;
2517 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2518 ok( sz == 1, "size wrong\n");
2519 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2520 ok( r == ERROR_SUCCESS, "format failed\n");
2521
2522 SetEnvironmentVariable("FOO", "BAR");
2523 r = MsiRecordSetString(hrec, 0, "[%FOO]");
2524 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2525 sz = sizeof buffer;
2526 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2527 ok( sz == 3, "size wrong\n");
2528 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2529 ok( r == ERROR_SUCCESS, "format failed\n");
2530
2531 r = MsiRecordSetString(hrec, 0, "[[1]]");
2532 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2533 r = MsiRecordSetString(hrec, 1, "%FOO");
2534 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2535 sz = sizeof buffer;
2536 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
2537 ok( sz == 3, "size wrong\n");
2538 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2539 ok( r == ERROR_SUCCESS, "format failed\n");
2540
2541 MsiCloseHandle( hrec );
2542 MsiCloseHandle( hpkg );
2543 DeleteFile(msifile);
2544 }
2545
2546 static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
2547 INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
2548 {
2549 UINT r;
2550 INSTALLSTATE state = 0xdeadbee;
2551 INSTALLSTATE action = 0xdeadbee;
2552
2553 r = MsiGetFeatureState( package, feature, &state, &action );
2554 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2555 if (r == ERROR_SUCCESS)
2556 {
2557 ok( state == expected_state, "%u: expected state %d got %d\n",
2558 line, expected_state, state );
2559 if (todo) todo_wine
2560 ok( action == expected_action, "%u: expected action %d got %d\n",
2561 line, expected_action, action );
2562 else
2563 ok( action == expected_action, "%u: expected action %d got %d\n",
2564 line, expected_action, action );
2565 }
2566 else
2567 {
2568 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
2569 if (todo) todo_wine
2570 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2571 else
2572 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
2573
2574 }
2575 }
2576
2577 static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
2578 INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
2579 {
2580 UINT r;
2581 INSTALLSTATE state = 0xdeadbee;
2582 INSTALLSTATE action = 0xdeadbee;
2583
2584 r = MsiGetComponentState( package, component, &state, &action );
2585 ok( r == error, "%u: expected %d got %d\n", line, error, r );
2586 if (r == ERROR_SUCCESS)
2587 {
2588 ok( state == expected_state, "%u: expected state %d got %d\n",
2589 line, expected_state, state );
2590 if (todo) todo_wine
2591 ok( action == expected_action, "%u: expected action %d got %d\n",
2592 line, expected_action, action );
2593 else
2594 ok( action == expected_action, "%u: expected action %d got %d\n",
2595 line, expected_action, action );
2596 }
2597 else
2598 {
2599 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
2600 line, state );
2601 if (todo) todo_wine
2602 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2603 line, action );
2604 else
2605 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
2606 line, action );
2607 }
2608 }
2609
2610 static void test_states(void)
2611 {
2612 static char msifile2[] = "winetest2-package.msi";
2613 static char msifile3[] = "winetest3-package.msi";
2614 static char msifile4[] = "winetest4-package.msi";
2615 MSIHANDLE hpkg;
2616 UINT r;
2617 MSIHANDLE hdb;
2618
2619 if (is_process_limited())
2620 {
2621 skip("process is limited\n");
2622 return;
2623 }
2624
2625 hdb = create_package_db();
2626 ok ( hdb, "failed to create package database\n" );
2627
2628 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2629 ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
2630
2631 r = create_property_table( hdb );
2632 ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r );
2633
2634 r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
2635 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2636
2637 r = add_property_entry( hdb, "'ProductLanguage', '1033'" );
2638 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2639
2640 r = add_property_entry( hdb, "'ProductName', 'MSITEST'" );
2641 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2642
2643 r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
2644 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2645
2646 r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
2647 ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
2648
2649 r = create_install_execute_sequence_table( hdb );
2650 ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r );
2651
2652 r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
2653 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2654
2655 r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
2656 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2657
2658 r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
2659 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2660
2661 r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
2662 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2663
2664 r = add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
2665 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2666
2667 r = add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
2668 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2669
2670 r = add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
2671 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2672
2673 r = add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
2674 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2675
2676 r = add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
2677 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2678
2679 r = add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
2680 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2681
2682 r = add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
2683 ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r );
2684
2685 r = create_media_table( hdb );
2686 ok( r == ERROR_SUCCESS, "cannot create media table: %d\n", r );
2687
2688 r = add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
2689 ok( r == ERROR_SUCCESS, "cannot add media entry: %d\n", r );
2690
2691 r = create_feature_table( hdb );
2692 ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
2693
2694 r = create_component_table( hdb );
2695 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
2696
2697 /* msidbFeatureAttributesFavorLocal */
2698 r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2699 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2700
2701 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2702 r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
2703 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2704
2705 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2706 r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
2707 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2708
2709 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2710 r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
2711 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2712
2713 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
2714 r = add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
2715 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2716
2717 /* msidbFeatureAttributesFavorSource */
2718 r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
2719 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2720
2721 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2722 r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
2723 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2724
2725 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2726 r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
2727 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2728
2729 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2730 r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
2731 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2732
2733 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
2734 r = add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
2735 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2736
2737 /* msidbFeatureAttributesFavorSource */
2738 r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
2739 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2740
2741 /* msidbFeatureAttributesFavorLocal */
2742 r = add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
2743 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2744
2745 /* disabled */
2746 r = add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
2747 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2748
2749 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2750 r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
2751 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2752
2753 /* no feature parent:msidbComponentAttributesLocalOnly */
2754 r = add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
2755 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2756
2757 /* msidbFeatureAttributesFavorLocal:removed */
2758 r = add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
2759 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2760
2761 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
2762 r = add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
2763 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2764
2765 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
2766 r = add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
2767 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2768
2769 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
2770 r = add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
2771 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2772
2773 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
2774 r = add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
2775 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2776
2777 /* msidbFeatureAttributesFavorSource:removed */
2778 r = add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
2779 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2780
2781 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
2782 r = add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
2783 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2784
2785 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
2786 r = add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
2787 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2788
2789 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
2790 r = add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
2791 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2792
2793 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
2794 r = add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
2795 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2796
2797 /* msidbFeatureAttributesFavorLocal */
2798 r = add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
2799 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2800
2801 r = add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
2802 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2803
2804 /* msidbFeatureAttributesFavorSource */
2805 r = add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
2806 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2807
2808 r = add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
2809 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2810
2811 /* msidbFeatureAttributesFavorAdvertise */
2812 r = add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
2813 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2814
2815 r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
2816 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2817
2818 /* msidbFeatureAttributesUIDisallowAbsent */
2819 r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
2820 ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2821
2822 r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
2823 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2824
2825 r = create_feature_components_table( hdb );
2826 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
2827
2828 r = add_feature_components_entry( hdb, "'one', 'alpha'" );
2829 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2830
2831 r = add_feature_components_entry( hdb, "'one', 'beta'" );
2832 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2833
2834 r = add_feature_components_entry( hdb, "'one', 'gamma'" );
2835 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2836
2837 r = add_feature_components_entry( hdb, "'one', 'theta'" );
2838 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2839
2840 r = add_feature_components_entry( hdb, "'two', 'delta'" );
2841 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2842
2843 r = add_feature_components_entry( hdb, "'two', 'epsilon'" );
2844 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2845
2846 r = add_feature_components_entry( hdb, "'two', 'zeta'" );
2847 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2848
2849 r = add_feature_components_entry( hdb, "'two', 'iota'" );
2850 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2851
2852 r = add_feature_components_entry( hdb, "'three', 'eta'" );
2853 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2854
2855 r = add_feature_components_entry( hdb, "'four', 'eta'" );
2856 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2857
2858 r = add_feature_components_entry( hdb, "'five', 'eta'" );
2859 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2860
2861 r = add_feature_components_entry( hdb, "'six', 'lambda'" );
2862 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2863
2864 r = add_feature_components_entry( hdb, "'six', 'mu'" );
2865 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2866
2867 r = add_feature_components_entry( hdb, "'six', 'nu'" );
2868 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2869
2870 r = add_feature_components_entry( hdb, "'six', 'xi'" );
2871 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2872
2873 r = add_feature_components_entry( hdb, "'seven', 'omicron'" );
2874 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2875
2876 r = add_feature_components_entry( hdb, "'seven', 'pi'" );
2877 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2878
2879 r = add_feature_components_entry( hdb, "'seven', 'rho'" );
2880 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2881
2882 r = add_feature_components_entry( hdb, "'seven', 'sigma'" );
2883 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2884
2885 r = add_feature_components_entry( hdb, "'eight', 'tau'" );
2886 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2887
2888 r = add_feature_components_entry( hdb, "'nine', 'phi'" );
2889 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2890
2891 r = add_feature_components_entry( hdb, "'ten', 'chi'" );
2892 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2893
2894 r = add_feature_components_entry( hdb, "'eleven', 'psi'" );
2895 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2896
2897 r = create_file_table( hdb );
2898 ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
2899
2900 r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
2901 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2902
2903 r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
2904 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2905
2906 r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
2907 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2908
2909 r = add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
2910 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2911
2912 r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
2913 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2914
2915 r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
2916 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2917
2918 r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
2919 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2920
2921 r = add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
2922 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2923
2924 /* compressed file */
2925 r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
2926 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2927
2928 r = add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
2929 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2930
2931 r = add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
2932 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2933
2934 r = add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
2935 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2936
2937 r = add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
2938 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2939
2940 r = add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
2941 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2942
2943 r = add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
2944 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2945
2946 r = add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
2947 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2948
2949 r = add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
2950 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2951
2952 r = add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
2953 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2954
2955 r = add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
2956 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2957
2958 r = add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
2959 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2960
2961 r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
2962 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2963
2964 r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
2965 ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2966
2967 MsiDatabaseCommit(hdb);
2968
2969 /* these properties must not be in the saved msi file */
2970 r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
2971 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
2972
2973 r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
2974 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
2975
2976 r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
2977 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
2978
2979 r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
2980 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
2981
2982 r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
2983 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
2984
2985 r = package_from_db( hdb, &hpkg );
2986 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2987 {
2988 skip("Not enough rights to perform tests\n");
2989 DeleteFile(msifile);
2990 return;
2991 }
2992 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2993
2994 MsiCloseHandle(hdb);
2995
2996 CopyFileA(msifile, msifile2, FALSE);
2997 CopyFileA(msifile, msifile3, FALSE);
2998 CopyFileA(msifile, msifile4, FALSE);
2999
3000 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
3001 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
3002
3003 r = MsiDoAction( hpkg, "CostInitialize");
3004 ok( r == ERROR_SUCCESS, "cost init failed\n");
3005
3006 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3007 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3008
3009 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3010
3011 r = MsiDoAction( hpkg, "FileCost");
3012 ok( r == ERROR_SUCCESS, "file cost failed\n");
3013
3014 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3015 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
3016
3017 r = MsiDoAction( hpkg, "CostFinalize");
3018 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3019
3020 test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3021 test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3022 test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3023 test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3024 test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3025 test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3026 test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3027 test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3028 test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3029 test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3030 test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3031
3032 test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3033 test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3034 test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3035 test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3036 test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3037 test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3038 test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
3039 test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3040 test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
3041 test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3042 test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3043 test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3044 test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3045 test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3046 test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3047 test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3048 test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3049 test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3050 test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3051 test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3052 test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3053 test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
3054
3055 MsiCloseHandle( hpkg );
3056
3057 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3058
3059 /* publish the features and components */
3060 r = MsiInstallProduct(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3062
3063 r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
3064 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3065
3066 /* these properties must not be in the saved msi file */
3067 r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3068 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3069
3070 r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3071 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3072
3073 r = add_property_entry( hdb, "'REMOVE', 'six,seven'");
3074 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3075
3076 r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3077 ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
3078
3079 r = package_from_db( hdb, &hpkg );
3080 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3081
3082 MsiCloseHandle(hdb);