ReactOS 0.4.17-dev-923-g4c9a150
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];
243 WCHAR substrW[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);
646 sprintf(query, insert, values);
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
3275
3299
3300 MsiCloseHandle(hpkg);
3301
3302 /* uninstall the product */
3303 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3305
3306 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3307 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3308 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3309 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3310
3311 /* all features installed locally */
3312 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3314
3315 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3316 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3317 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3318 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3319
3321 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3322
3323 /* these properties must not be in the saved msi file */
3324 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3325
3326 r = package_from_db( hdb, &hpkg );
3327 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3328
3329 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3330 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3331
3332 r = MsiDoActionA( hpkg, "CostInitialize");
3333 ok( r == ERROR_SUCCESS, "cost init failed\n");
3334
3337
3338 r = MsiDoActionA( hpkg, "CostFinalize");
3339 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3340
3354
3378
3379 MsiCloseHandle(hpkg);
3380
3381 /* uninstall the product */
3382 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384
3385 /* all features installed from source */
3386 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3388
3389 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3390 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3391 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3392 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3393
3394 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3395 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3396
3397 /* this property must not be in the saved msi file */
3398 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3399
3400 r = package_from_db( hdb, &hpkg );
3401 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3402
3403 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3404 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3405
3406 r = MsiDoActionA( hpkg, "CostInitialize");
3407 ok( r == ERROR_SUCCESS, "cost init failed\n");
3408
3411
3412 r = MsiDoActionA( hpkg, "FileCost");
3413 ok( r == ERROR_SUCCESS, "file cost failed\n");
3414
3417
3418 r = MsiDoActionA( hpkg, "CostFinalize");
3419 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3420
3434
3458
3459 MsiCloseHandle(hpkg);
3460
3461 /* reinstall the product */
3462 r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464
3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3466 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3467 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3468 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3469
3470 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3471 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3472
3473 /* this property must not be in the saved msi file */
3474 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3475
3476 r = package_from_db( hdb, &hpkg );
3477 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3478
3479 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3480 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3481
3482 r = MsiDoActionA( hpkg, "CostInitialize");
3483 ok( r == ERROR_SUCCESS, "cost init failed\n");
3484
3487
3488 r = MsiDoActionA( hpkg, "FileCost");
3489 ok( r == ERROR_SUCCESS, "file cost failed\n");
3490
3493
3494 r = MsiDoActionA( hpkg, "CostFinalize");
3495 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3496
3510
3534
3535 MsiCloseHandle(hpkg);
3536
3537 /* test source only install */
3538 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3540 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3541 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3542 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3543 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3544
3545 r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3547 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3548 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3549 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3550 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3551
3552 /* no arguments test */
3553 cache_file_name_len = sizeof(msi_cache_file);
3554 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3555 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3558 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3559
3561 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3562 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3563 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3564 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3565 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3566 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3567 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3568 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3570 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3571
3572 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3573 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3574 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3575 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3576 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3577 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3578 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3579 /* Add "one" feature action tests */
3580 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3581 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3582 r = MsiDatabaseCommit(hdb);
3583 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3584 r = package_from_db( hdb, &hpkg );
3585 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3586 MsiCloseHandle(hdb);
3587
3588 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3589 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3590 r = MsiDoActionA( hpkg, "CostInitialize");
3591 ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3594
3595 r = MsiDoActionA( hpkg, "FileCost");
3596 ok( r == ERROR_SUCCESS, "FileCost failed\n");
3599
3600 r = MsiDoActionA( hpkg, "CostFinalize");
3601 ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3627
3628 r = MsiDoActionA( hpkg, "InstallValidate");
3629 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3632 MsiCloseHandle( hpkg );
3633
3635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3637 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3638 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3639 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3640 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3641 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3642
3643 /* minor upgrade test with no REINSTALL argument */
3644 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3646 size = MAX_PATH;
3647 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3649 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
3650 MsiCloseHandle(hprod);
3651
3652 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3653 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3654 update_ProductVersion_property( hdb, "1.1.2" );
3655 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3656 r = MsiDatabaseCommit(hdb);
3657 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3658 MsiCloseHandle(hdb);
3659
3661 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
3662
3663 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3665
3666 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668 size = MAX_PATH;
3669 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3672 MsiCloseHandle(hprod);
3673
3674 /* major upgrade test */
3675 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3676 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3677 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3678 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3679 create_upgrade_table( hdb );
3680 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3681 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3682 update_ProductVersion_property( hdb, "1.1.3" );
3683 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3684 r = MsiDatabaseCommit(hdb);
3685 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3686 MsiCloseHandle(hdb);
3687
3689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3690
3691 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3692 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3693 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
3694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3695 size = MAX_PATH;
3696 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
3699 MsiCloseHandle(hprod);
3700
3701 /* uninstall the product */
3702 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3704
3707 DeleteFileA(msifile3);
3708 DeleteFileA(msifile4);
3709}
3710
3711static void test_removefiles(void)
3712{
3713 MSIHANDLE hpkg;
3714 UINT r;
3715 MSIHANDLE hdb;
3716 INSTALLSTATE installed, action;
3717
3718 hdb = create_package_db();
3719 ok ( hdb, "failed to create package database\n" );
3720
3721 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3722
3723 create_feature_table( hdb );
3724 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3725
3727 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3728 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3729 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3730 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3731 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3732 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3733 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3734
3736 add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3737 add_feature_components_entry( hdb, "'one', 'helium'" );
3738 add_feature_components_entry( hdb, "'one', 'lithium'" );
3739 add_feature_components_entry( hdb, "'one', 'beryllium'" );
3740 add_feature_components_entry( hdb, "'one', 'boron'" );
3741 add_feature_components_entry( hdb, "'one', 'carbon'" );
3742 add_feature_components_entry( hdb, "'one', 'oxygen'" );
3743
3744 create_file_table( hdb );
3745 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3746 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3747 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3748 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3749 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3750 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3751 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3752
3754
3755 r = package_from_db( hdb, &hpkg );
3757 {
3758 skip("Not enough rights to perform tests\n");
3760 return;
3761 }
3762 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3763
3764 MsiCloseHandle( hdb );
3765
3766 create_test_file( "hydrogen.txt" );
3767 create_test_file( "helium.txt" );
3768 create_test_file( "lithium.txt" );
3769 create_test_file( "beryllium.txt" );
3770 create_test_file( "boron.txt" );
3771 create_test_file( "carbon.txt" );
3772 create_test_file( "oxygen.txt" );
3773
3774 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3775 ok( r == ERROR_SUCCESS, "set property failed\n");
3776
3778
3779 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3780 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3781
3782 r = MsiDoActionA( hpkg, "CostInitialize");
3783 ok( r == ERROR_SUCCESS, "cost init failed\n");
3784
3785 r = MsiDoActionA( hpkg, "FileCost");
3786 ok( r == ERROR_SUCCESS, "file cost failed\n");
3787
3788 installed = action = 0xdeadbeef;
3789 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3790 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3791 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3792 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3793
3794 r = MsiDoActionA( hpkg, "CostFinalize");
3795 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3796
3797 r = MsiDoActionA( hpkg, "InstallValidate");
3798 ok( r == ERROR_SUCCESS, "install validate failed\n");
3799
3800 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3801 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3802
3803 installed = action = 0xdeadbeef;
3804 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3805 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3806 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3807 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3808
3809 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3810 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3811
3812 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3813 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3814
3815 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3816 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3817
3818 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3819 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3820
3821 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3822 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3823
3824 installed = action = 0xdeadbeef;
3825 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3826 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3827 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3828 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3829
3830 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3831 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3832
3833 installed = action = 0xdeadbeef;
3834 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3835 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3836 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3837 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3838
3839 r = MsiDoActionA( hpkg, "RemoveFiles");
3840 ok( r == ERROR_SUCCESS, "remove files failed\n");
3841
3842 installed = action = 0xdeadbeef;
3843 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3844 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3845 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3846 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3847
3848 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3849 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
3850 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
3851 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
3852 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
3853 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
3854 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
3855
3856 MsiCloseHandle( hpkg );
3858}
3859
3860static void test_appsearch(void)
3861{
3862 MSIHANDLE hpkg;
3863 UINT r;
3864 MSIHANDLE hdb;
3865 CHAR prop[MAX_PATH];
3866 DWORD size;
3867 HKEY hkey;
3868 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
3869
3870 hdb = create_package_db();
3871 ok ( hdb, "failed to create package database\n" );
3872
3874 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
3875 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
3876 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
3877 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
3878 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
3879
3881 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
3882
3883 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
3884 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3885 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
3886 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3887 RegCloseKey(hkey);
3888 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3889
3890 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
3891 NULL, &hkey, NULL);
3892 if (r == ERROR_ACCESS_DENIED)
3893 {
3894 skip("insufficient rights\n");
3895 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3896 MsiCloseHandle(hdb);
3898 return;
3899 }
3900 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3901
3902 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3903 sizeof("c:\\windows\\system32\\notepad.exe"));
3904 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3905 RegCloseKey(hkey);
3906 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
3907
3908 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
3909 NULL, &hkey, NULL);
3910 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
3911 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
3912 sizeof("c:\\windows\\system32\\notepad.exe"));
3913 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
3914 RegCloseKey(hkey);
3915 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
3917
3919 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
3920
3922 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
3923 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3924 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3925 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3926 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
3927
3928 r = package_from_db( hdb, &hpkg );
3930 {
3931 skip("Not enough rights to perform tests\n");
3933 return;
3934 }
3935 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3936 MsiCloseHandle( hdb );
3937 if (r != ERROR_SUCCESS)
3938 goto done;
3939
3941
3942 r = MsiDoActionA( hpkg, "AppSearch" );
3943 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
3944
3945 size = sizeof(prop);
3946 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
3947 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3948 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3949
3950 size = sizeof(prop);
3951 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
3952 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3953
3954 size = sizeof(prop);
3955 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
3956 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3957 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3958
3959 size = sizeof(prop);
3960 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
3961 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3962 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3963
3964 size = sizeof(prop);
3965 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
3966 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3967 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
3968
3969done:
3970 MsiCloseHandle( hpkg );
3972 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
3973 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY, 0);
3974 RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY, 0);
3975}
3976
3978{
3979 MSIHANDLE hpkg, hdb;
3980 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
3981 LPSTR usersid;
3982 DWORD size;
3983 UINT r;
3984
3985 if (!(usersid = get_user_sid()))
3986 return;
3987
3988 if (!is_process_elevated())
3989 {
3990 skip("process is limited\n");
3991 return;
3992 }
3993
3994 create_test_file("FileName1");
3995 create_test_file("FileName4");
3997 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
3998
3999 create_test_file("FileName2");
4001 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4002
4003 create_test_file("FileName3");
4005 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4006
4007 create_test_file("FileName5");
4009 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4010
4011 create_test_file("FileName6");
4013 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4014
4015 create_test_file("FileName7");
4017 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4018
4019 /* dir is FALSE, but we're pretending it's a directory */
4021 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4022
4023 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4025 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4026
4027 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4029 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4030
4031 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4033 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4034
4035 hdb = create_package_db();
4036 ok(hdb, "Expected a valid database handle\n");
4037
4039 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4040 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4041 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4042 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4043 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4044 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4045 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4046 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4047 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4048 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4049 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4050 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4051
4053
4054 /* published component, machine, file, signature, misdbLocatorTypeFile */
4055 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4056
4057 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4058 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4059
4060 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4061 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4062
4063 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4064 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4065
4066 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4067 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4068
4069 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4070 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4071
4072 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4073 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4074
4075 /* unpublished component, no signature, misdbLocatorTypeDir */
4076 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4077
4078 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4079 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4080
4081 /* published component, signature w/ ver, misdbLocatorTypeFile */
4082 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4083
4084 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4085 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4086
4087 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4088 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4089
4091 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4092 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4093 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4094 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4095 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4096 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4097 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4098 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4099
4100 r = package_from_db(hdb, &hpkg);
4102 {
4103 skip("Not enough rights to perform tests\n");
4104 goto error;
4105 }
4106 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4107
4108 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4110
4112
4113 r = MsiDoActionA(hpkg, "AppSearch");
4114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115
4117 if (is_root(CURR_DIR)) expected[2] = 0;
4118
4119 size = MAX_PATH;
4120 sprintf(path, "%s\\FileName1", expected);
4121 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4124
4125 size = MAX_PATH;
4126 sprintf(path, "%s\\FileName2", expected);
4127 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4129 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4130
4131 size = MAX_PATH;
4132 sprintf(path, "%s\\FileName3", expected);
4133 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4135 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4136
4137 size = MAX_PATH;
4138 sprintf(path, "%s\\FileName4", expected);
4139 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4141 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4142
4143 size = MAX_PATH;
4144 sprintf(path, "%s\\FileName5", expected);
4145 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4147 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4148
4149 size = MAX_PATH;
4150 sprintf(path, "%s\\", expected);
4151 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4153 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4154
4155 size = MAX_PATH;
4156 sprintf(path, "%s\\", expected);
4157 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4159 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4160
4161 size = MAX_PATH;
4162 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4164 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4165
4166 size = MAX_PATH;
4167 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4169 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4170
4171 size = MAX_PATH;
4172 sprintf(path, "%s\\FileName8.dll", expected);
4173 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4175 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4176
4177 size = MAX_PATH;
4178 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4181
4182 size = MAX_PATH;
4183 sprintf(path, "%s\\FileName10.dll", expected);
4184 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4186 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4187
4188 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4190 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4192 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4194 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4196 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4198 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4200 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4202 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4204 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4206 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4208
4209 MsiCloseHandle(hpkg);
4210
4211error:
4212 DeleteFileA("FileName1");
4213 DeleteFileA("FileName2");
4214 DeleteFileA("FileName3");
4215 DeleteFileA("FileName4");
4216 DeleteFileA("FileName5");
4217 DeleteFileA("FileName6");
4218 DeleteFileA("FileName7");
4219 DeleteFileA("FileName8.dll");
4220 DeleteFileA("FileName9.dll");
4221 DeleteFileA("FileName10.dll");
4223 LocalFree(usersid);
4224}
4225
4227{
4228 MSIHANDLE hpkg, hdb;
4229 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4230 DWORD binary[2], size, val;
4231 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4232 HKEY hklm, classes, hkcu, users;
4233 LPSTR pathdata, pathvar, ptr;
4234 LONG res;
4235 UINT r, type = 0;
4237
4238 version = TRUE;
4239 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4240 version = FALSE;
4241
4242 DeleteFileA("test.dll");
4243
4244 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4245 if (res == ERROR_ACCESS_DENIED)
4246 {
4247 skip("Not enough rights to perform tests\n");
4248 return;
4249 }
4250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4251
4252 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4253 (const BYTE *)"regszdata", 10);
4254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4255
4256 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4258
4259 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4260 (const BYTE *)"regszdata", 10);
4261 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4262
4263 users = 0;
4264 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4266
4267 if (res == ERROR_SUCCESS)
4268 {
4269 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4270 (const BYTE *)"regszdata", 10);
4271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4272 }
4273
4274 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4276
4277 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4279
4280 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4281 (const BYTE *)"regszdata", 10);
4282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4283
4284 val = 42;
4285 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4286 (const BYTE *)&val, sizeof(DWORD));
4287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4288
4289 val = -42;
4290 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4291 (const BYTE *)&val, sizeof(DWORD));
4292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4293
4294 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4295 (const BYTE *)"%PATH%", 7);
4296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4297
4298 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4299 (const BYTE *)"my%NOVAR%", 10);
4300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4301
4302 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4303 (const BYTE *)"one\0two\0", 9);
4304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4305
4306 binary[0] = 0x1234abcd;
4307 binary[1] = 0x567890ef;
4308 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4309 (const BYTE *)binary, sizeof(binary));
4310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4311
4312 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4313 (const BYTE *)"#regszdata", 11);
4314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4315
4317 if (is_root(CURR_DIR)) expected[2] = 0;
4318
4319 create_test_file("FileName1");
4320 sprintf(path, "%s\\FileName1", expected);
4321 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4322 (const BYTE *)path, lstrlenA(path) + 1);
4323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4324
4325 sprintf(path, "%s\\FileName2", expected);
4326 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4327 (const BYTE *)path, lstrlenA(path) + 1);
4328 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4329
4331 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4332 (const BYTE *)path, lstrlenA(path) + 1);
4333 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4334
4335 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4336 (const BYTE *)"", 1);
4337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4338
4339 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4340 sprintf(path, "%s\\FileName3.dll", expected);
4341 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4342 (const BYTE *)path, lstrlenA(path) + 1);
4343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4344
4345 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4346 sprintf(path, "%s\\FileName4.dll", expected);
4347 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4348 (const BYTE *)path, lstrlenA(path) + 1);
4349 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4350
4351 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4352 sprintf(path, "%s\\FileName5.dll", expected);
4353 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4354 (const BYTE *)path, lstrlenA(path) + 1);
4355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4356
4357 sprintf(path, "\"%s\\FileName1\" -option", expected);
4358 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4359 (const BYTE *)path, lstrlenA(path) + 1);
4360 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4361
4362 space = strchr(expected, ' ') != NULL;
4363 sprintf(path, "%s\\FileName1 -option", expected);
4364 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4365 (const BYTE *)path, lstrlenA(path) + 1);
4366 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4367
4368 hdb = create_package_db();
4369 ok(hdb, "Expected a valid database handle\n");
4370
4372 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4373 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4374 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4375 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4376 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4377 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4378 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4379 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4380 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4381 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4382 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4383 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4384 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4385 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4386 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4387 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4388 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4389 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4390 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4391 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4392 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4393 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4394 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4395 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4396 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4397 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4398 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4399 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4400 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4401 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4402
4404
4406 if (is_64bit)
4408
4409 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4410 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4411
4412 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4413 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4414
4415 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4416 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4417
4418 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4419 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4420
4421 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4422 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4423
4424 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4425 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4426
4427 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4428 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4429
4430 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4431 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4432
4434 if (is_64bit)
4436
4437 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4438 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4439
4440 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4441 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4442
4443 /* HKLM, msidbLocatorTypeFileName, no signature */
4444 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4445
4447 if (is_64bit)
4449
4450 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4451 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4452
4453 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4454 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4455
4456 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4457 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4458
4460 if (is_64bit)
4462
4463 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4464 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4465
4466 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4467 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4468
4469 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4470 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4471
4472 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4473 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4474
4475 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4476 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4477
4478 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4479 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4480
4482 if (is_64bit)
4484
4485 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4486 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4487
4488 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4489 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4490
4491 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4492 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4493
4494 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4495 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4496
4497 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4498 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4499
4501 if (is_64bit)
4503
4504 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4505 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4506
4507 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4508 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4509
4510 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4511 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4512
4514 if (is_64bit)
4516
4517 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4518 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4519
4520 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4521 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4522
4524 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4525 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4526 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4527 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4528 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4529 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4530
4531 if (!is_root(CURR_DIR))
4532 {
4533 ptr = strrchr(expected, '\\') + 1;
4534 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4536 }
4537 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4538 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4539 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4540
4541 r = package_from_db(hdb, &hpkg);
4542 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4543
4545
4546 r = MsiDoActionA(hpkg, "AppSearch");
4547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4548
4549 size = MAX_PATH;
4550 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4552 ok(!lstrcmpA(prop, "regszdata"),
4553 "Expected \"regszdata\", got \"%s\"\n", prop);
4554
4555 size = MAX_PATH;
4556 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4558 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4559
4560 size = MAX_PATH;
4561 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4563 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4564
4565 memset(&si, 0, sizeof(si));
4567
4569 {
4570 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4571 pathvar = malloc(size);
4572 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4573
4574 size = 0;
4575 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4577
4578 pathdata = malloc(++size);
4579 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4581 ok(!lstrcmpA(pathdata, pathvar),
4582 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4583
4584 free(pathvar);
4585 free(pathdata);
4586 }
4587
4588 size = MAX_PATH;
4589 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4591 ok(!lstrcmpA(prop,
4592 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4593
4594 size = MAX_PATH;
4595 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4597 todo_wine
4598 {
4599 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4600 "Expected \"\\0one\\0two\\0\\0\"\n");
4601 }
4602
4603 size = MAX_PATH;
4604 lstrcpyA(path, "#xCDAB3412EF907856");
4605 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4607 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4608
4609 size = MAX_PATH;
4610 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4612 ok(!lstrcmpA(prop, "##regszdata"),
4613 "Expected \"##regszdata\", got \"%s\"\n", prop);
4614
4615 size = MAX_PATH;
4616 sprintf(path, "%s\\FileName1", expected);
4617 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4619 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4620
4621 size = MAX_PATH;
4622 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4624 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4625
4626 size = MAX_PATH;
4627 sprintf(path, "%s\\", expected);
4628 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4630 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4631
4632 size = MAX_PATH;
4633 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4635 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4636
4637 size = MAX_PATH;
4638 sprintf(path, "%s\\", expected);
4639 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4641 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4642
4643 size = MAX_PATH;
4644 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4646 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4647
4648 size = MAX_PATH;
4649 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4651 ok(!lstrcmpA(prop, "regszdata"),
4652 "Expected \"regszdata\", got \"%s\"\n", prop);
4653
4654 size = MAX_PATH;
4655 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4657 ok(!lstrcmpA(prop, "regszdata"),
4658 "Expected \"regszdata\", got \"%s\"\n", prop);
4659
4660 if (users)
4661 {
4662 size = MAX_PATH;
4663 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4665 ok(!lstrcmpA(prop, "regszdata"),
4666 "Expected \"regszdata\", got \"%s\"\n", prop);
4667 }
4668
4669 size = MAX_PATH;
4670 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4672 ok(!lstrcmpA(prop, "defvalue"),
4673 "Expected \"defvalue\", got \"%s\"\n", prop);
4674
4675 size = MAX_PATH;
4676 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4679
4680 size = MAX_PATH;
4681 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4682 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4683 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4684
4685 if (version)
4686 {
4687 size = MAX_PATH;
4688 sprintf(path, "%s\\FileName3.dll", expected);
4689 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4692
4693 size = MAX_PATH;
4694 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4697
4698 size = MAX_PATH;
4699 sprintf(path, "%s\\FileName5.dll", expected);
4700 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4703 }
4704
4705 if (!is_root(CURR_DIR))
4706 {
4707 size = MAX_PATH;
4709 ptr = strrchr(path, '\\') + 1;
4710 *ptr = '\0';
4711 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4713 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4714 }
4715 size = MAX_PATH;
4716 sprintf(path, "%s\\", expected);
4717 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4719 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4720
4721 size = MAX_PATH;
4722 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4724 if (is_root(CURR_DIR))
4725 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4726 else
4727 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4728
4729 size = MAX_PATH;
4730 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4732 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4733
4734 size = MAX_PATH;
4735 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4737 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4738
4739 size = MAX_PATH;
4740 sprintf(path, "%s\\FileName1", expected);
4741 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4744
4745 size = MAX_PATH;
4746 sprintf(path, "%s\\FileName1", expected);
4747 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749 if (space)
4750 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4751 else
4752 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4753
4754 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4755 RegDeleteValueA(hklm, "Value1");
4756 RegDeleteValueA(hklm, "Value2");
4757 RegDeleteValueA(hklm, "Value3");
4758 RegDeleteValueA(hklm, "Value4");
4759 RegDeleteValueA(hklm, "Value5");
4760 RegDeleteValueA(hklm, "Value6");
4761 RegDeleteValueA(hklm, "Value7");
4762 RegDeleteValueA(hklm, "Value8");
4763 RegDeleteValueA(hklm, "Value9");
4764 RegDeleteValueA(hklm, "Value10");
4765 RegDeleteValueA(hklm, "Value11");
4766 RegDeleteValueA(hklm, "Value12");
4767 RegDeleteValueA(hklm, "Value13");
4768 RegDeleteValueA(hklm, "Value14");
4769 RegDeleteValueA(hklm, "Value15");
4770 RegDeleteValueA(hklm, "Value16");
4771 RegDeleteValueA(hklm, "Value17");
4772 RegDeleteKeyA(hklm, "");
4773 RegCloseKey(hklm);
4774
4775 RegDeleteValueA(classes, "Value1");
4778
4779 RegDeleteValueA(hkcu, "Value1");
4780 RegDeleteKeyA(hkcu, "");
4781 RegCloseKey(hkcu);
4782
4783 RegDeleteValueA(users, "Value1");
4784 RegDeleteKeyA(users, "");
4785 RegCloseKey(users);
4786
4787 DeleteFileA("FileName1");
4788 DeleteFileA("FileName3.dll");
4789 DeleteFileA("FileName4.dll");
4790 DeleteFileA("FileName5.dll");
4791 MsiCloseHandle(hpkg);
4793}
4794
4796{
4798
4800 lstrcatA(path, "\\");
4801 lstrcatA(path, file);
4802
4804}
4805
4807{
4808 MSIHANDLE hpkg, hdb;
4809 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4810 BOOL version;
4811 LPSTR ptr;
4812 DWORD size;
4813 UINT r;
4814
4815 version = TRUE;
4816 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4817 version = FALSE;
4818
4819 DeleteFileA("test.dll");
4820
4821 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4822
4824 if (is_root(CURR_DIR)) expected[2] = 0;
4825
4826 create_test_file("FileName1");
4827 sprintf(path, "%s\\FileName1", expected);
4828 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4829
4830 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4831
4832 sprintf(path, "%s\\IDontExist", expected);
4833 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4834
4835 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4836 sprintf(path, "%s\\FileName2.dll", expected);
4837 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4838
4839 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4840 sprintf(path, "%s\\FileName3.dll", expected);
4841 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4842
4843 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4844 sprintf(path, "%s\\FileName4.dll", expected);
4845 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4846
4847 hdb = create_package_db();
4848 ok(hdb, "Expected a valid database handle\n");
4849
4851 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4852 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4853 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4854 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4855 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4856 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4857 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4858 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4859 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4860 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4861 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4862 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4863
4865
4866 /* msidbLocatorTypeRawValue, field 1 */
4867 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
4868
4869 /* msidbLocatorTypeRawValue, field 2 */
4870 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
4871
4872 /* msidbLocatorTypeRawValue, entire field */
4873 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
4874
4875 /* msidbLocatorTypeFile */
4876 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4877
4878 /* msidbLocatorTypeDirectory, file */
4879 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
4880
4881 /* msidbLocatorTypeDirectory, directory */
4882 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
4883
4884 /* msidbLocatorTypeFile, file, no signature */
4885 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
4886
4887 /* msidbLocatorTypeFile, dir, no signature */
4888 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
4889
4890 /* msidbLocatorTypeFile, file does not exist */
4891 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
4892
4893 /* msidbLocatorTypeFile, signature with version */
4894 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
4895
4896 /* msidbLocatorTypeFile, signature with version, ver > max */
4897 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
4898
4899 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
4900 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
4901
4903 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
4904 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
4905 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4906 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4907 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4908
4909 r = package_from_db(hdb, &hpkg);
4911 {
4912 skip("Not enough rights to perform tests\n");
4913 goto error;
4914 }
4915 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4916
4917 MsiCloseHandle( hdb );
4919
4920 r = MsiDoActionA(hpkg, "AppSearch");
4921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4922
4923 size = MAX_PATH;
4924 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4926 if (!prop[0])
4927 {
4928 win_skip("broken result\n");
4929 MsiCloseHandle(hpkg);
4930 goto error;
4931 }
4932 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
4933
4934 size = MAX_PATH;
4935 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4937 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
4938
4939 size = MAX_PATH;
4940 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942 ok(!lstrcmpA(prop, "keydata,field2"),
4943 "Expected \"keydata,field2\", got \"%s\"\n", prop);
4944
4945 size = MAX_PATH;
4946 sprintf(path, "%s\\FileName1", expected);
4947 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4950
4951 size = MAX_PATH;
4952 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4955
4956 size = MAX_PATH;
4957 sprintf(path, "%s\\", expected);
4958 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4961
4962 size = MAX_PATH;
4963 sprintf(path, "%s\\", expected);
4964 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4966 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4967
4968 if (!is_root(CURR_DIR))
4969 {
4970 size = MAX_PATH;
4972 ptr = strrchr(path, '\\');
4973 *(ptr + 1) = 0;
4974 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4976 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4977 }
4978 size = MAX_PATH;
4979 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4981 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4982
4983 if (version)
4984 {
4985 size = MAX_PATH;
4986 sprintf(path, "%s\\FileName2.dll", expected);
4987 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4989 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4990
4991 size = MAX_PATH;
4992 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4994 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4995
4996 size = MAX_PATH;
4997 sprintf(path, "%s\\FileName4.dll", expected);
4998 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5000 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5001 }
5002
5003 MsiCloseHandle(hpkg);
5004
5005error:
5006 delete_win_ini("IniFile.ini");
5007 DeleteFileA("FileName1");
5008 DeleteFileA("FileName2.dll");
5009 DeleteFileA("FileName3.dll");
5010 DeleteFileA("FileName4.dll");
5012}
5013
5014/*
5015 * MSI AppSearch action on DrLocator table always returns absolute paths.
5016 * If a relative path was set, it returns the first absolute path that
5017 * matches or an empty string if it didn't find anything.
5018 * This helper function replicates this behaviour.
5019 */
5020static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5021{
5022 int i, size;
5023 DWORD attr, drives;
5024
5025 size = lstrlenA(relative);
5026 drives = GetLogicalDrives();
5027 lstrcpyA(absolute, "A:\\");
5028 for (i = 0; i < 26; absolute[0] = '\0', i++)
5029 {
5030 if (!(drives & (1 << i)))
5031 continue;
5032
5033 absolute[0] = 'A' + i;
5034 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5035 continue;
5036
5037 lstrcpynA(absolute + 3, relative, size + 1);
5038 attr = GetFileAttributesA(absolute);
5041 {
5042 if (absolute[3 + size - 1] != '\\')
5043 lstrcatA(absolute, "\\");
5044 break;
5045 }
5046 absolute[3] = '\0';
5047 }
5048}
5049
5051{
5052 MSIHANDLE hpkg, hdb;
5053 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5054 BOOL version;
5055 DWORD size;
5056 UINT r;
5057
5058 version = TRUE;
5059 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5060 version = FALSE;
5061
5062 DeleteFileA("test.dll");
5063
5064 create_test_file("FileName1");
5065 CreateDirectoryA("one", NULL);
5066 CreateDirectoryA("one\\two", NULL);
5067 CreateDirectoryA("one\\two\\three", NULL);
5068 create_test_file("one\\two\\three\\FileName2");
5069 CreateDirectoryA("another", NULL);
5070 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5071 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5072 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5073
5074 hdb = create_package_db();
5075 ok(hdb, "Expected a valid database handle\n");
5076
5078 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5079 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5080 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5081 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5082 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5083 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5084 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5085 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5086 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5087 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5088 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5089 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5090
5092
5094 if (is_root(CURR_DIR)) expected[2] = 0;
5095
5096 /* no parent, full path, depth 0, signature */
5097 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5099
5100 /* no parent, full path, depth 0, no signature */
5101 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5103
5104 /* no parent, relative path, depth 0, no signature */
5105 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5107
5108 /* no parent, full path, depth 2, signature */
5109 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5111
5112 /* no parent, full path, depth 3, signature */
5113 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5115
5116 /* no parent, full path, depth 1, signature is dir */
5117 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5119
5120 /* parent is in DrLocator, relative path, depth 0, signature */
5121 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5123
5124 /* no parent, full path, depth 0, signature w/ version */
5125 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5127
5128 /* no parent, full path, depth 0, signature w/ version, ver > max */
5129 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5131
5132 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5133 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5135
5136 /* no parent, relative empty path, depth 0, no signature */
5137 sprintf(path, "'NewSignature11', '', '', 0");
5139
5141
5142 /* parent */
5143 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5144
5145 /* parent is in RegLocator, no path, depth 0, no signature */
5146 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5148
5150 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5151 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5152 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5153 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5154 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5155 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5156 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5157 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5158
5159 r = package_from_db(hdb, &hpkg);
5161 {
5162 skip("Not enough rights to perform tests\n");
5163 goto error;
5164 }
5165 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5166
5168
5169 r = MsiDoActionA(hpkg, "AppSearch");
5170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5171
5172 size = MAX_PATH;
5173 sprintf(path, "%s\\FileName1", expected);
5174 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5176 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5177
5178 size = MAX_PATH;
5179 sprintf(path, "%s\\", expected);
5180 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5182 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5183
5184 size = MAX_PATH;
5186 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5188 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5189
5190 size = MAX_PATH;
5191 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5193 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5194
5195 size = MAX_PATH;
5196 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5197 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5199 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5200
5201 size = MAX_PATH;
5202 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5204 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5205
5206 size = MAX_PATH;
5207 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5208 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5210 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5211
5212 if (version)
5213 {
5214 size = MAX_PATH;
5215 sprintf(path, "%s\\FileName3.dll", expected);
5216 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5218 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5219
5220 size = MAX_PATH;
5221 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5223 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5224
5225 size = MAX_PATH;
5226 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5228 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5229 }
5230
5231 size = MAX_PATH;
5233 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5236
5237 size = MAX_PATH;
5238 strcpy(path, "c:\\");
5239 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5242
5243 MsiCloseHandle(hpkg);
5244
5245error:
5246 DeleteFileA("FileName1");
5247 DeleteFileA("FileName3.dll");
5248 DeleteFileA("FileName4.dll");
5249 DeleteFileA("FileName5.dll");
5250 DeleteFileA("one\\two\\three\\FileName2");
5251 RemoveDirectoryA("one\\two\\three");
5252 RemoveDirectoryA("one\\two");
5253 RemoveDirectoryA("one");
5254 RemoveDirectoryA("another");
5256}
5257
5258static void test_featureparents(void)
5259{
5260 MSIHANDLE hpkg;
5261 UINT r;
5262 MSIHANDLE hdb;
5263
5264 hdb = create_package_db();
5265 ok ( hdb, "failed to create package database\n" );
5266
5267 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5268
5269 create_feature_table( hdb );
5272 create_file_table( hdb );
5273
5274 /* msidbFeatureAttributesFavorLocal */
5275 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5276
5277 /* msidbFeatureAttributesFavorSource */
5278 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5279
5280 /* msidbFeatureAttributesFavorLocal */
5281 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5282
5283 /* msidbFeatureAttributesUIDisallowAbsent */
5284 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5285
5286 /* msidbFeatureAttributesDisallowAdvertise */
5287 add_feature_entry( hdb, "'cygnus', '', '', '', 2, 1, '', 8" );
5288
5289 /* advertise allowed */
5290 add_feature_entry( hdb, "'lacerta', '', '', '', 2, 1, '', 0" );
5291
5292 /* disabled because of install level */
5293 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5294
5295 /* child feature of disabled feature */
5296 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5297
5298 /* component of disabled feature (install level) */
5299 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5300
5301 /* component of disabled child feature (install level) */
5302 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5303
5304 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5305 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5306
5307 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5308 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5309
5310 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5311 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5312
5313 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5314 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5315
5316 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5317 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5318
5319 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5320 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5321
5322 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5323 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5324
5325 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5326 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5327
5328 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5329 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5330
5331 add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5332 add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5333 add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5334 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5335 add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5336 add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5337 add_feature_components_entry( hdb, "'orion', 'leo'" );
5338 add_feature_components_entry( hdb, "'orion', 'virgo'" );
5339 add_feature_components_entry( hdb, "'orion', 'libra'" );
5340 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5341 add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5342 add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5343 add_feature_components_entry( hdb, "'orion', 'canis'" );
5344 add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5345 add_feature_components_entry( hdb, "'orion', 'lepus'" );
5346 add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5347 add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5348
5349 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5350 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5351 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5352 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5353 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5354 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5355 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5356 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5357 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5358 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5359 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5360
5361 r = package_from_db( hdb, &hpkg );
5363 {
5364 skip("Not enough rights to perform tests\n");
5366 return;
5367 }
5368 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5369
5370 MsiCloseHandle( hdb );
5371
5373
5374 r = MsiDoActionA( hpkg, "CostInitialize");
5375 ok( r == ERROR_SUCCESS, "cost init failed\n");
5376
5377 r = MsiDoActionA( hpkg, "FileCost");
5378 ok( r == ERROR_SUCCESS, "file cost failed\n");
5379
5380 r = MsiDoActionA( hpkg, "CostFinalize");
5381 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5382
5391
5403
5404 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5405 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5406
5407 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5408 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5409
5410 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5411 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5412
5414 ok(!r, "got %d\n", r);
5415
5416 r = MsiSetFeatureStateA(hpkg, "lacerta", INSTALLSTATE_ADVERTISED);
5417 ok(!r, "got %d\n", r);
5418
5427
5439
5440 MsiCloseHandle(hpkg);
5442}
5443
5444static void test_installprops(void)
5445{
5446 MSIHANDLE hpkg, hdb;
5448 DWORD size, type;
5449 LANGID langid;
5450 HKEY hkey1, hkey2, pathkey = NULL;
5451 int res;
5452 UINT r;
5455 INSTALLUILEVEL uilevel;
5456
5457 if (is_wow64)
5459
5461 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5463
5465
5466 hdb = create_package_db();
5467 ok( hdb, "failed to create database\n");
5468
5469 r = package_from_db(hdb, &hpkg);
5471 {
5472 skip("Not enough rights to perform tests\n");
5473 MsiSetInternalUI(uilevel, NULL);
5475 return;
5476 }
5477 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5478
5479 MsiCloseHandle(hdb);
5480
5481 buf[0] = 0;
5482 size = MAX_PATH;
5483 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5484 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5485 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5486
5488
5489 buf[0] = 0;
5490 size = MAX_PATH;
5491 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5492 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5493 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5494
5495 buf[0] = 0;
5496 size = MAX_PATH;
5497 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5498 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5499 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5500
5501 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5502 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5503 if (res == ERROR_ACCESS_DENIED)
5504 {
5505 win_skip("no access\n");
5506 goto done;
5507 }
5508 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5509 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5510
5511 size = MAX_PATH;
5512 type = REG_SZ;
5513 *path = '\0';
5514 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5515 {
5516 size = MAX_PATH;
5517 type = REG_SZ;
5518 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5519 }
5520
5521 buf[0] = 0;
5522 size = MAX_PATH;
5523 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5524 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5525 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5526
5527 size = MAX_PATH;
5528 type = REG_SZ;
5529 *path = '\0';
5530 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5531 {
5532 size = MAX_PATH;
5533 type = REG_SZ;
5534 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5535 }
5536
5537 if (*path)
5538 {
5539 buf[0] = 0;
5540 size = MAX_PATH;
5541 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5542 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5543 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5544 }
5545
5546 buf[0] = 0;
5547 size = MAX_PATH;
5548 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5549 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5550 trace("VersionDatabase = %s\n", buf);
5551
5552 buf[0] = 0;
5553 size = MAX_PATH;
5554 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5555 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5556 trace("VersionMsi = %s\n", buf);
5557
5558 buf[0] = 0;
5559 size = MAX_PATH;
5560 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5561 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5562 trace("Date = %s\n", buf);
5563
5564 buf[0] = 0;
5565 size = MAX_PATH;
5566 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5567 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5568 trace("Time = %s\n", buf);
5569
5570 buf[0] = 0;
5571 size = MAX_PATH;
5572 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5573 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5574 trace("PackageCode = %s\n", buf);
5575
5576 buf[0] = 0;
5577 size = MAX_PATH;
5578 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5579 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5580 trace("ComputerName = %s\n", buf);
5581
5583 sprintf(path, "%d", langid);
5584
5585 buf[0] = 0;
5586 size = MAX_PATH;
5587 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5588 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5589 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5590
5592 buf[0] = 0;
5593 size = MAX_PATH;
5594 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5595 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5596 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5597
5599 buf[0] = 0;
5600 size = MAX_PATH;
5601 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5602 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5603 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5604
5605 buf[0] = 0;
5606 size = MAX_PATH;
5607 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
5608 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
5609
5610 buf[0] = 0;
5611 size = MAX_PATH;
5612 r = MsiGetPropertyA(hpkg, "AdminUser", buf, &size);
5613 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5614 trace("AdminUser = %s\n", buf);
5615
5616 buf[0] = 0;
5617 size = MAX_PATH;
5618 r = MsiGetPropertyA(hpkg, "Privileged", buf, &size);
5619 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5620 trace("Privileged = %s\n", buf);
5621
5622 buf[0] = 0;
5623 size = MAX_PATH;
5624 r = MsiGetPropertyA(hpkg, "MsiTrueAdminUser", buf, &size);
5625 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5626 trace("MsiTrueAdminUser = %s\n", buf);
5627
5628 buf[0] = 0;
5629 size = MAX_PATH;
5630 r = MsiGetPropertyA(hpkg, "MsiRunningElevated", buf, &size);
5631 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5632 trace("MsiRunningElevated = %s\n", buf);
5633
5635
5636 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5637 check_prop(hpkg, "VersionNT", buf, 1, 1);
5638
5641 {
5642 sprintf(buf, "%d", si.wProcessorLevel);
5643 check_prop(hpkg, "Intel", buf, 1, 0);
5644 check_prop(hpkg, "MsiAMD64", buf, 1, 0);
5645 check_prop(hpkg, "Msix64", buf, 1, 0);
5646 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5647 check_prop(hpkg, "VersionNT64", buf, 1, 1);
5648
5650 strcat(path, "\\");
5651 check_prop(hpkg, "System64Folder", path, 0, 0);
5652
5654 strcat(path, "\\");
5655 check_prop(hpkg, "SystemFolder", path, 0, 0);
5656
5657 size = MAX_PATH;
5658 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5659 strcat(path, "\\");
5660 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5661
5662 size = MAX_PATH;
5663 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5664 strcat(path, "\\");
5665 check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0);
5666
5667 size = MAX_PATH;
5668 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5669 strcat(path, "\\");
5670 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5671
5672 size = MAX_PATH;
5673 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5674 strcat(path, "\\");
5675 check_prop(hpkg, "CommonFiles64Folder", path, 0, 0);
5676 }
5678 {
5679 sprintf(buf, "%d", si.wProcessorLevel);
5680 check_prop(hpkg, "Intel", buf, 1, 0);
5681
5683 strcat(path, "\\");
5684 check_prop(hpkg, "SystemFolder", path, 0, 0);
5685
5686 size = MAX_PATH;
5687 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5688 strcat(path, "\\");
5689 check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
5690
5691 size = MAX_PATH;
5692 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5693 strcat(path, "\\");
5694 check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
5695
5696 check_prop(hpkg, "MsiAMD64", "", 1, 0);
5697 check_prop(hpkg, "Msix64", "", 1, 0);
5698 check_prop(hpkg, "VersionNT64", "", 1, 0);
5699 check_prop(hpkg, "System64Folder", "", 0, 0);
5700 check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0);
5701 check_prop(hpkg, "CommonFiles64Dir", "", 0, 0);
5702 }
5703
5704done:
5705 CloseHandle(hkey1);
5706 CloseHandle(hkey2);
5707 RegCloseKey(pathkey);
5708 MsiCloseHandle(hpkg);
5710 MsiSetInternalUI(uilevel, NULL);
5711}
5712
5713static void test_launchconditions(void)
5714{
5715 MSIHANDLE hpkg;
5716 MSIHANDLE hdb;
5717 UINT r;
5718
5720
5721 hdb = create_package_db();
5722 ok( hdb, "failed to create package database\n" );
5723
5725
5726 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5727
5728 /* invalid condition */
5729 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5730
5731 r = package_from_db( hdb, &hpkg );
5733 {
5734 skip("Not enough rights to perform tests\n");
5736 return;
5737 }
5738 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5739
5740 MsiCloseHandle( hdb );
5741
5742 r = MsiSetPropertyA( hpkg, "X", "1" );
5743 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5744
5746
5747 /* invalid conditions are ignored */
5748 r = MsiDoActionA( hpkg, "LaunchConditions" );
5749 ok( r == ERROR_SUCCESS, "cost init failed\n" );
5750
5751 /* verify LaunchConditions still does some verification */
5752 r = MsiSetPropertyA( hpkg, "X", "2" );
5753 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5754
5755 r = MsiDoActionA( hpkg, "LaunchConditions" );
5756 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5757
5758 MsiCloseHandle( hpkg );
5760}
5761
5762static void test_ccpsearch(void)
5763{
5764 MSIHANDLE hdb, hpkg;
5765 CHAR prop[MAX_PATH];
5767 UINT r;
5768
5769 hdb = create_package_db();
5770 ok(hdb, "failed to create package database\n");
5771
5773 add_ccpsearch_entry(hdb, "'CCP_random'");
5774 add_ccpsearch_entry(hdb, "'RMCCP_random'");
5775
5777 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5778
5780 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5781
5783
5784 r = package_from_db(hdb, &hpkg);
5786 {
5787 skip("Not enough rights to perform tests\n");
5789 return;
5790 }
5791 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5792
5793 MsiCloseHandle(hdb);
5794
5796
5797 r = MsiDoActionA(hpkg, "CCPSearch");
5798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5799
5800 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5802 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5803
5804 MsiCloseHandle(hpkg);
5806}
5807
5808static void test_complocator(void)
5809{
5810 MSIHANDLE hdb, hpkg;
5811 UINT r;
5812 CHAR prop[MAX_PATH];
5815
5816 hdb = create_package_db();
5817 ok(hdb, "failed to create package database\n");
5818
5820 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5821 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5822 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5823 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5824 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5825 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5826 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5827 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5828 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5829 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5830 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5831 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5832 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5833 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5834 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5835 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5836
5838 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5839 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5840 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5841 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5842 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5843 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5844 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5845 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5846 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5847 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5848 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5849 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5850 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5851 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5852 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5853 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5854
5856 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5857 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5858 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5859 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5860 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5861 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5862 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5863 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5864
5865 r = package_from_db(hdb, &hpkg);
5867 {
5868 skip("Not enough rights to perform tests\n");
5870 return;
5871 }
5872 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5873
5874 MsiCloseHandle(hdb);
5875
5876 create_test_file("abelisaurus");
5877 create_test_file("bactrosaurus");
5878 create_test_file("camelotia");
5879 create_test_file("diclonius");
5880 create_test_file("echinodon");
5881 create_test_file("falcarius");
5882 create_test_file("gallimimus");
5883 create_test_file("hagryphus");
5884 CreateDirectoryA("iguanodon", NULL);
5885 CreateDirectoryA("jobaria", NULL);
5886 CreateDirectoryA("kakuru", NULL);
5887 CreateDirectoryA("labocania", NULL);
5888 CreateDirectoryA("megaraptor", NULL);
5889 CreateDirectoryA("neosodon", NULL);
5890 CreateDirectoryA("olorotitan", NULL);
5891 CreateDirectoryA("pantydraco", NULL);
5892
5894 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5896 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5898 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5900 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
5902 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
5904 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
5906 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
5908 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
5909
5911
5912 r = MsiDoActionA(hpkg, "AppSearch");
5913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5914
5915 size = MAX_PATH;
5916 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
5917 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5918
5920 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5921 lstrcatA(expected, "abelisaurus");
5922 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5923 "Expected %s or empty string, got %s\n", expected, prop);
5924
5925 size = MAX_PATH;
5926 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
5927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5928 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5929
5930 size = MAX_PATH;
5931 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
5932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5933 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5934
5935 size = MAX_PATH;
5936 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
5937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5938 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5939
5940 size = MAX_PATH;
5941 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
5942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5943
5945 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5946 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5947 "Expected %s or empty string, got %s\n", expected, prop);
5948
5949 size = MAX_PATH;
5950 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
5951 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5952 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5953
5954 size = MAX_PATH;
5955 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
5956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5957 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5958
5959 size = MAX_PATH;
5960 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
5961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5962 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5963
5964 size = MAX_PATH;
5965 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
5966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5967 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5968
5969 size = MAX_PATH;
5970 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
5971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5972 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5973
5974 size = MAX_PATH;
5975 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
5976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5977 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5978
5979 size = MAX_PATH;
5980 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5982 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
5983
5984 size = MAX_PATH;
5985 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
5986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5987
5989 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5990 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
5991 "Expected %s or empty string, got %s\n", expected, prop);
5992
5993 size = MAX_PATH;
5994 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
5995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5996
5998 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
5999 lstrcatA(expected, "neosodon\\");
6000 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6001 "Expected %s or empty string, got %s\n", expected, prop);
6002
6003 size = MAX_PATH;
6004 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6006 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6007
6008 size = MAX_PATH;
6009 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6011 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6012
6013 MsiCloseHandle(hpkg);
6014 DeleteFileA("abelisaurus");
6015 DeleteFileA("bactrosaurus");
6016 DeleteFileA("camelotia");
6017 DeleteFileA("diclonius");
6018 DeleteFileA("echinodon");
6019 DeleteFileA("falcarius");
6020 DeleteFileA("gallimimus");
6021 DeleteFileA("hagryphus");
6022 RemoveDirectoryA("iguanodon");
6023 RemoveDirectoryA("jobaria");
6024 RemoveDirectoryA("kakuru");
6025 RemoveDirectoryA("labocania");
6026 RemoveDirectoryA("megaraptor");
6027 RemoveDirectoryA("neosodon");
6028 RemoveDirectoryA("olorotitan");
6029 RemoveDirectoryA("pantydraco");
6030 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6032 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6034 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6036 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6038 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6040 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6042 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6044 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6047}
6048
6050{
6051 MSIHANDLE summary;
6052 UINT r;
6053
6054 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6056
6057 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6058 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6059
6060 r = MsiSummaryInfoPersist(summary);
6061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6062
6063 MsiCloseHandle(summary);
6064}
6065
6066static void test_MsiGetSourcePath(void)
6067{
6068 MSIHANDLE hdb, hpkg;
6070 CHAR cwd[MAX_PATH];
6071 CHAR subsrc[MAX_PATH];
6072 CHAR sub2[MAX_PATH];
6073 DWORD size;
6074 UINT r;
6075
6076 lstrcpyA(cwd, CURR_DIR);
6077 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6078
6079 lstrcpyA(subsrc, cwd);
6080 lstrcatA(subsrc, "subsource");
6081 lstrcatA(subsrc, "\\");
6082
6083 lstrcpyA(sub2, subsrc);
6084 lstrcatA(sub2, "sub2");
6085 lstrcatA(sub2, "\\");
6086
6087 /* uncompressed source */
6088
6089 hdb = create_package_db();
6090 ok( hdb, "failed to create database\n");
6091
6093
6094 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6095 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6096 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6097
6098 r = MsiDatabaseCommit(hdb);
6099 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6100
6101 r = package_from_db(hdb, &hpkg);
6103 {
6104 skip("Not enough rights to perform tests\n");
6106 return;
6107 }
6108 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6109
6110 MsiCloseHandle(hdb);
6111
6112 /* invalid database handle */
6113 size = MAX_PATH;
6114 lstrcpyA(path, "kiwi");
6115 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6117 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6118 ok(!lstrcmpA(path, "kiwi"),
6119 "Expected path to be unchanged, got \"%s\"\n", path);
6120 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6121
6122 /* NULL szFolder */
6123 size = MAX_PATH;
6124 lstrcpyA(path, "kiwi");
6125 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6127 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6128 ok(!lstrcmpA(path, "kiwi"),
6129 "Expected path to be unchanged, got \"%s\"\n", path);
6130 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6131
6132 /* empty szFolder */
6133 size = MAX_PATH;
6134 lstrcpyA(path, "kiwi");
6135 r = MsiGetSourcePathA(hpkg, "", path, &size);
6136 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6137 ok(!lstrcmpA(path, "kiwi"),
6138 "Expected path to be unchanged, got \"%s\"\n", path);
6139 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6140
6141 /* try TARGETDIR */
6142 size = MAX_PATH;
6143 lstrcpyA(path, "kiwi");
6144 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6145 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6146 ok(!lstrcmpA(path, "kiwi"),
6147 "Expected path to be unchanged, got \"%s\"\n", path);
6148 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6149
6150 size = MAX_PATH;
6151 lstrcpyA(path, "kiwi");
6152 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6154 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6155 ok(size == 0, "Expected 0, got %lu\n", size);
6156
6157 size = MAX_PATH;
6158 lstrcpyA(path, "kiwi");
6159 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6161 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6162 ok(size == 0, "Expected 0, got %lu\n", size);
6163
6164 /* try SourceDir */
6165 size = MAX_PATH;
6166 lstrcpyA(path, "kiwi");
6167 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6168 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6169 ok(!lstrcmpA(path, "kiwi"),
6170 "Expected path to be unchanged, got \"%s\"\n", path);
6171 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6172
6173 /* try SOURCEDIR */
6174 size = MAX_PATH;
6175 lstrcpyA(path, "kiwi");
6176 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6177 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6178 ok(!lstrcmpA(path, "kiwi"),
6179 "Expected path to be unchanged, got \"%s\"\n", path);
6180 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6181
6182 /* source path does not exist, but the property exists */
6183 size = MAX_PATH;
6184 lstrcpyA(path, "kiwi");
6185 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6187 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6188 ok(size == 0, "Expected 0, got %lu\n", size);
6189
6190 size = MAX_PATH;
6191 lstrcpyA(path, "kiwi");
6192 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6194 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6195 ok(size == 0, "Expected 0, got %lu\n", size);
6196
6197 /* try SubDir */
6198 size = MAX_PATH;
6199 lstrcpyA(path, "kiwi");
6200 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6201 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6202 ok(!lstrcmpA(path, "kiwi"),
6203 "Expected path to be unchanged, got \"%s\"\n", path);
6204 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6205
6206 /* try SubDir2 */
6207 size = MAX_PATH;
6208 lstrcpyA(path, "kiwi");
6209 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6210 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6211 ok(!lstrcmpA(path, "kiwi"),
6212 "Expected path to be unchanged, got \"%s\"\n", path);
6213 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6214
6216
6217 r = MsiDoActionA(hpkg, "CostInitialize");
6218 ok(r == ERROR_SUCCESS, "cost init failed\n");
6219
6220 /* try TARGETDIR after CostInitialize */
6221 size = MAX_PATH;
6222 lstrcpyA(path, "kiwi");
6223 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6225 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6226 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6227
6228 /* try SourceDir after CostInitialize */
6229 size = MAX_PATH;
6230 lstrcpyA(path, "kiwi");
6231 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6233 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6234 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6235
6236 /* try SOURCEDIR after CostInitialize */
6237 size = MAX_PATH;
6238 lstrcpyA(path, "kiwi");
6239 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6240 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6241 ok(!lstrcmpA(path, "kiwi"),
6242 "Expected path to be unchanged, got \"%s\"\n", path);
6243 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6244
6245 /* source path does not exist, but the property exists */
6246 size = MAX_PATH;
6247 lstrcpyA(path, "kiwi");
6248 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6250 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6251 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6252
6253 size = MAX_PATH;
6254 lstrcpyA(path, "kiwi");
6255 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6257 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6258 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6259
6260 /* try SubDir after CostInitialize */
6261 size = MAX_PATH;
6262 lstrcpyA(path, "kiwi");
6263 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6265 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6266 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6267
6268 /* try SubDir2 after CostInitialize */
6269 size = MAX_PATH;
6270 lstrcpyA(path, "kiwi");
6271 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6273 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6274 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6275
6276 r = MsiDoActionA(hpkg, "ResolveSource");
6277 ok(r == ERROR_SUCCESS, "file cost failed\n");
6278
6279 /* try TARGETDIR after ResolveSource */
6280 size = MAX_PATH;
6281 lstrcpyA(path, "kiwi");
6282 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6284 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6285 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6286
6287 /* try SourceDir after ResolveSource */
6288 size = MAX_PATH;
6289 lstrcpyA(path, "kiwi");
6290 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6292 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6293 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6294
6295 /* try SOURCEDIR after ResolveSource */
6296 size = MAX_PATH;
6297 lstrcpyA(path, "kiwi");
6298 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6299 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6300 ok(!lstrcmpA(path, "kiwi"),
6301 "Expected path to be unchanged, got \"%s\"\n", path);
6302 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6303
6304 /* source path does not exist, but the property exists */
6305 size = MAX_PATH;
6306 lstrcpyA(path, "kiwi");
6307 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6309 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6310 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6311
6312 size = MAX_PATH;
6313 lstrcpyA(path, "kiwi");
6314 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6316 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6317 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6318
6319 /* try SubDir after ResolveSource */
6320 size = MAX_PATH;
6321 lstrcpyA(path, "kiwi");
6322 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6324 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6325 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6326
6327 /* try SubDir2 after ResolveSource */
6328 size = MAX_PATH;
6329 lstrcpyA(path, "kiwi");
6330 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6332 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6333 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6334
6335 r = MsiDoActionA(hpkg, "FileCost");
6336 ok(r == ERROR_SUCCESS, "file cost failed\n");
6337
6338 /* try TARGETDIR after FileCost */
6339 size = MAX_PATH;
6340 lstrcpyA(path, "kiwi");
6341 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6343 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6344 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6345
6346 /* try SourceDir after FileCost */
6347 size = MAX_PATH;
6348 lstrcpyA(path, "kiwi");
6349 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6351 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6352 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6353
6354 /* try SOURCEDIR after FileCost */
6355 size = MAX_PATH;
6356 lstrcpyA(path, "kiwi");
6357 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6358 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6359 ok(!lstrcmpA(path, "kiwi"),
6360 "Expected path to be unchanged, got \"%s\"\n", path);
6361 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6362
6363 /* source path does not exist, but the property exists */
6364 size = MAX_PATH;
6365 lstrcpyA(path, "kiwi");
6366 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6368 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6369 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6370
6371 size = MAX_PATH;
6372 lstrcpyA(path, "kiwi");
6373 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6375 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6376 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6377
6378 /* try SubDir after FileCost */
6379 size = MAX_PATH;
6380 lstrcpyA(path, "kiwi");
6381 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6383 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6384 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6385
6386 /* try SubDir2 after FileCost */
6387 size = MAX_PATH;
6388 lstrcpyA(path, "kiwi");
6389 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6391 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6392 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6393
6394 r = MsiDoActionA(hpkg, "CostFinalize");
6395 ok(r == ERROR_SUCCESS, "file cost failed\n");
6396
6397 /* try TARGETDIR after CostFinalize */
6398 size = MAX_PATH;
6399 lstrcpyA(path, "kiwi");
6400 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6402 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6403 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6404
6405 /* try SourceDir after CostFinalize */
6406 size = MAX_PATH;
6407 lstrcpyA(path, "kiwi");
6408 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6410 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6411 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6412
6413 /* try SOURCEDIR after CostFinalize */
6414 size = MAX_PATH;
6415 lstrcpyA(path, "kiwi");
6416 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6417 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6418 ok(!lstrcmpA(path, "kiwi"),
6419 "Expected path to be unchanged, got \"%s\"\n", path);
6420 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6421
6422 /* source path does not exist, but the property exists */
6423 size = MAX_PATH;
6424 lstrcpyA(path, "kiwi");
6425 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6427 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6428 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6429
6430 size = MAX_PATH;
6431 lstrcpyA(path, "kiwi");
6432 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6434 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6435 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6436
6437 /* try SubDir after CostFinalize */
6438 size = MAX_PATH;
6439 lstrcpyA(path, "kiwi");
6440 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6442 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6443 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6444
6445 /* try SubDir2 after CostFinalize */
6446 size = MAX_PATH;
6447 lstrcpyA(path, "kiwi");
6448 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6450 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6451 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6452
6453 /* nonexistent directory */
6454 size = MAX_PATH;
6455 lstrcpyA(path, "kiwi");
6456 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6457 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6458 ok(!lstrcmpA(path, "kiwi"),
6459 "Expected path to be unchanged, got \"%s\"\n", path);
6460 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6461
6462 /* NULL szPathBuf */
6463 size = MAX_PATH;
6464 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6466 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6467
6468 /* NULL pcchPathBuf */
6469 lstrcpyA(path, "kiwi");
6470 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6472 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6473 ok(!lstrcmpA(path, "kiwi"),
6474 "Expected path to be unchanged, got \"%s\"\n", path);
6475
6476 /* pcchPathBuf is 0 */
6477 size = 0;
6478 lstrcpyA(path, "kiwi");
6479 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6480 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6481 ok(!lstrcmpA(path, "kiwi"),
6482 "Expected path to be unchanged, got \"%s\"\n", path);
6483 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6484
6485 /* pcchPathBuf does not have room for NULL terminator */
6486 size = lstrlenA(cwd);
6487 lstrcpyA(path, "kiwi");
6488 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6489 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6490 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6491 "Expected path with no backslash, got \"%s\"\n", path);
6492 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6493
6494 /* pcchPathBuf has room for NULL terminator */
6495 size = lstrlenA(cwd) + 1;
6496 lstrcpyA(path, "kiwi");
6497 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6499 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6500 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6501
6502 /* remove property */
6503 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6504 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6505
6506 /* try SourceDir again */
6507 size = MAX_PATH;
6508 lstrcpyA(path, "kiwi");
6509 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6511 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6512 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6513
6514 /* set property to a valid directory */
6515 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6517
6518 /* try SOURCEDIR again */
6519 size = MAX_PATH;
6520 lstrcpyA(path, "kiwi");
6521 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6522 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6523 ok(!lstrcmpA(path, "kiwi"),
6524 "Expected path to be unchanged, got \"%s\"\n", path);
6525 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6526
6527 MsiCloseHandle(hpkg);
6528
6529 /* compressed source */
6530
6532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6533
6535
6536 r = package_from_db(hdb, &hpkg);
6537 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6538
6539 /* try TARGETDIR */
6540 size = MAX_PATH;
6541 lstrcpyA(path, "kiwi");
6542 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6543 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6544 ok(!lstrcmpA(path, "kiwi"),
6545 "Expected path to be unchanged, got \"%s\"\n", path);
6546 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6547
6548 /* try SourceDir */
6549 size = MAX_PATH;
6550 lstrcpyA(path, "kiwi");
6551 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6552 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6553 ok(!lstrcmpA(path, "kiwi"),
6554 "Expected path to be unchanged, got \"%s\"\n", path);
6555 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6556
6557 /* try SOURCEDIR */
6558 size = MAX_PATH;
6559 lstrcpyA(path, "kiwi");
6560 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6561 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6562 ok(!lstrcmpA(path, "kiwi"),
6563 "Expected path to be unchanged, got \"%s\"\n", path);
6564 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6565
6566 /* source path nor the property exist */
6567 size = MAX_PATH;
6568 lstrcpyA(path, "kiwi");
6569 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6570 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6571 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6572 ok(size == 0, "Expected 0, got %lu\n", size);
6573
6574 size = MAX_PATH;
6575 lstrcpyA(path, "kiwi");
6576 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6578 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6579 ok(size == 0, "Expected 0, got %lu\n", size);
6580
6581 /* try SubDir */
6582 size = MAX_PATH;
6583 lstrcpyA(path, "kiwi");
6584 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6585 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6586 ok(!lstrcmpA(path, "kiwi"),
6587 "Expected path to be unchanged, got \"%s\"\n", path);
6588 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6589
6590 /* try SubDir2 */
6591 size = MAX_PATH;
6592 lstrcpyA(path, "kiwi");
6593 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6594 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6595 ok(!lstrcmpA(path, "kiwi"),
6596 "Expected path to be unchanged, got \"%s\"\n", path);
6597 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6598
6599 r = MsiDoActionA(hpkg, "CostInitialize");
6600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6601
6602 /* try TARGETDIR after CostInitialize */
6603 size = MAX_PATH;
6604 lstrcpyA(path, "kiwi");
6605 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6607 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6608 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6609
6610 /* try SourceDir after CostInitialize */
6611 size = MAX_PATH;
6612 lstrcpyA(path, "kiwi");
6613 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6615 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6616 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6617
6618 /* try SOURCEDIR after CostInitialize */
6619 size = MAX_PATH;
6620 lstrcpyA(path, "kiwi");
6621 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6622 todo_wine
6623 {
6624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6625 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6626 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6627 }
6628
6629 /* source path does not exist, but the property exists */
6630 size = MAX_PATH;
6631 lstrcpyA(path, "kiwi");
6632 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6634 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6635 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6636
6637 size = MAX_PATH;
6638 lstrcpyA(path, "kiwi");
6639 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6641 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6642 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6643
6644 /* try SubDir after CostInitialize */
6645 size = MAX_PATH;
6646 lstrcpyA(path, "kiwi");
6647 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6649 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6650 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6651
6652 /* try SubDir2 after CostInitialize */
6653 size = MAX_PATH;
6654 lstrcpyA(path, "kiwi");
6655 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6657 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6658 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6659
6660 r = MsiDoActionA(hpkg, "ResolveSource");
6661 ok(r == ERROR_SUCCESS, "file cost failed\n");
6662
6663 /* try TARGETDIR after ResolveSource */
6664 size = MAX_PATH;
6665 lstrcpyA(path, "kiwi");
6666 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6668 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6669 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6670
6671 /* try SourceDir after ResolveSource */
6672 size = MAX_PATH;
6673 lstrcpyA(path, "kiwi");
6674 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6676 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6677 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6678
6679 /* try SOURCEDIR after ResolveSource */
6680 size = MAX_PATH;
6681 lstrcpyA(path, "kiwi");
6682 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6683 todo_wine
6684 {
6685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6686 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6687 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6688 }
6689
6690 /* source path and the property exist */
6691 size = MAX_PATH;
6692 lstrcpyA(path, "kiwi");
6693 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6695 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6696 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6697
6698 size = MAX_PATH;
6699 lstrcpyA(path, "kiwi");
6700 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6702 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6703 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6704
6705 /* try SubDir after ResolveSource */
6706 size = MAX_PATH;
6707 lstrcpyA(path, "kiwi");
6708 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6710 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6711 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6712
6713 /* try SubDir2 after ResolveSource */
6714 size = MAX_PATH;
6715 lstrcpyA(path, "kiwi");
6716 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6718 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6719 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6720
6721 r = MsiDoActionA(hpkg, "FileCost");
6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723
6724 /* try TARGETDIR after CostFinalize */
6725 size = MAX_PATH;
6726 lstrcpyA(path, "kiwi");
6727 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6729 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6730 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6731
6732 /* try SourceDir after CostFinalize */
6733 size = MAX_PATH;
6734 lstrcpyA(path, "kiwi");
6735 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6737 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6738 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6739
6740 /* try SOURCEDIR after CostFinalize */
6741 size = MAX_PATH;
6742 lstrcpyA(path, "kiwi");
6743 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6744 todo_wine
6745 {
6746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6747 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6748 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6749 }
6750
6751 /* source path and the property exist */
6752 size = MAX_PATH;
6753 lstrcpyA(path, "kiwi");
6754 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6756 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6757 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6758
6759 size = MAX_PATH;
6760 lstrcpyA(path, "kiwi");
6761 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6763 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6764 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6765
6766 /* try SubDir after CostFinalize */
6767 size = MAX_PATH;
6768 lstrcpyA(path, "kiwi");
6769 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6771 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6772 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6773
6774 /* try SubDir2 after CostFinalize */
6775 size = MAX_PATH;
6776 lstrcpyA(path, "kiwi");
6777 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6778 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6779 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6780 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6781
6782 r = MsiDoActionA(hpkg, "CostFinalize");
6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6784
6785 /* try TARGETDIR after CostFinalize */
6786 size = MAX_PATH;
6787 lstrcpyA(path, "kiwi");
6788 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6790 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6791 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6792
6793 /* try SourceDir after CostFinalize */
6794 size = MAX_PATH;
6795 lstrcpyA(path, "kiwi");
6796 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6798 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6799 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6800
6801 /* try SOURCEDIR after CostFinalize */
6802 size = MAX_PATH;
6803 lstrcpyA(path, "kiwi");
6804 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6805 todo_wine
6806 {
6807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6808 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6809 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6810 }
6811
6812 /* source path and the property exist */
6813 size = MAX_PATH;
6814 lstrcpyA(path, "kiwi");
6815 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6817 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6818 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6819
6820 size = MAX_PATH;
6821 lstrcpyA(path, "kiwi");
6822 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6824 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6825 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6826
6827 /* try SubDir after CostFinalize */
6828 size = MAX_PATH;
6829 lstrcpyA(path, "kiwi");
6830 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6832 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6833 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6834
6835 /* try SubDir2 after CostFinalize */
6836 size = MAX_PATH;
6837 lstrcpyA(path, "kiwi");
6838 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6840 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6841 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6842
6843 MsiCloseHandle(hpkg);
6845}
6846
6847static void test_shortlongsource(void)
6848{
6849 MSIHANDLE hdb, hpkg;
6851 CHAR cwd[MAX_PATH];
6852 CHAR subsrc[MAX_PATH];
6853 DWORD size;
6854 UINT r;
6855
6856 lstrcpyA(cwd, CURR_DIR);
6857 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6858
6859 lstrcpyA(subsrc, cwd);
6860 lstrcatA(subsrc, "long");
6861 lstrcatA(subsrc, "\\");
6862
6863 /* long file names */
6864
6865 hdb = create_package_db();
6866 ok( hdb, "failed to create database\n");
6867
6869
6870 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6871 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6872
6873 /* CostInitialize:short */
6874 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6875
6876 /* CostInitialize:long */
6877 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6878
6879 /* FileCost:short */
6880 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6881
6882 /* FileCost:long */
6883 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6884
6885 /* CostFinalize:short */
6886 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6887
6888 /* CostFinalize:long */
6889 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6890
6891 r = MsiDatabaseCommit(hdb);
6892 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6893
6894 r = package_from_db(hdb, &hpkg);
6896 {
6897 skip("Not enough rights to perform tests\n");
6899 return;
6900 }
6901 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6902
6903 MsiCloseHandle(hdb);
6904
6905 CreateDirectoryA("one", NULL);
6906 CreateDirectoryA("four", NULL);
6907
6909
6910 r = MsiDoActionA(hpkg, "CostInitialize");
6911 ok(r == ERROR_SUCCESS, "file cost failed\n");
6912
6913 CreateDirectoryA("five", NULL);
6914 CreateDirectoryA("eight", NULL);
6915
6916 r = MsiDoActionA(hpkg, "FileCost");
6917 ok(r == ERROR_SUCCESS, "file cost failed\n");
6918
6919 CreateDirectoryA("nine", NULL);
6920 CreateDirectoryA("twelve", NULL);
6921
6922 r = MsiDoActionA(hpkg, "CostFinalize");
6923 ok(r == ERROR_SUCCESS, "file cost failed\n");
6924
6925 /* neither short nor long source directories exist */
6926 size = MAX_PATH;
6927 lstrcpyA(path, "kiwi");
6928 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6930 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6931 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6932
6933 CreateDirectoryA("short", NULL);
6934
6935 /* short source directory exists */
6936 size = MAX_PATH;
6937 lstrcpyA(path, "kiwi");
6938 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6940 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6941 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6942
6943 CreateDirectoryA("long", NULL);
6944
6945 /* both short and long source directories exist */
6946 size = MAX_PATH;
6947 lstrcpyA(path, "kiwi");
6948 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6949 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6950 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6951 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6952
6953 lstrcpyA(subsrc, cwd);
6954 lstrcatA(subsrc, "two");
6955 lstrcatA(subsrc, "\\");
6956
6957 /* short dir exists before CostInitialize */
6958 size = MAX_PATH;
6959 lstrcpyA(path, "kiwi");
6960 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6962 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6963 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6964
6965 lstrcpyA(subsrc, cwd);
6966 lstrcatA(subsrc, "four");
6967 lstrcatA(subsrc, "\\");
6968
6969 /* long dir exists before CostInitialize */
6970 size = MAX_PATH;
6971 lstrcpyA(path, "kiwi");
6972 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
6973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6974 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6975 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6976
6977 lstrcpyA(subsrc, cwd);
6978 lstrcatA(subsrc, "six");
6979 lstrcatA(subsrc, "\\");
6980
6981 /* short dir exists before FileCost */
6982 size = MAX_PATH;
6983 lstrcpyA(path, "kiwi");
6984 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
6985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6986 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6987 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6988
6989 lstrcpyA(subsrc, cwd);
6990 lstrcatA(subsrc, "eight");
6991 lstrcatA(subsrc, "\\");
6992
6993 /* long dir exists before FileCost */
6994 size = MAX_PATH;
6995 lstrcpyA(path, "kiwi");
6996 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
6997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6998 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6999 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7000
7001 lstrcpyA(subsrc, cwd);
7002 lstrcatA(subsrc, "ten");
7003 lstrcatA(subsrc, "\\");
7004
7005 /* short dir exists before CostFinalize */
7006 size = MAX_PATH;
7007 lstrcpyA(path, "kiwi");
7008 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7009 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7010 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7011 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7012
7013 lstrcpyA(subsrc, cwd);
7014 lstrcatA(subsrc, "twelve");
7015 lstrcatA(subsrc, "\\");
7016
7017 /* long dir exists before CostFinalize */
7018 size = MAX_PATH;
7019 lstrcpyA(path, "kiwi");
7020 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7021 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7022 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7023 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7024
7025 MsiCloseHandle(hpkg);
7026 RemoveDirectoryA("short");
7027 RemoveDirectoryA("long");
7028 RemoveDirectoryA("one");
7029 RemoveDirectoryA("four");
7030 RemoveDirectoryA("five");
7031 RemoveDirectoryA("eight");
7032 RemoveDirectoryA("nine");
7033 RemoveDirectoryA("twelve");
7034
7035 /* short file names */
7036
7038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7039
7041
7042 r = package_from_db(hdb, &hpkg);
7043 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7044
7045 MsiCloseHandle(hdb);
7046
7047 CreateDirectoryA("one", NULL);
7048 CreateDirectoryA("four", NULL);
7049
7050 r = MsiDoActionA(hpkg, "CostInitialize");
7051 ok(r == ERROR_SUCCESS, "file cost failed\n");
7052
7053 CreateDirectoryA("five", NULL);
7054 CreateDirectoryA("eight", NULL);
7055
7056 r = MsiDoActionA(hpkg, "FileCost");
7057 ok(r == ERROR_SUCCESS, "file cost failed\n");
7058
7059 CreateDirectoryA("nine", NULL);
7060 CreateDirectoryA("twelve", NULL);
7061
7062 r = MsiDoActionA(hpkg, "CostFinalize");
7063 ok(r == ERROR_SUCCESS, "file cost failed\n");
7064
7065 lstrcpyA(subsrc, cwd);
7066 lstrcatA(subsrc, "short");
7067 lstrcatA(subsrc, "\\");
7068
7069 /* neither short nor long source directories exist */
7070 size = MAX_PATH;
7071 lstrcpyA(path, "kiwi");
7072 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7074 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7075 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7076
7077 CreateDirectoryA("short", NULL);
7078
7079 /* short source directory exists */
7080 size = MAX_PATH;
7081 lstrcpyA(path, "kiwi");
7082 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7084 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7085 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7086
7087 CreateDirectoryA("long", NULL);
7088
7089 /* both short and long source directories exist */
7090 size = MAX_PATH;
7091 lstrcpyA(path, "kiwi");
7092 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7094 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7095 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7096
7097 lstrcpyA(subsrc, cwd);
7098 lstrcatA(subsrc, "one");
7099 lstrcatA(subsrc, "\\");
7100
7101 /* short dir exists before CostInitialize */
7102 size = MAX_PATH;
7103 lstrcpyA(path, "kiwi");
7104 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7106 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7107 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7108
7109 lstrcpyA(subsrc, cwd);
7110 lstrcatA(subsrc, "three");
7111 lstrcatA(subsrc, "\\");
7112
7113 /* long dir exists before CostInitialize */
7114 size = MAX_PATH;
7115 lstrcpyA(path, "kiwi");
7116 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7118 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7119 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7120
7121 lstrcpyA(subsrc, cwd);
7122 lstrcatA(subsrc, "five");
7123 lstrcatA(subsrc, "\\");
7124
7125 /* short dir exists before FileCost */
7126 size = MAX_PATH;
7127 lstrcpyA(path, "kiwi");
7128 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7130 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7131 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7132
7133 lstrcpyA(subsrc, cwd);
7134 lstrcatA(subsrc, "seven");
7135 lstrcatA(subsrc, "\\");
7136
7137 /* long dir exists before FileCost */
7138 size = MAX_PATH;
7139 lstrcpyA(path, "kiwi");
7140 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7142 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7143 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7144
7145 lstrcpyA(subsrc, cwd);
7146 lstrcatA(subsrc, "nine");
7147 lstrcatA(subsrc, "\\");
7148
7149 /* short dir exists before CostFinalize */
7150 size = MAX_PATH;
7151 lstrcpyA(path, "kiwi");
7152 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7154 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7155 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7156
7157 lstrcpyA(subsrc, cwd);
7158 lstrcatA(subsrc, "eleven");
7159 lstrcatA(subsrc, "\\");
7160
7161 /* long dir exists before CostFinalize */
7162 size = MAX_PATH;
7163 lstrcpyA(path, "kiwi");
7164 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7166 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7167 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7168
7169 MsiCloseHandle(hpkg);
7170 RemoveDirectoryA("short");
7171 RemoveDirectoryA("long");
7172 RemoveDirectoryA("one");
7173 RemoveDirectoryA("four");
7174 RemoveDirectoryA("five");
7175 RemoveDirectoryA("eight");
7176 RemoveDirectoryA("nine");
7177 RemoveDirectoryA("twelve");
7179}
7180
7181static void test_sourcedir(void)
7182{
7183 MSIHANDLE hdb, hpkg;
7184 CHAR package[12];
7186 CHAR cwd[MAX_PATH];
7187 CHAR subsrc[MAX_PATH];
7188 DWORD size;
7189 UINT r;
7190
7191 lstrcpyA(cwd, CURR_DIR);
7192 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7193
7194 lstrcpyA(subsrc, cwd);
7195 lstrcatA(subsrc, "long");
7196 lstrcatA(subsrc, "\\");
7197
7198 hdb = create_package_db();
7199 ok( hdb, "failed to create database\n");
7200
7201 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7202
7203 sprintf(package, "#%lu", hdb);
7204 r = MsiOpenPackageA(package, &hpkg);
7206 {
7207 skip("Not enough rights to perform tests\n");
7208 goto error;
7209 }
7210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7211
7212 /* properties only */
7213
7214 /* SourceDir prop */
7215 size = MAX_PATH;
7216 lstrcpyA(path, "kiwi");
7217 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7219 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7220 ok(size == 0, "Expected 0, got %lu\n", size);
7221
7222 /* SOURCEDIR prop */
7223 size = MAX_PATH;
7224 lstrcpyA(path, "kiwi");
7225 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7226 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7227 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7228 ok(size == 0, "Expected 0, got %lu\n", size);
7229
7231
7232 r = MsiDoActionA(hpkg, "CostInitialize");
7233 ok(r == ERROR_SUCCESS, "file cost failed\n");
7234
7235 /* SourceDir after CostInitialize */
7236 size = MAX_PATH;
7237 lstrcpyA(path, "kiwi");
7238 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7240 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7241 ok(size == 0, "Expected 0, got %lu\n", size);
7242
7243 /* SOURCEDIR after CostInitialize */
7244 size = MAX_PATH;
7245 lstrcpyA(path, "kiwi");
7246 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7248 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7249 ok(size == 0, "Expected 0, got %lu\n", size);
7250
7251 r = MsiDoActionA(hpkg, "FileCost");
7252 ok(r == ERROR_SUCCESS, "file cost failed\n");
7253
7254 /* SourceDir after FileCost */
7255 size = MAX_PATH;
7256 lstrcpyA(path, "kiwi");
7257 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7259 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7260 ok(size == 0, "Expected 0, got %lu\n", size);
7261
7262 /* SOURCEDIR after FileCost */
7263 size = MAX_PATH;
7264 lstrcpyA(path, "kiwi");
7265 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7267 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7268 ok(size == 0, "Expected 0, got %lu\n", size);
7269
7270 r = MsiDoActionA(hpkg, "CostFinalize");
7271 ok(r == ERROR_SUCCESS, "file cost failed\n");
7272
7273 /* SourceDir after CostFinalize */
7274 size = MAX_PATH;
7275 lstrcpyA(path, "kiwi");
7276 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7278 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7279 ok(size == 0, "Expected 0, got %lu\n", size);
7280
7281 /* SOURCEDIR after CostFinalize */
7282 size = MAX_PATH;
7283 lstrcpyA(path, "kiwi");
7284 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7286 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7287 ok(size == 0, "Expected 0, got %lu\n", size);
7288
7289 size = MAX_PATH;
7290 lstrcpyA(path, "kiwi");
7291 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7292 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7293 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7294 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
7295
7296 /* SOURCEDIR after calling MsiGetSourcePath */
7297 size = MAX_PATH;
7298 lstrcpyA(path, "kiwi");
7299 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7301 todo_wine {
7302 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7303 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7304 }
7305
7306 r = MsiDoActionA(hpkg, "ResolveSource");
7307 ok(r == ERROR_SUCCESS, "file cost failed\n");
7308
7309 /* SourceDir after ResolveSource */
7310 size = MAX_PATH;
7311 lstrcpyA(path, "kiwi");
7312 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7314 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7315 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7316
7317 /* SOURCEDIR after ResolveSource */
7318 size = MAX_PATH;
7319 lstrcpyA(path, "kiwi");
7320 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7322 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7323 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7324
7325 /* random casing */
7326 size = MAX_PATH;
7327 lstrcpyA(path, "kiwi");
7328 r = MsiGetPropertyA(hpkg, "SoUrCeDiR", path, &size);
7329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7330 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7331 ok(size == 0, "Expected 0, got %lu\n", size);
7332
7333 MsiCloseHandle(hpkg);
7334
7335 /* reset the package state */
7336 sprintf(package, "#%lu", hdb);
7337 r = MsiOpenPackageA(package, &hpkg);
7338 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7339
7340 /* test how MsiGetSourcePath affects the properties */
7341
7342 /* SourceDir prop */
7343 size = MAX_PATH;
7344 lstrcpyA(path, "kiwi");
7345 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7347 todo_wine
7348 {
7349 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7350 ok(size == 0, "Expected 0, got %lu\n", size);
7351 }
7352
7353 size = MAX_PATH;
7354 lstrcpyA(path, "kiwi");
7355 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7356 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7357 ok(!lstrcmpA(path, "kiwi"),
7358 "Expected path to be unchanged, got \"%s\"\n", path);
7359 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7360
7361 /* SourceDir after MsiGetSourcePath */
7362 size = MAX_PATH;
7363 lstrcpyA(path, "kiwi");
7364 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7366 todo_wine
7367 {
7368 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7369 ok(size == 0, "Expected 0, got %lu\n", size);
7370 }
7371
7372 /* SOURCEDIR prop */
7373 size = MAX_PATH;
7374 lstrcpyA(path, "kiwi");
7375 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7377 todo_wine
7378 {
7379 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7380 ok(size == 0, "Expected 0, got %lu\n", size);
7381 }
7382
7383 size = MAX_PATH;
7384 lstrcpyA(path, "kiwi");
7385 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7386 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7387 ok(!lstrcmpA(path, "kiwi"),
7388 "Expected path to be unchanged, got \"%s\"\n", path);
7389 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7390
7391 /* SOURCEDIR prop after MsiGetSourcePath */
7392 size = MAX_PATH;
7393 lstrcpyA(path, "kiwi");
7394 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7396 todo_wine
7397 {
7398 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7399 ok(size == 0, "Expected 0, got %lu\n", size);
7400 }
7401
7402 r = MsiDoActionA(hpkg, "CostInitialize");
7403 ok(r == ERROR_SUCCESS, "file cost failed\n");
7404
7405 /* SourceDir after CostInitialize */
7406 size = MAX_PATH;
7407 lstrcpyA(path, "kiwi");
7408 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7410 todo_wine
7411 {
7412 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7413 ok(size == 0, "Expected 0, got %lu\n", size);
7414 }
7415
7416 size = MAX_PATH;
7417 lstrcpyA(path, "kiwi");
7418 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7420 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7421 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7422
7423 /* SourceDir after MsiGetSourcePath */
7424 size = MAX_PATH;
7425 lstrcpyA(path, "kiwi");
7426 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7428 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7429 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7430
7431 /* SOURCEDIR after CostInitialize */
7432 size = MAX_PATH;
7433 lstrcpyA(path, "kiwi");
7434 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7435 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7436 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7437 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7438
7439 /* SOURCEDIR source path still does not exist */
7440 size = MAX_PATH;
7441 lstrcpyA(path, "kiwi");
7442 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7443 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7444 ok(!lstrcmpA(path, "kiwi"),
7445 "Expected path to be unchanged, got \"%s\"\n", path);
7446 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7447
7448 r = MsiDoActionA(hpkg, "FileCost");
7449 ok(r == ERROR_SUCCESS, "file cost failed\n");
7450
7451 /* SourceDir after FileCost */
7452 size = MAX_PATH;
7453 lstrcpyA(path, "kiwi");
7454 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7456 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7457 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7458
7459 /* SOURCEDIR after FileCost */
7460 size = MAX_PATH;
7461 lstrcpyA(path, "kiwi");
7462 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7464 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7465 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7466
7467 /* SOURCEDIR source path still does not exist */
7468 size = MAX_PATH;
7469 lstrcpyA(path, "kiwi");
7470 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7471 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7472 ok(!lstrcmpA(path, "kiwi"),
7473 "Expected path to be unchanged, got \"%s\"\n", path);
7474 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7475
7476 r = MsiDoActionA(hpkg, "CostFinalize");
7477 ok(r == ERROR_SUCCESS, "file cost failed\n");
7478
7479 /* SourceDir after CostFinalize */
7480 size = MAX_PATH;
7481 lstrcpyA(path, "kiwi");
7482 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7484 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7485 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7486
7487 /* SOURCEDIR after CostFinalize */
7488 size = MAX_PATH;
7489 lstrcpyA(path, "kiwi");
7490 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7491 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7492 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7493 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7494
7495 /* SOURCEDIR source path still does not exist */
7496 size = MAX_PATH;
7497 lstrcpyA(path, "kiwi");
7498 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7499 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7500 ok(!lstrcmpA(path, "kiwi"),
7501 "Expected path to be unchanged, got \"%s\"\n", path);
7502 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7503
7504 r = MsiDoActionA(hpkg, "ResolveSource");
7505 ok(r == ERROR_SUCCESS, "file cost failed\n");
7506
7507 /* SourceDir after ResolveSource */
7508 size = MAX_PATH;
7509 lstrcpyA(path, "kiwi");
7510 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7512 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7513 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7514
7515 /* SOURCEDIR after ResolveSource */
7516 size = MAX_PATH;
7517 lstrcpyA(path, "kiwi");
7518 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7520 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7521 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7522
7523 /* SOURCEDIR source path still does not exist */
7524 size = MAX_PATH;
7525 lstrcpyA(path, "kiwi");
7526 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7527 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7528 ok(!lstrcmpA(path, "kiwi"),
7529 "Expected path to be unchanged, got \"%s\"\n", path);
7530 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7531
7532 MsiCloseHandle(hpkg);
7533
7534error:
7535 MsiCloseHandle(hdb);
7537}
7538
7540{
7544};
7545
7546static const struct access_res create[16] =
7547{
7548 { TRUE, ERROR_SUCCESS, TRUE },
7549 { TRUE, ERROR_SUCCESS, TRUE },
7550 { TRUE, ERROR_SUCCESS, FALSE },
7551 { TRUE, ERROR_SUCCESS, FALSE },
7555 { TRUE, ERROR_SUCCESS, FALSE },
7559 { TRUE, ERROR_SUCCESS, TRUE },
7563 { TRUE, ERROR_SUCCESS, TRUE }
7564};
7565
7566static const struct access_res create_commit[16] =
7567{
7568 { TRUE, ERROR_SUCCESS, TRUE },
7569 { TRUE, ERROR_SUCCESS, TRUE },
7570 { TRUE, ERROR_SUCCESS, FALSE },
7571 { TRUE, ERROR_SUCCESS, FALSE },
7575 { TRUE, ERROR_SUCCESS, FALSE },
7579 { TRUE, ERROR_SUCCESS, TRUE },
7583 { TRUE, ERROR_SUCCESS, TRUE }
7584};
7585
7586static const struct access_res create_close[16] =
7587{
7588 { TRUE, ERROR_SUCCESS, FALSE },
7589 { TRUE, ERROR_SUCCESS, FALSE },
7590 { TRUE, ERROR_SUCCESS, FALSE },
7591 { TRUE, ERROR_SUCCESS, FALSE },
7592 { TRUE, ERROR_SUCCESS, FALSE },
7593 { TRUE, ERROR_SUCCESS, FALSE },
7594 { TRUE, ERROR_SUCCESS, FALSE },
7595 { TRUE, ERROR_SUCCESS, FALSE },
7596 { TRUE, ERROR_SUCCESS, FALSE },
7597 { TRUE, ERROR_SUCCESS, FALSE },
7598 { TRUE, ERROR_SUCCESS, FALSE },
7599 { TRUE, ERROR_SUCCESS, FALSE },
7600 { TRUE, ERROR_SUCCESS, FALSE },
7601 { TRUE, ERROR_SUCCESS, FALSE },
7602 { TRUE, ERROR_SUCCESS, FALSE },
7603 { TRUE, ERROR_SUCCESS }
7604};
7605
7606static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7607{
7608 DWORD access = 0, share = 0;
7609 DWORD lasterr;
7610 HANDLE hfile;
7611 int i, j, idx = 0;
7612
7613 for (i = 0; i < 4; i++)
7614 {
7615 if (i == 0) access = 0;
7616 if (i == 1) access = GENERIC_READ;
7617 if (i == 2) access = GENERIC_WRITE;
7618 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7619
7620 for (j = 0; j < 4; j++)
7621 {
7622 if (ares[idx].ignore)
7623 continue;
7624
7625 if (j == 0) share = 0;
7626 if (j == 1) share = FILE_SHARE_READ;
7627 if (j == 2) share = FILE_SHARE_WRITE;
7628 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7629
7630 SetLastError(0xdeadbeef);
7631 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7634
7635 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7636 "(%lu, handle, %d): Expected %d, got %d\n",
7637 line, idx, ares[idx].gothandle,
7638 (hfile != INVALID_HANDLE_VALUE));
7639
7640 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n",
7641 line, idx, ares[idx].lasterr, lasterr);
7642
7643 CloseHandle(hfile);
7644 idx++;
7645 }
7646 }
7647}
7648
7649#define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7650
7651static void test_access(void)
7652{
7653 MSIHANDLE hdb;
7654 UINT r;
7655
7657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7658
7660
7661 r = MsiDatabaseCommit(hdb);
7662 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7663
7665 MsiCloseHandle(hdb);
7666
7669
7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7672
7674
7675 r = MsiDatabaseCommit(hdb);
7676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7677
7679 MsiCloseHandle(hdb);
7680
7683}
7684
7685static void test_emptypackage(void)
7686{
7687 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7688 MSIHANDLE hview = 0, hrec = 0;
7691 DWORD size;
7692 UINT r;
7693
7694 r = MsiOpenPackageA("", &hpkg);
7696 {
7697 skip("Not enough rights to perform tests\n");
7698 return;
7699 }
7700 todo_wine
7701 {
7702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7703 }
7704
7705 hdb = MsiGetActiveDatabase(hpkg);
7706 todo_wine
7707 {
7708 ok(hdb != 0, "Expected a valid database handle\n");
7709 }
7710
7711 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7712 todo_wine
7713 {
7714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7715 }
7716 r = MsiViewExecute(hview, 0);
7717 todo_wine
7718 {
7719 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7720 }
7721
7722 r = MsiViewFetch(hview, &hrec);
7723 todo_wine
7724 {
7725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7726 }
7727
7728 buffer[0] = 0;
7729 size = MAX_PATH;
7730 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7731 todo_wine
7732 {
7733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7734 ok(!lstrcmpA(buffer, "_Property"),
7735 "Expected \"_Property\", got \"%s\"\n", buffer);
7736 }
7737
7738 MsiCloseHandle(hrec);
7739
7740 r = MsiViewFetch(hview, &hrec);
7741 todo_wine
7742 {
7743 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7744 }
7745
7746 size = MAX_PATH;
7747 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7748 todo_wine
7749 {
7750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7751 ok(!lstrcmpA(buffer, "#_FolderCache"),
7752 "Expected \"_Property\", got \"%s\"\n", buffer);
7753 }
7754
7755 MsiCloseHandle(hrec);
7756 MsiViewClose(hview);
7757 MsiCloseHandle(hview);
7758
7759 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7760 todo_wine
7761 {
7763 "Expected MSICONDITION_FALSE, got %d\n", condition);
7764 }
7765
7766 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7767 todo_wine
7768 {
7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7770 }
7771 r = MsiViewExecute(hview, 0);
7772 todo_wine
7773 {
7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7775 }
7776
7777 /* _Property table is not empty */
7778 r = MsiViewFetch(hview, &hrec);
7779 todo_wine
7780 {
7781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7782 }
7783
7784 MsiCloseHandle(hrec);
7785 MsiViewClose(hview);
7786 MsiCloseHandle(hview);
7787
7788 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7789 todo_wine
7790 {
7792 "Expected MSICONDITION_FALSE, got %d\n", condition);
7793 }
7794
7795 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7796 todo_wine
7797 {
7798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7799 }
7800 r = MsiViewExecute(hview, 0);
7801 todo_wine
7802 {
7803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7804 }
7805
7806 /* #_FolderCache is not empty */
7807 r = MsiViewFetch(hview, &hrec);
7808 todo_wine
7809 {
7810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7811 }
7812
7813 MsiCloseHandle(hrec);
7814 MsiViewClose(hview);
7815 MsiCloseHandle(hview);
7816
7817 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7818 todo_wine
7819 {
7821 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7822 }
7823
7824 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7825 todo_wine
7826 {
7828 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7829 }
7830
7831 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7832 todo_wine
7833 {
7835 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7836 }
7837
7838 MsiCloseHandle(hsuminfo);
7839
7840 r = MsiDatabaseCommit(hdb);
7841 todo_wine
7842 {
7843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7844 }
7845
7846 MsiCloseHandle(hdb);
7847 MsiCloseHandle(hpkg);
7848}
7849
7851{
7852 WCHAR valW[MAX_PATH];
7853 MSIHANDLE hprod, hdb;
7854 CHAR val[MAX_PATH];
7856 CHAR query[MAX_PATH + 17];
7857 CHAR keypath[MAX_PATH*2];
7858 CHAR prodcode[MAX_PATH];
7859 WCHAR prodcodeW[MAX_PATH];
7860 CHAR prod_squashed[MAX_PATH];
7861 WCHAR prod_squashedW[MAX_PATH];
7862 HKEY prodkey, userkey, props;
7863 DWORD size;
7864 LONG res;
7865 UINT r;
7867
7869 lstrcatA(path, "\\");
7870
7871 create_test_guid(prodcode, prod_squashed);
7872 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7873 squash_guid(prodcodeW, prod_squashedW);
7874
7875 if (is_wow64)
7877
7879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7880
7881 r = MsiDatabaseCommit(hdb);
7882 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7883
7884 r = set_summary_info(hdb);
7885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7886
7887 r = run_query(hdb, 0,
7888 "CREATE TABLE `Directory` ( "
7889 "`Directory` CHAR(255) NOT NULL, "
7890 "`Directory_Parent` CHAR(255), "
7891 "`DefaultDir` CHAR(255) NOT NULL "
7892 "PRIMARY KEY `Directory`)");
7893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7894
7896
7897 sprintf(query, "'ProductCode', '%s'", prodcode);
7898 r = add_property_entry(hdb, query);
7899
7900 r = MsiDatabaseCommit(hdb);
7901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7902
7903 MsiCloseHandle(hdb);
7904
7905 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7906 lstrcatA(keypath, prod_squashed);
7907
7908 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7909 if (res == ERROR_ACCESS_DENIED)
7910 {
7911 skip("Not enough rights to perform tests\n");
7913 return;
7914 }
7915 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7916
7917 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7918 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7919 lstrcatA(keypath, prod_squashed);
7920
7921 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7922 if (res == ERROR_ACCESS_DENIED)
7923 {
7924 skip("Not enough rights to perform tests\n");
7925 RegDeleteKeyA(prodkey, "");
7926 RegCloseKey(prodkey);
7928 return;
7929 }
7930 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7931
7932 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7933 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7934
7935 lstrcpyA(val, path);
7936 lstrcatA(val, "\\");
7938 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1);
7939 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7940
7941 hprod = 0xdeadbeef;
7942 r = MsiOpenProductA(prodcode, &hprod);
7943 if (r == ERROR_UNKNOWN_PRODUCT)
7944 {
7945 win_skip("broken result, skipping tests\n");
7946 goto done;
7947 }
7948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7949 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7950
7951 /* hProduct is invalid */
7952 size = MAX_PATH;
7953 lstrcpyA(val, "apple");
7954 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
7956 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7957 ok(!lstrcmpA(val, "apple"),
7958 "Expected val to be unchanged, got \"%s\"\n", val);
7959 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7960
7961 size = MAX_PATH;
7962 lstrcpyW(valW, L"apple");
7963 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
7965 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7966 ok(!lstrcmpW(valW, L"apple"),
7967 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
7968 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7969
7970 /* szProperty is NULL */
7971 size = MAX_PATH;
7972 lstrcpyA(val, "apple");
7973 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
7975 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7976 ok(!lstrcmpA(val, "apple"),
7977 "Expected val to be unchanged, got \"%s\"\n", val);
7978 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7979
7980 size = MAX_PATH;
7981 lstrcpyW(valW, L"apple");
7982 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
7984 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7985 ok(!lstrcmpW(valW, L"apple"),
7986 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
7987 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7988
7989 /* szProperty is empty */
7990 size = MAX_PATH;
7991 lstrcpyA(val, "apple");
7992 r = MsiGetProductPropertyA(hprod, "", val, &size);
7993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7994 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
7995 ok(size == 0, "Expected 0, got %lu\n", size);
7996
7997 size = MAX_PATH;
7998 lstrcpyW(valW, L"apple");
7999 r = MsiGetProductPropertyW(hprod, L"", valW, &size);
8000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8001 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8002 ok(size == 0, "Expected 0, got %lu\n", size);
8003
8004 /* get the property */
8005 size = MAX_PATH;
8006 lstrcpyA(val, "apple");
8007 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8009 ok(!lstrcmpA(val, prodcode),
8010 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8011 ok(size == lstrlenA(prodcode),
8012 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8013
8014 size = MAX_PATH;
8015 lstrcpyW(valW, L"apple");
8016 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8018 ok(!lstrcmpW(valW, prodcodeW),
8019 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8020 ok(size == lstrlenW(prodcodeW),
8021 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8022
8023 /* lpValueBuf is NULL */
8024 size = MAX_PATH;
8025 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8027 ok(size == lstrlenA(prodcode),
8028 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8029
8030 size = MAX_PATH;
8031 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
8032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8033 ok(size == lstrlenW(prodcodeW),
8034 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8035
8036 /* pcchValueBuf is NULL */
8037 lstrcpyA(val, "apple");
8038 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8040 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8041 ok(!lstrcmpA(val, "apple"),
8042 "Expected val to be unchanged, got \"%s\"\n", val);
8043 ok(size == lstrlenA(prodcode),
8044 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8045
8046 lstrcpyW(valW, L"apple");
8047 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8049 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8050 ok(!lstrcmpW(valW, L"apple"),
8051 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8052 ok(size == lstrlenW(prodcodeW),
8053 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8054
8055 /* pcchValueBuf is too small */
8056 size = 4;
8057 lstrcpyA(val, "apple");
8058 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8059 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8060 ok(!strncmp(val, prodcode, 3),
8061 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8062 ok(size == lstrlenA(prodcode),
8063 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8064
8065 size = 4;
8066 lstrcpyW(valW, L"apple");
8067 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8068 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8069 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8070 "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8071 ok(size == lstrlenW(prodcodeW),
8072 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8073
8074 /* pcchValueBuf does not leave room for NULL terminator */
8075 size = lstrlenA(prodcode);
8076 lstrcpyA(val, "apple");
8077 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8078 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8079 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8080 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8081 ok(size == lstrlenA(prodcode),
8082 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8083
8084 size = lstrlenW(prodcodeW);
8085 lstrcpyW(valW, L"apple");
8086 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8087 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8088 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8089 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8090 ok(size == lstrlenW(prodcodeW),
8091 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8092
8093 /* pcchValueBuf has enough room for NULL terminator */
8094 size = lstrlenA(prodcode) + 1;
8095 lstrcpyA(val, "apple");
8096 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8098 ok(!lstrcmpA(val, prodcode),
8099 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8100 ok(size == lstrlenA(prodcode),
8101 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8102
8103 size = lstrlenW(prodcodeW) + 1;
8104 lstrcpyW(valW, L"apple");
8105 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8107 ok(!lstrcmpW(valW, prodcodeW),
8108 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8109 ok(size == lstrlenW(prodcodeW),
8110 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8111
8112 /* nonexistent property */
8113 size = MAX_PATH;
8114 lstrcpyA(val, "apple");
8115 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8117 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8118 ok(size == 0, "Expected 0, got %lu\n", size);
8119
8120 size = MAX_PATH;
8121 lstrcpyW(valW, L"apple");
8122 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8124 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8125 ok(size == 0, "Expected 0, got %lu\n", size);
8126
8127 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8129
8130 /* non-product property set */
8131 size = MAX_PATH;
8132 lstrcpyA(val, "apple");
8133 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8135 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8136 ok(size == 0, "Expected 0, got %lu\n", size);
8137
8138 size = MAX_PATH;
8139 lstrcpyW(valW, L"apple");
8140 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8142 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8143 ok(size == 0, "Expected 0, got %lu\n", size);
8144
8145 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8147
8148 /* non-product property that is also a product property set */
8149 size = MAX_PATH;
8150 lstrcpyA(val, "apple");
8151 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8153 ok(!lstrcmpA(val, prodcode),
8154 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8155 ok(size == lstrlenA(prodcode),
8156 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8157
8158 size = MAX_PATH;
8159 lstrcpyW(valW, L"apple");
8160 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8162 ok(!lstrcmpW(valW, prodcodeW),
8163 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8164 ok(size == lstrlenW(prodcodeW),
8165 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8166
8167 MsiCloseHandle(hprod);
8168done:
8169 RegDeleteValueA(props, "LocalPackage");
8170 RegDeleteKeyExA(props, "", access, 0);
8172 RegDeleteKeyExA(userkey, "", access, 0);
8173 RegCloseKey(userkey);
8174 RegDeleteKeyExA(prodkey, "", access, 0);
8175 RegCloseKey(prodkey);
8177}
8178
8179static void test_MsiSetProperty(void)
8180{
8181 MSIHANDLE hpkg, hdb, hrec;
8182 CHAR buf[MAX_PATH];
8183 LPCSTR query;
8184 DWORD size;
8185 UINT r;
8186
8189 {
8190 skip("Not enough rights to perform tests\n");
8192 return;
8193 }
8194 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8195
8196 /* invalid hInstall */
8197 r = MsiSetPropertyA(0, "Prop", "Val");
8199 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8200
8201 /* invalid hInstall */
8202 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8204 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8205
8206 /* szName is NULL */
8207 r = MsiSetPropertyA(hpkg, NULL, "Val");
8209 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8210
8211 /* both szName and szValue are NULL */
8212 r = MsiSetPropertyA(hpkg, NULL, NULL);
8214 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8215
8216 /* szName is empty */
8217 r = MsiSetPropertyA(hpkg, "", "Val");
8219 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8220
8221 /* szName is empty and szValue is NULL */
8222 r = MsiSetPropertyA(hpkg, "", NULL);
8223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8224
8225 /* set a property */
8226 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8228
8229 /* get the property */
8230 size = MAX_PATH;
8231 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8233 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8234 ok(size == 3, "Expected 3, got %lu\n", size);
8235
8236 /* update the property */
8237 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8239
8240 /* get the property */
8241 size = MAX_PATH;
8242 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8244 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8245 ok(size == 4, "Expected 4, got %lu\n", size);
8246
8247 hdb = MsiGetActiveDatabase(hpkg);
8248 ok(hdb != 0, "Expected a valid database handle\n");
8249
8250 /* set prop is not in the _Property table */
8251 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8252 r = do_query(hdb, query, &hrec);
8254 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8255
8256 /* set prop is not in the Property table */
8257 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8258 r = do_query(hdb, query, &hrec);
8260 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8261
8262 MsiCloseHandle(hdb);
8263
8264 /* szValue is an empty string */
8265 r = MsiSetPropertyA(hpkg, "Prop", "");
8266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8267
8268 /* try to get the property */
8269 size = MAX_PATH;
8270 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8272 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8273 ok(size == 0, "Expected 0, got %lu\n", size);
8274
8275 /* reset the property */
8276 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278
8279 /* delete the property */
8280 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8282
8283 /* try to get the property */
8284 size = MAX_PATH;
8285 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8287 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8288 ok(size == 0, "Expected 0, got %lu\n", size);
8289
8290 MsiCloseHandle(hpkg);
8292}
8293
8295{
8297
8299 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8300
8302 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8303
8305 if (type == DRIVE_FIXED)
8306 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8307 else
8308 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8309
8311 if (type == DRIVE_FIXED)
8312 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8313 else
8314 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8315
8317 if (type == DRIVE_FIXED)
8318 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8319 else
8320 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8321
8322 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8323 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8324
8325 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8326 if (type == DRIVE_FIXED)
8327 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8328 else
8329 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8330
8331 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8332 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8333
8334 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8335 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8336}
8337
8338static void test_MsiApplyPatch(void)
8339{
8340 UINT r;
8341
8343 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8344
8346 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8347}
8348
8349static void test_costs(void)
8350{
8351 MSIHANDLE hdb, hpkg;
8352 char package[12], drive[3];
8353 DWORD len;
8354 UINT r;
8355 int cost, temp;
8356
8357 hdb = create_package_db();
8358 ok( hdb, "failed to create database\n" );
8359
8360 create_property_table( hdb );
8361 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8362 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8363 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8364
8365 create_media_table( hdb );
8366 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8367
8368 create_file_table( hdb );
8369 add_file_entry( hdb, "'a.txt', 'one', 'a.txt', 2048000000, '', '', 8192, 1" );
8370 add_file_entry( hdb, "'b.txt', 'one', 'b.txt', 2048000000, '', '', 8192, 1" );
8371 add_file_entry( hdb, "'c.txt', 'one', 'c.txt', 2048000000, '', '', 8192, 1" );
8372 add_file_entry( hdb, "'d.txt', 'one', 'd.txt', 4097, '', '', 8192, 1" );
8373 add_file_entry( hdb, "'e.txt', 'one', 'e.txt', 1, '', '', 8192, 1" );
8374
8376 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'a.txt'" );
8377 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8378
8379 create_feature_table( hdb );
8380 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8381 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8382
8384 add_feature_components_entry( hdb, "'one', 'one'" );
8385 add_feature_components_entry( hdb, "'two', 'two'" );
8386
8388 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8389 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8390 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8391 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8392
8393 r = MsiDatabaseCommit( hdb );
8394 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8395
8396 sprintf( package, "#%lu", hdb );
8397 r = MsiOpenPackageA( package, &hpkg );
8399 {
8400 skip("Not enough rights to perform tests\n");
8401 goto error;
8402 }
8403 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8404
8406 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8407
8409 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8410
8412 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8413
8415 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8416
8418 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8419
8420 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8421 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8422
8424 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8425
8426 len = sizeof(drive);
8427 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8428 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8429
8430 len = sizeof(drive);
8431 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8432 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8433
8434 len = sizeof(drive);
8435 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8436 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8437
8438 len = sizeof(drive);
8439 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8440 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8441
8443
8444 r = MsiDoActionA( hpkg, "CostInitialize" );
8445 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8446
8447 r = MsiDoActionA( hpkg, "FileCost" );
8448 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8449
8450 len = sizeof(drive);
8451 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8452 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8453
8454 r = MsiDoActionA( hpkg, "CostFinalize" );
8455 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8456
8457 /* contrary to what msdn says InstallValidate must be called too */
8458 len = sizeof(drive);
8459 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8460 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8461
8462 r = MsiDoActionA( hpkg, "InstallValidate" );
8463 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8464
8465 len = 0;
8466 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8467 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8468
8469 len = 0;
8470 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8471 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8472 ok( len == 2, "expected len == 2, got %lu\n", len );
8473
8474 len = 2;
8475 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8476 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8477 ok( len == 2, "expected len == 2, got %lu\n", len );
8478
8479 len = 2;
8480 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8481 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8482 ok( len == 2, "expected len == 2, got %lu\n", len );
8483
8484 /* install state doesn't seem to matter */
8485 len = sizeof(drive);
8486 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8487 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8488
8489 len = sizeof(drive);
8490 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8491 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8492
8493 len = sizeof(drive);
8494 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8495 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8496
8497 len = sizeof(drive);
8498 drive[0] = 0;
8499 cost = temp = 0xdead;
8500 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8501 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8502 ok( len == 2, "expected len == 2, got %lu\n", len );
8503 ok( drive[0], "expected a drive\n" );
8504 ok( cost == 12000024, "got %d\n", cost );
8505 ok( !temp, "expected temp == 0, got %d\n", temp );
8506
8507 len = sizeof(drive);
8508 drive[0] = 0;
8509 cost = temp = 0xdead;
8510 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8511 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8512 ok( len == 2, "expected len == 2, got %lu\n", len );
8513 ok( drive[0], "expected a drive\n" );
8514 ok( !cost, "expected cost == 0, got %d\n", cost );
8515 ok( !temp, "expected temp == 0, got %d\n", temp );
8516
8517 len = sizeof(drive);
8518 drive[0] = 0;
8519 cost = temp = 0xdead;
8520 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8521 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8522 ok( len == 2, "expected len == 2, got %lu\n", len );
8523 ok( drive[0], "expected a drive\n" );
8524 ok( !cost, "expected cost == 0, got %d\n", cost );
8525 todo_wine ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8526
8527 /* increased index */
8528 len = sizeof(drive);
8529 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8530 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8531
8532 len = sizeof(drive);
8533 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8534 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8535
8536 /* test MsiGetFeatureCost */
8537 cost = 0xdead;
8539 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8540 ok( cost == 0xdead, "got %d\n", cost );
8541
8543 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8544
8545 cost = 0xdead;
8547 ok( !r, "got %u\n", r);
8548 ok( cost == 12000024, "got %d\n", cost );
8549
8550 MsiCloseHandle( hpkg );
8551error:
8552 MsiCloseHandle( hdb );
8554}
8555
8556static void test_MsiDatabaseCommit(void)
8557{
8558 UINT r;
8559 MSIHANDLE hdb, hpkg = 0;
8560 char buf[32], package[12];
8561 DWORD sz;
8562
8563 hdb = create_package_db();
8564 ok( hdb, "failed to create database\n" );
8565
8566 create_property_table( hdb );
8567
8568 sprintf( package, "#%lu", hdb );
8569 r = MsiOpenPackageA( package, &hpkg );
8571 {
8572 skip("Not enough rights to perform tests\n");
8573 goto error;
8574 }
8575 ok( r == ERROR_SUCCESS, "got %u\n", r );
8576
8577 r = MsiSetPropertyA( hpkg, "PROP", "value" );
8578 ok( r == ERROR_SUCCESS, "got %u\n", r );
8579
8580 buf[0] = 0;
8581 sz = sizeof(buf);
8582 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8583 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8584 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8585
8586 r = MsiDatabaseCommit( hdb );
8587 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8588
8589 buf[0] = 0;
8590 sz = sizeof(buf);
8591 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8592 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8593 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8594
8595 MsiCloseHandle( hpkg );
8596error:
8597 MsiCloseHandle( hdb );
8599}
8600
8602
8604{
8605 externalui_ran = 1;
8606 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8607 return 0;
8608}
8609
8611
8612static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
8613{
8614 INT retval = context ? *((INT *)context) : 0;
8615 UINT r;
8617 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8618 r = MsiRecordGetFieldCount(hrecord);
8619 ok(r == 1, "expected 1, got %u\n", r);
8620 r = MsiRecordGetInteger(hrecord, 1);
8621 ok(r == 12345, "expected 12345, got %u\n", r);
8622 return retval;
8623}
8624
8625static void test_externalui(void)
8626{
8627 /* test that external UI handlers work correctly */
8628
8629 INSTALLUI_HANDLERA prev;
8630 INSTALLUI_HANDLER_RECORD prev_record;
8631 MSIHANDLE hpkg, hrecord;
8632 UINT r;
8633 INT retval = 0;
8634
8636
8639 {
8640 skip("Not enough rights to perform tests\n");
8642 return;
8643 }
8644 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8645
8646 hrecord = MsiCreateRecord(1);
8647 ok(hrecord, "Expected a valid record\n");
8648 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
8649 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
8650 r = MsiRecordSetInteger(hrecord, 1, 12345);
8651 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
8652
8653 externalui_ran = 0;
8654 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8655 ok(r == 0, "expected 0, got %u\n", r);
8656 ok(externalui_ran == 1, "external UI callback did not run\n");
8657
8658 prev = MsiSetExternalUIA(prev, 0, NULL);
8659 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
8661 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8662
8664 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8665 ok(r == 0, "expected 0, got %u\n", r);
8666 ok(externalui_ran == 0, "external UI callback should not have run\n");
8667 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8668
8670
8672 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8673 ok(r == 0, "expected 0, got %u\n", r);
8674 ok(externalui_ran == 1, "external UI callback did not run\n");
8675 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8676
8677 retval = 1;
8679 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8680 ok(r == 1, "expected 1, got %u\n", r);
8681 ok(externalui_ran == 0, "external UI callback should not have run\n");
8682 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8683
8684 /* filter and context should be kept separately */
8686 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8687
8689 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8690 ok(r == 0, "expected 0, got %u\n", r);
8691 ok(externalui_ran == 1, "external UI callback did not run\n");
8692 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
8693
8694 MsiCloseHandle(hpkg);
8696}
8697
8701 char field[4][100];
8702 int match[4]; /* should we test for a match */
8704};
8705
8708
8709static void add_message(const struct externalui_message *msg)
8710{
8711 if (!sequence)
8712 {
8713 sequence_size = 10;
8714 sequence = malloc(sequence_size * sizeof(*sequence));
8715 }
8717 {
8718 sequence_size *= 2;
8720 }
8721
8724}
8725
8726static void flush_sequence(void)
8727{
8728 free(sequence);
8729 sequence = NULL;
8731}
8732
8733static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
8734 const char *file, int line)
8735{
8736 static const struct externalui_message end_of_sequence = {0};
8737 const struct externalui_message *actual;
8738 int failcount = 0;
8739 int i;
8740
8741 add_message(&end_of_sequence);
8742
8743 actual = sequence;
8744
8745 while (expected->message && actual->message)
8746 {
8747 if (expected->message == actual->message)
8748 {
8749 if (expected->field_count < actual->field_count)
8750 {
8752 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
8753 context, expected->message, expected->field_count, actual->field_count);
8754 failcount++;
8755 }
8756
8757 for (i = 0; i <= actual->field_count; i++)
8758 {
8759 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
8760 {
8762 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8763 context, expected->message, i, expected->field[i], actual->field[i]);
8764 failcount++;
8765 }
8766 }
8767
8768 expected++;
8769 actual++;
8770 }
8771 else if (expected->optional)
8772 {
8773 expected++;
8774 }
8775 else
8776 {
8778 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8779 context, expected->message, actual->message);
8780 failcount++;
8781 if (todo)
8782 goto done;
8783 expected++;
8784 actual++;
8785 }
8786 }
8787
8788 if (expected->message || actual->message)
8789 {
8791 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8792 context, expected->message, actual->message);
8793 failcount++;
8794 }
8795
8796 if(todo && !failcount) /* succeeded yet marked todo */
8797 {
8798 todo_wine
8799 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
8800 }
8801
8802done:
8804}
8805
8806#define ok_sequence(exp, contx, todo) \
8807 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8808
8809/* don't use PROGRESS, which is timing-dependent,
8810 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8828
8829static const struct externalui_message empty_sequence[] = {
8830 {0}
8831};
8832
8836 {0}
8837};
8838
8841 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8842 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
8843 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8844 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8845 {0}
8846};
8847
8849 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8850 {0}
8851};
8852
8854 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8855 {0}
8856};
8857
8859 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8860 {0}
8861};
8862
8864 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8865 {0}
8866};
8867
8869 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8870 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8871 {0}
8872};
8873
8875 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8876 {0}
8877};
8878
8880 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8881 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8882 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8883 {0}
8884};
8885
8887 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8888 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8889 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8890 {0}
8891};
8892
8894 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8895 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
8896 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8897 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8898 {0}
8899};
8900
8902 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8903 {0}
8904};
8905
8907 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8908 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8909 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8910 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
8911 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
8912 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8913 {0}
8914};
8915
8917 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8918 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
8919 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8920 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
8921 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
8922 {0}
8923};
8924
8926 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
8927 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
8928 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
8929 {0}
8930};
8931
8933 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8934 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
8935 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8936 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
8937 {0}
8938};
8939
8941 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
8942 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
8943 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
8944 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
8945 {0}
8946};
8947
8950 {0}
8951};
8952
8954{
8955 INT retval = context ? *((INT *)context) : 0;
8956 struct externalui_message msg;
8957
8958 msg.message = message;
8959 msg.field_count = 0;
8960 strcpy(msg.field[0], string);
8961 add_message(&msg);
8962
8963 return retval;
8964}
8965
8967{
8968 INT retval = context ? *((INT *)context) : 0;
8969 struct externalui_message msg;
8970 char buffer[256];
8971 DWORD length;
8972 UINT r;
8973 int i;
8974
8975 msg.message = message;
8977 {
8978 /* trying to access the record seems to hang on some versions of Windows */
8979 msg.field_count = -1;
8980 add_message(&msg);
8981 return 1;
8982 }
8983 msg.field_count = MsiRecordGetFieldCount(hrecord);
8984 for (i = 0; i <= msg.field_count; i++)
8985 {
8986 length = sizeof(buffer);
8987 r = MsiRecordGetStringA(hrecord, i, buffer, &length);
8988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8989 memcpy(msg.field[i], buffer, min(100, length+1));
8990 }
8991
8992 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
8993 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
8994 return retval;
8995
8996 add_message(&msg);
8997
8998 return retval;
8999}
9000
9002{
9003 /* test that events trigger the correct sequence of messages */
9004
9006 MSIHANDLE hdb, hpkg, hrecord;
9007 INT retval = 1;
9008 UINT r;
9009
9011
9014
9016
9018
9019 hdb = create_package_db();
9020 ok(hdb, "failed to create database\n");
9021
9022 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
9023 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9025
9026 r = run_query(hdb, 0, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9027 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
9028 r = run_query(hdb, 0, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9029 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
9030
9032 add_actiontext_entry(hdb, "'custom', 'description', 'template'");
9033 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
9034
9035 r = MsiOpenPackageA(NULL, &hpkg);
9036 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9037 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
9038
9039 r = MsiOpenPackageA("nonexistent", &hpkg);
9040 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9041 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9042
9043 r = package_from_db(hdb, &hpkg);
9045 {
9046 skip("Not enough rights to perform tests\n");
9048 return;
9049 }
9050 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9051 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9052
9053 /* Test MsiProcessMessage */
9054 hrecord = MsiCreateRecord(3);
9055 ok(hrecord, "failed to create record\n");
9056
9057 MsiRecordSetStringA(hrecord, 0, "zero");
9058 MsiRecordSetStringA(hrecord, 1, "one");
9059 MsiRecordSetStringA(hrecord, 2, "two");
9060 MsiRecordSetStringA(hrecord, 3, "three");
9061 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9062 ok(r == 1, "Expected 1, got %d\n", r);
9063 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9064
9065 MsiRecordSetStringA(hrecord, 1, "name");
9066 MsiRecordSetStringA(hrecord, 2, "description");
9067 MsiRecordSetStringA(hrecord, 3, "template");
9069 ok(r == 1, "Expected 1, got %d\n", r);
9070 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9071
9072 MsiRecordSetStringA(hrecord, 0, "apple");
9073 MsiRecordSetStringA(hrecord, 1, "cherry");
9074 MsiRecordSetStringA(hrecord, 2, "banana");
9075 MsiRecordSetStringA(hrecord, 3, "guava");
9077 ok(r == 1, "Expected 1, got %d\n", r);
9078 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9079
9080 /* non-internal error */
9081 MsiRecordSetStringA(hrecord, 0, NULL);
9082 MsiRecordSetInteger(hrecord, 1, 1311);
9083 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9084 ok(r == 1, "Expected 1, got %d\n", r);
9085 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9086
9087 /* internal error */
9088 MsiRecordSetStringA(hrecord, 0, NULL);
9089 MsiRecordSetInteger(hrecord, 1, 2726);
9090 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9091 ok(r == 0, "Expected 0, got %d\n", r);
9092 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9093
9094 /* with format field */
9095 MsiRecordSetStringA(hrecord, 0, "starfruit");
9096 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9097 ok(r == 1, "Expected 1, got %d\n", r);
9098 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9099
9100 /* Test a standard action */
9101 r = MsiDoActionA(hpkg, "CostInitialize");
9102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9103 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9104
9105 /* Test a custom action */
9106 r = MsiDoActionA(hpkg, "custom");
9107 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9108 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9109
9110 /* close the package */
9111 MsiCloseHandle(hpkg);
9112 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9113
9114 /* Test dialogs */
9115 hdb = create_package_db();
9116 ok(hdb, "failed to create database\n");
9117
9118 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9120
9122 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9123
9125 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9126
9127 r = package_from_db(hdb, &hpkg);
9128 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9129 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9130
9131 /* Test a custom action */
9132 r = MsiDoActionA(hpkg, "custom");
9133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9134 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9135
9136 retval = 2;
9137 r = MsiDoActionA(hpkg, "custom");
9138 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9139 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9140
9141 retval = 0;
9142 r = MsiDoActionA(hpkg, "custom");
9143 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9144 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9145
9146 r = MsiDoActionA(hpkg, "dialog");
9147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9148 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9149
9150 retval = -1;
9151 r = MsiDoActionA(hpkg, "error");
9152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9153 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9154
9155 r = MsiDoActionA(hpkg, "error");
9156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9157 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9158
9159 retval = -2;
9160 r = MsiDoActionA(hpkg, "custom");
9161 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9162 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9163
9164 retval = 3;
9165 r = MsiDoActionA(hpkg, "dialog");
9166 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9167 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9168
9169 retval = 12345;
9170 r = MsiDoActionA(hpkg, "dialog");
9171 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9172 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9173
9174 MsiCloseHandle(hpkg);
9175 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9176
9177 MsiCloseHandle(hrecord);
9180 DeleteFileA("forcecodepage.idt");
9181}
9182
9184 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9185 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9186 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9187 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9188
9189 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9190 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9191 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9192
9193 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9194
9195 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9196 {0}
9197};
9198
9200 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9201 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9202 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9203 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9204
9205 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9206 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9207 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9208
9209 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9210
9211 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9212 {0}
9213};
9214
9215static void test_controlevent(void)
9216{
9218 MSIHANDLE hdb, hpkg;
9219 UINT r;
9220
9222 {
9223 skip("interactive ControlEvent tests\n");
9224 return;
9225 }
9226
9228
9231
9233
9235
9236 hdb = create_package_db();
9237 ok(hdb, "failed to create database\n");
9238
9239 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
9240 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9242
9244 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9245 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9246 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9247 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9248
9250 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9251 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9252 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9253 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9254
9256 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9257 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9258
9260 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9261
9262 /* SpawnDialog and EndDialog should trigger after all other events */
9263 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9264 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9265
9266 /* Multiple dialog events cause only the last one to be triggered */
9267 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9268 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9269 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9270
9271 r = package_from_db(hdb, &hpkg);
9272 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9273 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9274
9275 r = MsiDoActionA(hpkg, "spawn");
9276 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9277 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9278
9279 r = MsiDoActionA(hpkg, "spawn2");
9280 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9281 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9282
9283 MsiCloseHandle(hpkg);
9284 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9285
9288 DeleteFileA("forcecodepage.idt");
9289}
9290
9292 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9293 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9294
9295 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9296 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9297 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9298 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9299 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9300
9301 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9302 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9303 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9304
9305 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9306 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9307 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9308
9309 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9310 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9311 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9312
9313 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9314 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9315 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9316
9317 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9318 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9319
9320 /* property dump */
9321
9322 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9323 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9324 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9325 {0}
9326};
9327
9329 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9330 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9331
9332 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9333 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9334 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9335
9336 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9337 {0}
9338};
9339
9341 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9342 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9343
9344 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9345 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9346 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9347 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9348
9349 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9350 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9351 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9352
9353 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9354 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9355 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9356
9357 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9358 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9359 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9360
9361 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9362 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9363 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9364
9365 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9366 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9367
9368 /* property dump */
9369
9370 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9371 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9372 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9373 {0}
9374};
9375
9377 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9378 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9379
9380 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9381 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9382 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9383 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9384
9385 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9386 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9387 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9388
9389 /* property dump */
9390
9391 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9392 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9393 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9394 {0}
9395};
9396
9399
9400 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9401 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9402 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9403 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9404 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9405
9406 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9407 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9408
9409 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9410 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9411 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9412
9413 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9414
9415 /* property dump */
9416
9417 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9419 {0}
9420};
9421
9424
9425 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9426 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9427 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9428 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9429 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9430
9431 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9432 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9433 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9434
9435 /* property dump */
9436
9437 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9439 {0}
9440};
9441
9442/* tests involving top-level actions: INSTALL, ExecuteAction */
9443static void test_top_level_action(void)
9444{
9446 MSIHANDLE hdb, hpkg;
9447 UINT r;
9448 char msifile_absolute[MAX_PATH];
9449
9451
9454
9456
9458
9459 hdb = create_package_db();
9460 ok(hdb, "failed to create database\n");
9461
9462 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") -1 );
9463 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9465
9467 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9468
9470 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9471 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9472 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9473
9475 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9476
9477 MsiDatabaseCommit(hdb);
9478
9479 /* for some reason we have to open the package from file using an absolute path */
9480 MsiCloseHandle(hdb);
9481 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9482 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9483 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9484 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9485
9486 /* test INSTALL */
9487 r = MsiDoActionA(hpkg, "INSTALL");
9488 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9489 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9490
9491 /* test INSTALL with reduced+ UI */
9492 /* for some reason we need to re-open the package to change the internal UI */
9493 MsiCloseHandle(hpkg);
9494 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9496 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9497 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9498 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9499
9500 r = MsiDoActionA(hpkg, "INSTALL");
9501 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9502 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9503
9504 /* test ExecuteAction with EXECUTEACTION property unset */
9505 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9506 r = MsiDoActionA(hpkg, "ExecuteAction");
9507 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9508 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9509
9510 /* test ExecuteAction with EXECUTEACTION property set */
9511 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9512 r = MsiDoActionA(hpkg, "ExecuteAction");
9513 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9514 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9515
9516 MsiCloseHandle(hpkg);
9517 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9518
9519 /* test MsiInstallProduct() */
9520 r = MsiInstallProductA(msifile_absolute, NULL);
9521 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9522 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9523
9524 r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9525 todo_wine
9526 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9527 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9528
9531 DeleteFileA("forcecodepage.idt");
9532}
9533
9535{
9536 char temp_path[MAX_PATH], prev_path[MAX_PATH];
9537 DWORD len;
9538
9540
9542
9543 GetCurrentDirectoryA(MAX_PATH, prev_path);
9546
9549
9550 if (len && (CURR_DIR[len - 1] == '\\'))
9551 CURR_DIR[len - 1] = 0;
9552
9554 test_doaction();
9557 test_props();
9563 test_states();
9578 test_access();
9584 test_costs();
9590
9591 SetCurrentDirectoryA(prev_path);
9592}
static char CURR_DIR[MAX_PATH]
#define add_message(msg)
Definition: SystemMenu.c:98
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define isalpha(c)
Definition: acclib.h:74
#define REG_SZ
Definition: layer.c:22
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
static int run_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse)
Definition: query.c:311
void ls(int argc, const char *argv[])
Definition: cmds.c:1136
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:20
#define RegCloseKey(hKey)
Definition: registry.h:49
#define _stricmp
Definition: cat.c:22
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copyansi.c:58
static const WCHAR msifile2W[]
Definition: db.c:38
static const char * msifile2
Definition: db.c:35
static const CHAR suminfo[]
Definition: db.c:2166
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const GUID * classes[]
Definition: loader.c:49
unsigned int idx
Definition: utils.c:40
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1254
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegSetValueA(HKEY hKeyOriginal, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData)
Definition: reg.c:4954
LONG WINAPI RegDeleteKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1286
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3637
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
HRESULT WINAPI CoCreateGuid(GUID *guid)
Definition: combase.c:1016
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define lstrcpynA
Definition: compat.h:751
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define GENERIC_READ
Definition: compat.h:135
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
@ VT_LPSTR
Definition: compat.h:2324
@ VT_I4
Definition: compat.h:2298
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:372
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:191
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:682
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:620
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2164
UINT WINAPI GetSystemWow64DirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2456
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2355
DWORD WINAPI GetFullPathNameA(IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
Definition: path.c:1051
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2224
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2072
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2301
VOID WINAPI GetNativeSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:207
BOOL WINAPI DECLSPEC_HOTPATCH WritePrivateProfileStringA(LPCSTR section, LPCSTR entry, LPCSTR string, LPCSTR filename)
Definition: profile.c:1484
BOOL WINAPI UpdateResourceA(HANDLE hUpdate, LPCSTR lpType, LPCSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
Definition: res.c:1738
HANDLE WINAPI BeginUpdateResourceA(LPCSTR pFileName, BOOL bDeleteExistingResources)
Definition: res.c:1657
BOOL WINAPI EndUpdateResourceA(HANDLE hUpdate, BOOL fDiscard)
Definition: res.c:1697
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4104
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:746
GUID guid
Definition: version.c:147
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:975
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
Definition: database.c:863
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:317
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiFormatRecordA(MSIHANDLE hinst, MSIHANDLE hrec, char *buf, DWORD *sz)
Definition: format.c:954
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
UINT WINAPI MsiGetSourcePathA(MSIHANDLE hinst, const char *folder, char *buf, DWORD *sz)
Definition: install.c:409
UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
Definition: install.c:1398
UINT WINAPI MsiGetTargetPathW(MSIHANDLE hinst, const WCHAR *folder, WCHAR *buf, DWORD *sz)
Definition: install.c:311
UINT WINAPI MsiDoActionA(MSIHANDLE hInstall, LPCSTR szAction)
Definition: install.c:45
UINT WINAPI MsiGetTargetPathA(MSIHANDLE hinst, const char *folder, char *buf, DWORD *sz)
Definition: install.c:252
UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, INSTALLSTATE iState)
Definition: install.c:817
UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, LPCSTR szFolderPath)
Definition: install.c:519
UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature, MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
Definition: install.c:1131
UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
Definition: install.c:1055
UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, INSTALLSTATE iState)
Definition: install.c:1382
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
Definition: msi.c:80
UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD handler, DWORD filter, void *context, INSTALLUI_HANDLER_RECORD *prev)
Definition: msi.c:4149
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:198
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, DWORD dwMessageFilter, void *pvContext)
Definition: msi.c:2306
UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, const char *szProperty, char *szValue, DWORD *pccbValue)
Definition: msi.c:2590
UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, const WCHAR *szProperty, WCHAR *szValue, DWORD *pccbValue)
Definition: msi.c:2650
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, LPDWORD pcchValueBuf)
Definition: msi.c:1254
UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR szPatchPackages, LPCSTR szProductCode, LPCSTR szPropertiesList)
Definition: msi.c:424
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2281
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
Definition: msi.c:3023
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage, INSTALLTYPE eInstallType, LPCSTR szCommandLine)
Definition: msi.c:286
UINT WINAPI MsiEnumComponentCostsA(MSIHANDLE handle, const char *component, DWORD index, INSTALLSTATE state, char *drive, DWORD *buflen, int *cost, int *temp)
Definition: msi.c:1925
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
Definition: package.c:1696
UINT WINAPI MsiSetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
Definition: package.c:2099
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
Definition: package.c:1701
UINT WINAPI MsiGetPropertyW(MSIHANDLE hinst, const WCHAR *name, WCHAR *buf, DWORD *sz)
Definition: package.c:2417
UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz)
Definition: package.c:2345
INT WINAPI MsiProcessMessage(MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, MSIHANDLE hRecord)
Definition: package.c:2049
int WINAPI MsiRecordGetInteger(MSIHANDLE handle, UINT iField)
Definition: record.c:237
UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField, char *szValue, DWORD *pcchValue)
Definition: record.c:403
MSIHANDLE WINAPI MsiCreateRecord(UINT cParams)
Definition: record.c:92
UINT WINAPI MsiRecordSetInteger(MSIHANDLE handle, UINT iField, int iVal)
Definition: record.c:303
UINT WINAPI MsiRecordSetStringA(MSIHANDLE handle, UINT iField, const char *szValue)
Definition: record.c:549
UINT WINAPI MsiRecordGetFieldCount(MSIHANDLE handle)
Definition: record.c:113
UINT WINAPI MsiSummaryInfoSetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const char *szValue)
Definition: suminfo.c:941
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:588
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1226
int WINAPIV fprintf(FILE *file, const char *format,...)
Definition: file.c:5549
#define assert(_expr)
Definition: assert.h:32
#define stderr
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP __msvcrt_long __cdecl atol(const char *)
Definition: string.c:1787
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3291
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3335
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3303
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
static BOOL is_process_elevated(void)
Definition: dplayx.c:10558
return ret
Definition: mutex.c:147
action
Definition: namespace.c:707
#define L(x)
Definition: resources.c:13
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum condition
Definition: glext.h:9255
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
const GLuint GLenum const GLvoid * binary
Definition: glext.h:7538
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define resource
Definition: kernel32.h:9
#define wine_dbgstr_w
Definition: kernel32.h:34
BOOL is_wow64
Definition: main.c:38
USHORT LANGID
Definition: mui.h:9
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define win_skip
Definition: minitest.h:67
int winetest_interactive
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2000
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmcache.c:793
static SYSTEM_INFO si
Definition: virtual.c:39
void restart_as_admin_elevated(void)
Definition: action.c:6478
static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
Definition: package.c:8966
#define add_install_ui_sequence_entry(hdb, values)
Definition: package.c:703
static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
Definition: package.c:6049
#define add_signature_entry(hdb, values)
Definition: package.c:680
static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
Definition: package.c:845
static UINT create_complocator_table(MSIHANDLE hdb)
Definition: package.c:516
static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value)
Definition: package.c:1993
static const struct externalui_message openpackage_nonexistent_sequence[]
Definition: package.c:8833
static UINT create_appsearch_table(MSIHANDLE hdb)
Definition: package.c:389
static const struct externalui_message toplevel_install_ui_sequence[]
Definition: package.c:9328
static void test_removefiles(void)
Definition: package.c:3711
static UINT create_control_table(MSIHANDLE hdb)
Definition: package.c:575
static void test_property_table(void)
Definition: package.c:2222
static void test_formatrecord_tables(void)
Definition: package.c:2600
static UINT create_install_ui_sequence_table(MSIHANDLE hdb)
Definition: package.c:466
static void test_access(void)
Definition: package.c:7651
#define add_install_execute_sequence_entry(hdb, values)
Definition: package.c:699
static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo, const char *file, int line)
Definition: package.c:8733
static void test_doaction(void)
Definition: package.c:962
static const WCHAR msifileW[]
Definition: package.c:39
static void test_controlevent(void)
Definition: package.c:9215
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: package.c:122
static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[]
Definition: package.c:9422
static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
Definition: package.c:239
#define add_control_entry(hdb, values)
Definition: package.c:736
static const struct externalui_message toplevel_install_sequence[]
Definition: package.c:9291
static char * get_user_sid(void)
Definition: package.c:41
static UINT create_feature_table(MSIHANDLE hdb)
Definition: package.c:330
static const struct externalui_message doaction_custom_cancel_sequence[]
Definition: package.c:8901
static UINT create_reglocator_table(MSIHANDLE hdb)
Definition: package.c:400
static void test_MsiApplyPatch(void)
Definition: package.c:8338
static struct externalui_message * sequence
Definition: package.c:8706
static const struct externalui_message doaction_costinitialize_sequence[]
Definition: package.c:8879
#define add_component_entry(hdb, values)
Definition: package.c:653
static const struct externalui_message processmessage_actionstart_sequence[]
Definition: package.c:8853
#define add_dialog_entry(hdb, values)
Definition: package.c:732
static UINT create_launchcondition_table(MSIHANDLE hdb)
Definition: package.c:432
static void test_msipackage(void)
Definition: package.c:2415
static const struct access_res create[16]
Definition: package.c:7546
static const struct externalui_message toplevel_msiinstallproduct_sequence[]
Definition: package.c:9397
static void test_installprops(void)
Definition: package.c:5444
static void test_component_states(UINT line, MSIHANDLE package, const char *component, UINT error, INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo)
Definition: package.c:2886
static const char msifile[]
Definition: package.c:38
static const struct externalui_message doaction_dialog_12345_sequence[]
Definition: package.c:8940
static UINT create_upgrade_table(MSIHANDLE hdb)
Definition: package.c:623
static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
Definition: package.c:8603
static UINT create_feature_components_table(MSIHANDLE hdb)
Definition: package.c:347
static const struct externalui_message processmessage_error_format_sequence[]
Definition: package.c:8874
#define add_actiontext_entry(hdb, values)
Definition: package.c:744
static int externalui_record_ran
Definition: package.c:8610
static int externalui_ran
Definition: package.c:8601
#define add_media_entry(hdb, values)
Definition: package.c:707
static void test_appsearch_reglocator(void)
Definition: package.c:4226
static UINT try_query(MSIHANDLE hdb, LPCSTR szQuery)
Definition: package.c:2376
#define update_ProductCode_property(hdb, value)
Definition: package.c:696
#define add_ccpsearch_entry(hdb, values)
Definition: package.c:712
static const struct externalui_message doaction_dialog_3_sequence[]
Definition: package.c:8932
static UINT create_install_execute_sequence_table(MSIHANDLE hdb)
Definition: package.c:454
static UINT create_controlevent_table(MSIHANDLE hdb)
Definition: package.c:596
static UINT create_inilocator_table(MSIHANDLE hdb)
Definition: package.c:528
static void test_props(void)
Definition: package.c:2006
static void test_complocator(void)
Definition: package.c:5808
static UINT create_component_table(MSIHANDLE hdb)
Definition: package.c:315
static void test_MsiDatabaseCommit(void)
Definition: package.c:8556
static void test_appsearch(void)
Definition: package.c:3860
#define ok_sequence(exp, contx, todo)
Definition: package.c:8806
static void test_MsiGetProductProperty(void)
Definition: package.c:7850
#define add_complocator_entry(hdb, values)
Definition: package.c:719
#define add_inilocator_entry(hdb, values)
Definition: package.c:723
static void test_appsearch_drlocator(void)
Definition: package.c:5050
static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
Definition: package.c:890
static void test_MsiGetSourcePath(void)
Definition: package.c:6066
#define add_file_entry(hdb, values)
Definition: package.c:671
static void test_feature_states(UINT line, MSIHANDLE package, const char *feature, UINT error, INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo)
Definition: package.c:2860
static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
Definition: package.c:8612
static UINT create_actiontext_table(MSIHANDLE hdb)
Definition: package.c:611
static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, LPCSTR guid, LPSTR usersid, BOOL dir)
Definition: package.c:173
static void test_settargetpath(void)
Definition: package.c:1076
struct _tagVS_VERSIONINFO VS_VERSIONINFO
static const struct externalui_message controlevent_spawn_sequence[]
Definition: package.c:9183
static void test_gettargetpath_bad(void)
Definition: package.c:992
static int sequence_size
Definition: package.c:8707
static const struct access_res create_close[16]
Definition: package.c:7586
static const struct externalui_message processmessage_internal_error_sequence[]
Definition: package.c:8868
static void flush_sequence(void)
Definition: package.c:8726
static UINT create_drlocator_table(MSIHANDLE hdb)
Definition: package.c:503
static const struct externalui_message processmessage_error_sequence[]
Definition: package.c:8863
static void test_sourcedir(void)
Definition: package.c:7181
static void test_MsiApplyMultiplePatches(void)
Definition: package.c:8294
static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE
Definition: package.c:8811
static BOOL is_root(const char *path)
Definition: package.c:938
static UINT add_reglocator_entry(MSIHANDLE hdb, const char *sig, UINT root, const char *path, const char *name, UINT type)
Definition: package.c:752
static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
Definition: package.c:7606
static void test_MsiSetProperty(void)
Definition: package.c:8179
static void test_ccpsearch(void)
Definition: package.c:5762
static MSIHANDLE create_package_db(void)
Definition: package.c:815
static void test_createpackage(void)
Definition: package.c:943
static void test_launchconditions(void)
Definition: package.c:5713
static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
Definition: package.c:1057
static const struct externalui_message toplevel_executeaction_install_sequence[]
Definition: package.c:9340
static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
Definition: package.c:2182
static UINT create_remove_file_table(MSIHANDLE hdb)
Definition: package.c:375
static UINT create_custom_action_table(MSIHANDLE hdb)
Definition: package.c:543
static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
Definition: package.c:293
static void test_emptypackage(void)
Definition: package.c:7685
static UINT try_query_param(MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec)
Definition: package.c:2348
#define add_property_entry(hdb, values)
Definition: package.c:690
#define add_feature_components_entry(hdb, values)
Definition: package.c:667
static void test_featureparents(void)
Definition: package.c:5258
static void test_shortlongsource(void)
Definition: package.c:6847
#define add_drlocator_entry(hdb, values)
Definition: package.c:715
static UINT create_property_table(MSIHANDLE hdb)
Definition: package.c:443
static void test_condition(void)
Definition: package.c:1244
static void test_appsearch_inilocator(void)
Definition: package.c:4806
static const struct access_res create_commit[16]
Definition: package.c:7566
#define add_feature_entry(hdb, values)
Definition: package.c:662
static const struct externalui_message closehandle_sequence[]
Definition: package.c:8948
static const struct externalui_message toplevel_executeaction_costinitialize_sequence[]
Definition: package.c:9376
static const struct externalui_message empty_sequence[]
Definition: package.c:8829
#define add_launchcondition_entry(hdb, values)
Definition: package.c:686
static void test_costs(void)
Definition: package.c:8349
static void test_appsearch_complocator(void)
Definition: package.c:3977
#define update_ProductVersion_property(hdb, value)
Definition: package.c:693
#define add_controlevent_entry(hdb, values)
Definition: package.c:740
static const struct externalui_message processmessage_info_sequence[]
Definition: package.c:8848
static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
Definition: package.c:2398
static const struct externalui_message doaction_custom_fullui_sequence[]
Definition: package.c:8893
static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
Definition: package.c:61
static const struct externalui_message doaction_dialog_error_sequence[]
Definition: package.c:8925
static const struct externalui_message doaction_custom_sequence[]
Definition: package.c:8886
static const struct externalui_message processmessage_actiondata_sequence[]
Definition: package.c:8858
#define test_file_access(file, ares)
Definition: package.c:7649
static const struct externalui_message doaction_dialog_nonexistent_sequence[]
Definition: package.c:8906
static UINT set_summary_info(MSIHANDLE hdb)
Definition: package.c:770
#define add_directory_entry(hdb, values)
Definition: package.c:658
static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
Definition: package.c:8953
static UINT create_dialog_table(MSIHANDLE hdb)
Definition: package.c:556
static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
Definition: package.c:2381
static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
Definition: package.c:5020
static void test_top_level_action(void)
Definition: package.c:9443
static void delete_win_ini(LPCSTR file)
Definition: package.c:4795
static int sequence_count
Definition: package.c:8707
static void create_test_file(const CHAR *name)
Definition: package.c:870
static UINT create_signature_table(MSIHANDLE hdb)
Definition: package.c:414
static const struct externalui_message openpackage_sequence[]
Definition: package.c:8839
static void test_externalui_message(void)
Definition: package.c:9001
static const struct externalui_message controlevent_spawn2_sequence[]
Definition: package.c:9199
static UINT create_media_table(MSIHANDLE hdb)
Definition: package.c:478
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: package.c:154
static void test_externalui(void)
Definition: package.c:8625
#define add_upgrade_entry(hdb, values)
Definition: package.c:748
#define roundpos(a, b, r)
Definition: package.c:888
#define add_appsearch_entry(hdb, values)
Definition: package.c:676
static void test_states(void)
Definition: package.c:2913
static UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
Definition: package.c:639
static const struct externalui_message doaction_dialog_sequence[]
Definition: package.c:8916
static UINT create_file_table(MSIHANDLE hdb)
Definition: package.c:358
static void test_formatrecord2(void)
Definition: package.c:2510
#define add_custom_action_entry(hdb, values)
Definition: package.c:728
static UINT create_ccpsearch_table(MSIHANDLE hdb)
Definition: package.c:493
#define PID_PAGECOUNT
Definition: suminfo.c:56
#define PID_WORDCOUNT
Definition: suminfo.c:57
#define PID_REVNUMBER
Definition: suminfo.c:51
INTERNETFEATURELIST feature
Definition: misc.c:1807
#define min(a, b)
Definition: monoChain.cc:55
LANGID langid
Definition: msctf.idl:626
#define INSTALLPROPERTY_LOCALPACKAGEA
Definition: msi.h:342
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
@ INSTALLLOGMODE_INSTALLSTART
Definition: msi.h:150
@ INSTALLLOGMODE_FILESINUSE
Definition: msi.h:136
@ INSTALLLOGMODE_ACTIONDATA
Definition: msi.h:140
@ INSTALLLOGMODE_ACTIONSTART
Definition: msi.h:139
@ INSTALLLOGMODE_FATALEXIT
Definition: msi.h:131
@ INSTALLLOGMODE_RESOLVESOURCE
Definition: msi.h:137
@ INSTALLLOGMODE_COMMONDATA
Definition: msi.h:143
@ INSTALLLOGMODE_WARNING
Definition: msi.h:133
@ INSTALLLOGMODE_INITIALIZE
Definition: msi.h:144
@ INSTALLLOGMODE_TERMINATE
Definition: msi.h:146
@ INSTALLLOGMODE_RMFILESINUSE
Definition: msi.h:149
@ INSTALLLOGMODE_OUTOFDISKSPACE
Definition: msi.h:138
@ INSTALLLOGMODE_ERROR
Definition: msi.h:132
@ INSTALLLOGMODE_INFO
Definition: msi.h:135
@ INSTALLLOGMODE_SHOWDIALOG
Definition: msi.h:148
@ INSTALLLOGMODE_INSTALLEND
Definition: msi.h:151
@ INSTALLLOGMODE_USER
Definition: msi.h:134
@ INSTALLTYPE_DEFAULT
Definition: msi.h:189
INT(CALLBACK * INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR)
Definition: msi.h:420
@ INSTALLMESSAGE_ACTIONSTART
Definition: msi.h:102
@ INSTALLMESSAGE_USER
Definition: msi.h:97
@ INSTALLMESSAGE_TERMINATE
Definition: msi.h:107
@ INSTALLMESSAGE_ACTIONDATA
Definition: msi.h:103
@ INSTALLMESSAGE_COMMONDATA
Definition: msi.h:105
@ INSTALLMESSAGE_INFO
Definition: msi.h:98
@ INSTALLMESSAGE_INITIALIZE
Definition: msi.h:106
@ INSTALLMESSAGE_INSTALLSTART
Definition: msi.h:110
@ INSTALLMESSAGE_SHOWDIALOG
Definition: msi.h:108
@ INSTALLMESSAGE_INSTALLEND
Definition: msi.h:111
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
@ INSTALLSTATE_LOCAL
Definition: msi.h:46
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
@ INSTALLSTATE_SOURCE
Definition: msi.h:47
@ INSTALLSTATE_ADVERTISED
Definition: msi.h:44
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
@ MSIINSTALLCONTEXT_USERMANAGED
Definition: msi.h:198
INT(CALLBACK * INSTALLUI_HANDLER_RECORD)(LPVOID, UINT, MSIHANDLE)
Definition: msi.h:422
enum tagINSTALLUILEVEL INSTALLUILEVEL
enum tagINSTALLLOGMODE INSTALLLOGMODE
@ INSTALLUILEVEL_FULL
Definition: msi.h:69
@ INSTALLUILEVEL_BASIC
Definition: msi.h:67
@ INSTALLUILEVEL_REDUCED
Definition: msi.h:68
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
@ INSTALLUILEVEL_SOURCERESONLY
Definition: msi.h:73
@ msidbLocatorType64bit
Definition: msidefs.h:190
@ msidbLocatorTypeRawValue
Definition: msidefs.h:189
@ msidbLocatorTypeDirectory
Definition: msidefs.h:187
@ msidbLocatorTypeFileName
Definition: msidefs.h:188
@ msidbSumInfoSourceTypeSFN
Definition: msidefs.h:221
@ msidbSumInfoSourceTypeCompressed
Definition: msidefs.h:222
static const BOOL is_64bit
Definition: msipriv.h:44
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:465
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:514
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:958
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:400
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1142
MSICONDITION WINAPI MsiEvaluateConditionW(MSIHANDLE, LPCWSTR)
#define MSIDBOPEN_CREATEDIRECT
Definition: msiquery.h:70
#define MSIDBOPEN_DIRECT
Definition: msiquery.h:68
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
@ MSICONDITION_FALSE
Definition: msiquery.h:26
@ MSICONDITION_ERROR
Definition: msiquery.h:29
@ MSICONDITION_NONE
Definition: msiquery.h:28
@ MSICONDITION_TRUE
Definition: msiquery.h:27
MSICONDITION WINAPI MsiEvaluateConditionA(MSIHANDLE, LPCSTR)
@ MSICOSTTREE_SELFONLY
Definition: msiquery.h:42
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define GENERIC_WRITE
Definition: nt_native.h:90
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define VS_VERSION_INFO
Definition: ntverrsrc.c:27
#define RT_VERSION
Definition: ntverrsrc.c:26
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
#define SM_CYSCREEN
Definition: winuser.h:971
#define MB_ICONHAND
Definition: winuser.h:799
#define SM_CXSCREEN
Definition: winuser.h:970
int WINAPI GetSystemMetrics(_In_ int)
static calc_node_t temp
Definition: rpn_ieee.c:38
#define REG_DWORD
Definition: sdbapi.c:615
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_NEUTRAL
Definition: nls.h:167
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41
WCHAR szKey[17]
Definition: fusionpriv.h:378
WORD wProcessorLevel
Definition: winbase.h:903
WORD wProcessorArchitecture
Definition: winbase.h:892
WORD wChildren[1]
Definition: package.c:884
WORD wPadding1[1]
Definition: package.c:881
VS_FIXEDFILEINFO Value
Definition: package.c:882
WORD wPadding2[1]
Definition: package.c:883
WCHAR szKey[1]
Definition: package.c:880
DWORD lasterr
Definition: package.c:7542
BOOL ignore
Definition: package.c:7543
BOOL gothandle
Definition: package.c:7541
Definition: cookie.c:202
Definition: http.c:7252
char field[4][100]
Definition: package.c:8701
Definition: parser.c:44
Definition: fci.c:123
Definition: parser.c:49
Definition: match.c:28
Definition: tftpd.h:60
Definition: name.c:39
DWORD dwFileVersionLS
Definition: compat.h:903
DWORD dwFileVersionMS
Definition: compat.h:902
DWORD dwProductVersionLS
Definition: compat.h:905
DWORD dwProductVersionMS
Definition: compat.h:904
#define max(a, b)
Definition: svc.c:63
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
Definition: pdh_main.c:64
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static const WCHAR props[]
Definition: wbemdisp.c:288
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int retval
Definition: wcstombs.cpp:91
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_FIXED
Definition: winbase.h:277
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
int MSICONDITION
Definition: winemsi.idl:29
unsigned long MSIHANDLE
Definition: winemsi.idl:27
int INSTALLSTATE
Definition: winemsi.idl:31
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:1311
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:1309
#define ERROR_INSTALL_PACKAGE_INVALID
Definition: winerror.h:1326
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:1308
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:257
#define ERROR_INVALID_HANDLE_STATE
Definition: winerror.h:1315
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_DIRECTORY
Definition: winerror.h:416
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:1331
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:1313
#define ERROR_PRODUCT_VERSION
Definition: winerror.h:1344
#define ERROR_UNKNOWN_FEATURE
Definition: winerror.h:1312
#define ERROR_PATCH_PACKAGE_OPEN_FAILED
Definition: winerror.h:1341
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:1321
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:1332
#define PROCESSOR_ARCHITECTURE_ARM64
Definition: winnt_old.h:503
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define TOKEN_QUERY
Definition: setypes.h:940
@ TokenUser
Definition: setypes.h:978
unsigned char BYTE
Definition: xxhash.c:193