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