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