ReactOS 0.4.15-dev-7788-g1ad9096
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
37static const char msifile[] = "winetest-package.msi";
38static const WCHAR msifileW[] = L"winetest-package.msi";
39static char CURR_DIR[MAX_PATH];
40
41static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
42
43static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
44static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
45static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
46static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
47static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
48
49static void init_functionpointers(void)
50{
51 HMODULE hmsi = GetModuleHandleA("msi.dll");
52 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
53 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
54 HMODULE hsrclient = LoadLibraryA("srclient.dll");
55
56#define GET_PROC(mod, func) \
57 p ## func = (void*)GetProcAddress(mod, #func);
58
60
61 GET_PROC(hadvapi32, RegDeleteKeyExA)
62 GET_PROC(hadvapi32, RegDeleteKeyExW)
64
66 GET_PROC(hsrclient, SRSetRestorePointA);
67
68#undef GET_PROC
69}
70
72{
74 PSID Group = NULL;
75 BOOL IsInGroup;
77
79 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
80 !CheckTokenMembership(NULL, Group, &IsInGroup))
81 {
82 trace("Could not check if the current user is an administrator\n");
84 return FALSE;
85 }
87
88 if (!IsInGroup)
89 {
93 0, 0, 0, 0, 0, 0, &Group) ||
94 !CheckTokenMembership(NULL, Group, &IsInGroup))
95 {
96 trace("Could not check if the current user is a power user\n");
97 return FALSE;
98 }
99 if (!IsInGroup)
100 {
101 /* Only administrators and power users can be powerful */
102 return TRUE;
103 }
104 }
105
107 {
108 BOOL ret;
110 DWORD size;
111
114 return (ret && type == TokenElevationTypeLimited);
115 }
116 return FALSE;
117}
118
120{
121 if (pRegDeleteKeyExA)
122 return pRegDeleteKeyExA( key, subkey, access, 0 );
123 return RegDeleteKeyA( key, subkey );
124}
125
126static char *get_user_sid(void)
127{
129 DWORD size = 0;
131 char *usersid = NULL;
132
135
136 user = malloc(size);
138 ConvertSidToStringSidA(user->User.Sid, &usersid);
139 free(user);
140
142 return usersid;
143}
144
145/* RegDeleteTreeW from dlls/advapi32/registry.c */
147{
148 LONG ret;
149 DWORD dwMaxSubkeyLen, dwMaxValueLen;
150 DWORD dwMaxLen, dwSize;
151 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
152 HKEY hSubKey = hKey;
153
154 if(lpszSubKey)
155 {
156 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
157 if (ret) return ret;
158 }
159
160 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
161 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
162 if (ret) goto cleanup;
163
164 dwMaxSubkeyLen++;
165 dwMaxValueLen++;
166 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
167 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
168 {
169 /* Name too big: alloc a buffer for it */
170 if (!(lpszName = malloc(dwMaxLen * sizeof(WCHAR))))
171 {
173 goto cleanup;
174 }
175 }
176
177 /* Recursively delete all the subkeys */
178 while (TRUE)
179 {
180 dwSize = dwMaxLen;
181 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
182 NULL, NULL, NULL)) break;
183
184 ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
185 if (ret) goto cleanup;
186 }
187
188 if (lpszSubKey)
189 {
190 if (pRegDeleteKeyExW)
191 ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
192 else
193 ret = RegDeleteKeyW(hKey, lpszSubKey);
194 }
195 else
196 while (TRUE)
197 {
198 dwSize = dwMaxLen;
199 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
200 NULL, NULL, NULL, NULL)) break;
201
202 ret = RegDeleteValueW(hKey, lpszName);
203 if (ret) goto cleanup;
204 }
205
206cleanup:
207 if (lpszName != szNameBuf) free(lpszName);
208 if (lpszSubKey) RegCloseKey(hSubKey);
209 return ret;
210}
211
213{
214 DWORD i,n=1;
215 GUID guid;
216
217 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
218 return FALSE;
219
220 for(i=0; i<8; i++)
221 out[7-i] = in[n++];
222 n++;
223 for(i=0; i<4; i++)
224 out[11-i] = in[n++];
225 n++;
226 for(i=0; i<4; i++)
227 out[15-i] = in[n++];
228 n++;
229 for(i=0; i<2; i++)
230 {
231 out[17+i*2] = in[n++];
232 out[16+i*2] = in[n++];
233 }
234 n++;
235 for( ; i<8; i++)
236 {
237 out[17+i*2] = in[n++];
238 out[16+i*2] = in[n++];
239 }
240 out[32]=0;
241 return TRUE;
242}
243
244static void create_test_guid(LPSTR prodcode, LPSTR squashed)
245{
246 WCHAR guidW[MAX_PATH];
247 WCHAR squashedW[MAX_PATH];
248 GUID guid;
249 HRESULT hr;
250 int size;
251
252 hr = CoCreateGuid(&guid);
253 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
254
255 size = StringFromGUID2(&guid, guidW, MAX_PATH);
256 ok(size == 39, "Expected 39, got %#lx\n", hr);
257
258 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
259 squash_guid(guidW, squashedW);
260 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
261}
262
264 LPCSTR guid, LPSTR usersid, BOOL dir)
265{
266 WCHAR guidW[MAX_PATH];
267 WCHAR squashedW[MAX_PATH];
268 CHAR squashed[MAX_PATH];
269 CHAR comppath[MAX_PATH + 81];
270 CHAR prodpath[MAX_PATH];
272 LPCSTR prod = NULL;
273 HKEY hkey;
275
276 if (is_wow64)
278
279 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
280 squash_guid(guidW, squashedW);
281 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
282
284 {
285 prod = "3D0DAE300FACA1300AD792060BCDAA92";
286 sprintf(comppath,
287 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
288 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
289 lstrcpyA(prodpath,
290 "SOFTWARE\\Classes\\Installer\\"
291 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
292 }
294 {
295 prod = "7D2F387510109040002000060BECB6AB";
296 sprintf(comppath,
297 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
298 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
299 sprintf(prodpath,
300 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
301 "Installer\\%s\\Installer\\Products\\"
302 "7D2F387510109040002000060BECB6AB", usersid);
303 }
305 {
306 prod = "7D2F387510109040002000060BECB6AB";
307 sprintf(comppath,
308 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
309 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
310 sprintf(prodpath,
311 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
312 "Installer\\Managed\\%s\\Installer\\Products\\"
313 "7D2F387510109040002000060BECB6AB", usersid);
314 }
315
316 RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
317
319 lstrcatA(path, "\\");
320 if (!dir) lstrcatA(path, filename);
321
322 RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
323 RegCloseKey(hkey);
324
325 RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
326 RegCloseKey(hkey);
327}
328
330{
331 WCHAR guidW[MAX_PATH];
332 WCHAR squashedW[MAX_PATH];
334 CHAR squashed[MAX_PATH];
335 CHAR comppath[MAX_PATH + 81];
336 CHAR prodpath[MAX_PATH];
338
339 if (is_wow64)
341
342 MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
343 squash_guid(guidW, squashedW);
344 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
345
347 {
348 sprintf(comppath,
349 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
350 "Installer\\UserData\\S-1-5-18\\Components\\%s", squashed);
351 lstrcpyA(prodpath,
352 "SOFTWARE\\Classes\\Installer\\"
353 "Products\\3D0DAE300FACA1300AD792060BCDAA92");
354 }
356 {
357 sprintf(comppath,
358 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
359 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
360 sprintf(prodpath,
361 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
362 "Installer\\%s\\Installer\\Products\\"
363 "7D2F387510109040002000060BECB6AB", usersid);
364 }
366 {
367 sprintf(comppath,
368 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
369 "Installer\\UserData\\%s\\Components\\%s", usersid, squashed);
370 sprintf(prodpath,
371 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
372 "Installer\\Managed\\%s\\Installer\\Products\\"
373 "7D2F387510109040002000060BECB6AB", usersid);
374 }
375
376 MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
378
379 MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
381}
382
383static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
384{
385 MSIHANDLE hview = 0;
386 UINT r, ret;
387
388 /* open a select query */
389 r = MsiDatabaseOpenViewA(hdb, query, &hview);
390 if (r != ERROR_SUCCESS)
391 return r;
392 r = MsiViewExecute(hview, 0);
393 if (r != ERROR_SUCCESS)
394 return r;
395 ret = MsiViewFetch(hview, phrec);
396 r = MsiViewClose(hview);
397 if (r != ERROR_SUCCESS)
398 return r;
399 r = MsiCloseHandle(hview);
400 if (r != ERROR_SUCCESS)
401 return r;
402 return ret;
403}
404
405static UINT run_query( MSIHANDLE hdb, const char *query )
406{
407 MSIHANDLE hview = 0;
408 UINT r;
409
410 r = MsiDatabaseOpenViewA(hdb, query, &hview);
411 if( r != ERROR_SUCCESS )
412 return r;
413
414 r = MsiViewExecute(hview, 0);
415 if( r == ERROR_SUCCESS )
416 r = MsiViewClose(hview);
417 MsiCloseHandle(hview);
418 return r;
419}
420
422{
423 UINT r = run_query( hdb,
424 "CREATE TABLE `Component` ( "
425 "`Component` CHAR(72) NOT NULL, "
426 "`ComponentId` CHAR(38), "
427 "`Directory_` CHAR(72) NOT NULL, "
428 "`Attributes` SHORT NOT NULL, "
429 "`Condition` CHAR(255), "
430 "`KeyPath` CHAR(72) "
431 "PRIMARY KEY `Component`)" );
432 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
433 return r;
434}
435
437{
438 UINT r = run_query( hdb,
439 "CREATE TABLE `Feature` ( "
440 "`Feature` CHAR(38) NOT NULL, "
441 "`Feature_Parent` CHAR(38), "
442 "`Title` CHAR(64), "
443 "`Description` CHAR(255), "
444 "`Display` SHORT NOT NULL, "
445 "`Level` SHORT NOT NULL, "
446 "`Directory_` CHAR(72), "
447 "`Attributes` SHORT NOT NULL "
448 "PRIMARY KEY `Feature`)" );
449 ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r);
450 return r;
451}
452
454{
455 UINT r = run_query( hdb,
456 "CREATE TABLE `FeatureComponents` ( "
457 "`Feature_` CHAR(38) NOT NULL, "
458 "`Component_` CHAR(72) NOT NULL "
459 "PRIMARY KEY `Feature_`, `Component_` )" );
460 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
461 return r;
462}
463
465{
466 UINT r = run_query( hdb,
467 "CREATE TABLE `File` ("
468 "`File` CHAR(72) NOT NULL, "
469 "`Component_` CHAR(72) NOT NULL, "
470 "`FileName` CHAR(255) NOT NULL, "
471 "`FileSize` LONG NOT NULL, "
472 "`Version` CHAR(72), "
473 "`Language` CHAR(20), "
474 "`Attributes` SHORT, "
475 "`Sequence` SHORT NOT NULL "
476 "PRIMARY KEY `File`)" );
477 ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r);
478 return r;
479}
480
482{
483 UINT r = run_query( hdb,
484 "CREATE TABLE `RemoveFile` ("
485 "`FileKey` CHAR(72) NOT NULL, "
486 "`Component_` CHAR(72) NOT NULL, "
487 "`FileName` CHAR(255) LOCALIZABLE, "
488 "`DirProperty` CHAR(72) NOT NULL, "
489 "`InstallMode` SHORT NOT NULL "
490 "PRIMARY KEY `FileKey`)" );
491 ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r);
492 return r;
493}
494
496{
497 UINT r = run_query( hdb,
498 "CREATE TABLE `AppSearch` ("
499 "`Property` CHAR(72) NOT NULL, "
500 "`Signature_` CHAR(72) NOT NULL "
501 "PRIMARY KEY `Property`, `Signature_`)" );
502 ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r);
503 return r;
504}
505
507{
508 UINT r = run_query( hdb,
509 "CREATE TABLE `RegLocator` ("
510 "`Signature_` CHAR(72) NOT NULL, "
511 "`Root` SHORT NOT NULL, "
512 "`Key` CHAR(255) NOT NULL, "
513 "`Name` CHAR(255), "
514 "`Type` SHORT "
515 "PRIMARY KEY `Signature_`)" );
516 ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r);
517 return r;
518}
519
521{
522 UINT r = run_query( hdb,
523 "CREATE TABLE `Signature` ("
524 "`Signature` CHAR(72) NOT NULL, "
525 "`FileName` CHAR(255) NOT NULL, "
526 "`MinVersion` CHAR(20), "
527 "`MaxVersion` CHAR(20), "
528 "`MinSize` LONG, "
529 "`MaxSize` LONG, "
530 "`MinDate` LONG, "
531 "`MaxDate` LONG, "
532 "`Languages` CHAR(255) "
533 "PRIMARY KEY `Signature`)" );
534 ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r);
535 return r;
536}
537
539{
540 UINT r = run_query( hdb,
541 "CREATE TABLE `LaunchCondition` ("
542 "`Condition` CHAR(255) NOT NULL, "
543 "`Description` CHAR(255) NOT NULL "
544 "PRIMARY KEY `Condition`)" );
545 ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r);
546 return r;
547}
548
550{
551 UINT r = run_query( hdb,
552 "CREATE TABLE `Property` ("
553 "`Property` CHAR(72) NOT NULL, "
554 "`Value` CHAR(0) "
555 "PRIMARY KEY `Property`)" );
556 ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r);
557 return r;
558}
559
561{
562 UINT r = run_query( hdb,
563 "CREATE TABLE `InstallExecuteSequence` ("
564 "`Action` CHAR(72) NOT NULL, "
565 "`Condition` CHAR(255), "
566 "`Sequence` SHORT "
567 "PRIMARY KEY `Action`)" );
568 ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r);
569 return r;
570}
571
573{
574 UINT r = run_query( hdb,
575 "CREATE TABLE `InstallUISequence` ("
576 "`Action` CHAR(72) NOT NULL, "
577 "`Condition` CHAR(255), "
578 "`Sequence` SHORT "
579 "PRIMARY KEY `Action`)" );
580 ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r);
581 return r;
582}
583
585{
586 UINT r = run_query( hdb,
587 "CREATE TABLE `Media` ("
588 "`DiskId` SHORT NOT NULL, "
589 "`LastSequence` SHORT NOT NULL, "
590 "`DiskPrompt` CHAR(64), "
591 "`Cabinet` CHAR(255), "
592 "`VolumeLabel` CHAR(32), "
593 "`Source` CHAR(72) "
594 "PRIMARY KEY `DiskId`)" );
595 ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r);
596 return r;
597}
598
600{
601 UINT r = run_query( hdb,
602 "CREATE TABLE `CCPSearch` ("
603 "`Signature_` CHAR(72) NOT NULL "
604 "PRIMARY KEY `Signature_`)" );
605 ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r);
606 return r;
607}
608
610{
611 UINT r = run_query( hdb,
612 "CREATE TABLE `DrLocator` ("
613 "`Signature_` CHAR(72) NOT NULL, "
614 "`Parent` CHAR(72), "
615 "`Path` CHAR(255), "
616 "`Depth` SHORT "
617 "PRIMARY KEY `Signature_`, `Parent`, `Path`)" );
618 ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r);
619 return r;
620}
621
623{
624 UINT r = run_query( hdb,
625 "CREATE TABLE `CompLocator` ("
626 "`Signature_` CHAR(72) NOT NULL, "
627 "`ComponentId` CHAR(38) NOT NULL, "
628 "`Type` SHORT "
629 "PRIMARY KEY `Signature_`)" );
630 ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r);
631 return r;
632}
633
635{
636 UINT r = run_query( hdb,
637 "CREATE TABLE `IniLocator` ("
638 "`Signature_` CHAR(72) NOT NULL, "
639 "`FileName` CHAR(255) NOT NULL, "
640 "`Section` CHAR(96)NOT NULL, "
641 "`Key` CHAR(128)NOT NULL, "
642 "`Field` SHORT, "
643 "`Type` SHORT "
644 "PRIMARY KEY `Signature_`)" );
645 ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r);
646 return r;
647}
648
650{
651 UINT r = run_query( hdb,
652 "CREATE TABLE `CustomAction` ("
653 "`Action` CHAR(72) NOT NULL, "
654 "`Type` SHORT NOT NULL, "
655 "`Source` CHAR(75), "
656 "`Target` CHAR(255) "
657 "PRIMARY KEY `Action`)" );
658 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
659 return r;
660}
661
663{
664 UINT r = run_query(hdb,
665 "CREATE TABLE `Dialog` ("
666 "`Dialog` CHAR(72) NOT NULL, "
667 "`HCentering` SHORT NOT NULL, "
668 "`VCentering` SHORT NOT NULL, "
669 "`Width` SHORT NOT NULL, "
670 "`Height` SHORT NOT NULL, "
671 "`Attributes` LONG, "
672 "`Title` CHAR(128) LOCALIZABLE, "
673 "`Control_First` CHAR(50) NOT NULL, "
674 "`Control_Default` CHAR(50), "
675 "`Control_Cancel` CHAR(50) "
676 "PRIMARY KEY `Dialog`)");
677 ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r);
678 return r;
679}
680
682{
683 UINT r = run_query(hdb,
684 "CREATE TABLE `Control` ("
685 "`Dialog_` CHAR(72) NOT NULL, "
686 "`Control` CHAR(50) NOT NULL, "
687 "`Type` CHAR(20) NOT NULL, "
688 "`X` SHORT NOT NULL, "
689 "`Y` SHORT NOT NULL, "
690 "`Width` SHORT NOT NULL, "
691 "`Height` SHORT NOT NULL, "
692 "`Attributes` LONG, "
693 "`Property` CHAR(50), "
694 "`Text` CHAR(0) LOCALIZABLE, "
695 "`Control_Next` CHAR(50), "
696 "`Help` CHAR(255) LOCALIZABLE "
697 "PRIMARY KEY `Dialog_`, `Control`)");
698 ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r);
699 return r;
700}
701
703{
704 UINT r = run_query(hdb,
705 "CREATE TABLE `ControlEvent` ("
706 "`Dialog_` CHAR(72) NOT NULL, "
707 "`Control_` CHAR(50) NOT NULL, "
708 "`Event` CHAR(50) NOT NULL, "
709 "`Argument` CHAR(255) NOT NULL, "
710 "`Condition` CHAR(255), "
711 "`Ordering` SHORT "
712 "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)");
713 ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r);
714 return r;
715}
716
718{
719 UINT r = run_query(hdb,
720 "CREATE TABLE `ActionText` ("
721 "`Action` CHAR(72) NOT NULL, "
722 "`Description` CHAR(64) LOCALIZABLE, "
723 "`Template` CHAR(128) LOCALIZABLE "
724 "PRIMARY KEY `Action`)");
725 ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r);
726 return r;
727}
728
730{
731 UINT r = run_query( hdb,
732 "CREATE TABLE `Upgrade` ("
733 "`UpgradeCode` CHAR(38) NOT NULL, "
734 "`VersionMin` CHAR(20), "
735 "`VersionMax` CHAR(20), "
736 "`Language` CHAR(255), "
737 "`Attributes` SHORT, "
738 "`Remove` CHAR(255), "
739 "`ActionProperty` CHAR(72) NOT NULL "
740 "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
741 ok(r == ERROR_SUCCESS, "Failed to create Upgrade table: %u\n", r);
742 return r;
743}
744
745static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
746{
747 char *query;
748 UINT sz, r;
749
750 sz = strlen(values) + strlen(insert) + 1;
751 query = malloc(sz);
753 r = run_query(hdb, query);
754 free(query);
755 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
756 return r;
757}
758
759#define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
760 "INSERT INTO `Component` " \
761 "(`Component`, `ComponentId`, `Directory_`, " \
762 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
763
764#define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \
765 "INSERT INTO `Directory` " \
766 "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
767
768#define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \
769 "INSERT INTO `Feature` " \
770 "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \
771 "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
772
773#define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
774 "INSERT INTO `FeatureComponents` " \
775 "(`Feature_`, `Component_`) VALUES( %s )")
776
777#define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \
778 "INSERT INTO `File` " \
779 "(`File`, `Component_`, `FileName`, `FileSize`, " \
780 "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
781
782#define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \
783 "INSERT INTO `AppSearch` " \
784 "(`Property`, `Signature_`) VALUES( %s )")
785
786#define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \
787 "INSERT INTO `Signature` " \
788 "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \
789 " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \
790 "VALUES( %s )")
791
792#define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \
793 "INSERT INTO `LaunchCondition` " \
794 "(`Condition`, `Description`) VALUES( %s )")
795
796#define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
797 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
798
799#define update_ProductVersion_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
800 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
801
802#define update_ProductCode_property(hdb, value) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
803 "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
804
805#define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
806 "INSERT INTO `InstallExecuteSequence` " \
807 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
808
809#define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \
810 "INSERT INTO `InstallUISequence` " \
811 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
812
813#define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \
814 "INSERT INTO `Media` " \
815 "(`DiskId`, `LastSequence`, `DiskPrompt`, " \
816 "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )")
817
818#define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \
819 "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )")
820
821#define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \
822 "INSERT INTO `DrLocator` " \
823 "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )")
824
825#define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \
826 "INSERT INTO `CompLocator` " \
827 "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )")
828
829#define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \
830 "INSERT INTO `IniLocator` " \
831 "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \
832 "VALUES( %s )")
833
834#define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
835 "INSERT INTO `CustomAction` " \
836 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
837
838#define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \
839 "INSERT INTO `Dialog` " \
840 "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )")
841
842#define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \
843 "INSERT INTO `Control` " \
844 "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )");
845
846#define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \
847 "INSERT INTO `ControlEvent` " \
848 "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )");
849
850#define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \
851 "INSERT INTO `ActionText` " \
852 "(`Action`, `Description`, `Template`) VALUES( %s )");
853
854#define add_upgrade_entry(hdb, values) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
855 "INSERT INTO `Upgrade` " \
856 "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
857
858static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
859 const char *name, UINT type )
860{
861 const char insert[] =
862 "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
863 "VALUES( '%s', %u, '%s', '%s', %u )";
864 char *query;
865 UINT sz, r;
866
867 sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
868 query = malloc( sz );
869 sprintf( query, insert, sig, root, path, name, type );
870 r = run_query( hdb, query );
871 free( query );
872 ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
873 return r;
874}
875
877{
878 UINT res;
880
881 /* build summary info */
883 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
884
886 "Installation Database");
887 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
888
890 "Installation Database");
891 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
892
894 "Wine Hackers");
895 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
896
898 ";1033");
899 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
900
902 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
903 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
904
906 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
907
909 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
910
912 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
913
915 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
916
917 return res;
918}
919
920
922{
923 MSIHANDLE hdb = 0;
924 UINT res;
925
927
928 /* create an empty database */
930 ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
931 if( res != ERROR_SUCCESS )
932 return hdb;
933
934 res = MsiDatabaseCommit( hdb );
935 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
936
937 res = set_summary_info(hdb);
938 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
939
940 res = run_query( hdb,
941 "CREATE TABLE `Directory` ( "
942 "`Directory` CHAR(255) NOT NULL, "
943 "`Directory_Parent` CHAR(255), "
944 "`DefaultDir` CHAR(255) NOT NULL "
945 "PRIMARY KEY `Directory`)" );
946 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
947
948 return hdb;
949}
950
952{
953 UINT res;
954 CHAR szPackage[12];
955 MSIHANDLE hPackage;
956
957 sprintf(szPackage, "#%lu", hdb);
958 res = MsiOpenPackageA(szPackage, &hPackage);
959 if (res != ERROR_SUCCESS)
960 {
961 MsiCloseHandle(hdb);
962 return res;
963 }
964
965 res = MsiCloseHandle(hdb);
966 if (res != ERROR_SUCCESS)
967 {
968 MsiCloseHandle(hPackage);
969 return res;
970 }
971
972 *handle = hPackage;
973 return ERROR_SUCCESS;
974}
975
977{
978 HANDLE file;
979 DWORD written;
980
982 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
984 return;
985
986 WriteFile(file, data, strlen(data), &written, NULL);
987 WriteFile(file, "\n", strlen("\n"), &written, NULL);
988
990}
991
992static void create_test_file(const CHAR *name)
993{
995}
996
997typedef struct _tagVS_VERSIONINFO
998{
1008
1009#define roundoffs(a, b, r) (((BYTE *)(b) - (BYTE *)(a) + ((r) - 1)) & ~((r) - 1))
1010#define roundpos(a, b, r) (((BYTE *)(a)) + roundoffs(a, b, r))
1011
1013{
1014 VS_VERSIONINFO *pVerInfo;
1015 VS_FIXEDFILEINFO *pFixedInfo;
1016 LPBYTE buffer, ofs;
1018 DWORD handle, size;
1020 BOOL ret = FALSE;
1021
1023 /* Some dlls can't be updated on Vista/W2K8 */
1024 lstrcatA(path, "\\version.dll");
1025
1027
1029 buffer = malloc(size);
1030
1032
1033 pVerInfo = (VS_VERSIONINFO *)buffer;
1034 ofs = (BYTE *)&pVerInfo->szKey[lstrlenW(pVerInfo->szKey) + 1];
1035 pFixedInfo = (VS_FIXEDFILEINFO *)roundpos(pVerInfo, ofs, 4);
1036
1037 pFixedInfo->dwFileVersionMS = ms;
1038 pFixedInfo->dwFileVersionLS = ls;
1039 pFixedInfo->dwProductVersionMS = ms;
1040 pFixedInfo->dwProductVersionLS = ls;
1041
1043 if (!resource)
1044 goto done;
1045
1048 goto done;
1049
1051 goto done;
1052
1053 ret = TRUE;
1054
1055done:
1056 free(buffer);
1057 return ret;
1058}
1059
1061{
1062 RESTOREPOINTINFOA spec;
1063
1064 spec.dwEventType = event_type;
1066 spec.llSequenceNumber = status->llSequenceNumber;
1067 lstrcpyA(spec.szDescription, "msitest restore point");
1068
1069 return pSRSetRestorePointA(&spec, status);
1070}
1071
1072static void remove_restore_point(DWORD seq_number)
1073{
1074 DWORD res;
1075
1076 res = pSRRemoveRestorePoint(seq_number);
1077 if (res != ERROR_SUCCESS)
1078 trace("Failed to remove the restore point: %#lx\n", res);
1079}
1080
1081static BOOL is_root(const char *path)
1082{
1083 return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
1084}
1085
1086static void test_createpackage(void)
1087{
1088 MSIHANDLE hPackage = 0;
1089 UINT res;
1090
1091 res = package_from_db(create_package_db(), &hPackage);
1093 {
1094 skip("Not enough rights to perform tests\n");
1096 return;
1097 }
1098 ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
1099
1100 res = MsiCloseHandle( hPackage);
1101 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
1103}
1104
1105static void test_doaction( void )
1106{
1107 MSIHANDLE hpkg;
1108 UINT r;
1109
1110 r = MsiDoActionA( -1, NULL );
1111 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1112
1115 {
1116 skip("Not enough rights to perform tests\n");
1118 return;
1119 }
1120 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1121
1122 r = MsiDoActionA(hpkg, NULL);
1123 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1124
1125 r = MsiDoActionA(0, "boo");
1126 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1127
1128 r = MsiDoActionA(hpkg, "boo");
1129 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
1130
1131 MsiCloseHandle( hpkg );
1133}
1134
1135static void test_gettargetpath_bad(void)
1136{
1137 char buffer[0x80];
1138 WCHAR bufferW[0x80];
1139 MSIHANDLE hpkg;
1140 DWORD sz;
1141 UINT r;
1142
1145 {
1146 skip("Not enough rights to perform tests\n");
1148 return;
1149 }
1150 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1151
1152 r = MsiGetTargetPathA( 0, NULL, NULL, NULL );
1153 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1154
1155 r = MsiGetTargetPathA( 0, NULL, NULL, &sz );
1156 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1157
1158 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1159 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1160
1161 r = MsiGetTargetPathA( 0, "boo", NULL, NULL );
1162 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1163
1164 r = MsiGetTargetPathA( hpkg, "boo", NULL, NULL );
1165 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1166
1167 r = MsiGetTargetPathA( hpkg, "boo", buffer, NULL );
1168 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1169
1170 sz = 0;
1171 r = MsiGetTargetPathA( hpkg, "", buffer, &sz );
1172 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1173
1174 r = MsiGetTargetPathW( 0, NULL, NULL, NULL );
1175 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1176
1177 r = MsiGetTargetPathW( 0, NULL, NULL, &sz );
1178 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1179
1180 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1181 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1182
1183 r = MsiGetTargetPathW( 0, L"boo", NULL, NULL );
1184 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1185
1186 r = MsiGetTargetPathW( hpkg, L"boo", NULL, NULL );
1187 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1188
1189 r = MsiGetTargetPathW( hpkg, L"boo", bufferW, NULL );
1190 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1191
1192 sz = 0;
1193 r = MsiGetTargetPathW( hpkg, L"", bufferW, &sz );
1194 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1195
1196 MsiCloseHandle( hpkg );
1198}
1199
1201{
1202 UINT r;
1203 DWORD size;
1204 MSIHANDLE rec;
1205
1206 rec = MsiCreateRecord( 1 );
1207 ok(rec, "MsiCreate record failed\n");
1208
1209 r = MsiRecordSetStringA( rec, 0, file );
1210 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1211
1212 size = MAX_PATH;
1213 r = MsiFormatRecordA( hpkg, rec, buff, &size );
1214 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
1215
1216 MsiCloseHandle( rec );
1217}
1218
1219static void test_settargetpath(void)
1220{
1221 char tempdir[MAX_PATH+8], buffer[MAX_PATH], file[MAX_PATH + 20];
1222 DWORD sz;
1223 MSIHANDLE hpkg;
1224 UINT r;
1225 MSIHANDLE hdb;
1226
1227 hdb = create_package_db();
1228 ok ( hdb, "failed to create package database\n" );
1229
1230 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
1231
1233 add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" );
1234 add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" );
1235
1236 create_feature_table( hdb );
1237 add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" );
1238
1240 add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" );
1241 add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" );
1242
1243 add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
1244 add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
1245
1246 create_file_table( hdb );
1247 add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" );
1248 add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
1249
1250 r = package_from_db( hdb, &hpkg );
1252 {
1253 skip("Not enough rights to perform tests\n");
1255 return;
1256 }
1257 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1258
1260
1261 r = MsiDoActionA( hpkg, "CostInitialize");
1262 ok( r == ERROR_SUCCESS, "cost init failed\n");
1263
1264 r = MsiDoActionA( hpkg, "FileCost");
1265 ok( r == ERROR_SUCCESS, "file cost failed\n");
1266
1267 r = MsiDoActionA( hpkg, "CostFinalize");
1268 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
1269
1270 buffer[0] = 0;
1271 sz = sizeof(buffer);
1272 r = MsiGetPropertyA( hpkg, "OutOfNoRbDiskSpace", buffer, &sz );
1273 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1274 trace( "OutOfNoRbDiskSpace = \"%s\"\n", buffer );
1275
1276 r = MsiSetTargetPathA( 0, NULL, NULL );
1277 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1278
1279 r = MsiSetTargetPathA( 0, "boo", "C:\\bogusx" );
1280 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1281
1282 r = MsiSetTargetPathA( hpkg, "boo", NULL );
1283 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1284
1285 r = MsiSetTargetPathA( hpkg, "boo", "c:\\bogusx" );
1286 ok( r == ERROR_DIRECTORY, "wrong return val\n");
1287
1288 sz = sizeof tempdir - 1;
1289 r = MsiGetTargetPathA( hpkg, "TARGETDIR", tempdir, &sz );
1290 sprintf( file, "%srootfile.txt", tempdir );
1291 buffer[0] = 0;
1292 query_file_path( hpkg, "[#RootFile]", buffer );
1293 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1294 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer );
1295
1296 GetTempFileNameA( tempdir, "_wt", 0, buffer );
1297 sprintf( tempdir, "%s\\subdir", buffer );
1298
1299 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1301 "MsiSetTargetPath on file returned %d\n", r );
1302
1303 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1305 "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
1306
1308
1309 r = MsiSetTargetPathA( hpkg, "TARGETDIR", buffer );
1310 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1311
1313 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
1314
1315 r = MsiSetTargetPathA( hpkg, "TARGETDIR", tempdir );
1316 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
1317
1318 buffer[0] = 0;
1319 sz = sizeof buffer - 1;
1320 lstrcatA( tempdir, "\\" );
1321 r = MsiGetTargetPathA( hpkg, "TARGETDIR", buffer, &sz );
1322 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1323 ok( !lstrcmpA(buffer, tempdir), "Expected %s, got %s\n", tempdir, buffer);
1324
1325 sprintf( file, "%srootfile.txt", tempdir );
1326 query_file_path( hpkg, "[#RootFile]", buffer );
1327 ok( !lstrcmpA(buffer, file), "Expected %s, got %s\n", file, buffer);
1328
1329 buffer[0] = 0;
1330 sz = sizeof(buffer);
1331 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1332 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1333 lstrcatA( tempdir, "TestParent\\" );
1334 ok( !lstrcmpiA(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
1335
1336 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two" );
1337 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1338
1339 buffer[0] = 0;
1340 sz = sizeof(buffer);
1341 r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
1342 ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
1343 ok( lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\"),
1344 "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
1345
1346 buffer[0] = 0;
1347 query_file_path( hpkg, "[#TestFile]", buffer );
1348 ok( !lstrcmpiA(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
1349 "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
1350
1351 buffer[0] = 0;
1352 sz = sizeof buffer - 1;
1353 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1354 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1355 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected C:\\one\\two\\, got %s\n", buffer);
1356
1357 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\one\\two\\three" );
1358 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1359
1360 buffer[0] = 0;
1361 sz = sizeof buffer - 1;
1362 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1363 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1364 ok( !lstrcmpiA(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
1365
1366 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\one\\\\two " );
1367 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1368
1369 buffer[0] = 0;
1370 sz = sizeof buffer - 1;
1371 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1372 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1373 ok( !lstrcmpiA(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
1374
1375 r = MsiSetTargetPathA( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
1376 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
1377
1378 buffer[0] = 0;
1379 sz = sizeof buffer - 1;
1380 r = MsiGetTargetPathA( hpkg, "TestParent", buffer, &sz );
1381 ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
1382 ok( !lstrcmpiA(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
1383
1384 MsiCloseHandle( hpkg );
1385}
1386
1387static void test_condition(void)
1388{
1390 MSIHANDLE hpkg;
1391
1394 {
1395 skip("Not enough rights to perform tests\n");
1397 return;
1398 }
1399 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
1400
1402 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1403
1404 r = MsiEvaluateConditionA(hpkg, NULL);
1405 ok( r == MSICONDITION_NONE, "wrong return val\n");
1406
1407 r = MsiEvaluateConditionA(hpkg, "");
1408 ok( r == MSICONDITION_NONE, "wrong return val\n");
1409
1410 r = MsiEvaluateConditionA(hpkg, "1");
1411 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1412
1413 r = MsiEvaluateConditionA(hpkg, "0");
1414 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1415
1416 r = MsiEvaluateConditionA(hpkg, "-1");
1417 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1418
1419 r = MsiEvaluateConditionA(hpkg, "0 = 0");
1420 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1421
1422 r = MsiEvaluateConditionA(hpkg, "0 <> 0");
1423 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1424
1425 r = MsiEvaluateConditionA(hpkg, "0 = 1");
1426 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1427
1428 r = MsiEvaluateConditionA(hpkg, "0 > 1");
1429 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1430
1431 r = MsiEvaluateConditionA(hpkg, "0 ~> 1");
1432 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1433
1434 r = MsiEvaluateConditionA(hpkg, "1 > 1");
1435 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1436
1437 r = MsiEvaluateConditionA(hpkg, "1 ~> 1");
1438 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1439
1440 r = MsiEvaluateConditionA(hpkg, "0 >= 1");
1441 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1442
1443 r = MsiEvaluateConditionA(hpkg, "0 ~>= 1");
1444 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1445
1446 r = MsiEvaluateConditionA(hpkg, "1 >= 1");
1447 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1448
1449 r = MsiEvaluateConditionA(hpkg, "1 ~>= 1");
1450 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1451
1452 r = MsiEvaluateConditionA(hpkg, "0 < 1");
1453 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1454
1455 r = MsiEvaluateConditionA(hpkg, "0 ~< 1");
1456 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1457
1458 r = MsiEvaluateConditionA(hpkg, "1 < 1");
1459 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1460
1461 r = MsiEvaluateConditionA(hpkg, "1 ~< 1");
1462 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1463
1464 r = MsiEvaluateConditionA(hpkg, "0 <= 1");
1465 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1466
1467 r = MsiEvaluateConditionA(hpkg, "0 ~<= 1");
1468 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1469
1470 r = MsiEvaluateConditionA(hpkg, "1 <= 1");
1471 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1472
1473 r = MsiEvaluateConditionA(hpkg, "1 ~<= 1");
1474 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1475
1476 r = MsiEvaluateConditionA(hpkg, "0 >=");
1477 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1478
1479 r = MsiEvaluateConditionA(hpkg, " ");
1480 ok( r == MSICONDITION_NONE, "wrong return val\n");
1481
1482 r = MsiEvaluateConditionA(hpkg, "LicView <> \"1\"");
1483 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1484
1485 r = MsiEvaluateConditionA(hpkg, "LicView <> \"0\"");
1486 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1487
1488 r = MsiEvaluateConditionA(hpkg, "LicView <> LicView");
1489 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1490
1491 r = MsiEvaluateConditionA(hpkg, "not 0");
1492 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1493
1494 r = MsiEvaluateConditionA(hpkg, "not LicView");
1495 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1496
1497 r = MsiEvaluateConditionA(hpkg, "\"Testing\" ~<< \"Testing\"");
1498 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1499
1500 r = MsiEvaluateConditionA(hpkg, "LicView ~<< \"Testing\"");
1501 ok (r == MSICONDITION_FALSE, "wrong return val\n");
1502
1503 r = MsiEvaluateConditionA(hpkg, "Not LicView ~<< \"Testing\"");
1504 ok (r == MSICONDITION_TRUE, "wrong return val\n");
1505
1506 r = MsiEvaluateConditionA(hpkg, "not \"A\"");
1507 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1508
1509 r = MsiEvaluateConditionA(hpkg, "~not \"A\"");
1510 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1511
1512 r = MsiEvaluateConditionA(hpkg, "\"0\"");
1513 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1514
1515 r = MsiEvaluateConditionA(hpkg, "1 and 2");
1516 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1517
1518 r = MsiEvaluateConditionA(hpkg, "not 0 and 3");
1519 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1520
1521 r = MsiEvaluateConditionA(hpkg, "not 0 and 0");
1522 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1523
1524 r = MsiEvaluateConditionA(hpkg, "not 0 or 1");
1525 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1526
1527 r = MsiEvaluateConditionA(hpkg, "(0)");
1528 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1529
1530 r = MsiEvaluateConditionA(hpkg, "(((((1))))))");
1531 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1532
1533 r = MsiEvaluateConditionA(hpkg, "(((((1)))))");
1534 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1535
1536 r = MsiEvaluateConditionA(hpkg, " \"A\" < \"B\" ");
1537 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1538
1539 r = MsiEvaluateConditionA(hpkg, " \"A\" > \"B\" ");
1540 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1541
1542 r = MsiEvaluateConditionA(hpkg, " \"1\" > \"12\" ");
1543 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1544
1545 r = MsiEvaluateConditionA(hpkg, " \"100\" < \"21\" ");
1546 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1547
1548 r = MsiEvaluateConditionA(hpkg, "0 < > 0");
1549 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1550
1551 r = MsiEvaluateConditionA(hpkg, "(1<<1) == 2");
1552 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1553
1554 r = MsiEvaluateConditionA(hpkg, " \"A\" = \"a\" ");
1555 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1556
1557 r = MsiEvaluateConditionA(hpkg, " \"A\" ~ = \"a\" ");
1558 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1559
1560 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= \"a\" ");
1561 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1562
1563 r = MsiEvaluateConditionA(hpkg, " \"A\" ~= 1 ");
1564 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1565
1566 r = MsiEvaluateConditionA(hpkg, " \"A\" = 1 ");
1567 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1568
1569 r = MsiEvaluateConditionA(hpkg, " 1 ~= 1 ");
1570 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1571
1572 r = MsiEvaluateConditionA(hpkg, " 1 ~= \"1\" ");
1573 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1574
1575 r = MsiEvaluateConditionA(hpkg, " 1 = \"1\" ");
1576 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1577
1578 r = MsiEvaluateConditionA(hpkg, " 0 = \"1\" ");
1579 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1580
1581 r = MsiEvaluateConditionA(hpkg, " 0 < \"100\" ");
1582 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1583
1584 r = MsiEvaluateConditionA(hpkg, " 100 > \"0\" ");
1585 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1586
1587 r = MsiEvaluateConditionA(hpkg, "1 XOR 1");
1588 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1589
1590 r = MsiEvaluateConditionA(hpkg, "1 IMP 1");
1591 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1592
1593 r = MsiEvaluateConditionA(hpkg, "1 IMP 0");
1594 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1595
1596 r = MsiEvaluateConditionA(hpkg, "0 IMP 0");
1597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1598
1599 r = MsiEvaluateConditionA(hpkg, "0 EQV 0");
1600 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1601
1602 r = MsiEvaluateConditionA(hpkg, "0 EQV 1");
1603 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1604
1605 r = MsiEvaluateConditionA(hpkg, "1 IMP 1 OR 0");
1606 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1607
1608 r = MsiEvaluateConditionA(hpkg, "1 IMPL 1");
1609 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1610
1611 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" >< \"S\" ");
1612 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1613
1614 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"s\" ");
1615 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1616
1617 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"\" ");
1618 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1619
1620 r = MsiEvaluateConditionA(hpkg, "\"ASFD\" ~>< \"sss\" ");
1621 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1622
1623 MsiSetPropertyA(hpkg, "mm", "5" );
1624
1625 r = MsiEvaluateConditionA(hpkg, "mm = 5");
1626 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1627
1628 r = MsiEvaluateConditionA(hpkg, "mm < 6");
1629 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1630
1631 r = MsiEvaluateConditionA(hpkg, "mm <= 5");
1632 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1633
1634 r = MsiEvaluateConditionA(hpkg, "mm > 4");
1635 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1636
1637 r = MsiEvaluateConditionA(hpkg, "mm < 12");
1638 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1639
1640 r = MsiEvaluateConditionA(hpkg, "mm = \"5\"");
1641 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1642
1643 r = MsiEvaluateConditionA(hpkg, "0 = \"\"");
1644 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1645
1646 r = MsiEvaluateConditionA(hpkg, "0 AND \"\"");
1647 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1648
1649 r = MsiEvaluateConditionA(hpkg, "1 AND \"\"");
1650 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1651
1652 r = MsiEvaluateConditionA(hpkg, "1 AND \"1\"");
1653 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1654
1655 r = MsiEvaluateConditionA(hpkg, "3 >< 1");
1656 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1657
1658 r = MsiEvaluateConditionA(hpkg, "3 >< 4");
1659 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1660
1661 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 0");
1662 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1663
1664 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1");
1665 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1666
1667 r = MsiEvaluateConditionA(hpkg, "NOT 1 OR 0");
1668 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1669
1670 r = MsiEvaluateConditionA(hpkg, "0 AND 1 OR 1");
1671 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1672
1673 r = MsiEvaluateConditionA(hpkg, "0 AND 0 OR 1");
1674 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1675
1676 r = MsiEvaluateConditionA(hpkg, "NOT 0 AND 1 OR 0");
1677 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1678
1679 r = MsiEvaluateConditionA(hpkg, "_1 = _1");
1680 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1681
1682 r = MsiEvaluateConditionA(hpkg, "( 1 AND 1 ) = 2");
1683 ok( r == MSICONDITION_ERROR, "wrong return val\n");
1684
1685 r = MsiEvaluateConditionA(hpkg, "NOT ( 1 AND 1 )");
1686 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1687
1688 r = MsiEvaluateConditionA(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1689 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1690
1691 r = MsiEvaluateConditionA(hpkg, "Installed<>\"\"");
1692 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1693
1694 r = MsiEvaluateConditionA(hpkg, "NOT 1 AND 0");
1695 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1696
1697 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1698 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1699
1700 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1701 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1702
1703 r = MsiEvaluateConditionA(hpkg, "bandalmael<0");
1704 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1705
1706 r = MsiEvaluateConditionA(hpkg, "bandalmael>0");
1707 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1708
1709 r = MsiEvaluateConditionA(hpkg, "bandalmael>=0");
1710 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1711
1712 r = MsiEvaluateConditionA(hpkg, "bandalmael<=0");
1713 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1714
1715 r = MsiEvaluateConditionA(hpkg, "bandalmael~<>0");
1716 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1717
1718 MsiSetPropertyA(hpkg, "bandalmael", "0" );
1719 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1720 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1721
1722 MsiSetPropertyA(hpkg, "bandalmael", "" );
1723 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1724 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1725
1726 MsiSetPropertyA(hpkg, "bandalmael", "asdf" );
1727 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1728 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1729
1730 MsiSetPropertyA(hpkg, "bandalmael", "0asdf" );
1731 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1732 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1733
1734 MsiSetPropertyA(hpkg, "bandalmael", "0 " );
1735 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1736 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1737
1738 MsiSetPropertyA(hpkg, "bandalmael", "-0" );
1739 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1740 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1741
1742 MsiSetPropertyA(hpkg, "bandalmael", "0000000000000" );
1743 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1744 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1745
1746 MsiSetPropertyA(hpkg, "bandalmael", "--0" );
1747 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1748 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1749
1750 MsiSetPropertyA(hpkg, "bandalmael", "0x00" );
1751 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1752 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1753
1754 MsiSetPropertyA(hpkg, "bandalmael", "-" );
1755 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1756 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1757
1758 MsiSetPropertyA(hpkg, "bandalmael", "+0" );
1759 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1760 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1761
1762 MsiSetPropertyA(hpkg, "bandalmael", "0.0" );
1763 r = MsiEvaluateConditionA(hpkg, "bandalmael=0");
1764 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1765 r = MsiEvaluateConditionA(hpkg, "bandalmael<>0");
1766 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1767
1768 MsiSetPropertyA(hpkg, "one", "hi");
1769 MsiSetPropertyA(hpkg, "two", "hithere");
1770 r = MsiEvaluateConditionA(hpkg, "one >< two");
1771 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1772
1773 MsiSetPropertyA(hpkg, "one", "hithere");
1774 MsiSetPropertyA(hpkg, "two", "hi");
1775 r = MsiEvaluateConditionA(hpkg, "one >< two");
1776 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1777
1778 MsiSetPropertyA(hpkg, "one", "hello");
1779 MsiSetPropertyA(hpkg, "two", "hi");
1780 r = MsiEvaluateConditionA(hpkg, "one >< two");
1781 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1782
1783 MsiSetPropertyA(hpkg, "one", "hellohithere");
1784 MsiSetPropertyA(hpkg, "two", "hi");
1785 r = MsiEvaluateConditionA(hpkg, "one >< two");
1786 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1787
1788 MsiSetPropertyA(hpkg, "one", "");
1789 MsiSetPropertyA(hpkg, "two", "hi");
1790 r = MsiEvaluateConditionA(hpkg, "one >< two");
1791 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1792
1793 MsiSetPropertyA(hpkg, "one", "hi");
1794 MsiSetPropertyA(hpkg, "two", "");
1795 r = MsiEvaluateConditionA(hpkg, "one >< two");
1796 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1797
1798 MsiSetPropertyA(hpkg, "one", "");
1799 MsiSetPropertyA(hpkg, "two", "");
1800 r = MsiEvaluateConditionA(hpkg, "one >< two");
1801 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1802
1803 MsiSetPropertyA(hpkg, "one", "1234");
1804 MsiSetPropertyA(hpkg, "two", "1");
1805 r = MsiEvaluateConditionA(hpkg, "one >< two");
1806 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1807
1808 MsiSetPropertyA(hpkg, "one", "one 1234");
1809 MsiSetPropertyA(hpkg, "two", "1");
1810 r = MsiEvaluateConditionA(hpkg, "one >< two");
1811 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1812
1813 MsiSetPropertyA(hpkg, "one", "hithere");
1814 MsiSetPropertyA(hpkg, "two", "hi");
1815 r = MsiEvaluateConditionA(hpkg, "one << two");
1816 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1817
1818 MsiSetPropertyA(hpkg, "one", "hi");
1819 MsiSetPropertyA(hpkg, "two", "hithere");
1820 r = MsiEvaluateConditionA(hpkg, "one << two");
1821 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1822
1823 MsiSetPropertyA(hpkg, "one", "hi");
1824 MsiSetPropertyA(hpkg, "two", "hi");
1825 r = MsiEvaluateConditionA(hpkg, "one << two");
1826 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1827
1828 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1829 MsiSetPropertyA(hpkg, "two", "hi");
1830 r = MsiEvaluateConditionA(hpkg, "one << two");
1831 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1832
1833 MsiSetPropertyA(hpkg, "one", "");
1834 MsiSetPropertyA(hpkg, "two", "hi");
1835 r = MsiEvaluateConditionA(hpkg, "one << two");
1836 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1837
1838 MsiSetPropertyA(hpkg, "one", "hithere");
1839 MsiSetPropertyA(hpkg, "two", "");
1840 r = MsiEvaluateConditionA(hpkg, "one << two");
1841 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1842
1843 MsiSetPropertyA(hpkg, "one", "");
1844 MsiSetPropertyA(hpkg, "two", "");
1845 r = MsiEvaluateConditionA(hpkg, "one << two");
1846 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1847
1848 MsiSetPropertyA(hpkg, "one", "1234");
1849 MsiSetPropertyA(hpkg, "two", "1");
1850 r = MsiEvaluateConditionA(hpkg, "one << two");
1851 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1852
1853 MsiSetPropertyA(hpkg, "one", "1234 one");
1854 MsiSetPropertyA(hpkg, "two", "1");
1855 r = MsiEvaluateConditionA(hpkg, "one << two");
1856 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1857
1858 MsiSetPropertyA(hpkg, "one", "hithere");
1859 MsiSetPropertyA(hpkg, "two", "there");
1860 r = MsiEvaluateConditionA(hpkg, "one >> two");
1861 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1862
1863 MsiSetPropertyA(hpkg, "one", "hithere");
1864 MsiSetPropertyA(hpkg, "two", "hi");
1865 r = MsiEvaluateConditionA(hpkg, "one >> two");
1866 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1867
1868 MsiSetPropertyA(hpkg, "one", "there");
1869 MsiSetPropertyA(hpkg, "two", "hithere");
1870 r = MsiEvaluateConditionA(hpkg, "one >> two");
1871 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1872
1873 MsiSetPropertyA(hpkg, "one", "there");
1874 MsiSetPropertyA(hpkg, "two", "there");
1875 r = MsiEvaluateConditionA(hpkg, "one >> two");
1876 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1877
1878 MsiSetPropertyA(hpkg, "one", "abcdhithere");
1879 MsiSetPropertyA(hpkg, "two", "hi");
1880 r = MsiEvaluateConditionA(hpkg, "one >> two");
1881 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1882
1883 MsiSetPropertyA(hpkg, "one", "");
1884 MsiSetPropertyA(hpkg, "two", "there");
1885 r = MsiEvaluateConditionA(hpkg, "one >> two");
1886 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1887
1888 MsiSetPropertyA(hpkg, "one", "there");
1889 MsiSetPropertyA(hpkg, "two", "");
1890 r = MsiEvaluateConditionA(hpkg, "one >> two");
1891 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1892
1893 MsiSetPropertyA(hpkg, "one", "");
1894 MsiSetPropertyA(hpkg, "two", "");
1895 r = MsiEvaluateConditionA(hpkg, "one >> two");
1896 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1897
1898 MsiSetPropertyA(hpkg, "one", "1234");
1899 MsiSetPropertyA(hpkg, "two", "4");
1900 r = MsiEvaluateConditionA(hpkg, "one >> two");
1901 ok( r == MSICONDITION_FALSE, "wrong return val\n");
1902
1903 MsiSetPropertyA(hpkg, "one", "one 1234");
1904 MsiSetPropertyA(hpkg, "two", "4");
1905 r = MsiEvaluateConditionA(hpkg, "one >> two");
1906 ok( r == MSICONDITION_TRUE, "wrong return val\n");
1907
1908 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", NULL); /* make sure it's empty */
1909
1910 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
1911 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1912
1913 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport > \"1.1.4322\"");
1914 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1915
1916 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport >= \"1.1.4322\"");
1917 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1918
1919 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <= \"1.1.4322\"");
1920 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1921
1922 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport <> \"1.1.4322\"");
1923 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1924
1925 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport ~< \"1.1.4322\"");
1926 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1927
1928 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"abcd\"");
1929 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1930
1931 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a1.1.4322\"");
1932 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1933
1934 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322a\"");
1935 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1936
1937 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0000001.1.4322\"");
1938 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1939
1940 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1\"");
1941 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1942
1943 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322.1.1\"");
1944 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1945
1946 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1");
1947 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
1948
1949 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"1.1\"");
1950 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1951
1952 r = MsiEvaluateConditionA(hpkg, "\"2\" < \"12.1\"");
1953 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
1954
1955 r = MsiEvaluateConditionA(hpkg, "\"02.1\" < \"2.11\"");
1956 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1957
1958 r = MsiEvaluateConditionA(hpkg, "\"02.1.1\" < \"2.1\"");
1959 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1960
1961 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
1962 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1963
1964 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
1965 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1966
1967 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"0\"");
1968 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1969
1970 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"-1\"");
1971 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1972
1973 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a\"");
1974 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1975
1976 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1977 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1978
1979 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"!\"");
1980 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1981
1982 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"/\"");
1983 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1984
1985 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \" \"");
1986 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1987
1988 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"azAZ_\"");
1989 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1990
1991 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]\"");
1992 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1993
1994 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a[a]a\"");
1995 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1996
1997 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]\"");
1998 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
1999
2000 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a]a\"");
2001 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2002
2003 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a}\"");
2004 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2005
2006 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"{a\"");
2007 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2008
2009 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"[a\"");
2010 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2011
2012 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a{\"");
2013 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2014
2015 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"a]\"");
2016 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2017
2018 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"A\"");
2019 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2020
2021 MsiSetPropertyA(hpkg, "MsiNetAssemblySupport", "1.1.4322");
2022 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.4322\"");
2023 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2024
2025 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.14322\"");
2026 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2027
2028 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1.5\"");
2029 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2030
2031 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1.1\"");
2032 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2033
2034 r = MsiEvaluateConditionA(hpkg, "MsiNetAssemblySupport < \"1\"");
2035 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2036
2037 MsiSetPropertyA(hpkg, "one", "1");
2038 r = MsiEvaluateConditionA(hpkg, "one < \"1\"");
2039 ok( r == MSICONDITION_FALSE, "wrong return val\n");
2040
2041 MsiSetPropertyA(hpkg, "X", "5.0");
2042
2043 r = MsiEvaluateConditionA(hpkg, "X != \"\"");
2044 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2045
2046 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\"");
2047 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2048
2049 r = MsiEvaluateConditionA(hpkg, "X =\"5.1\"");
2050 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2051
2052 r = MsiEvaluateConditionA(hpkg, "X =\"6.0\"");
2053 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2054
2055 r = MsiEvaluateConditionA(hpkg, "X =\"5.0\" or X =\"5.1\" or X =\"6.0\"");
2056 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2057
2058 r = MsiEvaluateConditionA(hpkg, "(X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2059 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2060
2061 r = MsiEvaluateConditionA(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
2062 ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
2063
2064 /* feature doesn't exist */
2065 r = MsiEvaluateConditionA(hpkg, "&nofeature");
2066 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2067 r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\"");
2068 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2069 r = MsiEvaluateConditionA(hpkg, "&nofeature<>3");
2070 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2071 r = MsiEvaluateConditionA(hpkg, "\"\"<>3");
2072 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2073 r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\"");
2074 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2075 r = MsiEvaluateConditionA(hpkg, "$nocomponent=\"\"");
2076 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2077 r = MsiEvaluateConditionA(hpkg, "?nocomponent=\"\"");
2078 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2079
2080 MsiSetPropertyA(hpkg, "A", "2");
2081 MsiSetPropertyA(hpkg, "X", "50");
2082
2083 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2084 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2085
2086 r = MsiEvaluateConditionA(hpkg, "A <= X");
2087 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2088
2089 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2090 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2091
2092 MsiSetPropertyA(hpkg, "X", "50val");
2093
2094 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2095 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2096
2097 r = MsiEvaluateConditionA(hpkg, "A <= X");
2098 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2099
2100 MsiSetPropertyA(hpkg, "A", "7");
2101 MsiSetPropertyA(hpkg, "X", "50");
2102
2103 r = MsiEvaluateConditionA(hpkg, "7 <= X");
2104 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2105
2106 r = MsiEvaluateConditionA(hpkg, "A <= X");
2107 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2108
2109 r = MsiEvaluateConditionA(hpkg, "A <= 50");
2110 ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
2111
2112 MsiSetPropertyA(hpkg, "X", "50val");
2113
2114 r = MsiEvaluateConditionA(hpkg, "2 <= X");
2115 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2116
2117 r = MsiEvaluateConditionA(hpkg, "A <= X");
2118 ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
2119
2120 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
2122 "wrong return val (%d)\n", r);
2123
2124 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
2126 "wrong return val (%d)\n", r);
2127
2128 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
2130 "wrong return val (%d)\n", r);
2131
2132 r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
2134 "wrong return val (%d)\n", r);
2135
2136 MsiCloseHandle( hpkg );
2138}
2139
2140static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case)
2141{
2142 char buffer[MAX_PATH] = "x";
2143 DWORD sz = sizeof(buffer);
2144 UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz);
2145 ok(!r, "'%s': got %u\n", prop, r);
2146 ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz);
2147 if (match_case)
2148 ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2149 else
2150 ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
2151}
2152
2153static void test_props(void)
2154{
2155 MSIHANDLE hpkg, hdb;
2156 UINT r;
2157 DWORD sz;
2158 char buffer[0x100];
2159 WCHAR bufferW[10];
2160
2161 hdb = create_package_db();
2162
2164 add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'");
2165
2166 r = package_from_db( hdb, &hpkg );
2168 {
2169 skip("Not enough rights to perform tests\n");
2171 return;
2172 }
2173 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2174
2175 /* test invalid values */
2176 r = MsiGetPropertyA( 0, NULL, NULL, NULL );
2177 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2178
2179 r = MsiGetPropertyA( hpkg, NULL, NULL, NULL );
2180 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2181
2182 r = MsiGetPropertyA( hpkg, "boo", NULL, NULL );
2183 ok(!r, "got %u\n", r);
2184
2185 r = MsiGetPropertyA( hpkg, "boo", buffer, NULL );
2186 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2187
2188 /* test retrieving an empty/nonexistent property */
2189 sz = sizeof buffer;
2190 r = MsiGetPropertyA( hpkg, "boo", NULL, &sz );
2191 ok(!r, "got %u\n", r);
2192 ok(sz == 0, "got size %lu\n", sz);
2193
2194 sz = 0;
2195 strcpy(buffer,"x");
2196 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2197 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2198 ok(!strcmp(buffer,"x"), "got \"%s\"\n", buffer);
2199 ok(sz == 0, "got size %lu\n", sz);
2200
2201 sz = 1;
2202 strcpy(buffer,"x");
2203 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2204 ok(!r, "got %u\n", r);
2205 ok(!buffer[0], "got \"%s\"\n", buffer);
2206 ok(sz == 0, "got size %lu\n", sz);
2207
2208 /* set the property to something */
2209 r = MsiSetPropertyA( 0, NULL, NULL );
2210 ok(r == ERROR_INVALID_HANDLE, "got %u\n", r);
2211
2212 r = MsiSetPropertyA( hpkg, NULL, NULL );
2213 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2214
2215 r = MsiSetPropertyA( hpkg, "", NULL );
2216 ok(!r, "got %u\n", r);
2217
2218 r = MsiSetPropertyA( hpkg, "", "asdf" );
2219 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
2220
2221 r = MsiSetPropertyA( hpkg, "=", "asdf" );
2222 ok(!r, "got %u\n", r);
2223 check_prop(hpkg, "=", "asdf", 1);
2224
2225 r = MsiSetPropertyA( hpkg, " ", "asdf" );
2226 ok(!r, "got %u\n", r);
2227 check_prop(hpkg, " ", "asdf", 1);
2228
2229 r = MsiSetPropertyA( hpkg, "'", "asdf" );
2230 ok(!r, "got %u\n", r);
2231 check_prop(hpkg, "'", "asdf", 1);
2232
2233 /* set empty values */
2234 r = MsiSetPropertyA( hpkg, "boo", NULL );
2235 ok(!r, "got %u\n", r);
2236 check_prop(hpkg, "boo", "", 1);
2237
2238 r = MsiSetPropertyA( hpkg, "boo", "" );
2239 ok(!r, "got %u\n", r);
2240 check_prop(hpkg, "boo", "", 1);
2241
2242 /* set a non-empty value */
2243 r = MsiSetPropertyA( hpkg, "boo", "xyz" );
2244 ok(!r, "got %u\n", r);
2245 check_prop(hpkg, "boo", "xyz", 1);
2246
2247 r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
2248 ok(!r, "got %u\n", r);
2249
2250 r = MsiGetPropertyA(hpkg, "boo", buffer, NULL);
2251 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2252
2253 sz = 0;
2254 r = MsiGetPropertyA(hpkg, "boo", NULL, &sz);
2255 ok(!r, "got %u\n", r);
2256 ok(sz == 3, "got size %lu\n", sz);
2257
2258 sz = 0;
2259 strcpy(buffer, "q");
2260 r = MsiGetPropertyA(hpkg, "boo", buffer, &sz);
2261 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2262 ok(!strcmp(buffer, "q"), "got \"%s\"", buffer);
2263 ok(sz == 3, "got size %lu\n", sz);
2264
2265 sz = 1;
2266 strcpy(buffer,"x");
2267 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2268 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2269 ok(!buffer[0], "got \"%s\"\n", buffer);
2270 ok(sz == 3, "got size %lu\n", sz);
2271
2272 sz = 3;
2273 strcpy(buffer,"x");
2274 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2275 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2276 ok(!strcmp(buffer,"xy"), "got \"%s\"\n", buffer);
2277 ok(sz == 3, "got size %lu\n", sz);
2278
2279 sz = 4;
2280 strcpy(buffer,"x");
2281 r = MsiGetPropertyA( hpkg, "boo", buffer, &sz );
2282 ok(!r, "got %u\n", r);
2283 ok(!strcmp(buffer,"xyz"), "got \"%s\"\n", buffer);
2284 ok(sz == 3, "got size %lu\n", sz);
2285
2286 sz = 0;
2287 r = MsiGetPropertyW(hpkg, L"boo", NULL, &sz);
2288 ok(!r, "got %u\n", r);
2289 ok(sz == 3, "got size %lu\n", sz);
2290
2291 sz = 0;
2292 lstrcpyW(bufferW, L"boo");
2293 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz);
2294 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2295 ok(!lstrcmpW(bufferW, L"boo"), "got %s\n", wine_dbgstr_w(bufferW));
2296 ok(sz == 3, "got size %lu\n", sz);
2297
2298 sz = 1;
2299 lstrcpyW(bufferW, L"boo");
2300 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2301 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2302 ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
2303 ok(sz == 3, "got size %lu\n", sz);
2304
2305 sz = 3;
2306 lstrcpyW(bufferW, L"boo");
2307 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2308 ok(r == ERROR_MORE_DATA, "got %u\n", r);
2309 ok(!lstrcmpW(bufferW, L"xy"), "got %s\n", wine_dbgstr_w(bufferW));
2310 ok(sz == 3, "got size %lu\n", sz);
2311
2312 sz = 4;
2313 lstrcpyW(bufferW, L"boo");
2314 r = MsiGetPropertyW(hpkg, L"boo", bufferW, &sz );
2315 ok(!r, "got %u\n", r);
2316 ok(!lstrcmpW(bufferW, L"xyz"), "got %s\n", wine_dbgstr_w(bufferW));
2317 ok(sz == 3, "got size %lu\n", sz);
2318
2319 /* properties are case-sensitive */
2320 check_prop(hpkg, "BOO", "", 1);
2321
2322 /* properties set in Property table should work */
2323 check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1);
2324
2325 MsiCloseHandle( hpkg );
2327}
2328
2330{
2331 MSIHANDLE hview, hrec;
2332 BOOL found = FALSE;
2334 DWORD sz;
2335 UINT r;
2336
2337 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
2338 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2339 r = MsiViewExecute(hview, 0);
2340 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
2341
2342 if (len < 0) len = lstrlenA(val);
2343
2344 while (r == ERROR_SUCCESS && !found)
2345 {
2346 r = MsiViewFetch(hview, &hrec);
2347 if (r != ERROR_SUCCESS) break;
2348
2349 sz = MAX_PATH;
2350 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
2351 if (r == ERROR_SUCCESS && !lstrcmpA(buffer, prop))
2352 {
2353 sz = MAX_PATH;
2354 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
2355 if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
2356 {
2357 ok(sz == len, "wrong size %lu\n", sz);
2358 found = TRUE;
2359 }
2360 }
2361
2362 MsiCloseHandle(hrec);
2363 }
2364 MsiViewClose(hview);
2365 MsiCloseHandle(hview);
2366 return found;
2367}
2368
2369static void test_property_table(void)
2370{
2371 const char *query;
2372 UINT r;
2373 MSIHANDLE hpkg, hdb, hrec;
2374 char buffer[MAX_PATH], package[10];
2375 DWORD sz;
2376 BOOL found;
2377
2378 hdb = create_package_db();
2379 ok( hdb, "failed to create package\n");
2380
2381 r = package_from_db(hdb, &hpkg);
2383 {
2384 skip("Not enough rights to perform tests\n");
2386 return;
2387 }
2388 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2389
2390 MsiCloseHandle(hdb);
2391
2392 hdb = MsiGetActiveDatabase(hpkg);
2393
2394 query = "CREATE TABLE `_Property` ( "
2395 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2396 r = run_query(hdb, query);
2397 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2398
2399 MsiCloseHandle(hdb);
2400 MsiCloseHandle(hpkg);
2402
2403 hdb = create_package_db();
2404 ok( hdb, "failed to create package\n");
2405
2406 query = "CREATE TABLE `_Property` ( "
2407 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
2408 r = run_query(hdb, query);
2409 ok(r == ERROR_SUCCESS, "failed to create table\n");
2410
2411 query = "ALTER `_Property` ADD `foo` INTEGER";
2412 r = run_query(hdb, query);
2413 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2414
2415 query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
2416 r = run_query(hdb, query);
2417 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
2418
2419 query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
2420 r = run_query(hdb, query);
2421 ok(r == ERROR_SUCCESS, "failed to add column\n");
2422
2423 sprintf(package, "#%lu", hdb);
2424 r = MsiOpenPackageA(package, &hpkg);
2425 ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
2426 if (r == ERROR_SUCCESS)
2427 MsiCloseHandle(hpkg);
2428
2429 r = MsiCloseHandle(hdb);
2430 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
2431
2432 hdb = create_package_db();
2433 ok (hdb, "failed to create package database\n");
2434
2436 add_property_entry(hdb, "'prop', 'val'");
2437
2439 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
2440
2441 r = package_from_db(hdb, &hpkg);
2442 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
2443
2444 MsiCloseHandle(hdb);
2445
2446 sz = MAX_PATH;
2447 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
2448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2449 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
2450
2451 hdb = MsiGetActiveDatabase(hpkg);
2452
2453 found = find_prop_in_property(hdb, "prop", "val", -1);
2454 ok(found, "prop should be in the _Property table\n");
2455
2456 add_property_entry(hdb, "'dantes', 'mercedes'");
2457
2458 query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'";
2459 r = do_query(hdb, query, &hrec);
2460 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2461
2462 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2463 ok(found == FALSE, "dantes should not be in the _Property table\n");
2464
2465 sz = MAX_PATH;
2466 lstrcpyA(buffer, "aaa");
2467 r = MsiGetPropertyA(hpkg, "dantes", buffer, &sz);
2468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2469 ok(!buffer[0], "Expected empty string, got %s\n", buffer);
2470
2471 r = MsiSetPropertyA(hpkg, "dantes", "mercedes");
2472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2473
2474 found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
2475 ok(found == TRUE, "dantes should be in the _Property table\n");
2476
2477 r = MsiDoActionA( hpkg, "EmbedNull" );
2478 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2479
2480 sz = MAX_PATH;
2481 memset( buffer, 'a', sizeof(buffer) );
2482 r = MsiGetPropertyA( hpkg, "prop2", buffer, &sz );
2483 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2484 ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
2485 ok( sz == sizeof("\0np") - 1, "got %lu\n", sz );
2486
2487 found = find_prop_in_property(hdb, "prop2", "\0np", 3);
2488 ok(found == TRUE, "prop2 should be in the _Property table\n");
2489
2490 MsiCloseHandle(hdb);
2491 MsiCloseHandle(hpkg);
2493}
2494
2495static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
2496{
2497 MSIHANDLE htab = 0;
2498 UINT res;
2499
2500 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
2501 if( res == ERROR_SUCCESS )
2502 {
2503 UINT r;
2504
2505 r = MsiViewExecute( htab, hrec );
2506 if( r != ERROR_SUCCESS )
2507 {
2508 res = r;
2509 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
2510 }
2511
2512 r = MsiViewClose( htab );
2513 if( r != ERROR_SUCCESS )
2514 res = r;
2515
2516 r = MsiCloseHandle( htab );
2517 if( r != ERROR_SUCCESS )
2518 res = r;
2519 }
2520 return res;
2521}
2522
2523static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
2524{
2525 return try_query_param( hdb, szQuery, 0 );
2526}
2527
2529{
2530 MSIHANDLE summary;
2531 UINT r;
2532
2533 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2535
2537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2538
2539 r = MsiSummaryInfoPersist(summary);
2540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2541
2542 MsiCloseHandle(summary);
2543}
2544
2546{
2547 MSIHANDLE summary;
2548 UINT r;
2549
2550 r = MsiGetSummaryInformationA(hdb, NULL, 1, &summary);
2551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2552
2554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2555
2556 r = MsiSummaryInfoPersist(summary);
2557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2558
2559 MsiCloseHandle(summary);
2560}
2561
2562static void test_msipackage(void)
2563{
2564 MSIHANDLE hdb = 0, hpack = 100;
2565 UINT r;
2566 const char *query;
2567 char name[10];
2568
2569 /* NULL szPackagePath */
2570 r = MsiOpenPackageA(NULL, &hpack);
2571 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2572
2573 /* empty szPackagePath */
2574 r = MsiOpenPackageA("", &hpack);
2576 {
2577 skip("Not enough rights to perform tests\n");
2578 return;
2579 }
2580 todo_wine
2581 {
2582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2583 }
2584
2585 if (r == ERROR_SUCCESS)
2586 MsiCloseHandle(hpack);
2587
2588 /* nonexistent szPackagePath */
2589 r = MsiOpenPackageA("nonexistent", &hpack);
2590 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2591
2592 /* NULL hProduct */
2594 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2595
2596 name[0]='#';
2597 name[1]=0;
2598 r = MsiOpenPackageA(name, &hpack);
2599 ok(r == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", r);
2600
2602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2603
2604 /* database exists, but is empty */
2605 sprintf(name, "#%lu", hdb);
2606 r = MsiOpenPackageA(name, &hpack);
2608 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2609
2610 query = "CREATE TABLE `Property` ( "
2611 "`Property` CHAR(72), `Value` CHAR(0) "
2612 "PRIMARY KEY `Property`)";
2613 r = try_query(hdb, query);
2614 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
2615
2616 query = "CREATE TABLE `InstallExecuteSequence` ("
2617 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
2618 "PRIMARY KEY `Action`)";
2619 r = try_query(hdb, query);
2620 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
2621
2622 /* a few key tables exist */
2623 sprintf(name, "#%lu", hdb);
2624 r = MsiOpenPackageA(name, &hpack);
2626 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2627
2628 MsiCloseHandle(hdb);
2630
2631 /* start with a clean database to show what constitutes a valid package */
2633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2634
2635 sprintf(name, "#%lu", hdb);
2636
2637 /* The following summary information props must exist:
2638 * - PID_REVNUMBER
2639 * - PID_PAGECOUNT
2640 */
2641
2643 r = MsiOpenPackageA(name, &hpack);
2645 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
2646
2647 set_summary_str(hdb, PID_REVNUMBER, "{004757CD-5092-49C2-AD20-28E1CE0DF5F2}");
2648 r = MsiOpenPackageA(name, &hpack);
2649 ok(r == ERROR_SUCCESS,
2650 "Expected ERROR_SUCCESS, got %d\n", r);
2651
2652 MsiCloseHandle(hpack);
2653 MsiCloseHandle(hdb);
2655}
2656
2657static void test_formatrecord2(void)
2658{
2659 MSIHANDLE hpkg, hrec ;
2660 char buffer[0x100];
2661 DWORD sz;
2662 UINT r;
2663
2666 {
2667 skip("Not enough rights to perform tests\n");
2669 return;
2670 }
2671 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
2672
2673 r = MsiSetPropertyA(hpkg, "Manufacturer", " " );
2674 ok( r == ERROR_SUCCESS, "set property failed\n");
2675
2676 hrec = MsiCreateRecord(2);
2677 ok(hrec, "create record failed\n");
2678
2679 r = MsiRecordSetStringA( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
2680 ok( r == ERROR_SUCCESS, "format record failed\n");
2681
2682 buffer[0] = 0;
2683 sz = sizeof buffer;
2684 r = MsiFormatRecordA( hpkg, hrec, buffer, &sz );
2685 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2686
2687 r = MsiRecordSetStringA(hrec, 0, "[foo][1]");
2688 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2689 r = MsiRecordSetStringA(hrec, 1, "hoo");
2690 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2691 sz = sizeof buffer;
2692 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2693 ok( sz == 3, "size wrong\n");
2694 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2695 ok( r == ERROR_SUCCESS, "format failed\n");
2696
2697 r = MsiRecordSetStringA(hrec, 0, "x[~]x");
2698 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2699 sz = sizeof buffer;
2700 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2701 ok( sz == 3, "size wrong\n");
2702 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
2703 ok( r == ERROR_SUCCESS, "format failed\n");
2704
2705 r = MsiRecordSetStringA(hrec, 0, "[foo.$%}][1]");
2706 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2707 r = MsiRecordSetStringA(hrec, 1, "hoo");
2708 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2709 sz = sizeof buffer;
2710 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2711 ok( sz == 3, "size wrong\n");
2712 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
2713 ok( r == ERROR_SUCCESS, "format failed\n");
2714
2715 r = MsiRecordSetStringA(hrec, 0, "[\\[]");
2716 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2717 sz = sizeof buffer;
2718 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2719 ok( sz == 1, "size wrong\n");
2720 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
2721 ok( r == ERROR_SUCCESS, "format failed\n");
2722
2723 SetEnvironmentVariableA("FOO", "BAR");
2724 r = MsiRecordSetStringA(hrec, 0, "[%FOO]");
2725 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2726 sz = sizeof buffer;
2727 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2728 ok( sz == 3, "size wrong\n");
2729 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2730 ok( r == ERROR_SUCCESS, "format failed\n");
2731
2732 r = MsiRecordSetStringA(hrec, 0, "[[1]]");
2733 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2734 r = MsiRecordSetStringA(hrec, 1, "%FOO");
2735 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
2736 sz = sizeof buffer;
2737 r = MsiFormatRecordA(hpkg, hrec, buffer, &sz);
2738 ok( sz == 3, "size wrong\n");
2739 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
2740 ok( r == ERROR_SUCCESS, "format failed\n");
2741
2742 MsiCloseHandle( hrec );
2743 MsiCloseHandle( hpkg );
2745}
2746
2748{
2749 MSIHANDLE hdb, hrec, hpkg = 0;
2750 CHAR buf[MAX_PATH + 41];
2751 CHAR curr_dir[MAX_PATH];
2752 CHAR expected[MAX_PATH + 45];
2754 DWORD size;
2755 UINT r;
2756
2757 GetCurrentDirectoryA( MAX_PATH, curr_dir );
2758
2759 hdb = create_package_db();
2760 ok ( hdb, "failed to create package database\n");
2761
2762 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2763 add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2764 "'I am a really long directory'" );
2765
2766 create_feature_table( hdb );
2767 add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2768
2770 add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2771 add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2772 add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2773
2775 add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2776 add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2777 add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2778
2779 create_file_table( hdb );
2780 add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2781 add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2782 add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2783
2785 add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2786 add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2787 add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2788 add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2789 add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2790
2791 r = package_from_db( hdb, &hpkg );
2793 {
2794 skip("Not enough rights to perform tests\n");
2795 MsiCloseHandle( hdb );
2797 return;
2798 }
2799 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2800
2801 MsiCloseHandle( hdb );
2802
2803 r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2804 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2805
2806 hrec = MsiCreateRecord( 1 );
2807
2808 /* property doesn't exist */
2809 size = MAX_PATH;
2810 /*MsiRecordSetStringA( hrec, 0, "[1]" ); */
2811 MsiRecordSetStringA( hrec, 1, "[idontexist]" );
2812 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2813 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2814 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2815
2816 /* property exists */
2817 size = MAX_PATH;
2818 MsiRecordSetStringA( hrec, 1, "[imaprop]" );
2819 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2820 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2821 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2822
2823 size = MAX_PATH;
2824 MsiRecordSetStringA( hrec, 0, "1: [1] " );
2825 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2826 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2827 ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2828
2829 /* environment variable doesn't exist */
2830 size = MAX_PATH;
2831 MsiRecordSetStringA( hrec, 1, "[%idontexist]" );
2832 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2833 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2834 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2835
2836 /* environment variable exists */
2837 size = MAX_PATH;
2838 SetEnvironmentVariableA( "crazyvar", "crazyval" );
2839 MsiRecordSetStringA( hrec, 1, "[%crazyvar]" );
2840 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2841 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2842 ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2843
2844 /* file key before CostInitialize */
2845 size = MAX_PATH;
2846 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2847 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2848 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2849 ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf );
2850
2852
2853 r = MsiDoActionA(hpkg, "CostInitialize");
2854 ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2855
2856 r = MsiDoActionA(hpkg, "FileCost");
2857 ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2858
2859 r = MsiDoActionA(hpkg, "CostFinalize");
2860 ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2861
2862 size = MAX_PATH;
2863 MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size );
2864
2865 sprintf( expected, "1: %sfrontal.txt ", root);
2866
2867 /* frontal full file key */
2868 size = MAX_PATH;
2869 MsiRecordSetStringA( hrec, 1, "[#frontal_file]" );
2870 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2871 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2872 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2873
2874 /* frontal short file key */
2875 size = MAX_PATH;
2876 MsiRecordSetStringA( hrec, 1, "[!frontal_file]" );
2877 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2878 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2879 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2880
2881 sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2882
2883 /* temporal full file key */
2884 size = MAX_PATH;
2885 MsiRecordSetStringA( hrec, 1, "[#temporal_file]" );
2886 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2887 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2888 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2889
2890 /* temporal short file key */
2891 size = MAX_PATH;
2892 MsiRecordSetStringA( hrec, 1, "[!temporal_file]" );
2893 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2894 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2895 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2896
2897 /* custom action 51, files don't exist */
2898 r = MsiDoActionA( hpkg, "MyCustom" );
2899 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2900
2901 sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2902
2903 size = MAX_PATH;
2904 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2905 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2906 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2907
2908 sprintf( buf, "%sI am a really long directory", root );
2910
2911 lstrcatA( buf, "\\temporal.txt" );
2913
2914 /* custom action 51, files exist */
2915 r = MsiDoActionA( hpkg, "MyCustom" );
2916 ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2917
2918 size = MAX_PATH;
2919 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2920 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2921 todo_wine
2922 {
2923 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2924 }
2925
2926 /* custom action 51, escaped text 1 */
2927 r = MsiDoActionA( hpkg, "EscapeIt1" );
2928 ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2929
2930 size = MAX_PATH;
2931 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2932 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2933 ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2934
2935 /* custom action 51, escaped text 2 */
2936 r = MsiDoActionA( hpkg, "EscapeIt2" );
2937 ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2938
2939 size = MAX_PATH;
2940 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2941 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2942 ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf);
2943
2944 /* custom action 51, escaped text 3 */
2945 r = MsiDoActionA( hpkg, "EscapeIt3" );
2946 ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2947
2948 size = MAX_PATH;
2949 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2950 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2951 ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf);
2952
2953 /* custom action 51, embedded null */
2954 r = MsiDoActionA( hpkg, "EmbedNull" );
2955 ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2956
2957 size = MAX_PATH;
2958 memset( buf, 'a', sizeof(buf) );
2959 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2960 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2961 ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
2962 ok( size == sizeof("\0np") - 1, "got %lu\n", size );
2963
2964 r = MsiSetPropertyA( hpkg, "prop", "[~]np" );
2965 ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2966
2967 size = MAX_PATH;
2968 memset( buf, 'a', sizeof(buf) );
2969 r = MsiGetPropertyA( hpkg, "prop", buf, &size );
2970 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2971 ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2972
2973 sprintf( expected, "1: %sI am a really long directory\\ ", root);
2974
2975 /* component with INSTALLSTATE_LOCAL */
2976 size = MAX_PATH;
2977 MsiRecordSetStringA( hrec, 1, "[$temporal]" );
2978 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2979 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2980 ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2981
2982 r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE );
2983 ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2984
2985 /* component with INSTALLSTATE_SOURCE */
2986 lstrcpyA( expected, "1: " );
2987 lstrcatA( expected, curr_dir );
2988 if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" );
2989 lstrcatA( expected, " " );
2990 size = MAX_PATH;
2991 MsiRecordSetStringA( hrec, 1, "[$parietal]" );
2992 r = MsiFormatRecordA( hpkg, hrec, buf, &size );
2993 ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2994 ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2995
2996 sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2997 DeleteFileA( buf );
2998
2999 sprintf( buf, "%sI am a really long directory", root );
3001
3002 MsiCloseHandle( hrec );
3003 MsiCloseHandle( hpkg );
3005}
3006
3007static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
3008 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3009{
3010 UINT r;
3011 INSTALLSTATE state = 0xdeadbee;
3012 INSTALLSTATE action = 0xdeadbee;
3013
3014 r = MsiGetFeatureStateA( package, feature, &state, &action );
3015 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3016 if (r == ERROR_SUCCESS)
3017 {
3018 ok( state == expected_state, "%u: expected state %d got %d\n",
3019 line, expected_state, state );
3021 ok( action == expected_action, "%u: expected action %d got %d\n",
3022 line, expected_action, action );
3023 }
3024 else
3025 {
3026 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
3028 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
3029
3030 }
3031}
3032
3033static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
3034 INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo )
3035{
3036 UINT r;
3037 INSTALLSTATE state = 0xdeadbee;
3038 INSTALLSTATE action = 0xdeadbee;
3039
3040 r = MsiGetComponentStateA( package, component, &state, &action );
3041 ok( r == error, "%u: expected %d got %d\n", line, error, r );
3042 if (r == ERROR_SUCCESS)
3043 {
3044 ok( state == expected_state, "%u: expected state %d got %d\n",
3045 line, expected_state, state );
3047 ok( action == expected_action, "%u: expected action %d got %d\n",
3048 line, expected_action, action );
3049 }
3050 else
3051 {
3052 ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
3053 line, state );
3055 ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
3056 line, action );
3057 }
3058}
3059
3060static void test_states(void)
3061{
3062 static const char msifile2[] = "winetest2-package.msi";
3063 static const char msifile3[] = "winetest3-package.msi";
3064 static const char msifile4[] = "winetest4-package.msi";
3065 static const WCHAR msifile2W[] = L"winetest2-package.msi";
3066 static const WCHAR msifile3W[] = L"winetest3-package.msi";
3067 static const WCHAR msifile4W[] = L"winetest4-package.msi";
3068 char msi_cache_file[MAX_PATH];
3069 DWORD cache_file_name_len;
3071 MSIHANDLE hpkg, hprod;
3072 UINT r;
3073 MSIHANDLE hdb;
3074 BOOL is_broken;
3075 char value[MAX_PATH];
3076 DWORD size;
3077
3078 if (is_process_limited())
3079 {
3080 skip("process is limited\n");
3081 return;
3082 }
3083
3084 hdb = create_package_db();
3085 ok ( hdb, "failed to create package database\n" );
3086
3087 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3088
3089 create_property_table( hdb );
3090 add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
3091 add_property_entry( hdb, "'ProductLanguage', '1033'" );
3092 add_property_entry( hdb, "'ProductName', 'MSITEST'" );
3093 add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
3094 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
3095 add_property_entry( hdb, "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
3096
3098 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
3099 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
3100 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
3101 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" );
3102 add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" );
3103 add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" );
3104 add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" );
3105 add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" );
3106 add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" );
3107 add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" );
3108 add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" );
3109
3110 create_media_table( hdb );
3111 add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''");
3112
3113 create_feature_table( hdb );
3114
3116
3117 /* msidbFeatureAttributesFavorLocal */
3118 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3119
3120 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
3121 add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
3122
3123 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
3124 add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
3125
3126 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
3127 add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
3128
3129 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
3130 add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
3131
3132 /* msidbFeatureAttributesFavorSource */
3133 add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
3134
3135 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
3136 add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
3137
3138 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3139 add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
3140
3141 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
3142 add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
3143
3144 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
3145 add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
3146
3147 /* msidbFeatureAttributesFavorSource */
3148 add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
3149
3150 /* msidbFeatureAttributesFavorLocal */
3151 add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
3152
3153 /* disabled */
3154 add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
3155
3156 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
3157 add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
3158
3159 /* no feature parent:msidbComponentAttributesLocalOnly */
3160 add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" );
3161
3162 /* msidbFeatureAttributesFavorLocal:removed */
3163 add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" );
3164
3165 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */
3166 add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" );
3167
3168 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */
3169 add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" );
3170
3171 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */
3172 add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" );
3173
3174 /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */
3175 add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" );
3176
3177 /* msidbFeatureAttributesFavorSource:removed */
3178 add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" );
3179
3180 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */
3181 add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" );
3182
3183 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */
3184 add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" );
3185
3186 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */
3187 add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" );
3188
3189 /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */
3190 add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" );
3191
3192 /* msidbFeatureAttributesFavorLocal */
3193 add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" );
3194
3195 add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" );
3196
3197 /* msidbFeatureAttributesFavorSource */
3198 add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" );
3199
3200 add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" );
3201
3202 /* msidbFeatureAttributesFavorAdvertise */
3203 add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" );
3204
3205 add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
3206
3207 /* msidbFeatureAttributesUIDisallowAbsent */
3208 add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
3209
3210 add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
3211
3212 /* high install level */
3213 add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" );
3214
3215 add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" );
3216
3217 /* msidbFeatureAttributesFollowParent */
3218 add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" );
3219
3221 add_feature_components_entry( hdb, "'one', 'alpha'" );
3222 add_feature_components_entry( hdb, "'one', 'beta'" );
3223 add_feature_components_entry( hdb, "'one', 'gamma'" );
3224 add_feature_components_entry( hdb, "'one', 'theta'" );
3225 add_feature_components_entry( hdb, "'two', 'delta'" );
3226 add_feature_components_entry( hdb, "'two', 'epsilon'" );
3227 add_feature_components_entry( hdb, "'two', 'zeta'" );
3228 add_feature_components_entry( hdb, "'two', 'iota'" );
3229 add_feature_components_entry( hdb, "'three', 'eta'" );
3230 add_feature_components_entry( hdb, "'four', 'eta'" );
3231 add_feature_components_entry( hdb, "'five', 'eta'" );
3232 add_feature_components_entry( hdb, "'six', 'lambda'" );
3233 add_feature_components_entry( hdb, "'six', 'mu'" );
3234 add_feature_components_entry( hdb, "'six', 'nu'" );
3235 add_feature_components_entry( hdb, "'six', 'xi'" );
3236 add_feature_components_entry( hdb, "'seven', 'omicron'" );
3237 add_feature_components_entry( hdb, "'seven', 'pi'" );
3238 add_feature_components_entry( hdb, "'seven', 'rho'" );
3239 add_feature_components_entry( hdb, "'seven', 'sigma'" );
3240 add_feature_components_entry( hdb, "'eight', 'tau'" );
3241 add_feature_components_entry( hdb, "'nine', 'phi'" );
3242 add_feature_components_entry( hdb, "'ten', 'chi'" );
3243 add_feature_components_entry( hdb, "'eleven', 'psi'" );
3244 add_feature_components_entry( hdb, "'twelve', 'upsilon'" );
3245 add_feature_components_entry( hdb, "'thirteen', 'upsilon'" );
3246
3247 create_file_table( hdb );
3248 add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
3249 add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
3250 add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
3251 add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
3252 add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
3253 add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
3254 add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
3255 add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
3256
3257 /* compressed file */
3258 add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
3259
3260 add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" );
3261 add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" );
3262 add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" );
3263 add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" );
3264 add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" );
3265 add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" );
3266 add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" );
3267 add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" );
3268 add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" );
3269 add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" );
3270 add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" );
3271 add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
3272 add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
3273 add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" );
3274
3275 r = MsiDatabaseCommit(hdb);
3276 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
3277
3278 /* these properties must not be in the saved msi file */
3279 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3280 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3281 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3282 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3283 add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
3284
3285 r = package_from_db( hdb, &hpkg );
3287 {
3288 skip("Not enough rights to perform tests\n");
3290 return;
3291 }
3292 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3293
3294 MsiCloseHandle(hdb);
3295
3297 CopyFileA(msifile, msifile3, FALSE);
3298 CopyFileA(msifile, msifile4, FALSE);
3299
3300 size = sizeof(value);
3301 memset(value, 0, sizeof(value));
3302 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3303 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3304 ok(!value[0], "ProductToBeRegistered = %s\n", value);
3305
3306 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3307 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3308
3309 r = MsiDoActionA( hpkg, "CostInitialize");
3310 ok( r == ERROR_SUCCESS, "cost init failed\n");
3311
3314
3316
3317 r = MsiDoActionA( hpkg, "FileCost");
3318 ok( r == ERROR_SUCCESS, "file cost failed\n");
3319
3322
3323 r = MsiDoActionA( hpkg, "CostFinalize");
3324 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3325
3339
3363
3364 MsiCloseHandle( hpkg );
3365
3367
3368 /* publish the features and components */
3369 r = MsiInstallProductA(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
3370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3371
3373 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3374
3375 /* these properties must not be in the saved msi file */
3376 add_property_entry( hdb, "'ADDLOCAL', 'one,four'");
3377 add_property_entry( hdb, "'ADDSOURCE', 'two,three'");
3378 add_property_entry( hdb, "'REMOVE', 'six,seven'");
3379 add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
3380
3381 r = package_from_db( hdb, &hpkg );
3382 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3383
3384 MsiCloseHandle(hdb);
3385
3386 size = sizeof(value);
3387 memset(value, 0, sizeof(value));
3388 r = MsiGetPropertyA(hpkg, "ProductToBeRegistered", value, &size);
3389 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
3390 ok(value[0]=='1' && !value[1], "ProductToBeRegistered = %s\n", value);
3391
3392 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3393 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3394
3395 r = MsiDoActionA( hpkg, "CostInitialize");
3396 ok( r == ERROR_SUCCESS, "cost init failed\n");
3397
3400
3401 r = MsiDoActionA( hpkg, "FileCost");
3402 ok( r == ERROR_SUCCESS, "file cost failed\n");
3403
3406
3407 r = MsiDoActionA( hpkg, "CostFinalize");
3408 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3409
3423
3447
3448 MsiCloseHandle(hpkg);
3449
3450 /* uninstall the product */
3451 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3453
3454 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3455 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3456 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3457 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3458
3459 /* all features installed locally */
3460 r = MsiInstallProductA(msifile2, "ADDLOCAL=ALL");
3461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3462
3463 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3464 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3465 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3466 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3467
3469 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3470
3471 /* these properties must not be in the saved msi file */
3472 add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'");
3473
3474 r = package_from_db( hdb, &hpkg );
3475 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3476
3477 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3478 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3479
3480 r = MsiDoActionA( hpkg, "CostInitialize");
3481 ok( r == ERROR_SUCCESS, "cost init failed\n");
3482
3485
3486 r = MsiDoActionA( hpkg, "CostFinalize");
3487 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3488
3502
3526
3527 MsiCloseHandle(hpkg);
3528
3529 /* uninstall the product */
3530 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3532
3533 /* all features installed from source */
3534 r = MsiInstallProductA(msifile3, "ADDSOURCE=ALL");
3535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3536
3537 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3538 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3539 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3540 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3541
3542 r = MsiOpenDatabaseW(msifile3W, MSIDBOPEN_DIRECT, &hdb);
3543 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3544
3545 /* this property must not be in the saved msi file */
3546 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3547
3548 r = package_from_db( hdb, &hpkg );
3549 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3550
3551 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3552 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3553
3554 r = MsiDoActionA( hpkg, "CostInitialize");
3555 ok( r == ERROR_SUCCESS, "cost init failed\n");
3556
3559
3560 r = MsiDoActionA( hpkg, "FileCost");
3561 ok( r == ERROR_SUCCESS, "file cost failed\n");
3562
3565
3566 r = MsiDoActionA( hpkg, "CostFinalize");
3567 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3568
3582
3606
3607 MsiCloseHandle(hpkg);
3608
3609 /* reinstall the product */
3610 r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
3611 is_broken = (r == ERROR_INSTALL_FAILURE);
3612 ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r);
3613
3614 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
3615 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3616 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "twelve");
3617 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3618
3619 r = MsiOpenDatabaseW(msifile4W, MSIDBOPEN_DIRECT, &hdb);
3620 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3621
3622 /* this property must not be in the saved msi file */
3623 add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
3624
3625 r = package_from_db( hdb, &hpkg );
3626 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3627
3628 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3629 test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, FALSE );
3630
3631 r = MsiDoActionA( hpkg, "CostInitialize");
3632 ok( r == ERROR_SUCCESS, "cost init failed\n");
3633
3636
3637 r = MsiDoActionA( hpkg, "FileCost");
3638 ok( r == ERROR_SUCCESS, "file cost failed\n");
3639
3642
3643 r = MsiDoActionA( hpkg, "CostFinalize");
3644 ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
3645
3659
3683
3684 MsiCloseHandle(hpkg);
3685
3686 /* test source only install */
3687 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3688 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3689 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3690 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3691 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3692 ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
3693
3694 r = MsiInstallProductA(msifile, "ADDSOURCE=one");
3695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3696 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3697 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3698 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3699 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3700
3701 /* no arguments test */
3702 cache_file_name_len = sizeof(msi_cache_file);
3703 r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}",
3704 INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len);
3705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706 r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb);
3707 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3708
3710 add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" );
3711 add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" );
3712 add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" );
3713 add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" );
3714 add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" );
3715 add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" );
3716 add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" );
3717 add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" );
3719 "'VBFeatureRequest', 38, NULL, 'Session.FeatureRequestState(\"three\") = 3'" );
3720
3721 add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" );
3722 add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" );
3723 add_install_execute_sequence_entry( hdb, "'VBFeatureRequest', 'NOT REMOVE', '1001'" );
3724 add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" );
3725 add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" );
3726 add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" );
3727 add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" );
3728 /* Add "one" feature action tests */
3729 add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" );
3730 add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" );
3731 r = MsiDatabaseCommit(hdb);
3732 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3733 r = package_from_db( hdb, &hpkg );
3734 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3735 MsiCloseHandle(hdb);
3736
3737 test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3738 test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE );
3739 r = MsiDoActionA( hpkg, "CostInitialize");
3740 ok( r == ERROR_SUCCESS, "CostInitialize failed\n");
3743
3744 r = MsiDoActionA( hpkg, "FileCost");
3745 ok( r == ERROR_SUCCESS, "FileCost failed\n");
3748
3749 r = MsiDoActionA( hpkg, "CostFinalize");
3750 ok( r == ERROR_SUCCESS, "CostFinalize failed\n");
3776
3777 r = MsiDoActionA( hpkg, "InstallValidate");
3778 ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r);
3781 MsiCloseHandle( hpkg );
3782
3784 ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */,
3785 "Expected ERROR_SUCCESS, got %d\n", r);
3786 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
3787 ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
3788 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
3789 ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state);
3790 state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "three");
3791 ok(state == INSTALLSTATE_LOCAL, "state = %d\n", state);
3792
3793 /* minor upgrade test with no REINSTALL argument */
3794 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3796 size = MAX_PATH;
3797 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3799 ok(!strcmp(value, "1.1.1"), "ProductVersion = %s\n", value);
3800 MsiCloseHandle(hprod);
3801
3802 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3803 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3804 update_ProductVersion_property( hdb, "1.1.2" );
3805 set_summary_str(hdb, PID_REVNUMBER, "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}");
3806 r = MsiDatabaseCommit(hdb);
3807 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3808 MsiCloseHandle(hdb);
3809
3811 ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
3812
3813 r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
3814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3815
3816 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3818 size = MAX_PATH;
3819 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821 ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
3822 MsiCloseHandle(hprod);
3823
3824 /* major upgrade test */
3825 r = MsiOpenDatabaseA(msifile2, (const char*)MSIDBOPEN_DIRECT, &hdb);
3826 ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r);
3827 add_install_execute_sequence_entry( hdb, "'FindRelatedProducts', '', '100'" );
3828 add_install_execute_sequence_entry( hdb, "'RemoveExistingProducts', '', '1401'" );
3829 create_upgrade_table( hdb );
3830 add_upgrade_entry( hdb, "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.3', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'");
3831 update_ProductCode_property( hdb, "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3832 update_ProductVersion_property( hdb, "1.1.3" );
3833 set_summary_str(hdb, PID_REVNUMBER, "{5F99011C-02E6-48BD-8B8D-DE7CFABC7A09}");
3834 r = MsiDatabaseCommit(hdb);
3835 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r);
3836 MsiCloseHandle(hdb);
3837
3839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3840
3841 r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
3842 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3843 r = MsiOpenProductA("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}", &hprod);
3844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3845 size = MAX_PATH;
3846 r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
3847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3848 ok(!strcmp(value, "1.1.3"), "ProductVersion = %s\n", value);
3849 MsiCloseHandle(hprod);
3850
3851 /* uninstall the product */
3852 r = MsiInstallProductA(msifile2, "REMOVE=ALL");
3853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3854
3857 DeleteFileA(msifile3);
3858 DeleteFileA(msifile4);
3859}
3860
3861static void test_removefiles(void)
3862{
3863 MSIHANDLE hpkg;
3864 UINT r;
3865 MSIHANDLE hdb;
3866 INSTALLSTATE installed, action;
3867
3868 hdb = create_package_db();
3869 ok ( hdb, "failed to create package database\n" );
3870
3871 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
3872
3873 create_feature_table( hdb );
3874 add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
3875
3877 add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
3878 add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
3879 add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
3880 add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
3881 add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
3882 add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
3883 add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
3884
3886 add_feature_components_entry( hdb, "'one', 'hydrogen'" );
3887 add_feature_components_entry( hdb, "'one', 'helium'" );
3888 add_feature_components_entry( hdb, "'one', 'lithium'" );
3889 add_feature_components_entry( hdb, "'one', 'beryllium'" );
3890 add_feature_components_entry( hdb, "'one', 'boron'" );
3891 add_feature_components_entry( hdb, "'one', 'carbon'" );
3892 add_feature_components_entry( hdb, "'one', 'oxygen'" );
3893
3894 create_file_table( hdb );
3895 add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
3896 add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
3897 add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
3898 add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
3899 add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
3900 add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
3901 add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
3902
3904
3905 r = package_from_db( hdb, &hpkg );
3907 {
3908 skip("Not enough rights to perform tests\n");
3910 return;
3911 }
3912 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
3913
3914 MsiCloseHandle( hdb );
3915
3916 create_test_file( "hydrogen.txt" );
3917 create_test_file( "helium.txt" );
3918 create_test_file( "lithium.txt" );
3919 create_test_file( "beryllium.txt" );
3920 create_test_file( "boron.txt" );
3921 create_test_file( "carbon.txt" );
3922 create_test_file( "oxygen.txt" );
3923
3924 r = MsiSetPropertyA( hpkg, "TARGETDIR", CURR_DIR );
3925 ok( r == ERROR_SUCCESS, "set property failed\n");
3926
3928
3929 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3930 ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
3931
3932 r = MsiDoActionA( hpkg, "CostInitialize");
3933 ok( r == ERROR_SUCCESS, "cost init failed\n");
3934
3935 r = MsiDoActionA( hpkg, "FileCost");
3936 ok( r == ERROR_SUCCESS, "file cost failed\n");
3937
3938 installed = action = 0xdeadbeef;
3939 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3940 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3941 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3942 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3943
3944 r = MsiDoActionA( hpkg, "CostFinalize");
3945 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
3946
3947 r = MsiDoActionA( hpkg, "InstallValidate");
3948 ok( r == ERROR_SUCCESS, "install validate failed\n");
3949
3950 r = MsiSetComponentStateA( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
3951 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3952
3953 installed = action = 0xdeadbeef;
3954 r = MsiGetComponentStateA( hpkg, "hydrogen", &installed, &action );
3955 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3956 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3957 todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3958
3959 r = MsiSetComponentStateA( hpkg, "helium", INSTALLSTATE_LOCAL );
3960 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3961
3962 r = MsiSetComponentStateA( hpkg, "lithium", INSTALLSTATE_SOURCE );
3963 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3964
3965 r = MsiSetComponentStateA( hpkg, "beryllium", INSTALLSTATE_ABSENT );
3966 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3967
3968 r = MsiSetComponentStateA( hpkg, "boron", INSTALLSTATE_LOCAL );
3969 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3970
3971 r = MsiSetComponentStateA( hpkg, "carbon", INSTALLSTATE_SOURCE );
3972 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3973
3974 installed = action = 0xdeadbeef;
3975 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3976 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3977 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3978 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3979
3980 r = MsiSetComponentStateA( hpkg, "oxygen", INSTALLSTATE_ABSENT );
3981 ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
3982
3983 installed = action = 0xdeadbeef;
3984 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3985 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3986 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3987 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3988
3989 r = MsiDoActionA( hpkg, "RemoveFiles");
3990 ok( r == ERROR_SUCCESS, "remove files failed\n");
3991
3992 installed = action = 0xdeadbeef;
3993 r = MsiGetComponentStateA( hpkg, "oxygen", &installed, &action );
3994 ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
3995 ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
3996 ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
3997
3998 ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
3999 ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");
4000 ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
4001 ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
4002 ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
4003 ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
4004 ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
4005
4006 MsiCloseHandle( hpkg );
4008}
4009
4010static void test_appsearch(void)
4011{
4012 MSIHANDLE hpkg;
4013 UINT r;
4014 MSIHANDLE hdb;
4015 CHAR prop[MAX_PATH];
4016 DWORD size;
4017 HKEY hkey;
4018 const char reg_expand_value[] = "%systemroot%\\system32\\notepad.exe";
4019
4020 hdb = create_package_db();
4021 ok ( hdb, "failed to create package database\n" );
4022
4024 add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
4025 add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
4026 add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" );
4027 add_appsearch_entry( hdb, "'32KEYVAL', 'NewSignature4'" );
4028 add_appsearch_entry( hdb, "'64KEYVAL', 'NewSignature5'" );
4029
4031 add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
4032
4033 r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
4034 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4035 r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1);
4036 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4037 RegCloseKey(hkey);
4038 add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4039
4040 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY,
4041 NULL, &hkey, NULL);
4042 if (r == ERROR_ACCESS_DENIED)
4043 {
4044 skip("insufficient rights\n");
4045 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4046 MsiCloseHandle(hdb);
4048 return;
4049 }
4050 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4051
4052 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4053 sizeof("c:\\windows\\system32\\notepad.exe"));
4054 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4055 RegCloseKey(hkey);
4056 add_reglocator_entry( hdb, "NewSignature4", 2, "Software\\Winetest_msi", "", msidbLocatorTypeFileName );
4057
4058 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY,
4059 NULL, &hkey, NULL);
4060 ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r );
4061 r = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE *)"c:\\windows\\system32\\notepad.exe",
4062 sizeof("c:\\windows\\system32\\notepad.exe"));
4063 ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r);
4064 RegCloseKey(hkey);
4065 add_reglocator_entry( hdb, "NewSignature5", 2, "Software\\Winetest_msi", "",
4067
4069 add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
4070
4072 add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
4073 add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4074 add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4075 add_signature_entry( hdb, "'NewSignature4', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4076 add_signature_entry( hdb, "'NewSignature5', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
4077
4078 r = package_from_db( hdb, &hpkg );
4080 {
4081 skip("Not enough rights to perform tests\n");
4083 return;
4084 }
4085 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
4086 MsiCloseHandle( hdb );
4087 if (r != ERROR_SUCCESS)
4088 goto done;
4089
4091
4092 r = MsiDoActionA( hpkg, "AppSearch" );
4093 ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
4094
4095 size = sizeof(prop);
4096 r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
4097 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4098 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4099
4100 size = sizeof(prop);
4101 r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
4102 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4103
4104 size = sizeof(prop);
4105 r = MsiGetPropertyA( hpkg, "REGEXPANDVAL", prop, &size );
4106 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4107 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4108
4109 size = sizeof(prop);
4110 r = MsiGetPropertyA( hpkg, "32KEYVAL", prop, &size );
4111 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4112 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4113
4114 size = sizeof(prop);
4115 r = MsiGetPropertyA( hpkg, "64KEYVAL", prop, &size );
4116 ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
4117 ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
4118
4119done:
4120 MsiCloseHandle( hpkg );
4122 RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
4123 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY);
4124 delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY);
4125}
4126
4128{
4129 MSIHANDLE hpkg, hdb;
4130 char path[MAX_PATH + 15], expected[MAX_PATH], prop[MAX_PATH];
4131 LPSTR usersid;
4132 DWORD size;
4133 UINT r;
4134
4135 if (!(usersid = get_user_sid()))
4136 return;
4137
4138 if (is_process_limited())
4139 {
4140 skip("process is limited\n");
4141 return;
4142 }
4143
4144 create_test_file("FileName1");
4145 create_test_file("FileName4");
4147 "{A8AE6692-96BA-4198-8399-145D7D1D0D0E}", NULL, FALSE);
4148
4149 create_test_file("FileName2");
4151 "{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}", usersid, FALSE);
4152
4153 create_test_file("FileName3");
4155 "{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}", usersid, FALSE);
4156
4157 create_test_file("FileName5");
4159 "{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}", NULL, TRUE);
4160
4161 create_test_file("FileName6");
4163 "{C0ECD96F-7898-4410-9667-194BD8C1B648}", NULL, TRUE);
4164
4165 create_test_file("FileName7");
4167 "{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}", NULL, FALSE);
4168
4169 /* dir is FALSE, but we're pretending it's a directory */
4171 "{91B7359B-07F2-4221-AA8D-DE102BB87A5F}", NULL, FALSE);
4172
4173 create_file_with_version("FileName8.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4175 "{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}", NULL, FALSE);
4176
4177 create_file_with_version("FileName9.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4179 "{A204DF48-7346-4635-BA2E-66247DBAC9DF}", NULL, FALSE);
4180
4181 create_file_with_version("FileName10.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4183 "{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", NULL, FALSE);
4184
4185 hdb = create_package_db();
4186 ok(hdb, "Expected a valid database handle\n");
4187
4189 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4190 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4191 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4192 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4193 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4194 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4195 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4196 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4197 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4198 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4199 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4200 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4201
4203
4204 /* published component, machine, file, signature, misdbLocatorTypeFile */
4205 add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1");
4206
4207 /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */
4208 add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1");
4209
4210 /* published component, user-managed, file, signature, misdbLocatorTypeFile */
4211 add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1");
4212
4213 /* published component, machine, file, signature, misdbLocatorTypeDirectory */
4214 add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0");
4215
4216 /* published component, machine, dir, signature, misdbLocatorTypeDirectory */
4217 add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0");
4218
4219 /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */
4220 add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0");
4221
4222 /* published component, machine, file, no signature, misdbLocatorTypeFile */
4223 add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1");
4224
4225 /* unpublished component, no signature, misdbLocatorTypeDir */
4226 add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0");
4227
4228 /* published component, no signature, dir does not exist misdbLocatorTypeDir */
4229 add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0");
4230
4231 /* published component, signature w/ ver, misdbLocatorTypeFile */
4232 add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1");
4233
4234 /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */
4235 add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1");
4236
4237 /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */
4238 add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1");
4239
4241 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
4242 add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''");
4243 add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''");
4244 add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''");
4245 add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''");
4246 add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4247 add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4248 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4249
4250 r = package_from_db(hdb, &hpkg);
4252 {
4253 skip("Not enough rights to perform tests\n");
4254 goto error;
4255 }
4256 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4257
4258 r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
4259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4260
4262
4263 r = MsiDoActionA(hpkg, "AppSearch");
4264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4265
4267 if (is_root(CURR_DIR)) expected[2] = 0;
4268
4269 size = MAX_PATH;
4270 sprintf(path, "%s\\FileName1", expected);
4271 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4273 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4274
4275 size = MAX_PATH;
4276 sprintf(path, "%s\\FileName2", expected);
4277 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4279 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4280
4281 size = MAX_PATH;
4282 sprintf(path, "%s\\FileName3", expected);
4283 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4285 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4286
4287 size = MAX_PATH;
4288 sprintf(path, "%s\\FileName4", expected);
4289 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
4290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4291 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4292
4293 size = MAX_PATH;
4294 sprintf(path, "%s\\FileName5", expected);
4295 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4297 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4298
4299 size = MAX_PATH;
4300 sprintf(path, "%s\\", expected);
4301 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4303 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4304
4305 size = MAX_PATH;
4306 sprintf(path, "%s\\", expected);
4307 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4309 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4310
4311 size = MAX_PATH;
4312 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4314 ok(!lstrcmpA(prop, "october"), "Expected \"october\", got \"%s\"\n", prop);
4315
4316 size = MAX_PATH;
4317 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4319 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4320
4321 size = MAX_PATH;
4322 sprintf(path, "%s\\FileName8.dll", expected);
4323 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4325 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4326
4327 size = MAX_PATH;
4328 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4330 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4331
4332 size = MAX_PATH;
4333 sprintf(path, "%s\\FileName10.dll", expected);
4334 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4336 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4337
4338 delete_component_path("{A8AE6692-96BA-4198-8399-145D7D1D0D0E}",
4340 delete_component_path("{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}",
4342 delete_component_path("{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}",
4344 delete_component_path("{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}",
4346 delete_component_path("{C0ECD96F-7898-4410-9667-194BD8C1B648}",
4348 delete_component_path("{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}",
4350 delete_component_path("{91B7359B-07F2-4221-AA8D-DE102BB87A5F}",
4352 delete_component_path("{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}",
4354 delete_component_path("{A204DF48-7346-4635-BA2E-66247DBAC9DF}",
4356 delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
4358
4359 MsiCloseHandle(hpkg);
4360
4361error:
4362 DeleteFileA("FileName1");
4363 DeleteFileA("FileName2");
4364 DeleteFileA("FileName3");
4365 DeleteFileA("FileName4");
4366 DeleteFileA("FileName5");
4367 DeleteFileA("FileName6");
4368 DeleteFileA("FileName7");
4369 DeleteFileA("FileName8.dll");
4370 DeleteFileA("FileName9.dll");
4371 DeleteFileA("FileName10.dll");
4373 LocalFree(usersid);
4374}
4375
4377{
4378 MSIHANDLE hpkg, hdb;
4379 char path[MAX_PATH + 20], expected[MAX_PATH], prop[MAX_PATH];
4380 DWORD binary[2], size, val;
4381 BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
4382 HKEY hklm, classes, hkcu, users;
4383 LPSTR pathdata, pathvar, ptr;
4384 LONG res;
4385 UINT r, type = 0;
4386 SYSTEM_INFO si;
4387
4388 version = TRUE;
4389 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4390 version = FALSE;
4391
4392 DeleteFileA("test.dll");
4393
4394 res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
4395 if (res == ERROR_ACCESS_DENIED)
4396 {
4397 skip("Not enough rights to perform tests\n");
4398 return;
4399 }
4400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4401
4402 res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
4403 (const BYTE *)"regszdata", 10);
4404 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4405
4406 res = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine", &hkcu);
4407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4408
4409 res = RegSetValueExA(hkcu, "Value1", 0, REG_SZ,
4410 (const BYTE *)"regszdata", 10);
4411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4412
4413 users = 0;
4414 res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
4415 ok(res == ERROR_SUCCESS ||
4417 "Expected ERROR_SUCCESS, got %ld\n", res);
4418
4419 if (res == ERROR_SUCCESS)
4420 {
4421 res = RegSetValueExA(users, "Value1", 0, REG_SZ,
4422 (const BYTE *)"regszdata", 10);
4423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4424 }
4425
4426 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine", &hklm);
4427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4428
4429 res = RegSetValueA(hklm, NULL, REG_SZ, "defvalue", 8);
4430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4431
4432 res = RegSetValueExA(hklm, "Value1", 0, REG_SZ,
4433 (const BYTE *)"regszdata", 10);
4434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4435
4436 val = 42;
4437 res = RegSetValueExA(hklm, "Value2", 0, REG_DWORD,
4438 (const BYTE *)&val, sizeof(DWORD));
4439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4440
4441 val = -42;
4442 res = RegSetValueExA(hklm, "Value3", 0, REG_DWORD,
4443 (const BYTE *)&val, sizeof(DWORD));
4444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4445
4446 res = RegSetValueExA(hklm, "Value4", 0, REG_EXPAND_SZ,
4447 (const BYTE *)"%PATH%", 7);
4448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4449
4450 res = RegSetValueExA(hklm, "Value5", 0, REG_EXPAND_SZ,
4451 (const BYTE *)"my%NOVAR%", 10);
4452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4453
4454 res = RegSetValueExA(hklm, "Value6", 0, REG_MULTI_SZ,
4455 (const BYTE *)"one\0two\0", 9);
4456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4457
4458 binary[0] = 0x1234abcd;
4459 binary[1] = 0x567890ef;
4460 res = RegSetValueExA(hklm, "Value7", 0, REG_BINARY,
4461 (const BYTE *)binary, sizeof(binary));
4462 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4463
4464 res = RegSetValueExA(hklm, "Value8", 0, REG_SZ,
4465 (const BYTE *)"#regszdata", 11);
4466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4467
4469 if (is_root(CURR_DIR)) expected[2] = 0;
4470
4471 create_test_file("FileName1");
4472 sprintf(path, "%s\\FileName1", expected);
4473 res = RegSetValueExA(hklm, "Value9", 0, REG_SZ,
4474 (const BYTE *)path, lstrlenA(path) + 1);
4475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4476
4477 sprintf(path, "%s\\FileName2", expected);
4478 res = RegSetValueExA(hklm, "Value10", 0, REG_SZ,
4479 (const BYTE *)path, lstrlenA(path) + 1);
4480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4481
4483 res = RegSetValueExA(hklm, "Value11", 0, REG_SZ,
4484 (const BYTE *)path, lstrlenA(path) + 1);
4485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4486
4487 res = RegSetValueExA(hklm, "Value12", 0, REG_SZ,
4488 (const BYTE *)"", 1);
4489 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4490
4491 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4492 sprintf(path, "%s\\FileName3.dll", expected);
4493 res = RegSetValueExA(hklm, "Value13", 0, REG_SZ,
4494 (const BYTE *)path, lstrlenA(path) + 1);
4495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4496
4497 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4498 sprintf(path, "%s\\FileName4.dll", expected);
4499 res = RegSetValueExA(hklm, "Value14", 0, REG_SZ,
4500 (const BYTE *)path, lstrlenA(path) + 1);
4501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4502
4503 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4504 sprintf(path, "%s\\FileName5.dll", expected);
4505 res = RegSetValueExA(hklm, "Value15", 0, REG_SZ,
4506 (const BYTE *)path, lstrlenA(path) + 1);
4507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4508
4509 sprintf(path, "\"%s\\FileName1\" -option", expected);
4510 res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
4511 (const BYTE *)path, lstrlenA(path) + 1);
4512 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4513
4514 space = strchr(expected, ' ') != NULL;
4515 sprintf(path, "%s\\FileName1 -option", expected);
4516 res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
4517 (const BYTE *)path, lstrlenA(path) + 1);
4518 ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
4519
4520 hdb = create_package_db();
4521 ok(hdb, "Expected a valid database handle\n");
4522
4524 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
4525 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
4526 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
4527 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
4528 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
4529 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
4530 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
4531 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
4532 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
4533 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
4534 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
4535 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
4536 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
4537 add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'");
4538 add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'");
4539 add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'");
4540 add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'");
4541 add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'");
4542 add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'");
4543 add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'");
4544 add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'");
4545 add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'");
4546 add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'");
4547 add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'");
4548 add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'");
4549 add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'");
4550 add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'");
4551 add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'");
4552 add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'");
4553 add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'");
4554
4556
4558 if (is_64bit)
4560
4561 /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
4562 add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
4563
4564 /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
4565 add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
4566
4567 /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
4568 add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
4569
4570 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4571 add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
4572
4573 /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
4574 add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
4575
4576 /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
4577 add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
4578
4579 /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
4580 add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
4581
4582 /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
4583 add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
4584
4586 if (is_64bit)
4588
4589 /* HKLM, msidbLocatorTypeFileName, signature, file exists */
4590 add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
4591
4592 /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
4593 add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
4594
4595 /* HKLM, msidbLocatorTypeFileName, no signature */
4596 add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
4597
4599 if (is_64bit)
4601
4602 /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
4603 add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
4604
4605 /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
4606 add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
4607
4608 /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
4609 add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
4610
4612 if (is_64bit)
4614
4615 /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
4616 add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
4617
4618 /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
4619 add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
4620
4621 /* HKU, msidbLocatorTypeRawValue, REG_SZ */
4622 add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
4623
4624 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
4625 add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
4626
4627 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
4628 add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
4629
4630 /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
4631 add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
4632
4634 if (is_64bit)
4636
4637 /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
4638 add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
4639
4640 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
4641 add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
4642
4643 /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
4644 add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
4645
4646 /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
4647 add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
4648
4649 /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
4650 add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
4651
4653 if (is_64bit)
4655
4656 /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
4657 add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
4658
4659 /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
4660 add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
4661
4662 /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
4663 add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
4664
4666 if (is_64bit)
4668
4669 /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
4670 add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
4671
4672 /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
4673 add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
4674
4676 add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''");
4677 add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''");
4678 add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''");
4679 add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4680 add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4681 add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
4682
4683 if (!is_root(CURR_DIR))
4684 {
4685 ptr = strrchr(expected, '\\') + 1;
4686 sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr);
4688 }
4689 add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''");
4690 add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''");
4691 add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''");
4692
4693 r = package_from_db(hdb, &hpkg);
4694 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
4695
4697
4698 r = MsiDoActionA(hpkg, "AppSearch");
4699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4700
4701 size = MAX_PATH;
4702 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
4703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4704 ok(!lstrcmpA(prop, "regszdata"),
4705 "Expected \"regszdata\", got \"%s\"\n", prop);
4706
4707 size = MAX_PATH;
4708 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4710 ok(!lstrcmpA(prop, "#42"), "Expected \"#42\", got \"%s\"\n", prop);
4711
4712 size = MAX_PATH;
4713 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
4714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4715 ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
4716
4717 memset(&si, 0, sizeof(si));
4719
4720 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
4721 {
4722 size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
4723 pathvar = malloc(size);
4724 ExpandEnvironmentStringsA("%PATH%", pathvar, size);
4725
4726 size = 0;
4727 r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
4728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4729
4730 pathdata = malloc(++size);
4731 r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
4732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4733 ok(!lstrcmpA(pathdata, pathvar),
4734 "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
4735
4736 free(pathvar);
4737 free(pathdata);
4738 }
4739
4740 size = MAX_PATH;
4741 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743 ok(!lstrcmpA(prop,
4744 "my%NOVAR%"), "Expected \"my%%NOVAR%%\", got \"%s\"\n", prop);
4745
4746 size = MAX_PATH;
4747 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
4748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749 todo_wine
4750 {
4751 ok(!memcmp(prop, "\0one\0two\0\0", 10),
4752 "Expected \"\\0one\\0two\\0\\0\"\n");
4753 }
4754
4755 size = MAX_PATH;
4756 lstrcpyA(path, "#xCDAB3412EF907856");
4757 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
4758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4759 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4760
4761 size = MAX_PATH;
4762 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
4763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4764 ok(!lstrcmpA(prop, "##regszdata"),
4765 "Expected \"##regszdata\", got \"%s\"\n", prop);
4766
4767 size = MAX_PATH;
4768 sprintf(path, "%s\\FileName1", expected);
4769 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
4770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4771 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4772
4773 size = MAX_PATH;
4774 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4777
4778 size = MAX_PATH;
4779 sprintf(path, "%s\\", expected);
4780 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
4781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4782 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4783
4784 size = MAX_PATH;
4785 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
4786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4787 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4788
4789 size = MAX_PATH;
4790 sprintf(path, "%s\\", expected);
4791 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
4792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4793 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4794
4795 size = MAX_PATH;
4796 r = MsiGetPropertyA(hpkg, "SIGPROP14", prop, &size);
4797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4798 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4799
4800 size = MAX_PATH;
4801 r = MsiGetPropertyA(hpkg, "SIGPROP15", prop, &size);
4802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4803 ok(!lstrcmpA(prop, "regszdata"),
4804 "Expected \"regszdata\", got \"%s\"\n", prop);
4805
4806 size = MAX_PATH;
4807 r = MsiGetPropertyA(hpkg, "SIGPROP16", prop, &size);
4808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4809 ok(!lstrcmpA(prop, "regszdata"),
4810 "Expected \"regszdata\", got \"%s\"\n", prop);
4811
4812 if (users)
4813 {
4814 size = MAX_PATH;
4815 r = MsiGetPropertyA(hpkg, "SIGPROP17", prop, &size);
4816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4817 ok(!lstrcmpA(prop, "regszdata"),
4818 "Expected \"regszdata\", got \"%s\"\n", prop);
4819 }
4820
4821 size = MAX_PATH;
4822 r = MsiGetPropertyA(hpkg, "SIGPROP18", prop, &size);
4823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4824 ok(!lstrcmpA(prop, "defvalue"),
4825 "Expected \"defvalue\", got \"%s\"\n", prop);
4826
4827 size = MAX_PATH;
4828 r = MsiGetPropertyA(hpkg, "SIGPROP19", prop, &size);
4829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4830 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4831
4832 size = MAX_PATH;
4833 r = MsiGetPropertyA(hpkg, "SIGPROP20", prop, &size);
4834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4835 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4836
4837 if (version)
4838 {
4839 size = MAX_PATH;
4840 sprintf(path, "%s\\FileName3.dll", expected);
4841 r = MsiGetPropertyA(hpkg, "SIGPROP21", prop, &size);
4842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4843 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4844
4845 size = MAX_PATH;
4846 r = MsiGetPropertyA(hpkg, "SIGPROP22", prop, &size);
4847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4848 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4849
4850 size = MAX_PATH;
4851 sprintf(path, "%s\\FileName5.dll", expected);
4852 r = MsiGetPropertyA(hpkg, "SIGPROP23", prop, &size);
4853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4854 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4855 }
4856
4857 if (!is_root(CURR_DIR))
4858 {
4859 size = MAX_PATH;
4861 ptr = strrchr(path, '\\') + 1;
4862 *ptr = '\0';
4863 r = MsiGetPropertyA(hpkg, "SIGPROP24", prop, &size);
4864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4865 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4866 }
4867 size = MAX_PATH;
4868 sprintf(path, "%s\\", expected);
4869 r = MsiGetPropertyA(hpkg, "SIGPROP25", prop, &size);
4870 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4871 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4872
4873 size = MAX_PATH;
4874 r = MsiGetPropertyA(hpkg, "SIGPROP26", prop, &size);
4875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4876 if (is_root(CURR_DIR))
4877 ok(!lstrcmpA(prop, CURR_DIR), "Expected \"%s\", got \"%s\"\n", CURR_DIR, prop);
4878 else
4879 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4880
4881 size = MAX_PATH;
4882 r = MsiGetPropertyA(hpkg, "SIGPROP27", prop, &size);
4883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4884 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4885
4886 size = MAX_PATH;
4887 r = MsiGetPropertyA(hpkg, "SIGPROP28", prop, &size);
4888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4889 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4890
4891 size = MAX_PATH;
4892 sprintf(path, "%s\\FileName1", expected);
4893 r = MsiGetPropertyA(hpkg, "SIGPROP29", prop, &size);
4894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4896
4897 size = MAX_PATH;
4898 sprintf(path, "%s\\FileName1", expected);
4899 r = MsiGetPropertyA(hpkg, "SIGPROP30", prop, &size);
4900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4901 if (space)
4902 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
4903 else
4904 todo_wine ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
4905
4906 RegSetValueA(hklm, NULL, REG_SZ, "", 0);
4907 RegDeleteValueA(hklm, "Value1");
4908 RegDeleteValueA(hklm, "Value2");
4909 RegDeleteValueA(hklm, "Value3");
4910 RegDeleteValueA(hklm, "Value4");
4911 RegDeleteValueA(hklm, "Value5");
4912 RegDeleteValueA(hklm, "Value6");
4913 RegDeleteValueA(hklm, "Value7");
4914 RegDeleteValueA(hklm, "Value8");
4915 RegDeleteValueA(hklm, "Value9");
4916 RegDeleteValueA(hklm, "Value10");
4917 RegDeleteValueA(hklm, "Value11");
4918 RegDeleteValueA(hklm, "Value12");
4919 RegDeleteValueA(hklm, "Value13");
4920 RegDeleteValueA(hklm, "Value14");
4921 RegDeleteValueA(hklm, "Value15");
4922 RegDeleteValueA(hklm, "Value16");
4923 RegDeleteValueA(hklm, "Value17");
4924 RegDeleteKeyA(hklm, "");
4925 RegCloseKey(hklm);
4926
4927 RegDeleteValueA(classes, "Value1");
4928 RegDeleteKeyA(classes, "");
4929 RegCloseKey(classes);
4930
4931 RegDeleteValueA(hkcu, "Value1");
4932 RegDeleteKeyA(hkcu, "");
4933 RegCloseKey(hkcu);
4934
4935 RegDeleteValueA(users, "Value1");
4936 RegDeleteKeyA(users, "");
4937 RegCloseKey(users);
4938
4939 DeleteFileA("FileName1");
4940 DeleteFileA("FileName3.dll");
4941 DeleteFileA("FileName4.dll");
4942 DeleteFileA("FileName5.dll");
4943 MsiCloseHandle(hpkg);
4945}
4946
4948{
4950
4952 lstrcatA(path, "\\");
4953 lstrcatA(path, file);
4954
4956}
4957
4959{
4960 MSIHANDLE hpkg, hdb;
4961 char path[MAX_PATH + 14], expected[MAX_PATH], prop[MAX_PATH];
4962 BOOL version;
4963 LPSTR ptr;
4964 DWORD size;
4965 UINT r;
4966
4967 version = TRUE;
4968 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
4969 version = FALSE;
4970
4971 DeleteFileA("test.dll");
4972
4973 WritePrivateProfileStringA("Section", "Key", "keydata,field2", "IniFile.ini");
4974
4976 if (is_root(CURR_DIR)) expected[2] = 0;
4977
4978 create_test_file("FileName1");
4979 sprintf(path, "%s\\FileName1", expected);
4980 WritePrivateProfileStringA("Section", "Key2", path, "IniFile.ini");
4981
4982 WritePrivateProfileStringA("Section", "Key3", expected, "IniFile.ini");
4983
4984 sprintf(path, "%s\\IDontExist", expected);
4985 WritePrivateProfileStringA("Section", "Key4", path, "IniFile.ini");
4986
4987 create_file_with_version("FileName2.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4988 sprintf(path, "%s\\FileName2.dll", expected);
4989 WritePrivateProfileStringA("Section", "Key5", path, "IniFile.ini");
4990
4991 create_file_with_version("FileName3.dll", MAKELONG(1, 2), MAKELONG(3, 4));
4992 sprintf(path, "%s\\FileName3.dll", expected);
4993 WritePrivateProfileStringA("Section", "Key6", path, "IniFile.ini");
4994
4995 create_file_with_version("FileName4.dll", MAKELONG(2, 1), MAKELONG(4, 3));
4996 sprintf(path, "%s\\FileName4.dll", expected);
4997 WritePrivateProfileStringA("Section", "Key7", path, "IniFile.ini");
4998
4999 hdb = create_package_db();
5000 ok(hdb, "Expected a valid database handle\n");
5001
5003 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5004 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5005 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5006 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5007 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5008 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5009 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5010 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5011 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5012 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5013 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5014 add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'");
5015
5017
5018 /* msidbLocatorTypeRawValue, field 1 */
5019 add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2");
5020
5021 /* msidbLocatorTypeRawValue, field 2 */
5022 add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2");
5023
5024 /* msidbLocatorTypeRawValue, entire field */
5025 add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2");
5026
5027 /* msidbLocatorTypeFile */
5028 add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5029
5030 /* msidbLocatorTypeDirectory, file */
5031 add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0");
5032
5033 /* msidbLocatorTypeDirectory, directory */
5034 add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0");
5035
5036 /* msidbLocatorTypeFile, file, no signature */
5037 add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1");
5038
5039 /* msidbLocatorTypeFile, dir, no signature */
5040 add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1");
5041
5042 /* msidbLocatorTypeFile, file does not exist */
5043 add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1");
5044
5045 /* msidbLocatorTypeFile, signature with version */
5046 add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1");
5047
5048 /* msidbLocatorTypeFile, signature with version, ver > max */
5049 add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1");
5050
5051 /* msidbLocatorTypeFile, signature with version, sig->name ignored */
5052 add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1");
5053
5055 add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''");
5056 add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''");
5057 add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5058 add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5059 add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5060
5061 r = package_from_db(hdb, &hpkg);
5063 {
5064 skip("Not enough rights to perform tests\n");
5065 goto error;
5066 }
5067 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5068
5070
5071 r = MsiDoActionA(hpkg, "AppSearch");
5072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5073
5074 size = MAX_PATH;
5075 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5077 ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
5078
5079 size = MAX_PATH;
5080 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082 ok(!lstrcmpA(prop, "field2"), "Expected \"field2\", got \"%s\"\n", prop);
5083
5084 size = MAX_PATH;
5085 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5087 ok(!lstrcmpA(prop, "keydata,field2"),
5088 "Expected \"keydata,field2\", got \"%s\"\n", prop);
5089
5090 size = MAX_PATH;
5091 sprintf(path, "%s\\FileName1", expected);
5092 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5094 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5095
5096 size = MAX_PATH;
5097 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5099 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5100
5101 size = MAX_PATH;
5102 sprintf(path, "%s\\", expected);
5103 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5105 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5106
5107 size = MAX_PATH;
5108 sprintf(path, "%s\\", expected);
5109 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5111 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5112
5113 if (!is_root(CURR_DIR))
5114 {
5115 size = MAX_PATH;
5117 ptr = strrchr(path, '\\');
5118 *(ptr + 1) = 0;
5119 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5121 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5122 }
5123 size = MAX_PATH;
5124 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5126 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5127
5128 if (version)
5129 {
5130 size = MAX_PATH;
5131 sprintf(path, "%s\\FileName2.dll", expected);
5132 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5134 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5135
5136 size = MAX_PATH;
5137 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5139 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5140
5141 size = MAX_PATH;
5142 sprintf(path, "%s\\FileName4.dll", expected);
5143 r = MsiGetPropertyA(hpkg, "SIGPROP12", prop, &size);
5144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5145 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5146 }
5147
5148 MsiCloseHandle(hpkg);
5149
5150error:
5151 delete_win_ini("IniFile.ini");
5152 DeleteFileA("FileName1");
5153 DeleteFileA("FileName2.dll");
5154 DeleteFileA("FileName3.dll");
5155 DeleteFileA("FileName4.dll");
5157}
5158
5159/*
5160 * MSI AppSearch action on DrLocator table always returns absolute paths.
5161 * If a relative path was set, it returns the first absolute path that
5162 * matches or an empty string if it didn't find anything.
5163 * This helper function replicates this behaviour.
5164 */
5165static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
5166{
5167 int i, size;
5168 DWORD attr, drives;
5169
5170 size = lstrlenA(relative);
5171 drives = GetLogicalDrives();
5172 lstrcpyA(absolute, "A:\\");
5173 for (i = 0; i < 26; absolute[0] = '\0', i++)
5174 {
5175 if (!(drives & (1 << i)))
5176 continue;
5177
5178 absolute[0] = 'A' + i;
5179 if (GetDriveTypeA(absolute) != DRIVE_FIXED)
5180 continue;
5181
5182 lstrcpynA(absolute + 3, relative, size + 1);
5183 attr = GetFileAttributesA(absolute);
5186 {
5187 if (absolute[3 + size - 1] != '\\')
5188 lstrcatA(absolute, "\\");
5189 break;
5190 }
5191 absolute[3] = '\0';
5192 }
5193}
5194
5196{
5197 MSIHANDLE hpkg, hdb;
5198 char path[MAX_PATH + 27], expected[MAX_PATH], prop[MAX_PATH];
5199 BOOL version;
5200 DWORD size;
5201 UINT r;
5202
5203 version = TRUE;
5204 if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
5205 version = FALSE;
5206
5207 DeleteFileA("test.dll");
5208
5209 create_test_file("FileName1");
5210 CreateDirectoryA("one", NULL);
5211 CreateDirectoryA("one\\two", NULL);
5212 CreateDirectoryA("one\\two\\three", NULL);
5213 create_test_file("one\\two\\three\\FileName2");
5214 CreateDirectoryA("another", NULL);
5215 create_file_with_version("FileName3.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5216 create_file_with_version("FileName4.dll", MAKELONG(1, 2), MAKELONG(3, 4));
5217 create_file_with_version("FileName5.dll", MAKELONG(2, 1), MAKELONG(4, 3));
5218
5219 hdb = create_package_db();
5220 ok(hdb, "Expected a valid database handle\n");
5221
5223 add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'");
5224 add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'");
5225 add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'");
5226 add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'");
5227 add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'");
5228 add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'");
5229 add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'");
5230 add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'");
5231 add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'");
5232 add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'");
5233 add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
5234 add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
5235
5237
5239 if (is_root(CURR_DIR)) expected[2] = 0;
5240
5241 /* no parent, full path, depth 0, signature */
5242 sprintf(path, "'NewSignature1', '', '%s', 0", expected);
5244
5245 /* no parent, full path, depth 0, no signature */
5246 sprintf(path, "'NewSignature2', '', '%s', 0", expected);
5248
5249 /* no parent, relative path, depth 0, no signature */
5250 sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3);
5252
5253 /* no parent, full path, depth 2, signature */
5254 sprintf(path, "'NewSignature4', '', '%s', 2", expected);
5256
5257 /* no parent, full path, depth 3, signature */
5258 sprintf(path, "'NewSignature5', '', '%s', 3", expected);
5260
5261 /* no parent, full path, depth 1, signature is dir */
5262 sprintf(path, "'NewSignature6', '', '%s', 1", expected);
5264
5265 /* parent is in DrLocator, relative path, depth 0, signature */
5266 sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1");
5268
5269 /* no parent, full path, depth 0, signature w/ version */
5270 sprintf(path, "'NewSignature8', '', '%s', 0", expected);
5272
5273 /* no parent, full path, depth 0, signature w/ version, ver > max */
5274 sprintf(path, "'NewSignature9', '', '%s', 0", expected);
5276
5277 /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */
5278 sprintf(path, "'NewSignature10', '', '%s', 0", expected);
5280
5281 /* no parent, relative empty path, depth 0, no signature */
5282 sprintf(path, "'NewSignature11', '', '', 0");
5284
5286
5287 /* parent */
5288 add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
5289
5290 /* parent is in RegLocator, no path, depth 0, no signature */
5291 sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
5293
5295 add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''");
5296 add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''");
5297 add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''");
5298 add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''");
5299 add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''");
5300 add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5301 add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5302 add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
5303
5304 r = package_from_db(hdb, &hpkg);
5306 {
5307 skip("Not enough rights to perform tests\n");
5308 goto error;
5309 }
5310 ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
5311
5313
5314 r = MsiDoActionA(hpkg, "AppSearch");
5315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5316
5317 size = MAX_PATH;
5318 sprintf(path, "%s\\FileName1", expected);
5319 r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
5320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5321 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5322
5323 size = MAX_PATH;
5324 sprintf(path, "%s\\", expected);
5325 r = MsiGetPropertyA(hpkg, "SIGPROP2", prop, &size);
5326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5327 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5328
5329 size = MAX_PATH;
5331 r = MsiGetPropertyA(hpkg, "SIGPROP3", prop, &size);
5332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5333 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5334
5335 size = MAX_PATH;
5336 r = MsiGetPropertyA(hpkg, "SIGPROP4", prop, &size);
5337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5338 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5339
5340 size = MAX_PATH;
5341 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5342 r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
5343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5344 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5345
5346 size = MAX_PATH;
5347 r = MsiGetPropertyA(hpkg, "SIGPROP6", prop, &size);
5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5349 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5350
5351 size = MAX_PATH;
5352 sprintf(path, "%s\\one\\two\\three\\FileName2", expected);
5353 r = MsiGetPropertyA(hpkg, "SIGPROP7", prop, &size);
5354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5355 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5356
5357 if (version)
5358 {
5359 size = MAX_PATH;
5360 sprintf(path, "%s\\FileName3.dll", expected);
5361 r = MsiGetPropertyA(hpkg, "SIGPROP8", prop, &size);
5362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5363 ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5364
5365 size = MAX_PATH;
5366 r = MsiGetPropertyA(hpkg, "SIGPROP9", prop, &size);
5367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5368 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5369
5370 size = MAX_PATH;
5371 r = MsiGetPropertyA(hpkg, "SIGPROP10", prop, &size);
5372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5373 ok(!lstrcmpA(prop, ""), "Expected \"\", got \"%s\"\n", prop);
5374 }
5375
5376 size = MAX_PATH;
5378 r = MsiGetPropertyA(hpkg, "SIGPROP11", prop, &size);
5379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5380 ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
5381
5382 size = MAX_PATH;
5383 strcpy(path, "c:\\");
5384 r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
5385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5386 ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
5387
5388 MsiCloseHandle(hpkg);
5389
5390error:
5391 DeleteFileA("FileName1");
5392 DeleteFileA("FileName3.dll");
5393 DeleteFileA("FileName4.dll");
5394 DeleteFileA("FileName5.dll");
5395 DeleteFileA("one\\two\\three\\FileName2");
5396 RemoveDirectoryA("one\\two\\three");
5397 RemoveDirectoryA("one\\two");
5398 RemoveDirectoryA("one");
5399 RemoveDirectoryA("another");
5401}
5402
5403static void test_featureparents(void)
5404{
5405 MSIHANDLE hpkg;
5406 UINT r;
5407 MSIHANDLE hdb;
5408
5409 hdb = create_package_db();
5410 ok ( hdb, "failed to create package database\n" );
5411
5412 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
5413
5414 create_feature_table( hdb );
5417 create_file_table( hdb );
5418
5419 /* msidbFeatureAttributesFavorLocal */
5420 add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
5421
5422 /* msidbFeatureAttributesFavorSource */
5423 add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
5424
5425 /* msidbFeatureAttributesFavorLocal */
5426 add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
5427
5428 /* msidbFeatureAttributesUIDisallowAbsent */
5429 add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
5430
5431 /* disabled because of install level */
5432 add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
5433
5434 /* child feature of disabled feature */
5435 add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
5436
5437 /* component of disabled feature (install level) */
5438 add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" );
5439
5440 /* component of disabled child feature (install level) */
5441 add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" );
5442
5443 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5444 add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
5445
5446 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5447 add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
5448
5449 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5450 add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
5451
5452 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
5453 add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
5454
5455 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
5456 add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
5457
5458 /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
5459 add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
5460
5461 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
5462 add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
5463
5464 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
5465 add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
5466
5467 /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
5468 add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
5469
5470 add_feature_components_entry( hdb, "'zodiac', 'leo'" );
5471 add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
5472 add_feature_components_entry( hdb, "'zodiac', 'libra'" );
5473 add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
5474 add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
5475 add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
5476 add_feature_components_entry( hdb, "'orion', 'leo'" );
5477 add_feature_components_entry( hdb, "'orion', 'virgo'" );
5478 add_feature_components_entry( hdb, "'orion', 'libra'" );
5479 add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
5480 add_feature_components_entry( hdb, "'orion', 'cepheus'" );
5481 add_feature_components_entry( hdb, "'orion', 'andromeda'" );
5482 add_feature_components_entry( hdb, "'orion', 'canis'" );
5483 add_feature_components_entry( hdb, "'orion', 'monoceros'" );
5484 add_feature_components_entry( hdb, "'orion', 'lepus'" );
5485 add_feature_components_entry( hdb, "'waters', 'delphinus'" );
5486 add_feature_components_entry( hdb, "'bayer', 'hydrus'" );
5487
5488 add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
5489 add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
5490 add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
5491 add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
5492 add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
5493 add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
5494 add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
5495 add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
5496 add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
5497 add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" );
5498 add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
5499
5500 r = package_from_db( hdb, &hpkg );
5502 {
5503 skip("Not enough rights to perform tests\n");
5505 return;
5506 }
5507 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5508
5509 MsiCloseHandle( hdb );
5510
5512
5513 r = MsiDoActionA( hpkg, "CostInitialize");
5514 ok( r == ERROR_SUCCESS, "cost init failed\n");
5515
5516 r = MsiDoActionA( hpkg, "FileCost");
5517 ok( r == ERROR_SUCCESS, "file cost failed\n");
5518
5519 r = MsiDoActionA( hpkg, "CostFinalize");
5520 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
5521
5528
5540
5541 r = MsiSetFeatureStateA(hpkg, "orion", INSTALLSTATE_ABSENT);
5542 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5543
5544 r = MsiSetFeatureStateA(hpkg, "lyra", INSTALLSTATE_ABSENT);
5545 ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
5546
5547 r = MsiSetFeatureStateA(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
5548 ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
5549
5556
5568
5569 MsiCloseHandle(hpkg);
5571}
5572
5573static void test_installprops(void)
5574{
5575 MSIHANDLE hpkg, hdb;
5577 DWORD size, type;
5578 LANGID langid;
5579 HKEY hkey1, hkey2, pathkey;
5580 int res;
5581 UINT r;
5583 SYSTEM_INFO si;
5584 INSTALLUILEVEL uilevel;
5585
5586 if (is_wow64)
5588
5590 if (!is_root(CURR_DIR)) lstrcatA(path, "\\");
5592
5594
5595 hdb = create_package_db();
5596 ok( hdb, "failed to create database\n");
5597
5598 r = package_from_db(hdb, &hpkg);
5600 {
5601 skip("Not enough rights to perform tests\n");
5602 MsiSetInternalUI(uilevel, NULL);
5604 return;
5605 }
5606 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5607
5608 MsiCloseHandle(hdb);
5609
5610 buf[0] = 0;
5611 size = MAX_PATH;
5612 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5613 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5614 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5615
5617
5618 buf[0] = 0;
5619 size = MAX_PATH;
5620 r = MsiGetPropertyA(hpkg, "UILevel", buf, &size);
5621 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5622 ok( !lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5623
5624 buf[0] = 0;
5625 size = MAX_PATH;
5626 r = MsiGetPropertyA(hpkg, "DATABASE", buf, &size);
5627 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5628 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5629
5630 RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
5631 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
5632 RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
5633 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
5634
5635 size = MAX_PATH;
5636 type = REG_SZ;
5637 *path = '\0';
5638 if (RegQueryValueExA(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5639 {
5640 size = MAX_PATH;
5641 type = REG_SZ;
5642 RegQueryValueExA(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
5643 }
5644
5645 buf[0] = 0;
5646 size = MAX_PATH;
5647 r = MsiGetPropertyA(hpkg, "USERNAME", buf, &size);
5648 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5649 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5650
5651 size = MAX_PATH;
5652 type = REG_SZ;
5653 *path = '\0';
5654 if (RegQueryValueExA(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
5655 {
5656 size = MAX_PATH;
5657 type = REG_SZ;
5658 RegQueryValueExA(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
5659 }
5660
5661 if (*path)
5662 {
5663 buf[0] = 0;
5664 size = MAX_PATH;
5665 r = MsiGetPropertyA(hpkg, "COMPANYNAME", buf, &size);
5666 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5667 ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
5668 }
5669
5670 buf[0] = 0;
5671 size = MAX_PATH;
5672 r = MsiGetPropertyA(hpkg, "VersionDatabase", buf, &size);
5673 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5674 trace("VersionDatabase = %s\n", buf);
5675
5676 buf[0] = 0;
5677 size = MAX_PATH;
5678 r = MsiGetPropertyA(hpkg, "VersionMsi", buf, &size);
5679 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5680 trace("VersionMsi = %s\n", buf);
5681
5682 buf[0] = 0;
5683 size = MAX_PATH;
5684 r = MsiGetPropertyA(hpkg, "Date", buf, &size);
5685 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5686 trace("Date = %s\n", buf);
5687
5688 buf[0] = 0;
5689 size = MAX_PATH;
5690 r = MsiGetPropertyA(hpkg, "Time", buf, &size);
5691 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5692 trace("Time = %s\n", buf);
5693
5694 buf[0] = 0;
5695 size = MAX_PATH;
5696 r = MsiGetPropertyA(hpkg, "PackageCode", buf, &size);
5697 ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
5698 trace("PackageCode = %s\n", buf);
5699
5700 buf[0] = 0;
5701 size = MAX_PATH;
5702 r = MsiGetPropertyA(hpkg, "ComputerName", buf, &size);
5703 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5704 trace("ComputerName = %s\n", buf);
5705
5707 sprintf(path, "%d", langid);
5708
5709 buf[0] = 0;
5710 size = MAX_PATH;
5711 r = MsiGetPropertyA(hpkg, "UserLanguageID", buf, &size);
5712 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5713 ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
5714
5716 buf[0] = 0;
5717 size = MAX_PATH;
5718 r = MsiGetPropertyA(hpkg, "ScreenX", buf, &size);
5719 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5720 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5721
5723 buf[0] = 0;
5724 size = MAX_PATH;
5725 r = MsiGetPropertyA(hpkg, "ScreenY", buf, &size);
5726 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
5727 ok(atol(buf) == res, "Expected %d, got %s\n", res, buf);
5728
5729 buf[0] = 0;
5730 size = MAX_PATH;
5731 r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size);
5732 if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf );
5733
5735
5736 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5737 check_prop(hpkg, "VersionNT", buf, 1);
5738
5739 if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
5740 {
5741 sprintf(buf, "%d", si.wProcessorLevel);
5742 check_prop(hpkg, "Intel", buf, 1);
5743 check_prop(hpkg, "MsiAMD64", buf, 1);
5744 check_prop(hpkg, "Msix64", buf, 1);
5745 sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
5746 check_prop(hpkg, "VersionNT64", buf, 1);
5747
5749 strcat(path, "\\");
5750 check_prop(hpkg, "System64Folder", path, 0);
5751
5753 strcat(path, "\\");
5754 check_prop(hpkg, "SystemFolder", path, 0);
5755
5756 size = MAX_PATH;
5757 r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5758 strcat(path, "\\");
5759 check_prop(hpkg, "ProgramFilesFolder", path, 0);
5760
5761 size = MAX_PATH;
5762 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5763 strcat(path, "\\");
5764 check_prop(hpkg, "ProgramFiles64Folder", path, 0);
5765
5766 size = MAX_PATH;
5767 RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
5768 strcat(path, "\\");
5769 check_prop(hpkg, "CommonFilesFolder", path, 0);
5770
5771 size = MAX_PATH;
5772 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5773 strcat(path, "\\");
5774 check_prop(hpkg, "CommonFiles64Folder", path, 0);
5775 }
5776 else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
5777 {
5778 sprintf(buf, "%d", si.wProcessorLevel);
5779 check_prop(hpkg, "Intel", buf, 1);
5780
5782 strcat(path, "\\");
5783 check_prop(hpkg, "SystemFolder", path, 0);
5784
5785 size = MAX_PATH;
5786 RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
5787 strcat(path, "\\");
5788 check_prop(hpkg, "ProgramFilesFolder", path, 0);
5789
5790 size = MAX_PATH;
5791 RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
5792 strcat(path, "\\");
5793 check_prop(hpkg, "CommonFilesFolder", path, 0);
5794
5795 check_prop(hpkg, "MsiAMD64", "", 1);
5796 check_prop(hpkg, "Msix64", "", 1);
5797 check_prop(hpkg, "VersionNT64", "", 1);
5798 check_prop(hpkg, "System64Folder", "", 0);
5799 check_prop(hpkg, "ProgramFiles64Dir", "", 0);
5800 check_prop(hpkg, "CommonFiles64Dir", "", 0);
5801 }
5802
5803 CloseHandle(hkey1);
5804 CloseHandle(hkey2);
5805 RegCloseKey(pathkey);
5806 MsiCloseHandle(hpkg);
5808 MsiSetInternalUI(uilevel, NULL);
5809}
5810
5811static void test_launchconditions(void)
5812{
5813 MSIHANDLE hpkg;
5814 MSIHANDLE hdb;
5815 UINT r;
5816
5818
5819 hdb = create_package_db();
5820 ok( hdb, "failed to create package database\n" );
5821
5823
5824 add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" );
5825
5826 /* invalid condition */
5827 add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
5828
5829 r = package_from_db( hdb, &hpkg );
5831 {
5832 skip("Not enough rights to perform tests\n");
5834 return;
5835 }
5836 ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
5837
5838 MsiCloseHandle( hdb );
5839
5840 r = MsiSetPropertyA( hpkg, "X", "1" );
5841 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5842
5844
5845 /* invalid conditions are ignored */
5846 r = MsiDoActionA( hpkg, "LaunchConditions" );
5847 ok( r == ERROR_SUCCESS, "cost init failed\n" );
5848
5849 /* verify LaunchConditions still does some verification */
5850 r = MsiSetPropertyA( hpkg, "X", "2" );
5851 ok( r == ERROR_SUCCESS, "failed to set property\n" );
5852
5853 r = MsiDoActionA( hpkg, "LaunchConditions" );
5854 ok( r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r );
5855
5856 MsiCloseHandle( hpkg );
5858}
5859
5860static void test_ccpsearch(void)
5861{
5862 MSIHANDLE hdb, hpkg;
5863 CHAR prop[MAX_PATH];
5865 UINT r;
5866
5867 hdb = create_package_db();
5868 ok(hdb, "failed to create package database\n");
5869
5871 add_ccpsearch_entry(hdb, "'CCP_random'");
5872 add_ccpsearch_entry(hdb, "'RMCCP_random'");
5873
5875 add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
5876
5878 add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'");
5879
5881
5882 r = package_from_db(hdb, &hpkg);
5884 {
5885 skip("Not enough rights to perform tests\n");
5887 return;
5888 }
5889 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5890
5891 MsiCloseHandle(hdb);
5892
5894
5895 r = MsiDoActionA(hpkg, "CCPSearch");
5896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5897
5898 r = MsiGetPropertyA(hpkg, "CCP_Success", prop, &size);
5899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5900 ok(!lstrcmpA(prop, "1"), "Expected 1, got %s\n", prop);
5901
5902 MsiCloseHandle(hpkg);
5904}
5905
5906static void test_complocator(void)
5907{
5908 MSIHANDLE hdb, hpkg;
5909 UINT r;
5910 CHAR prop[MAX_PATH];
5913
5914 hdb = create_package_db();
5915 ok(hdb, "failed to create package database\n");
5916
5918 add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'");
5919 add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'");
5920 add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'");
5921 add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'");
5922 add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'");
5923 add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'");
5924 add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'");
5925 add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'");
5926 add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'");
5927 add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'");
5928 add_appsearch_entry(hdb, "'KAKURU', 'kakuru'");
5929 add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'");
5930 add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'");
5931 add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'");
5932 add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'");
5933 add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'");
5934
5936 add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1");
5937 add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0");
5938 add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1");
5939 add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0");
5940 add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1");
5941 add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0");
5942 add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1");
5943 add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0");
5944 add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1");
5945 add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0");
5946 add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1");
5947 add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0");
5948 add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1");
5949 add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0");
5950 add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1");
5951 add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0");
5952
5954 add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''");
5955 add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''");
5956 add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''");
5957 add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''");
5958 add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''");
5959 add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''");
5960 add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''");
5961 add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
5962
5963 r = package_from_db(hdb, &hpkg);
5965 {
5966 skip("Not enough rights to perform tests\n");
5968 return;
5969 }
5970 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
5971
5972 MsiCloseHandle(hdb);
5973
5974 create_test_file("abelisaurus");
5975 create_test_file("bactrosaurus");
5976 create_test_file("camelotia");
5977 create_test_file("diclonius");
5978 create_test_file("echinodon");
5979 create_test_file("falcarius");
5980 create_test_file("gallimimus");
5981 create_test_file("hagryphus");
5982 CreateDirectoryA("iguanodon", NULL);
5983 CreateDirectoryA("jobaria", NULL);
5984 CreateDirectoryA("kakuru", NULL);
5985 CreateDirectoryA("labocania", NULL);
5986 CreateDirectoryA("megaraptor", NULL);
5987 CreateDirectoryA("neosodon", NULL);
5988 CreateDirectoryA("olorotitan", NULL);
5989 CreateDirectoryA("pantydraco", NULL);
5990
5992 "{E3619EED-305A-418C-B9C7-F7D7377F0934}", NULL, FALSE);
5994 "{D56B688D-542F-42Ef-90FD-B6DA76EE8119}", NULL, FALSE);
5996 "{A19E16C5-C75D-4699-8111-C4338C40C3CB}", NULL, FALSE);
5998 "{17762FA1-A7AE-4CC6-8827-62873C35361D}", NULL, FALSE);
6000 "{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}", NULL, FALSE);
6002 "{243C22B1-8C51-4151-B9D1-1AE5265E079E}", NULL, FALSE);
6004 "{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}", NULL, FALSE);
6006 "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
6007
6009
6010 r = MsiDoActionA(hpkg, "AppSearch");
6011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6012
6013 size = MAX_PATH;
6014 r = MsiGetPropertyA(hpkg, "ABELISAURUS", prop, &size);
6015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6016
6018 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6019 lstrcatA(expected, "abelisaurus");
6020 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6021 "Expected %s or empty string, got %s\n", expected, prop);
6022
6023 size = MAX_PATH;
6024 r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
6025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6026 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6027
6028 size = MAX_PATH;
6029 r = MsiGetPropertyA(hpkg, "CAMELOTIA", prop, &size);
6030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6031 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6032
6033 size = MAX_PATH;
6034 r = MsiGetPropertyA(hpkg, "DICLONIUS", prop, &size);
6035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6036 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6037
6038 size = MAX_PATH;
6039 r = MsiGetPropertyA(hpkg, "ECHINODON", prop, &size);
6040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6041
6043 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6044 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6045 "Expected %s or empty string, got %s\n", expected, prop);
6046
6047 size = MAX_PATH;
6048 r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
6049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6050 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6051
6052 size = MAX_PATH;
6053 r = MsiGetPropertyA(hpkg, "GALLIMIMUS", prop, &size);
6054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6055 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6056
6057 size = MAX_PATH;
6058 r = MsiGetPropertyA(hpkg, "HAGRYPHUS", prop, &size);
6059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6060 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6061
6062 size = MAX_PATH;
6063 r = MsiGetPropertyA(hpkg, "IGUANODON", prop, &size);
6064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6065 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6066
6067 size = MAX_PATH;
6068 r = MsiGetPropertyA(hpkg, "JOBARIA", prop, &size);
6069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6070 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6071
6072 size = MAX_PATH;
6073 r = MsiGetPropertyA(hpkg, "KAKURU", prop, &size);
6074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6075 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6076
6077 size = MAX_PATH;
6078 r = MsiGetPropertyA(hpkg, "LABOCANIA", prop, &size);
6079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6080 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6081
6082 size = MAX_PATH;
6083 r = MsiGetPropertyA(hpkg, "MEGARAPTOR", prop, &size);
6084 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6085
6087 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6088 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6089 "Expected %s or empty string, got %s\n", expected, prop);
6090
6091 size = MAX_PATH;
6092 r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
6093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6094
6096 if (!is_root(CURR_DIR)) lstrcatA(expected, "\\");
6097 lstrcatA(expected, "neosodon\\");
6098 ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
6099 "Expected %s or empty string, got %s\n", expected, prop);
6100
6101 size = MAX_PATH;
6102 r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
6103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6104 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6105
6106 size = MAX_PATH;
6107 r = MsiGetPropertyA(hpkg, "PANTYDRACO", prop, &size);
6108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6109 ok(!lstrcmpA(prop, ""), "Expected , got %s\n", prop);
6110
6111 MsiCloseHandle(hpkg);
6112 DeleteFileA("abelisaurus");
6113 DeleteFileA("bactrosaurus");
6114 DeleteFileA("camelotia");
6115 DeleteFileA("diclonius");
6116 DeleteFileA("echinodon");
6117 DeleteFileA("falcarius");
6118 DeleteFileA("gallimimus");
6119 DeleteFileA("hagryphus");
6120 RemoveDirectoryA("iguanodon");
6121 RemoveDirectoryA("jobaria");
6122 RemoveDirectoryA("kakuru");
6123 RemoveDirectoryA("labocania");
6124 RemoveDirectoryA("megaraptor");
6125 RemoveDirectoryA("neosodon");
6126 RemoveDirectoryA("olorotitan");
6127 RemoveDirectoryA("pantydraco");
6128 delete_component_path("{E3619EED-305A-418C-B9C7-F7D7377F0934}",
6130 delete_component_path("{D56B688D-542F-42Ef-90FD-B6DA76EE8119}",
6132 delete_component_path("{A19E16C5-C75D-4699-8111-C4338C40C3CB}",
6134 delete_component_path("{17762FA1-A7AE-4CC6-8827-62873C35361D}",
6136 delete_component_path("{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}",
6138 delete_component_path("{243C22B1-8C51-4151-B9D1-1AE5265E079E}",
6140 delete_component_path("{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}",
6142 delete_component_path("{0B499649-197A-48EF-93D2-AF1C17ED6E90}",
6145}
6146
6148{
6149 MSIHANDLE summary;
6150 UINT r;
6151
6152 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6154
6155 r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL);
6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6157
6158 r = MsiSummaryInfoPersist(summary);
6159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6160
6161 MsiCloseHandle(summary);
6162}
6163
6164static void test_MsiGetSourcePath(void)
6165{
6166 MSIHANDLE hdb, hpkg;
6168 CHAR cwd[MAX_PATH];
6169 CHAR subsrc[MAX_PATH];
6170 CHAR sub2[MAX_PATH];
6171 DWORD size;
6172 UINT r;
6173
6174 lstrcpyA(cwd, CURR_DIR);
6175 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6176
6177 lstrcpyA(subsrc, cwd);
6178 lstrcatA(subsrc, "subsource");
6179 lstrcatA(subsrc, "\\");
6180
6181 lstrcpyA(sub2, subsrc);
6182 lstrcatA(sub2, "sub2");
6183 lstrcatA(sub2, "\\");
6184
6185 /* uncompressed source */
6186
6187 hdb = create_package_db();
6188 ok( hdb, "failed to create database\n");
6189
6191
6192 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6193 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'");
6194 add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'");
6195
6196 r = MsiDatabaseCommit(hdb);
6197 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6198
6199 r = package_from_db(hdb, &hpkg);
6201 {
6202 skip("Not enough rights to perform tests\n");
6204 return;
6205 }
6206 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6207
6208 MsiCloseHandle(hdb);
6209
6210 /* invalid database handle */
6211 size = MAX_PATH;
6212 lstrcpyA(path, "kiwi");
6213 r = MsiGetSourcePathA(-1, "TARGETDIR", path, &size);
6215 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
6216 ok(!lstrcmpA(path, "kiwi"),
6217 "Expected path to be unchanged, got \"%s\"\n", path);
6218 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6219
6220 /* NULL szFolder */
6221 size = MAX_PATH;
6222 lstrcpyA(path, "kiwi");
6223 r = MsiGetSourcePathA(hpkg, NULL, path, &size);
6225 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6226 ok(!lstrcmpA(path, "kiwi"),
6227 "Expected path to be unchanged, got \"%s\"\n", path);
6228 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6229
6230 /* empty szFolder */
6231 size = MAX_PATH;
6232 lstrcpyA(path, "kiwi");
6233 r = MsiGetSourcePathA(hpkg, "", path, &size);
6234 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6235 ok(!lstrcmpA(path, "kiwi"),
6236 "Expected path to be unchanged, got \"%s\"\n", path);
6237 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6238
6239 /* try TARGETDIR */
6240 size = MAX_PATH;
6241 lstrcpyA(path, "kiwi");
6242 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6243 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6244 ok(!lstrcmpA(path, "kiwi"),
6245 "Expected path to be unchanged, got \"%s\"\n", path);
6246 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6247
6248 size = MAX_PATH;
6249 lstrcpyA(path, "kiwi");
6250 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6252 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6253 ok(size == 0, "Expected 0, got %lu\n", size);
6254
6255 size = MAX_PATH;
6256 lstrcpyA(path, "kiwi");
6257 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6259 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6260 ok(size == 0, "Expected 0, got %lu\n", size);
6261
6262 /* try SourceDir */
6263 size = MAX_PATH;
6264 lstrcpyA(path, "kiwi");
6265 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6266 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6267 ok(!lstrcmpA(path, "kiwi"),
6268 "Expected path to be unchanged, got \"%s\"\n", path);
6269 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6270
6271 /* try SOURCEDIR */
6272 size = MAX_PATH;
6273 lstrcpyA(path, "kiwi");
6274 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6275 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6276 ok(!lstrcmpA(path, "kiwi"),
6277 "Expected path to be unchanged, got \"%s\"\n", path);
6278 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6279
6280 /* source path does not exist, but the property exists */
6281 size = MAX_PATH;
6282 lstrcpyA(path, "kiwi");
6283 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6285 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6286 ok(size == 0, "Expected 0, got %lu\n", size);
6287
6288 size = MAX_PATH;
6289 lstrcpyA(path, "kiwi");
6290 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6292 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6293 ok(size == 0, "Expected 0, got %lu\n", size);
6294
6295 /* try SubDir */
6296 size = MAX_PATH;
6297 lstrcpyA(path, "kiwi");
6298 r = MsiGetSourcePathA(hpkg, "SubDir", 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 /* try SubDir2 */
6305 size = MAX_PATH;
6306 lstrcpyA(path, "kiwi");
6307 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6308 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6309 ok(!lstrcmpA(path, "kiwi"),
6310 "Expected path to be unchanged, got \"%s\"\n", path);
6311 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6312
6314
6315 r = MsiDoActionA(hpkg, "CostInitialize");
6316 ok(r == ERROR_SUCCESS, "cost init failed\n");
6317
6318 /* try TARGETDIR after CostInitialize */
6319 size = MAX_PATH;
6320 lstrcpyA(path, "kiwi");
6321 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6323 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6324 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6325
6326 /* try SourceDir after CostInitialize */
6327 size = MAX_PATH;
6328 lstrcpyA(path, "kiwi");
6329 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6331 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6332 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6333
6334 /* try SOURCEDIR after CostInitialize */
6335 size = MAX_PATH;
6336 lstrcpyA(path, "kiwi");
6337 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6338 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6339 ok(!lstrcmpA(path, "kiwi"),
6340 "Expected path to be unchanged, got \"%s\"\n", path);
6341 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6342
6343 /* source path does not exist, but the property exists */
6344 size = MAX_PATH;
6345 lstrcpyA(path, "kiwi");
6346 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6348 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6349 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6350
6351 size = MAX_PATH;
6352 lstrcpyA(path, "kiwi");
6353 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6355 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6356 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6357
6358 /* try SubDir after CostInitialize */
6359 size = MAX_PATH;
6360 lstrcpyA(path, "kiwi");
6361 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6363 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6364 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6365
6366 /* try SubDir2 after CostInitialize */
6367 size = MAX_PATH;
6368 lstrcpyA(path, "kiwi");
6369 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6371 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6372 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6373
6374 r = MsiDoActionA(hpkg, "ResolveSource");
6375 ok(r == ERROR_SUCCESS, "file cost failed\n");
6376
6377 /* try TARGETDIR after ResolveSource */
6378 size = MAX_PATH;
6379 lstrcpyA(path, "kiwi");
6380 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6383 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6384
6385 /* try SourceDir after ResolveSource */
6386 size = MAX_PATH;
6387 lstrcpyA(path, "kiwi");
6388 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6390 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6391 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6392
6393 /* try SOURCEDIR after ResolveSource */
6394 size = MAX_PATH;
6395 lstrcpyA(path, "kiwi");
6396 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6397 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6398 ok(!lstrcmpA(path, "kiwi"),
6399 "Expected path to be unchanged, got \"%s\"\n", path);
6400 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6401
6402 /* source path does not exist, but the property exists */
6403 size = MAX_PATH;
6404 lstrcpyA(path, "kiwi");
6405 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6407 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6408 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6409
6410 size = MAX_PATH;
6411 lstrcpyA(path, "kiwi");
6412 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6414 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6415 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6416
6417 /* try SubDir after ResolveSource */
6418 size = MAX_PATH;
6419 lstrcpyA(path, "kiwi");
6420 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6422 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6423 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6424
6425 /* try SubDir2 after ResolveSource */
6426 size = MAX_PATH;
6427 lstrcpyA(path, "kiwi");
6428 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6430 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6431 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6432
6433 r = MsiDoActionA(hpkg, "FileCost");
6434 ok(r == ERROR_SUCCESS, "file cost failed\n");
6435
6436 /* try TARGETDIR after FileCost */
6437 size = MAX_PATH;
6438 lstrcpyA(path, "kiwi");
6439 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6441 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6442 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6443
6444 /* try SourceDir after FileCost */
6445 size = MAX_PATH;
6446 lstrcpyA(path, "kiwi");
6447 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6449 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6450 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6451
6452 /* try SOURCEDIR after FileCost */
6453 size = MAX_PATH;
6454 lstrcpyA(path, "kiwi");
6455 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6456 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6457 ok(!lstrcmpA(path, "kiwi"),
6458 "Expected path to be unchanged, got \"%s\"\n", path);
6459 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6460
6461 /* source path does not exist, but the property exists */
6462 size = MAX_PATH;
6463 lstrcpyA(path, "kiwi");
6464 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6466 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6467 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6468
6469 size = MAX_PATH;
6470 lstrcpyA(path, "kiwi");
6471 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6473 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6474 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6475
6476 /* try SubDir after FileCost */
6477 size = MAX_PATH;
6478 lstrcpyA(path, "kiwi");
6479 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6481 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6482 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6483
6484 /* try SubDir2 after FileCost */
6485 size = MAX_PATH;
6486 lstrcpyA(path, "kiwi");
6487 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6489 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6490 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6491
6492 r = MsiDoActionA(hpkg, "CostFinalize");
6493 ok(r == ERROR_SUCCESS, "file cost failed\n");
6494
6495 /* try TARGETDIR after CostFinalize */
6496 size = MAX_PATH;
6497 lstrcpyA(path, "kiwi");
6498 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6500 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6501 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6502
6503 /* try SourceDir after CostFinalize */
6504 size = MAX_PATH;
6505 lstrcpyA(path, "kiwi");
6506 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6508 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6509 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6510
6511 /* try SOURCEDIR after CostFinalize */
6512 size = MAX_PATH;
6513 lstrcpyA(path, "kiwi");
6514 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6515 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6516 ok(!lstrcmpA(path, "kiwi"),
6517 "Expected path to be unchanged, got \"%s\"\n", path);
6518 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6519
6520 /* source path does not exist, but the property exists */
6521 size = MAX_PATH;
6522 lstrcpyA(path, "kiwi");
6523 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6525 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6526 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6527
6528 size = MAX_PATH;
6529 lstrcpyA(path, "kiwi");
6530 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6532 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6533 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6534
6535 /* try SubDir after CostFinalize */
6536 size = MAX_PATH;
6537 lstrcpyA(path, "kiwi");
6538 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6540 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
6541 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
6542
6543 /* try SubDir2 after CostFinalize */
6544 size = MAX_PATH;
6545 lstrcpyA(path, "kiwi");
6546 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6548 ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path);
6549 ok(size == lstrlenA(sub2), "Expected %d, got %lu\n", lstrlenA(sub2), size);
6550
6551 /* nonexistent directory */
6552 size = MAX_PATH;
6553 lstrcpyA(path, "kiwi");
6554 r = MsiGetSourcePathA(hpkg, "IDontExist", path, &size);
6555 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6556 ok(!lstrcmpA(path, "kiwi"),
6557 "Expected path to be unchanged, got \"%s\"\n", path);
6558 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6559
6560 /* NULL szPathBuf */
6561 size = MAX_PATH;
6562 r = MsiGetSourcePathA(hpkg, "SourceDir", NULL, &size);
6563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6564 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6565
6566 /* NULL pcchPathBuf */
6567 lstrcpyA(path, "kiwi");
6568 r = MsiGetSourcePathA(hpkg, "SourceDir", path, NULL);
6570 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6571 ok(!lstrcmpA(path, "kiwi"),
6572 "Expected path to be unchanged, got \"%s\"\n", path);
6573
6574 /* pcchPathBuf is 0 */
6575 size = 0;
6576 lstrcpyA(path, "kiwi");
6577 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6578 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6579 ok(!lstrcmpA(path, "kiwi"),
6580 "Expected path to be unchanged, got \"%s\"\n", path);
6581 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6582
6583 /* pcchPathBuf does not have room for NULL terminator */
6584 size = lstrlenA(cwd);
6585 lstrcpyA(path, "kiwi");
6586 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6587 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
6588 ok(!strncmp(path, cwd, lstrlenA(cwd) - 1),
6589 "Expected path with no backslash, got \"%s\"\n", path);
6590 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6591
6592 /* pcchPathBuf has room for NULL terminator */
6593 size = lstrlenA(cwd) + 1;
6594 lstrcpyA(path, "kiwi");
6595 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6597 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6598 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6599
6600 /* remove property */
6601 r = MsiSetPropertyA(hpkg, "SourceDir", NULL);
6602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6603
6604 /* try SourceDir again */
6605 size = MAX_PATH;
6606 lstrcpyA(path, "kiwi");
6607 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6609 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6610 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6611
6612 /* set property to a valid directory */
6613 r = MsiSetPropertyA(hpkg, "SOURCEDIR", cwd);
6614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6615
6616 /* try SOURCEDIR again */
6617 size = MAX_PATH;
6618 lstrcpyA(path, "kiwi");
6619 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6620 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6621 ok(!lstrcmpA(path, "kiwi"),
6622 "Expected path to be unchanged, got \"%s\"\n", path);
6623 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6624
6625 MsiCloseHandle(hpkg);
6626
6627 /* compressed source */
6628
6630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6631
6633
6634 r = package_from_db(hdb, &hpkg);
6635 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
6636
6637 /* try TARGETDIR */
6638 size = MAX_PATH;
6639 lstrcpyA(path, "kiwi");
6640 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6641 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6642 ok(!lstrcmpA(path, "kiwi"),
6643 "Expected path to be unchanged, got \"%s\"\n", path);
6644 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6645
6646 /* try SourceDir */
6647 size = MAX_PATH;
6648 lstrcpyA(path, "kiwi");
6649 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6650 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6651 ok(!lstrcmpA(path, "kiwi"),
6652 "Expected path to be unchanged, got \"%s\"\n", path);
6653 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6654
6655 /* try SOURCEDIR */
6656 size = MAX_PATH;
6657 lstrcpyA(path, "kiwi");
6658 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6659 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6660 ok(!lstrcmpA(path, "kiwi"),
6661 "Expected path to be unchanged, got \"%s\"\n", path);
6662 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6663
6664 /* source path nor the property exist */
6665 size = MAX_PATH;
6666 lstrcpyA(path, "kiwi");
6667 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6670 ok(size == 0, "Expected 0, got %lu\n", size);
6671
6672 size = MAX_PATH;
6673 lstrcpyA(path, "kiwi");
6674 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6676 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
6677 ok(size == 0, "Expected 0, got %lu\n", size);
6678
6679 /* try SubDir */
6680 size = MAX_PATH;
6681 lstrcpyA(path, "kiwi");
6682 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6683 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6684 ok(!lstrcmpA(path, "kiwi"),
6685 "Expected path to be unchanged, got \"%s\"\n", path);
6686 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6687
6688 /* try SubDir2 */
6689 size = MAX_PATH;
6690 lstrcpyA(path, "kiwi");
6691 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6692 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
6693 ok(!lstrcmpA(path, "kiwi"),
6694 "Expected path to be unchanged, got \"%s\"\n", path);
6695 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
6696
6697 r = MsiDoActionA(hpkg, "CostInitialize");
6698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6699
6700 /* try TARGETDIR after CostInitialize */
6701 size = MAX_PATH;
6702 lstrcpyA(path, "kiwi");
6703 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6705 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6706 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6707
6708 /* try SourceDir after CostInitialize */
6709 size = MAX_PATH;
6710 lstrcpyA(path, "kiwi");
6711 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6713 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6714 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6715
6716 /* try SOURCEDIR after CostInitialize */
6717 size = MAX_PATH;
6718 lstrcpyA(path, "kiwi");
6719 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6720 todo_wine
6721 {
6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6724 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6725 }
6726
6727 /* source path does not exist, but the property exists */
6728 size = MAX_PATH;
6729 lstrcpyA(path, "kiwi");
6730 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6732 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6733 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6734
6735 size = MAX_PATH;
6736 lstrcpyA(path, "kiwi");
6737 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6739 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6740 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6741
6742 /* try SubDir after CostInitialize */
6743 size = MAX_PATH;
6744 lstrcpyA(path, "kiwi");
6745 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
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 /* try SubDir2 after CostInitialize */
6751 size = MAX_PATH;
6752 lstrcpyA(path, "kiwi");
6753 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6755 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6756 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6757
6758 r = MsiDoActionA(hpkg, "ResolveSource");
6759 ok(r == ERROR_SUCCESS, "file cost failed\n");
6760
6761 /* try TARGETDIR after ResolveSource */
6762 size = MAX_PATH;
6763 lstrcpyA(path, "kiwi");
6764 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6766 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6767 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6768
6769 /* try SourceDir after ResolveSource */
6770 size = MAX_PATH;
6771 lstrcpyA(path, "kiwi");
6772 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6774 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6775 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6776
6777 /* try SOURCEDIR after ResolveSource */
6778 size = MAX_PATH;
6779 lstrcpyA(path, "kiwi");
6780 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6781 todo_wine
6782 {
6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6784 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6785 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6786 }
6787
6788 /* source path and the property exist */
6789 size = MAX_PATH;
6790 lstrcpyA(path, "kiwi");
6791 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6793 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6794 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6795
6796 size = MAX_PATH;
6797 lstrcpyA(path, "kiwi");
6798 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6800 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6801 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6802
6803 /* try SubDir after ResolveSource */
6804 size = MAX_PATH;
6805 lstrcpyA(path, "kiwi");
6806 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
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 /* try SubDir2 after ResolveSource */
6812 size = MAX_PATH;
6813 lstrcpyA(path, "kiwi");
6814 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6816 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6817 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6818
6819 r = MsiDoActionA(hpkg, "FileCost");
6820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6821
6822 /* try TARGETDIR after CostFinalize */
6823 size = MAX_PATH;
6824 lstrcpyA(path, "kiwi");
6825 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6827 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6828 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6829
6830 /* try SourceDir after CostFinalize */
6831 size = MAX_PATH;
6832 lstrcpyA(path, "kiwi");
6833 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6835 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6836 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6837
6838 /* try SOURCEDIR after CostFinalize */
6839 size = MAX_PATH;
6840 lstrcpyA(path, "kiwi");
6841 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6842 todo_wine
6843 {
6844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6845 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6846 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6847 }
6848
6849 /* source path and the property exist */
6850 size = MAX_PATH;
6851 lstrcpyA(path, "kiwi");
6852 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6854 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6855 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6856
6857 size = MAX_PATH;
6858 lstrcpyA(path, "kiwi");
6859 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6861 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6862 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6863
6864 /* try SubDir after CostFinalize */
6865 size = MAX_PATH;
6866 lstrcpyA(path, "kiwi");
6867 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
6868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6869 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6870 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6871
6872 /* try SubDir2 after CostFinalize */
6873 size = MAX_PATH;
6874 lstrcpyA(path, "kiwi");
6875 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6877 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6878 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6879
6880 r = MsiDoActionA(hpkg, "CostFinalize");
6881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6882
6883 /* try TARGETDIR after CostFinalize */
6884 size = MAX_PATH;
6885 lstrcpyA(path, "kiwi");
6886 r = MsiGetSourcePathA(hpkg, "TARGETDIR", path, &size);
6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6889 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6890
6891 /* try SourceDir after CostFinalize */
6892 size = MAX_PATH;
6893 lstrcpyA(path, "kiwi");
6894 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
6895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6896 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6897 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6898
6899 /* try SOURCEDIR after CostFinalize */
6900 size = MAX_PATH;
6901 lstrcpyA(path, "kiwi");
6902 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
6903 todo_wine
6904 {
6905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6906 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6907 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6908 }
6909
6910 /* source path and the property exist */
6911 size = MAX_PATH;
6912 lstrcpyA(path, "kiwi");
6913 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
6914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6915 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6916 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6917
6918 size = MAX_PATH;
6919 lstrcpyA(path, "kiwi");
6920 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
6921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6922 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6923 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6924
6925 /* try SubDir after CostFinalize */
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, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6931 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6932
6933 /* try SubDir2 after CostFinalize */
6934 size = MAX_PATH;
6935 lstrcpyA(path, "kiwi");
6936 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
6937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6938 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
6939 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
6940
6941 MsiCloseHandle(hpkg);
6943}
6944
6945static void test_shortlongsource(void)
6946{
6947 MSIHANDLE hdb, hpkg;
6949 CHAR cwd[MAX_PATH];
6950 CHAR subsrc[MAX_PATH];
6951 DWORD size;
6952 UINT r;
6953
6954 lstrcpyA(cwd, CURR_DIR);
6955 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
6956
6957 lstrcpyA(subsrc, cwd);
6958 lstrcatA(subsrc, "long");
6959 lstrcatA(subsrc, "\\");
6960
6961 /* long file names */
6962
6963 hdb = create_package_db();
6964 ok( hdb, "failed to create database\n");
6965
6967
6968 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
6969 add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'");
6970
6971 /* CostInitialize:short */
6972 add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'");
6973
6974 /* CostInitialize:long */
6975 add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'");
6976
6977 /* FileCost:short */
6978 add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'");
6979
6980 /* FileCost:long */
6981 add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'");
6982
6983 /* CostFinalize:short */
6984 add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'");
6985
6986 /* CostFinalize:long */
6987 add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'");
6988
6989 r = MsiDatabaseCommit(hdb);
6990 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
6991
6992 r = package_from_db(hdb, &hpkg);
6994 {
6995 skip("Not enough rights to perform tests\n");
6997 return;
6998 }
6999 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7000
7001 MsiCloseHandle(hdb);
7002
7003 CreateDirectoryA("one", NULL);
7004 CreateDirectoryA("four", NULL);
7005
7007
7008 r = MsiDoActionA(hpkg, "CostInitialize");
7009 ok(r == ERROR_SUCCESS, "file cost failed\n");
7010
7011 CreateDirectoryA("five", NULL);
7012 CreateDirectoryA("eight", NULL);
7013
7014 r = MsiDoActionA(hpkg, "FileCost");
7015 ok(r == ERROR_SUCCESS, "file cost failed\n");
7016
7017 CreateDirectoryA("nine", NULL);
7018 CreateDirectoryA("twelve", NULL);
7019
7020 r = MsiDoActionA(hpkg, "CostFinalize");
7021 ok(r == ERROR_SUCCESS, "file cost failed\n");
7022
7023 /* neither short nor long source directories exist */
7024 size = MAX_PATH;
7025 lstrcpyA(path, "kiwi");
7026 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7028 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7029 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7030
7031 CreateDirectoryA("short", NULL);
7032
7033 /* short source directory exists */
7034 size = MAX_PATH;
7035 lstrcpyA(path, "kiwi");
7036 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7038 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7039 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7040
7041 CreateDirectoryA("long", NULL);
7042
7043 /* both short and long source directories exist */
7044 size = MAX_PATH;
7045 lstrcpyA(path, "kiwi");
7046 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7048 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7049 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7050
7051 lstrcpyA(subsrc, cwd);
7052 lstrcatA(subsrc, "two");
7053 lstrcatA(subsrc, "\\");
7054
7055 /* short dir exists before CostInitialize */
7056 size = MAX_PATH;
7057 lstrcpyA(path, "kiwi");
7058 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7060 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7061 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7062
7063 lstrcpyA(subsrc, cwd);
7064 lstrcatA(subsrc, "four");
7065 lstrcatA(subsrc, "\\");
7066
7067 /* long dir exists before CostInitialize */
7068 size = MAX_PATH;
7069 lstrcpyA(path, "kiwi");
7070 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7071 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7072 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7073 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7074
7075 lstrcpyA(subsrc, cwd);
7076 lstrcatA(subsrc, "six");
7077 lstrcatA(subsrc, "\\");
7078
7079 /* short dir exists before FileCost */
7080 size = MAX_PATH;
7081 lstrcpyA(path, "kiwi");
7082 r = MsiGetSourcePathA(hpkg, "SubDir4", 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 lstrcpyA(subsrc, cwd);
7088 lstrcatA(subsrc, "eight");
7089 lstrcatA(subsrc, "\\");
7090
7091 /* long dir exists before FileCost */
7092 size = MAX_PATH;
7093 lstrcpyA(path, "kiwi");
7094 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7096 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7097 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7098
7099 lstrcpyA(subsrc, cwd);
7100 lstrcatA(subsrc, "ten");
7101 lstrcatA(subsrc, "\\");
7102
7103 /* short dir exists before CostFinalize */
7104 size = MAX_PATH;
7105 lstrcpyA(path, "kiwi");
7106 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7108 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7109 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7110
7111 lstrcpyA(subsrc, cwd);
7112 lstrcatA(subsrc, "twelve");
7113 lstrcatA(subsrc, "\\");
7114
7115 /* long dir exists before CostFinalize */
7116 size = MAX_PATH;
7117 lstrcpyA(path, "kiwi");
7118 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7120 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7121 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7122
7123 MsiCloseHandle(hpkg);
7124 RemoveDirectoryA("short");
7125 RemoveDirectoryA("long");
7126 RemoveDirectoryA("one");
7127 RemoveDirectoryA("four");
7128 RemoveDirectoryA("five");
7129 RemoveDirectoryA("eight");
7130 RemoveDirectoryA("nine");
7131 RemoveDirectoryA("twelve");
7132
7133 /* short file names */
7134
7136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7137
7139
7140 r = package_from_db(hdb, &hpkg);
7141 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
7142
7143 MsiCloseHandle(hdb);
7144
7145 CreateDirectoryA("one", NULL);
7146 CreateDirectoryA("four", NULL);
7147
7148 r = MsiDoActionA(hpkg, "CostInitialize");
7149 ok(r == ERROR_SUCCESS, "file cost failed\n");
7150
7151 CreateDirectoryA("five", NULL);
7152 CreateDirectoryA("eight", NULL);
7153
7154 r = MsiDoActionA(hpkg, "FileCost");
7155 ok(r == ERROR_SUCCESS, "file cost failed\n");
7156
7157 CreateDirectoryA("nine", NULL);
7158 CreateDirectoryA("twelve", NULL);
7159
7160 r = MsiDoActionA(hpkg, "CostFinalize");
7161 ok(r == ERROR_SUCCESS, "file cost failed\n");
7162
7163 lstrcpyA(subsrc, cwd);
7164 lstrcatA(subsrc, "short");
7165 lstrcatA(subsrc, "\\");
7166
7167 /* neither short nor long source directories exist */
7168 size = MAX_PATH;
7169 lstrcpyA(path, "kiwi");
7170 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7172 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7173 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7174
7175 CreateDirectoryA("short", NULL);
7176
7177 /* short source directory exists */
7178 size = MAX_PATH;
7179 lstrcpyA(path, "kiwi");
7180 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7182 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7183 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7184
7185 CreateDirectoryA("long", NULL);
7186
7187 /* both short and long source directories exist */
7188 size = MAX_PATH;
7189 lstrcpyA(path, "kiwi");
7190 r = MsiGetSourcePathA(hpkg, "SubDir", path, &size);
7191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7192 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7193 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7194
7195 lstrcpyA(subsrc, cwd);
7196 lstrcatA(subsrc, "one");
7197 lstrcatA(subsrc, "\\");
7198
7199 /* short dir exists before CostInitialize */
7200 size = MAX_PATH;
7201 lstrcpyA(path, "kiwi");
7202 r = MsiGetSourcePathA(hpkg, "SubDir2", path, &size);
7203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7204 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7205 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7206
7207 lstrcpyA(subsrc, cwd);
7208 lstrcatA(subsrc, "three");
7209 lstrcatA(subsrc, "\\");
7210
7211 /* long dir exists before CostInitialize */
7212 size = MAX_PATH;
7213 lstrcpyA(path, "kiwi");
7214 r = MsiGetSourcePathA(hpkg, "SubDir3", path, &size);
7215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7216 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7217 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7218
7219 lstrcpyA(subsrc, cwd);
7220 lstrcatA(subsrc, "five");
7221 lstrcatA(subsrc, "\\");
7222
7223 /* short dir exists before FileCost */
7224 size = MAX_PATH;
7225 lstrcpyA(path, "kiwi");
7226 r = MsiGetSourcePathA(hpkg, "SubDir4", path, &size);
7227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7228 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7229 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7230
7231 lstrcpyA(subsrc, cwd);
7232 lstrcatA(subsrc, "seven");
7233 lstrcatA(subsrc, "\\");
7234
7235 /* long dir exists before FileCost */
7236 size = MAX_PATH;
7237 lstrcpyA(path, "kiwi");
7238 r = MsiGetSourcePathA(hpkg, "SubDir5", path, &size);
7239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7240 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7241 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7242
7243 lstrcpyA(subsrc, cwd);
7244 lstrcatA(subsrc, "nine");
7245 lstrcatA(subsrc, "\\");
7246
7247 /* short dir exists before CostFinalize */
7248 size = MAX_PATH;
7249 lstrcpyA(path, "kiwi");
7250 r = MsiGetSourcePathA(hpkg, "SubDir6", path, &size);
7251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7252 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7253 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7254
7255 lstrcpyA(subsrc, cwd);
7256 lstrcatA(subsrc, "eleven");
7257 lstrcatA(subsrc, "\\");
7258
7259 /* long dir exists before CostFinalize */
7260 size = MAX_PATH;
7261 lstrcpyA(path, "kiwi");
7262 r = MsiGetSourcePathA(hpkg, "SubDir7", path, &size);
7263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7264 ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path);
7265 ok(size == lstrlenA(subsrc), "Expected %d, got %lu\n", lstrlenA(subsrc), size);
7266
7267 MsiCloseHandle(hpkg);
7268 RemoveDirectoryA("short");
7269 RemoveDirectoryA("long");
7270 RemoveDirectoryA("one");
7271 RemoveDirectoryA("four");
7272 RemoveDirectoryA("five");
7273 RemoveDirectoryA("eight");
7274 RemoveDirectoryA("nine");
7275 RemoveDirectoryA("twelve");
7277}
7278
7279static void test_sourcedir(void)
7280{
7281 MSIHANDLE hdb, hpkg;
7282 CHAR package[12];
7284 CHAR cwd[MAX_PATH];
7285 CHAR subsrc[MAX_PATH];
7286 DWORD size;
7287 UINT r;
7288
7289 lstrcpyA(cwd, CURR_DIR);
7290 if (!is_root(CURR_DIR)) lstrcatA(cwd, "\\");
7291
7292 lstrcpyA(subsrc, cwd);
7293 lstrcatA(subsrc, "long");
7294 lstrcatA(subsrc, "\\");
7295
7296 hdb = create_package_db();
7297 ok( hdb, "failed to create database\n");
7298
7299 add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
7300
7301 sprintf(package, "#%lu", hdb);
7302 r = MsiOpenPackageA(package, &hpkg);
7304 {
7305 skip("Not enough rights to perform tests\n");
7306 goto error;
7307 }
7308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7309
7310 /* properties only */
7311
7312 /* SourceDir prop */
7313 size = MAX_PATH;
7314 lstrcpyA(path, "kiwi");
7315 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7317 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7318 ok(size == 0, "Expected 0, got %lu\n", size);
7319
7320 /* SOURCEDIR prop */
7321 size = MAX_PATH;
7322 lstrcpyA(path, "kiwi");
7323 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7325 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7326 ok(size == 0, "Expected 0, got %lu\n", size);
7327
7329
7330 r = MsiDoActionA(hpkg, "CostInitialize");
7331 ok(r == ERROR_SUCCESS, "file cost failed\n");
7332
7333 /* SourceDir after CostInitialize */
7334 size = MAX_PATH;
7335 lstrcpyA(path, "kiwi");
7336 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7338 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7339 ok(size == 0, "Expected 0, got %lu\n", size);
7340
7341 /* SOURCEDIR after CostInitialize */
7342 size = MAX_PATH;
7343 lstrcpyA(path, "kiwi");
7344 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7346 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7347 ok(size == 0, "Expected 0, got %lu\n", size);
7348
7349 r = MsiDoActionA(hpkg, "FileCost");
7350 ok(r == ERROR_SUCCESS, "file cost failed\n");
7351
7352 /* SourceDir after FileCost */
7353 size = MAX_PATH;
7354 lstrcpyA(path, "kiwi");
7355 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7357 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7358 ok(size == 0, "Expected 0, got %lu\n", size);
7359
7360 /* SOURCEDIR after FileCost */
7361 size = MAX_PATH;
7362 lstrcpyA(path, "kiwi");
7363 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7365 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7366 ok(size == 0, "Expected 0, got %lu\n", size);
7367
7368 r = MsiDoActionA(hpkg, "CostFinalize");
7369 ok(r == ERROR_SUCCESS, "file cost failed\n");
7370
7371 /* SourceDir after CostFinalize */
7372 size = MAX_PATH;
7373 lstrcpyA(path, "kiwi");
7374 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7376 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7377 ok(size == 0, "Expected 0, got %lu\n", size);
7378
7379 /* SOURCEDIR after CostFinalize */
7380 size = MAX_PATH;
7381 lstrcpyA(path, "kiwi");
7382 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7384 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7385 ok(size == 0, "Expected 0, got %lu\n", size);
7386
7387 size = MAX_PATH;
7388 lstrcpyA(path, "kiwi");
7389 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7390 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7391 ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
7392 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
7393
7394 /* SOURCEDIR after calling MsiGetSourcePath */
7395 size = MAX_PATH;
7396 lstrcpyA(path, "kiwi");
7397 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7399 todo_wine {
7400 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7401 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7402 }
7403
7404 r = MsiDoActionA(hpkg, "ResolveSource");
7405 ok(r == ERROR_SUCCESS, "file cost failed\n");
7406
7407 /* SourceDir after ResolveSource */
7408 size = MAX_PATH;
7409 lstrcpyA(path, "kiwi");
7410 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7412 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7413 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7414
7415 /* SOURCEDIR after ResolveSource */
7416 size = MAX_PATH;
7417 lstrcpyA(path, "kiwi");
7418 r = MsiGetPropertyA(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 /* random casing */
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, ""), "Expected \"\", got \"%s\"\n", path);
7429 ok(size == 0, "Expected 0, got %lu\n", size);
7430
7431 MsiCloseHandle(hpkg);
7432
7433 /* reset the package state */
7434 sprintf(package, "#%lu", hdb);
7435 r = MsiOpenPackageA(package, &hpkg);
7436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7437
7438 /* test how MsiGetSourcePath affects the properties */
7439
7440 /* SourceDir prop */
7441 size = MAX_PATH;
7442 lstrcpyA(path, "kiwi");
7443 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7444 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7445 todo_wine
7446 {
7447 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7448 ok(size == 0, "Expected 0, got %lu\n", size);
7449 }
7450
7451 size = MAX_PATH;
7452 lstrcpyA(path, "kiwi");
7453 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7454 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7455 ok(!lstrcmpA(path, "kiwi"),
7456 "Expected path to be unchanged, got \"%s\"\n", path);
7457 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7458
7459 /* SourceDir after MsiGetSourcePath */
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 todo_wine
7465 {
7466 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7467 ok(size == 0, "Expected 0, got %lu\n", size);
7468 }
7469
7470 /* SOURCEDIR prop */
7471 size = MAX_PATH;
7472 lstrcpyA(path, "kiwi");
7473 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7475 todo_wine
7476 {
7477 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7478 ok(size == 0, "Expected 0, got %lu\n", size);
7479 }
7480
7481 size = MAX_PATH;
7482 lstrcpyA(path, "kiwi");
7483 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7484 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7485 ok(!lstrcmpA(path, "kiwi"),
7486 "Expected path to be unchanged, got \"%s\"\n", path);
7487 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7488
7489 /* SOURCEDIR prop after MsiGetSourcePath */
7490 size = MAX_PATH;
7491 lstrcpyA(path, "kiwi");
7492 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7494 todo_wine
7495 {
7496 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7497 ok(size == 0, "Expected 0, got %lu\n", size);
7498 }
7499
7500 r = MsiDoActionA(hpkg, "CostInitialize");
7501 ok(r == ERROR_SUCCESS, "file cost failed\n");
7502
7503 /* SourceDir after CostInitialize */
7504 size = MAX_PATH;
7505 lstrcpyA(path, "kiwi");
7506 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7508 todo_wine
7509 {
7510 ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
7511 ok(size == 0, "Expected 0, got %lu\n", size);
7512 }
7513
7514 size = MAX_PATH;
7515 lstrcpyA(path, "kiwi");
7516 r = MsiGetSourcePathA(hpkg, "SourceDir", path, &size);
7517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7518 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7519 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7520
7521 /* SourceDir after MsiGetSourcePath */
7522 size = MAX_PATH;
7523 lstrcpyA(path, "kiwi");
7524 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7526 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7527 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7528
7529 /* SOURCEDIR after CostInitialize */
7530 size = MAX_PATH;
7531 lstrcpyA(path, "kiwi");
7532 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7534 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7535 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7536
7537 /* SOURCEDIR source path still does not exist */
7538 size = MAX_PATH;
7539 lstrcpyA(path, "kiwi");
7540 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7541 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7542 ok(!lstrcmpA(path, "kiwi"),
7543 "Expected path to be unchanged, got \"%s\"\n", path);
7544 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7545
7546 r = MsiDoActionA(hpkg, "FileCost");
7547 ok(r == ERROR_SUCCESS, "file cost failed\n");
7548
7549 /* SourceDir after FileCost */
7550 size = MAX_PATH;
7551 lstrcpyA(path, "kiwi");
7552 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7554 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7555 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7556
7557 /* SOURCEDIR after FileCost */
7558 size = MAX_PATH;
7559 lstrcpyA(path, "kiwi");
7560 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7562 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7563 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7564
7565 /* SOURCEDIR source path still does not exist */
7566 size = MAX_PATH;
7567 lstrcpyA(path, "kiwi");
7568 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7569 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7570 ok(!lstrcmpA(path, "kiwi"),
7571 "Expected path to be unchanged, got \"%s\"\n", path);
7572 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7573
7574 r = MsiDoActionA(hpkg, "CostFinalize");
7575 ok(r == ERROR_SUCCESS, "file cost failed\n");
7576
7577 /* SourceDir after CostFinalize */
7578 size = MAX_PATH;
7579 lstrcpyA(path, "kiwi");
7580 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7582 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7583 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7584
7585 /* SOURCEDIR after CostFinalize */
7586 size = MAX_PATH;
7587 lstrcpyA(path, "kiwi");
7588 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7590 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7591 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7592
7593 /* SOURCEDIR source path still does not exist */
7594 size = MAX_PATH;
7595 lstrcpyA(path, "kiwi");
7596 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7597 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7598 ok(!lstrcmpA(path, "kiwi"),
7599 "Expected path to be unchanged, got \"%s\"\n", path);
7600 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7601
7602 r = MsiDoActionA(hpkg, "ResolveSource");
7603 ok(r == ERROR_SUCCESS, "file cost failed\n");
7604
7605 /* SourceDir after ResolveSource */
7606 size = MAX_PATH;
7607 lstrcpyA(path, "kiwi");
7608 r = MsiGetPropertyA(hpkg, "SourceDir", path, &size);
7609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7610 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7611 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7612
7613 /* SOURCEDIR after ResolveSource */
7614 size = MAX_PATH;
7615 lstrcpyA(path, "kiwi");
7616 r = MsiGetPropertyA(hpkg, "SOURCEDIR", path, &size);
7617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7618 ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
7619 ok(size == lstrlenA(cwd), "Expected %d, got %lu\n", lstrlenA(cwd), size);
7620
7621 /* SOURCEDIR source path still does not exist */
7622 size = MAX_PATH;
7623 lstrcpyA(path, "kiwi");
7624 r = MsiGetSourcePathA(hpkg, "SOURCEDIR", path, &size);
7625 ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
7626 ok(!lstrcmpA(path, "kiwi"),
7627 "Expected path to be unchanged, got \"%s\"\n", path);
7628 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
7629
7630 MsiCloseHandle(hpkg);
7631
7632error:
7633 MsiCloseHandle(hdb);
7635}
7636
7638{
7642};
7643
7644static const struct access_res create[16] =
7645{
7646 { TRUE, ERROR_SUCCESS, TRUE },
7647 { TRUE, ERROR_SUCCESS, TRUE },
7648 { TRUE, ERROR_SUCCESS, FALSE },
7649 { TRUE, ERROR_SUCCESS, FALSE },
7653 { TRUE, ERROR_SUCCESS, FALSE },
7657 { TRUE, ERROR_SUCCESS, TRUE },
7661 { TRUE, ERROR_SUCCESS, TRUE }
7662};
7663
7664static const struct access_res create_commit[16] =
7665{
7666 { TRUE, ERROR_SUCCESS, TRUE },
7667 { TRUE, ERROR_SUCCESS, TRUE },
7668 { TRUE, ERROR_SUCCESS, FALSE },
7669 { TRUE, ERROR_SUCCESS, FALSE },
7673 { TRUE, ERROR_SUCCESS, FALSE },
7677 { TRUE, ERROR_SUCCESS, TRUE },
7681 { TRUE, ERROR_SUCCESS, TRUE }
7682};
7683
7684static const struct access_res create_close[16] =
7685{
7686 { TRUE, ERROR_SUCCESS, FALSE },
7687 { TRUE, ERROR_SUCCESS, FALSE },
7688 { TRUE, ERROR_SUCCESS, FALSE },
7689 { TRUE, ERROR_SUCCESS, FALSE },
7690 { TRUE, ERROR_SUCCESS, FALSE },
7691 { TRUE, ERROR_SUCCESS, FALSE },
7692 { TRUE, ERROR_SUCCESS, FALSE },
7693 { TRUE, ERROR_SUCCESS, FALSE },
7694 { TRUE, ERROR_SUCCESS, FALSE },
7695 { TRUE, ERROR_SUCCESS, FALSE },
7696 { TRUE, ERROR_SUCCESS, FALSE },
7697 { TRUE, ERROR_SUCCESS, FALSE },
7698 { TRUE, ERROR_SUCCESS, FALSE },
7699 { TRUE, ERROR_SUCCESS, FALSE },
7700 { TRUE, ERROR_SUCCESS, FALSE },
7701 { TRUE, ERROR_SUCCESS }
7702};
7703
7704static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
7705{
7706 DWORD access = 0, share = 0;
7707 DWORD lasterr;
7708 HANDLE hfile;
7709 int i, j, idx = 0;
7710
7711 for (i = 0; i < 4; i++)
7712 {
7713 if (i == 0) access = 0;
7714 if (i == 1) access = GENERIC_READ;
7715 if (i == 2) access = GENERIC_WRITE;
7716 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
7717
7718 for (j = 0; j < 4; j++)
7719 {
7720 if (ares[idx].ignore)
7721 continue;
7722
7723 if (j == 0) share = 0;
7724 if (j == 1) share = FILE_SHARE_READ;
7725 if (j == 2) share = FILE_SHARE_WRITE;
7726 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
7727
7728 SetLastError(0xdeadbeef);
7729 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
7732
7733 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
7734 "(%lu, handle, %d): Expected %d, got %d\n",
7735 line, idx, ares[idx].gothandle,
7736 (hfile != INVALID_HANDLE_VALUE));
7737
7738 ok(lasterr == ares[idx].lasterr, "(%lu, lasterr, %u): Expected %lu, got %lu\n",
7739 line, idx, ares[idx].lasterr, lasterr);
7740
7741 CloseHandle(hfile);
7742 idx++;
7743 }
7744 }
7745}
7746
7747#define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
7748
7749static void test_access(void)
7750{
7751 MSIHANDLE hdb;
7752 UINT r;
7753
7755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7756
7758
7759 r = MsiDatabaseCommit(hdb);
7760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7761
7763 MsiCloseHandle(hdb);
7764
7767
7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7770
7772
7773 r = MsiDatabaseCommit(hdb);
7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7775
7777 MsiCloseHandle(hdb);
7778
7781}
7782
7783static void test_emptypackage(void)
7784{
7785 MSIHANDLE hpkg = 0, hdb = 0, hsuminfo = 0;
7786 MSIHANDLE hview = 0, hrec = 0;
7789 DWORD size;
7790 UINT r;
7791
7792 r = MsiOpenPackageA("", &hpkg);
7794 {
7795 skip("Not enough rights to perform tests\n");
7796 return;
7797 }
7798 todo_wine
7799 {
7800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7801 }
7802
7803 hdb = MsiGetActiveDatabase(hpkg);
7804 todo_wine
7805 {
7806 ok(hdb != 0, "Expected a valid database handle\n");
7807 }
7808
7809 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Tables`", &hview);
7810 todo_wine
7811 {
7812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7813 }
7814 r = MsiViewExecute(hview, 0);
7815 todo_wine
7816 {
7817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7818 }
7819
7820 r = MsiViewFetch(hview, &hrec);
7821 todo_wine
7822 {
7823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7824 }
7825
7826 buffer[0] = 0;
7827 size = MAX_PATH;
7828 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7829 todo_wine
7830 {
7831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7832 ok(!lstrcmpA(buffer, "_Property"),
7833 "Expected \"_Property\", got \"%s\"\n", buffer);
7834 }
7835
7836 MsiCloseHandle(hrec);
7837
7838 r = MsiViewFetch(hview, &hrec);
7839 todo_wine
7840 {
7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7842 }
7843
7844 size = MAX_PATH;
7845 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7846 todo_wine
7847 {
7848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7849 ok(!lstrcmpA(buffer, "#_FolderCache"),
7850 "Expected \"_Property\", got \"%s\"\n", buffer);
7851 }
7852
7853 MsiCloseHandle(hrec);
7854 MsiViewClose(hview);
7855 MsiCloseHandle(hview);
7856
7857 condition = MsiDatabaseIsTablePersistentA(hdb, "_Property");
7858 todo_wine
7859 {
7861 "Expected MSICONDITION_FALSE, got %d\n", condition);
7862 }
7863
7864 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Property`", &hview);
7865 todo_wine
7866 {
7867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7868 }
7869 r = MsiViewExecute(hview, 0);
7870 todo_wine
7871 {
7872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7873 }
7874
7875 /* _Property table is not empty */
7876 r = MsiViewFetch(hview, &hrec);
7877 todo_wine
7878 {
7879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7880 }
7881
7882 MsiCloseHandle(hrec);
7883 MsiViewClose(hview);
7884 MsiCloseHandle(hview);
7885
7886 condition = MsiDatabaseIsTablePersistentA(hdb, "#_FolderCache");
7887 todo_wine
7888 {
7890 "Expected MSICONDITION_FALSE, got %d\n", condition);
7891 }
7892
7893 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `#_FolderCache`", &hview);
7894 todo_wine
7895 {
7896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7897 }
7898 r = MsiViewExecute(hview, 0);
7899 todo_wine
7900 {
7901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7902 }
7903
7904 /* #_FolderCache is not empty */
7905 r = MsiViewFetch(hview, &hrec);
7906 todo_wine
7907 {
7908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7909 }
7910
7911 MsiCloseHandle(hrec);
7912 MsiViewClose(hview);
7913 MsiCloseHandle(hview);
7914
7915 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Streams`", &hview);
7916 todo_wine
7917 {
7919 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7920 }
7921
7922 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `_Storages`", &hview);
7923 todo_wine
7924 {
7926 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7927 }
7928
7929 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsuminfo);
7930 todo_wine
7931 {
7933 "Expected ERROR_INSTALL_PACKAGE_INVALID, got %d\n", r);
7934 }
7935
7936 MsiCloseHandle(hsuminfo);
7937
7938 r = MsiDatabaseCommit(hdb);
7939 todo_wine
7940 {
7941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7942 }
7943
7944 MsiCloseHandle(hdb);
7945 MsiCloseHandle(hpkg);
7946}
7947
7949{
7950 WCHAR valW[MAX_PATH];
7951 MSIHANDLE hprod, hdb;
7952 CHAR val[MAX_PATH];
7954 CHAR query[MAX_PATH + 17];
7955 CHAR keypath[MAX_PATH*2];
7956 CHAR prodcode[MAX_PATH];
7957 WCHAR prodcodeW[MAX_PATH];
7958 CHAR prod_squashed[MAX_PATH];
7959 WCHAR prod_squashedW[MAX_PATH];
7960 HKEY prodkey, userkey, props;
7961 DWORD size;
7962 LONG res;
7963 UINT r;
7965
7967 lstrcatA(path, "\\");
7968
7969 create_test_guid(prodcode, prod_squashed);
7970 MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
7971 squash_guid(prodcodeW, prod_squashedW);
7972
7973 if (is_wow64)
7975
7977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7978
7979 r = MsiDatabaseCommit(hdb);
7980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7981
7982 r = set_summary_info(hdb);
7983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7984
7985 r = run_query(hdb,
7986 "CREATE TABLE `Directory` ( "
7987 "`Directory` CHAR(255) NOT NULL, "
7988 "`Directory_Parent` CHAR(255), "
7989 "`DefaultDir` CHAR(255) NOT NULL "
7990 "PRIMARY KEY `Directory`)");
7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7992
7994
7995 sprintf(query, "'ProductCode', '%s'", prodcode);
7996 r = add_property_entry(hdb, query);
7997
7998 r = MsiDatabaseCommit(hdb);
7999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8000
8001 MsiCloseHandle(hdb);
8002
8003 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8004 lstrcatA(keypath, prod_squashed);
8005
8006 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8007 if (res == ERROR_ACCESS_DENIED)
8008 {
8009 skip("Not enough rights to perform tests\n");
8011 return;
8012 }
8013 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8014
8015 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8016 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8017 lstrcatA(keypath, prod_squashed);
8018
8019 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8020 if (res == ERROR_ACCESS_DENIED)
8021 {
8022 skip("Not enough rights to perform tests\n");
8023 RegDeleteKeyA(prodkey, "");
8024 RegCloseKey(prodkey);
8025 return;
8026 }
8027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8028
8029 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8031
8032 lstrcpyA(val, path);
8033 lstrcatA(val, "\\");
8035 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8036 (const BYTE *)val, lstrlenA(val) + 1);
8037 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8038
8039 hprod = 0xdeadbeef;
8040 r = MsiOpenProductA(prodcode, &hprod);
8041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8042 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8043
8044 /* hProduct is invalid */
8045 size = MAX_PATH;
8046 lstrcpyA(val, "apple");
8047 r = MsiGetProductPropertyA(0xdeadbeef, "ProductCode", val, &size);
8049 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8050 ok(!lstrcmpA(val, "apple"),
8051 "Expected val to be unchanged, got \"%s\"\n", val);
8052 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8053
8054 size = MAX_PATH;
8055 lstrcpyW(valW, L"apple");
8056 r = MsiGetProductPropertyW(0xdeadbeef, L"ProductCode", valW, &size);
8058 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8059 ok(!lstrcmpW(valW, L"apple"),
8060 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8061 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8062
8063 /* szProperty is NULL */
8064 size = MAX_PATH;
8065 lstrcpyA(val, "apple");
8066 r = MsiGetProductPropertyA(hprod, NULL, val, &size);
8068 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8069 ok(!lstrcmpA(val, "apple"),
8070 "Expected val to be unchanged, got \"%s\"\n", val);
8071 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8072
8073 size = MAX_PATH;
8074 lstrcpyW(valW, L"apple");
8075 r = MsiGetProductPropertyW(hprod, NULL, valW, &size);
8077 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8078 ok(!lstrcmpW(valW, L"apple"),
8079 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8080 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8081
8082 /* szProperty is empty */
8083 size = MAX_PATH;
8084 lstrcpyA(val, "apple");
8085 r = MsiGetProductPropertyA(hprod, "", val, &size);
8086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8087 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8088 ok(size == 0, "Expected 0, got %lu\n", size);
8089
8090 size = MAX_PATH;
8091 lstrcpyW(valW, L"apple");
8092 r = MsiGetProductPropertyW(hprod, L"", valW, &size);
8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094 ok(*valW == 0, "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8095 ok(size == 0, "Expected 0, got %lu\n", size);
8096
8097 /* get the property */
8098 size = MAX_PATH;
8099 lstrcpyA(val, "apple");
8100 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8102 ok(!lstrcmpA(val, prodcode),
8103 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8104 ok(size == lstrlenA(prodcode),
8105 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8106
8107 size = MAX_PATH;
8108 lstrcpyW(valW, L"apple");
8109 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8111 ok(!lstrcmpW(valW, prodcodeW),
8112 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8113 ok(size == lstrlenW(prodcodeW),
8114 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8115
8116 /* lpValueBuf is NULL */
8117 size = MAX_PATH;
8118 r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
8119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8120 ok(size == lstrlenA(prodcode),
8121 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8122
8123 size = MAX_PATH;
8124 r = MsiGetProductPropertyW(hprod, L"ProductCode", NULL, &size);
8125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8126 ok(size == lstrlenW(prodcodeW),
8127 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8128
8129 /* pcchValueBuf is NULL */
8130 lstrcpyA(val, "apple");
8131 r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
8133 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8134 ok(!lstrcmpA(val, "apple"),
8135 "Expected val to be unchanged, got \"%s\"\n", val);
8136 ok(size == lstrlenA(prodcode),
8137 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8138
8139 lstrcpyW(valW, L"apple");
8140 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, NULL);
8142 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8143 ok(!lstrcmpW(valW, L"apple"),
8144 "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW));
8145 ok(size == lstrlenW(prodcodeW),
8146 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8147
8148 /* pcchValueBuf is too small */
8149 size = 4;
8150 lstrcpyA(val, "apple");
8151 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8152 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8153 ok(!strncmp(val, prodcode, 3),
8154 "Expected first 3 chars of \"%s\", got \"%s\"\n", prodcode, val);
8155 ok(size == lstrlenA(prodcode),
8156 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8157
8158 size = 4;
8159 lstrcpyW(valW, L"apple");
8160 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8161 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8162 ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)),
8163 "Expected first 3 chars of %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 /* pcchValueBuf does not leave room for NULL terminator */
8168 size = lstrlenA(prodcode);
8169 lstrcpyA(val, "apple");
8170 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8171 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8172 ok(!strncmp(val, prodcode, lstrlenA(prodcode) - 1),
8173 "Expected first 37 chars of \"%s\", got \"%s\"\n", prodcode, val);
8174 ok(size == lstrlenA(prodcode),
8175 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8176
8177 size = lstrlenW(prodcodeW);
8178 lstrcpyW(valW, L"apple");
8179 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8180 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8181 ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1),
8182 "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8183 ok(size == lstrlenW(prodcodeW),
8184 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8185
8186 /* pcchValueBuf has enough room for NULL terminator */
8187 size = lstrlenA(prodcode) + 1;
8188 lstrcpyA(val, "apple");
8189 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8191 ok(!lstrcmpA(val, prodcode),
8192 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8193 ok(size == lstrlenA(prodcode),
8194 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8195
8196 size = lstrlenW(prodcodeW) + 1;
8197 lstrcpyW(valW, L"apple");
8198 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8200 ok(!lstrcmpW(valW, prodcodeW),
8201 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8202 ok(size == lstrlenW(prodcodeW),
8203 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8204
8205 /* nonexistent property */
8206 size = MAX_PATH;
8207 lstrcpyA(val, "apple");
8208 r = MsiGetProductPropertyA(hprod, "IDontExist", val, &size);
8209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8210 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8211 ok(size == 0, "Expected 0, got %lu\n", size);
8212
8213 size = MAX_PATH;
8214 lstrcpyW(valW, L"apple");
8215 r = MsiGetProductPropertyW(hprod, L"IDontExist", valW, &size);
8216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8217 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8218 ok(size == 0, "Expected 0, got %lu\n", size);
8219
8220 r = MsiSetPropertyA(hprod, "NewProperty", "value");
8221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8222
8223 /* non-product property set */
8224 size = MAX_PATH;
8225 lstrcpyA(val, "apple");
8226 r = MsiGetProductPropertyA(hprod, "NewProperty", val, &size);
8227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8228 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
8229 ok(size == 0, "Expected 0, got %lu\n", size);
8230
8231 size = MAX_PATH;
8232 lstrcpyW(valW, L"apple");
8233 r = MsiGetProductPropertyW(hprod, L"NewProperty", valW, &size);
8234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8235 ok(!lstrcmpW(valW, L""), "Expected \"\", got %s\n", wine_dbgstr_w(valW));
8236 ok(size == 0, "Expected 0, got %lu\n", size);
8237
8238 r = MsiSetPropertyA(hprod, "ProductCode", "value");
8239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8240
8241 /* non-product property that is also a product property set */
8242 size = MAX_PATH;
8243 lstrcpyA(val, "apple");
8244 r = MsiGetProductPropertyA(hprod, "ProductCode", val, &size);
8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8246 ok(!lstrcmpA(val, prodcode),
8247 "Expected \"%s\", got \"%s\"\n", prodcode, val);
8248 ok(size == lstrlenA(prodcode),
8249 "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8250
8251 size = MAX_PATH;
8252 lstrcpyW(valW, L"apple");
8253 r = MsiGetProductPropertyW(hprod, L"ProductCode", valW, &size);
8254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8255 ok(!lstrcmpW(valW, prodcodeW),
8256 "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW));
8257 ok(size == lstrlenW(prodcodeW),
8258 "Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
8259
8260 MsiCloseHandle(hprod);
8261
8262 RegDeleteValueA(props, "LocalPackage");
8263 delete_key(props, "", access);
8265 delete_key(userkey, "", access);
8266 RegCloseKey(userkey);
8267 delete_key(prodkey, "", access);
8268 RegCloseKey(prodkey);
8270}
8271
8272static void test_MsiSetProperty(void)
8273{
8274 MSIHANDLE hpkg, hdb, hrec;
8275 CHAR buf[MAX_PATH];
8276 LPCSTR query;
8277 DWORD size;
8278 UINT r;
8279
8282 {
8283 skip("Not enough rights to perform tests\n");
8285 return;
8286 }
8287 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8288
8289 /* invalid hInstall */
8290 r = MsiSetPropertyA(0, "Prop", "Val");
8292 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8293
8294 /* invalid hInstall */
8295 r = MsiSetPropertyA(0xdeadbeef, "Prop", "Val");
8297 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
8298
8299 /* szName is NULL */
8300 r = MsiSetPropertyA(hpkg, NULL, "Val");
8302 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8303
8304 /* both szName and szValue are NULL */
8305 r = MsiSetPropertyA(hpkg, NULL, NULL);
8307 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8308
8309 /* szName is empty */
8310 r = MsiSetPropertyA(hpkg, "", "Val");
8312 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8313
8314 /* szName is empty and szValue is NULL */
8315 r = MsiSetPropertyA(hpkg, "", NULL);
8316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8317
8318 /* set a property */
8319 r = MsiSetPropertyA(hpkg, "Prop", "Val");
8320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8321
8322 /* get the property */
8323 size = MAX_PATH;
8324 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8326 ok(!lstrcmpA(buf, "Val"), "Expected \"Val\", got \"%s\"\n", buf);
8327 ok(size == 3, "Expected 3, got %lu\n", size);
8328
8329 /* update the property */
8330 r = MsiSetPropertyA(hpkg, "Prop", "Nuvo");
8331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8332
8333 /* get the property */
8334 size = MAX_PATH;
8335 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8337 ok(!lstrcmpA(buf, "Nuvo"), "Expected \"Nuvo\", got \"%s\"\n", buf);
8338 ok(size == 4, "Expected 4, got %lu\n", size);
8339
8340 hdb = MsiGetActiveDatabase(hpkg);
8341 ok(hdb != 0, "Expected a valid database handle\n");
8342
8343 /* set prop is not in the _Property table */
8344 query = "SELECT * FROM `_Property` WHERE `Property` = 'Prop'";
8345 r = do_query(hdb, query, &hrec);
8347 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8348
8349 /* set prop is not in the Property table */
8350 query = "SELECT * FROM `Property` WHERE `Property` = 'Prop'";
8351 r = do_query(hdb, query, &hrec);
8353 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8354
8355 MsiCloseHandle(hdb);
8356
8357 /* szValue is an empty string */
8358 r = MsiSetPropertyA(hpkg, "Prop", "");
8359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8360
8361 /* try to get the property */
8362 size = MAX_PATH;
8363 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8365 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8366 ok(size == 0, "Expected 0, got %lu\n", size);
8367
8368 /* reset the property */
8369 r = MsiSetPropertyA(hpkg, "Prop", "BlueTap");
8370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8371
8372 /* delete the property */
8373 r = MsiSetPropertyA(hpkg, "Prop", NULL);
8374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8375
8376 /* try to get the property */
8377 size = MAX_PATH;
8378 r = MsiGetPropertyA(hpkg, "Prop", buf, &size);
8379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8380 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8381 ok(size == 0, "Expected 0, got %lu\n", size);
8382
8383 MsiCloseHandle(hpkg);
8385}
8386
8388{
8390
8392 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8393
8395 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8396
8398 if (type == DRIVE_FIXED)
8399 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8400 else
8401 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8402
8404 if (type == DRIVE_FIXED)
8405 todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
8406 else
8407 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8408
8410 if (type == DRIVE_FIXED)
8411 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8412 else
8413 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8414
8415 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
8416 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8417
8418 r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
8419 if (type == DRIVE_FIXED)
8420 todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
8421 else
8422 ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
8423
8424 r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
8425 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8426
8427 r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
8428 todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
8429}
8430
8431static void test_MsiApplyPatch(void)
8432{
8433 UINT r;
8434
8436 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8437
8439 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
8440}
8441
8442static void test_costs(void)
8443{
8444 MSIHANDLE hdb, hpkg;
8445 char package[12], drive[3];
8446 DWORD len;
8447 UINT r;
8448 int cost, temp;
8449
8450 hdb = create_package_db();
8451 ok( hdb, "failed to create database\n" );
8452
8453 create_property_table( hdb );
8454 add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
8455 add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
8456 add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
8457
8458 create_media_table( hdb );
8459 add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
8460
8461 create_file_table( hdb );
8462 add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
8463
8465 add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
8466 add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
8467
8468 create_feature_table( hdb );
8469 add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
8470 add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
8471
8473 add_feature_components_entry( hdb, "'one', 'one'" );
8474 add_feature_components_entry( hdb, "'two', 'two'" );
8475
8477 add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
8478 add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
8479 add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
8480 add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
8481
8482 r = MsiDatabaseCommit( hdb );
8483 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8484
8485 sprintf( package, "#%lu", hdb );
8486 r = MsiOpenPackageA( package, &hpkg );
8488 {
8489 skip("Not enough rights to perform tests\n");
8490 goto error;
8491 }
8492 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8493
8495 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8496
8498 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8499
8501 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8502
8504 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8505
8507 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8508
8509 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
8510 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8511
8513 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8514
8515 len = sizeof(drive);
8516 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
8517 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8518
8519 len = sizeof(drive);
8520 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
8521 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8522
8523 len = sizeof(drive);
8524 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8525 todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
8526
8527 len = sizeof(drive);
8528 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
8529 ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
8530
8532
8533 r = MsiDoActionA( hpkg, "CostInitialize" );
8534 ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
8535
8536 r = MsiDoActionA( hpkg, "FileCost" );
8537 ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
8538
8539 len = sizeof(drive);
8540 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8541 ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8542
8543 r = MsiDoActionA( hpkg, "CostFinalize" );
8544 ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
8545
8546 /* contrary to what msdn says InstallValidate must be called too */
8547 len = sizeof(drive);
8548 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8549 todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
8550
8551 r = MsiDoActionA( hpkg, "InstallValidate" );
8552 ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
8553
8554 len = 0;
8555 r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8556 ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
8557
8558 len = 0;
8559 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8560 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8561 ok( len == 2, "expected len == 2, got %lu\n", len );
8562
8563 len = 2;
8564 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8565 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8566 ok( len == 2, "expected len == 2, got %lu\n", len );
8567
8568 len = 2;
8569 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8570 ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
8571 ok( len == 2, "expected len == 2, got %lu\n", len );
8572
8573 /* install state doesn't seem to matter */
8574 len = sizeof(drive);
8575 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8576 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8577
8578 len = sizeof(drive);
8579 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
8580 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8581
8582 len = sizeof(drive);
8583 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
8584 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8585
8586 len = sizeof(drive);
8587 drive[0] = 0;
8588 cost = temp = 0xdead;
8589 r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8590 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8591 ok( len == 2, "expected len == 2, got %lu\n", len );
8592 ok( drive[0], "expected a drive\n" );
8593 ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
8594 ok( !temp, "expected temp == 0, got %d\n", temp );
8595
8596 len = sizeof(drive);
8597 drive[0] = 0;
8598 cost = temp = 0xdead;
8599 r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8600 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8601 ok( len == 2, "expected len == 2, got %lu\n", len );
8602 ok( drive[0], "expected a drive\n" );
8603 ok( !cost, "expected cost == 0, got %d\n", cost );
8604 ok( !temp, "expected temp == 0, got %d\n", temp );
8605
8606 len = sizeof(drive);
8607 drive[0] = 0;
8608 cost = temp = 0xdead;
8609 r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8610 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
8611 ok( len == 2, "expected len == 2, got %lu\n", len );
8612 ok( drive[0], "expected a drive\n" );
8613 ok( !cost, "expected cost == 0, got %d\n", cost );
8614 ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
8615
8616 /* increased index */
8617 len = sizeof(drive);
8618 r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
8619 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8620
8621 len = sizeof(drive);
8622 r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
8623 ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
8624
8625 /* test MsiGetFeatureCost */
8626 cost = 0xdead;
8628 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8629 ok( cost == 0xdead, "got %d\n", cost );
8630
8632 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r);
8633
8634 cost = 0xdead;
8636 ok( !r, "got %u\n", r);
8637 ok( cost == 8, "got %d\n", cost );
8638
8639 MsiCloseHandle( hpkg );
8640error:
8641 MsiCloseHandle( hdb );
8643}
8644
8645static void test_MsiDatabaseCommit(void)
8646{
8647 UINT r;
8648 MSIHANDLE hdb, hpkg = 0;
8649 char buf[32], package[12];
8650 DWORD sz;
8651
8652 hdb = create_package_db();
8653 ok( hdb, "failed to create database\n" );
8654
8655 create_property_table( hdb );
8656
8657 sprintf( package, "#%lu", hdb );
8658 r = MsiOpenPackageA( package, &hpkg );
8660 {
8661 skip("Not enough rights to perform tests\n");
8662 goto error;
8663 }
8664 ok( r == ERROR_SUCCESS, "got %u\n", r );
8665
8666 r = MsiSetPropertyA( hpkg, "PROP", "value" );
8667 ok( r == ERROR_SUCCESS, "got %u\n", r );
8668
8669 buf[0] = 0;
8670 sz = sizeof(buf);
8671 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8672 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8673 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8674
8675 r = MsiDatabaseCommit( hdb );
8676 ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
8677
8678 buf[0] = 0;
8679 sz = sizeof(buf);
8680 r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
8681 ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
8682 ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
8683
8684 MsiCloseHandle( hpkg );
8685error:
8686 MsiCloseHandle( hdb );
8688}
8689
8691
8693{
8694 externalui_ran = 1;
8695 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8696 return 0;
8697}
8698
8700
8701static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
8702{
8703 INT retval = context ? *((INT *)context) : 0;
8704 UINT r;
8706 ok(message_type == INSTALLMESSAGE_USER, "expected INSTALLMESSAGE_USER, got %08x\n", message_type);
8707 r = MsiRecordGetFieldCount(hrecord);
8708 ok(r == 1, "expected 1, got %u\n", r);
8709 r = MsiRecordGetInteger(hrecord, 1);
8710 ok(r == 12345, "expected 12345, got %u\n", r);
8711 return retval;
8712}
8713
8714static void test_externalui(void)
8715{
8716 /* test that external UI handlers work correctly */
8717
8718 INSTALLUI_HANDLERA prev;
8719 INSTALLUI_HANDLER_RECORD prev_record;
8720 MSIHANDLE hpkg, hrecord;
8721 UINT r;
8722 INT retval = 0;
8723
8725
8728 {
8729 skip("Not enough rights to perform tests\n");
8731 return;
8732 }
8733 ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
8734
8735 hrecord = MsiCreateRecord(1);
8736 ok(hrecord, "Expected a valid record\n");
8737 r = MsiRecordSetStringA(hrecord, 0, "test message [1]");
8738 ok(r == ERROR_SUCCESS, "MsiSetString failed %u\n", r);
8739 r = MsiRecordSetInteger(hrecord, 1, 12345);
8740 ok(r == ERROR_SUCCESS, "MsiSetInteger failed %u\n", r);
8741
8742 externalui_ran = 0;
8743 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8744 ok(r == 0, "expected 0, got %u\n", r);
8745 ok(externalui_ran == 1, "external UI callback did not run\n");
8746
8747 prev = MsiSetExternalUIA(prev, 0, NULL);
8748 ok(prev == externalui_callback, "wrong callback function %p\n", prev);
8750 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8751
8753 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8754 ok(r == 0, "expected 0, got %u\n", r);
8755 ok(externalui_ran == 0, "external UI callback should not have run\n");
8756 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8757
8759
8761 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8762 ok(r == 0, "expected 0, got %u\n", r);
8763 ok(externalui_ran == 1, "external UI callback did not run\n");
8764 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8765
8766 retval = 1;
8768 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8769 ok(r == 1, "expected 1, got %u\n", r);
8770 ok(externalui_ran == 0, "external UI callback should not have run\n");
8771 ok(externalui_record_ran == 1, "external UI record callback did not run\n");
8772
8773 /* filter and context should be kept separately */
8775 ok(r == ERROR_SUCCESS, "MsiSetExternalUIRecord failed %u\n", r);
8776
8778 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
8779 ok(r == 0, "expected 0, got %u\n", r);
8780 ok(externalui_ran == 1, "external UI callback did not run\n");
8781 ok(externalui_record_ran == 0, "external UI record callback should not have run\n");
8782
8783 MsiCloseHandle(hpkg);
8785}
8786
8790 char field[4][100];
8791 int match[4]; /* should we test for a match */
8793};
8794
8797
8798static void add_message(const struct externalui_message *msg)
8799{
8800 if (!sequence)
8801 {
8802 sequence_size = 10;
8803 sequence = malloc(sequence_size * sizeof(*sequence));
8804 }
8806 {
8807 sequence_size *= 2;
8809 }
8810
8813}
8814
8815static void flush_sequence(void)
8816{
8817 free(sequence);
8818 sequence = NULL;
8820}
8821
8822static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo,
8823 const char *file, int line)
8824{
8825 static const struct externalui_message end_of_sequence = {0};
8826 const struct externalui_message *actual;
8827 int failcount = 0;
8828 int i;
8829
8830 add_message(&end_of_sequence);
8831
8832 actual = sequence;
8833
8834 while (expected->message && actual->message)
8835 {
8836 if (expected->message == actual->message)
8837 {
8838 if (expected->field_count < actual->field_count)
8839 {
8841 ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n",
8842 context, expected->message, expected->field_count, actual->field_count);
8843 failcount++;
8844 }
8845
8846 for (i = 0; i <= actual->field_count; i++)
8847 {
8848 if (expected->match[i] && strcmp(expected->field[i], actual->field[i]))
8849 {
8851 ok_(file, line) (FALSE, "%s: in msg 0x%08x field %d: expected \"%s\", got \"%s\"\n",
8852 context, expected->message, i, expected->field[i], actual->field[i]);
8853 failcount++;
8854 }
8855 }
8856
8857 expected++;
8858 actual++;
8859 }
8860 else if (expected->optional)
8861 {
8862 expected++;
8863 }
8864 else
8865 {
8867 ok_(file, line) (FALSE, "%s: the msg 0x%08x was expected, but got msg 0x%08x instead\n",
8868 context, expected->message, actual->message);
8869 failcount++;
8870 if (todo)
8871 goto done;
8872 expected++;
8873 actual++;
8874 }
8875 }
8876
8877 if (expected->message || actual->message)
8878 {
8880 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %08x - actual %08x\n",
8881 context, expected->message, actual->message);
8882 failcount++;
8883 }
8884
8885 if(todo && !failcount) /* succeeded yet marked todo */
8886 {
8887 todo_wine
8888 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
8889 }
8890
8891done:
8893}
8894
8895#define ok_sequence(exp, contx, todo) \
8896 ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__)
8897
8898/* don't use PROGRESS, which is timing-dependent,
8899 * or SHOWDIALOG, which due to a bug causes a hang on XP */
8917
8918static const struct externalui_message empty_sequence[] = {
8919 {0}
8920};
8921
8925 {0}
8926};
8927
8930 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
8931 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
8932 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
8933 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
8934 {0}
8935};
8936
8938 {INSTALLMESSAGE_INFO, 3, {"zero", "one", "two", "three"}, {1, 1, 1, 1}},
8939 {0}
8940};
8941
8943 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "name", "description", "template"}, {0, 1, 1, 1}},
8944 {0}
8945};
8946
8948 {INSTALLMESSAGE_ACTIONDATA, 3, {"{{name: }}template", "cherry", "banana", "guava"}, {1, 1, 1, 1}},
8949 {0}
8950};
8951
8953 {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
8954 {0}
8955};
8956
8958 {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8959 {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
8960 {0}
8961};
8962
8964 {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
8965 {0}
8966};
8967
8969 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "cost description", "cost template"}, {0, 1, 1, 1}},
8970 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
8971 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
8972 {0}
8973};
8974
8976 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "description", "template"}, {0, 1, 1, 1}},
8977 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8978 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
8979 {0}
8980};
8981
8983 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8984 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
8985 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8986 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8987 {0}
8988};
8989
8991 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8992 {0}
8993};
8994
8996 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
8997 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
8998 {INSTALLMESSAGE_SHOWDIALOG, 0, {"custom"}, {1}},
8999 {INSTALLMESSAGE_INFO, 2, {"DEBUG: Error [1]: Action not found: [2]", "2726", "custom"}, {1, 1, 1}},
9000 {INSTALLMESSAGE_INFO, 2, {"", "2726", "custom"}, {0, 1, 1}},
9001 {INSTALLMESSAGE_INFO, 2, {"", "custom", "0"}, {0, 1, 1}},
9002 {0}
9003};
9004
9006 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9007 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9008 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9009 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "dialog", "Dialog created"}, {0, 1, 1}},
9010 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "1"}, {0, 1, 1}},
9011 {0}
9012};
9013
9015 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "error", "", ""}, {0, 1, 1, 1}},
9016 {INSTALLMESSAGE_INFO, 2, {"", "error", "1"}, {0, 1, 1}},
9017 {INSTALLMESSAGE_SHOWDIALOG, 0, {"error"}, {1}},
9018 {0}
9019};
9020
9022 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9023 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
9024 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9025 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9026 {0}
9027};
9028
9030 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
9031 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
9032 {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
9033 {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
9034 {0}
9035};
9036
9039 {0}
9040};
9041
9043{
9044 INT retval = context ? *((INT *)context) : 0;
9045 struct externalui_message msg;
9046
9047 msg.message = message;
9048 msg.field_count = 0;
9049 strcpy(msg.field[0], string);
9050 add_message(&msg);
9051
9052 return retval;
9053}
9054
9056{
9057 INT retval = context ? *((INT *)context) : 0;
9058 struct externalui_message msg;
9059 char buffer[256];
9060 DWORD length;
9061 UINT r;
9062 int i;
9063
9064 msg.message = message;
9066 {
9067 /* trying to access the record seems to hang on some versions of Windows */
9068 msg.field_count = -1;
9069 add_message(&msg);
9070 return 1;
9071 }
9072 msg.field_count = MsiRecordGetFieldCount(hrecord);
9073 for (i = 0; i <= msg.field_count; i++)
9074 {
9075 length = sizeof(buffer);
9076 r = MsiRecordGetStringA(hrecord, i, buffer, &length);
9077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9078 memcpy(msg.field[i], buffer, min(100, length+1));
9079 }
9080
9081 /* top-level actions dump a list of all set properties; skip them since they're inconsistent */
9082 if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8))
9083 return retval;
9084
9085 add_message(&msg);
9086
9087 return retval;
9088}
9089
9091{
9092 /* test that events trigger the correct sequence of messages */
9093
9095 MSIHANDLE hdb, hpkg, hrecord;
9096 INT retval = 1;
9097 UINT r;
9098
9100
9103
9105
9107
9108 hdb = create_package_db();
9109 ok(hdb, "failed to create database\n");
9110
9111 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9112 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9114
9115 r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
9116 ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
9117 r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
9118 ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
9119
9121 add_actiontext_entry(hdb, "'custom', 'description', 'template'");
9122 add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'");
9123
9124 r = MsiOpenPackageA(NULL, &hpkg);
9125 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9126 ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
9127
9128 r = MsiOpenPackageA("nonexistent", &hpkg);
9129 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
9130 ok_sequence(openpackage_nonexistent_sequence, "MsiOpenPackage with nonexistent db", FALSE);
9131
9132 r = package_from_db(hdb, &hpkg);
9134 {
9135 skip("Not enough rights to perform tests\n");
9137 return;
9138 }
9139 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9140 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9141
9142 /* Test MsiProcessMessage */
9143 hrecord = MsiCreateRecord(3);
9144 ok(hrecord, "failed to create record\n");
9145
9146 MsiRecordSetStringA(hrecord, 0, "zero");
9147 MsiRecordSetStringA(hrecord, 1, "one");
9148 MsiRecordSetStringA(hrecord, 2, "two");
9149 MsiRecordSetStringA(hrecord, 3, "three");
9150 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_INFO, hrecord);
9151 ok(r == 1, "Expected 1, got %d\n", r);
9152 ok_sequence(processmessage_info_sequence, "MsiProcessMessage(INSTALLMESSAGE_INFO)", FALSE);
9153
9154 MsiRecordSetStringA(hrecord, 1, "name");
9155 MsiRecordSetStringA(hrecord, 2, "description");
9156 MsiRecordSetStringA(hrecord, 3, "template");
9158 ok(r == 1, "Expected 1, got %d\n", r);
9159 ok_sequence(processmessage_actionstart_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONSTART)", FALSE);
9160
9161 MsiRecordSetStringA(hrecord, 0, "apple");
9162 MsiRecordSetStringA(hrecord, 1, "cherry");
9163 MsiRecordSetStringA(hrecord, 2, "banana");
9164 MsiRecordSetStringA(hrecord, 3, "guava");
9166 ok(r == 1, "Expected 1, got %d\n", r);
9167 ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
9168
9169 /* non-internal error */
9170 MsiRecordSetStringA(hrecord, 0, NULL);
9171 MsiRecordSetInteger(hrecord, 1, 1311);
9172 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9173 ok(r == 1, "Expected 1, got %d\n", r);
9174 ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
9175
9176 /* internal error */
9177 MsiRecordSetStringA(hrecord, 0, NULL);
9178 MsiRecordSetInteger(hrecord, 1, 2726);
9179 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9180 ok(r == 0, "Expected 0, got %d\n", r);
9181 ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
9182
9183 /* with format field */
9184 MsiRecordSetStringA(hrecord, 0, "starfruit");
9185 r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
9186 ok(r == 1, "Expected 1, got %d\n", r);
9187 ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
9188
9189 /* Test a standard action */
9190 r = MsiDoActionA(hpkg, "CostInitialize");
9191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9192 ok_sequence(doaction_costinitialize_sequence, "MsiDoAction(\"CostInitialize\")", FALSE);
9193
9194 /* Test a custom action */
9195 r = MsiDoActionA(hpkg, "custom");
9196 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9197 ok_sequence(doaction_custom_sequence, "MsiDoAction(\"custom\")", FALSE);
9198
9199 /* close the package */
9200 MsiCloseHandle(hpkg);
9201 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9202
9203 /* Test dialogs */
9204 hdb = create_package_db();
9205 ok(hdb, "failed to create database\n");
9206
9207 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9209
9211 add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'");
9212
9214 add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'");
9215
9216 r = package_from_db(hdb, &hpkg);
9217 ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
9218 ok_sequence(openpackage_sequence, "MsiOpenPackage with valid db", FALSE);
9219
9220 /* Test a custom action */
9221 r = MsiDoActionA(hpkg, "custom");
9222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9223 ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
9224
9225 retval = 2;
9226 r = MsiDoActionA(hpkg, "custom");
9227 ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
9228 ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
9229
9230 retval = 0;
9231 r = MsiDoActionA(hpkg, "custom");
9232 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9233 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9234
9235 r = MsiDoActionA(hpkg, "dialog");
9236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9237 ok_sequence(doaction_dialog_sequence, "MsiDoAction(\"dialog\")", FALSE);
9238
9239 retval = -1;
9240 r = MsiDoActionA(hpkg, "error");
9241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9242 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9243
9244 r = MsiDoActionA(hpkg, "error");
9245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9246 ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
9247
9248 retval = -2;
9249 r = MsiDoActionA(hpkg, "custom");
9250 ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
9251 ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
9252
9253 retval = 3;
9254 r = MsiDoActionA(hpkg, "dialog");
9255 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9256 ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
9257
9258 retval = 12345;
9259 r = MsiDoActionA(hpkg, "dialog");
9260 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
9261 ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
9262
9263 MsiCloseHandle(hpkg);
9264 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9265
9266 MsiCloseHandle(hrecord);
9269 DeleteFileA("forcecodepage.idt");
9270}
9271
9273 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn", "", ""}, {0, 1, 1, 1}},
9274 {INSTALLMESSAGE_INFO, 2, {"", "spawn", ""}, {0, 1, 1}},
9275 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn"}, {1}},
9276 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn", "Dialog created"}, {0, 1, 1}},
9277
9278 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9279 {INSTALLMESSAGE_INFO, 2, {"", "custom", ""}, {0, 1, 1}},
9280 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9281
9282 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child1", "Dialog created"}, {0, 1, 1}},
9283
9284 {INSTALLMESSAGE_INFO, 2, {"", "spawn", "2"}, {0, 1, 1}},
9285 {0}
9286};
9287
9289 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "spawn2", "", ""}, {0, 1, 1, 1}},
9290 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9291 {INSTALLMESSAGE_SHOWDIALOG, 0, {"spawn2"}, {1}},
9292 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "spawn2", "Dialog created"}, {0, 1, 1}},
9293
9294 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
9295 {INSTALLMESSAGE_INFO, 2, {"", "custom", "2"}, {0, 1, 1}},
9296 {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
9297
9298 {INSTALLMESSAGE_ACTIONSTART, 2, {"", "child2", "Dialog created"}, {0, 1, 1}},
9299
9300 {INSTALLMESSAGE_INFO, 2, {"", "spawn2", "2"}, {0, 1, 1}},
9301 {0}
9302};
9303
9304static void test_controlevent(void)
9305{
9307 MSIHANDLE hdb, hpkg;
9308 UINT r;
9309
9311 {
9312 skip("interactive ControlEvent tests\n");
9313 return;
9314 }
9315
9317
9320
9322
9324
9325 hdb = create_package_db();
9326 ok(hdb, "failed to create database\n");
9327
9328 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9329 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9331
9333 add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'");
9334 add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'");
9335 add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'");
9336 add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'");
9337
9339 add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9340 add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9341 add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9342 add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'");
9343
9345 add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1");
9346 add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1");
9347
9349 add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'");
9350
9351 /* SpawnDialog and EndDialog should trigger after all other events */
9352 add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1");
9353 add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2");
9354
9355 /* Multiple dialog events cause only the last one to be triggered */
9356 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1");
9357 add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2");
9358 add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3");
9359
9360 r = package_from_db(hdb, &hpkg);
9361 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9362 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9363
9364 r = MsiDoActionA(hpkg, "spawn");
9365 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9366 ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE);
9367
9368 r = MsiDoActionA(hpkg, "spawn2");
9369 ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
9370 ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE);
9371
9372 MsiCloseHandle(hpkg);
9373 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9374
9377 DeleteFileA("forcecodepage.idt");
9378}
9379
9381 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9382 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9383
9384 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9385 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9386 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9387 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9388 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9389
9390 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9391 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9392 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9393
9394 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9395 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
9396 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9397
9398 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9399 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9400 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9401
9402 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9403 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9404 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9405
9406 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9407 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9408
9409 /* property dump */
9410
9411 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9412 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9413 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9414 {0}
9415};
9416
9418 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9419 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9420
9421 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9422 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9423 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9424
9425 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9426 {0}
9427};
9428
9430 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9431 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9432
9433 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9434 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9435 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9436 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9437
9438 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9439 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9440 {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1},
9441
9442 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9443 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}},
9444 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9445
9446 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}},
9447 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9448 {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}},
9449
9450 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}},
9451 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9452 {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}},
9453
9454 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9455 {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1},
9456
9457 /* property dump */
9458
9459 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9460 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9461 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9462 {0}
9463};
9464
9466 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}},
9467 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9468
9469 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9470 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9471 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9472 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9473
9474 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
9475 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}},
9476 {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}},
9477
9478 /* property dump */
9479
9480 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1},
9481 {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1},
9482 {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}},
9483 {0}
9484};
9485
9488
9489 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9490 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9491 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9492 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9493 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9494
9495 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}},
9496 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}},
9497
9498 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}},
9499 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}},
9500 {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}},
9501
9502 {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}},
9503
9504 /* property dump */
9505
9506 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9508 {0}
9509};
9510
9513
9514 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9515 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}},
9516 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9517 {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}},
9518 {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}},
9519
9520 {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}},
9521 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}},
9522 {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}},
9523
9524 /* property dump */
9525
9526 {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}},
9528 {0}
9529};
9530
9531/* tests involving top-level actions: INSTALL, ExecuteAction */
9532static void test_top_level_action(void)
9533{
9535 MSIHANDLE hdb, hpkg;
9536 UINT r;
9537 char msifile_absolute[MAX_PATH];
9538
9540
9543
9545
9547
9548 hdb = create_package_db();
9549 ok(hdb, "failed to create database\n");
9550
9551 create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
9552 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
9553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9554
9556 add_property_entry(hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'");
9557
9559 add_install_execute_sequence_entry(hdb, "'CostInitialize', '', 1");
9560 add_install_execute_sequence_entry(hdb, "'FileCost', '', 2");
9561 add_install_execute_sequence_entry(hdb, "'CostFinalize', '', 3");
9562
9564 add_install_ui_sequence_entry(hdb, "'AppSearch', '', 1");
9565
9566 MsiDatabaseCommit(hdb);
9567
9568 /* for some reason we have to open the package from file using an absolute path */
9569 MsiCloseHandle(hdb);
9570 GetFullPathNameA(msifile, MAX_PATH, msifile_absolute, NULL);
9571 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9572 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9573 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9574
9575 /* test INSTALL */
9576 r = MsiDoActionA(hpkg, "INSTALL");
9577 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9578 ok_sequence(toplevel_install_sequence, "INSTALL (no UI)", FALSE);
9579
9580 /* test INSTALL with reduced+ UI */
9581 /* for some reason we need to re-open the package to change the internal UI */
9582 MsiCloseHandle(hpkg);
9583 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9585 r = MsiOpenPackageA(msifile_absolute, &hpkg);
9586 ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r);
9587 ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
9588
9589 r = MsiDoActionA(hpkg, "INSTALL");
9590 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9591 ok_sequence(toplevel_install_ui_sequence, "INSTALL (reduced+ UI)", TRUE);
9592
9593 /* test ExecuteAction with EXECUTEACTION property unset */
9594 MsiSetPropertyA(hpkg, "EXECUTEACTION", NULL);
9595 r = MsiDoActionA(hpkg, "ExecuteAction");
9596 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9597 ok_sequence(toplevel_executeaction_install_sequence, "ExecuteAction: INSTALL", FALSE);
9598
9599 /* test ExecuteAction with EXECUTEACTION property set */
9600 MsiSetPropertyA(hpkg, "EXECUTEACTION", "CostInitialize");
9601 r = MsiDoActionA(hpkg, "ExecuteAction");
9602 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9603 ok_sequence(toplevel_executeaction_costinitialize_sequence, "ExecuteAction: CostInitialize", FALSE);
9604
9605 MsiCloseHandle(hpkg);
9606 ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
9607
9608 /* test MsiInstallProduct() */
9609 r = MsiInstallProductA(msifile_absolute, NULL);
9610 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
9611 ok_sequence(toplevel_msiinstallproduct_sequence, "MsiInstallProduct()", TRUE);
9612
9613 r = MsiInstallProductA(msifile_absolute, "ACTION=custom");
9614 todo_wine
9615 ok(r == ERROR_INSTALL_FAILURE, "expected ERROR_INSTALL_FAILURE, got %u\n", r);
9616 ok_sequence(toplevel_msiinstallproduct_custom_sequence, "MsiInstallProduct(ACTION=custom)", TRUE);
9617
9620 DeleteFileA("forcecodepage.idt");
9621}
9622
9624{
9625 char temp_path[MAX_PATH], prev_path[MAX_PATH];
9627 BOOL ret = FALSE;
9628 DWORD len;
9629
9631
9632 if (pIsWow64Process)
9633 pIsWow64Process(GetCurrentProcess(), &is_wow64);
9634
9635 GetCurrentDirectoryA(MAX_PATH, prev_path);
9638
9641
9642 if (len && (CURR_DIR[len - 1] == '\\'))
9643 CURR_DIR[len - 1] = 0;
9644
9645 /* Create a restore point ourselves so we circumvent the multitude of restore points
9646 * that would have been created by all the installation and removal tests.
9647 *
9648 * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
9649 * creation of restore points.
9650 */
9651 if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
9652 {
9653 memset(&status, 0, sizeof(status));
9655 }
9656
9658 test_doaction();
9661 test_props();
9667 test_states();
9682 test_access();
9688 test_costs();
9694
9695 if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
9696 {
9698 if (ret)
9699 remove_restore_point(status.llSequenceNumber);
9700 }
9701
9702 SetCurrentDirectoryA(prev_path);
9703}
#define add_message(msg)
Definition: SystemMenu.c:98
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define broken(x)
Definition: _sntprintf.h:21
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isalpha(c)
Definition: acclib.h:74
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
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
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:33
#define U(x)
Definition: wordpad.c:45
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:49
#define _stricmp
Definition: cat.c:22
static const WCHAR msifile2W[]
Definition: db.c:37
static const char * msifile2
Definition: db.c:34
static const CHAR suminfo[]
Definition: db.c:2206
#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
#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
unsigned int idx
Definition: utils.c:41
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:4828
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3327
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:2533
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3263
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2325
LONG WINAPI RegSetValueA(HKEY hKeyOriginal, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData)
Definition: reg.c:4983
LONG WINAPI RegDeleteKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1286
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2361
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:2859
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:3691
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:4038
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 CheckTokenMembership(IN HANDLE ExistingTokenHandle, IN PSID SidToCheck, OUT PBOOL IsMember)
Definition: token.c:21
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 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:674
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:698
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3637
#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
static const WCHAR substrW[]
Definition: string.c:60
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:404
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
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:636
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
UINT WINAPI GetSystemWow64DirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2438
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2337
DWORD WINAPI GetFullPathNameA(IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
Definition: path.c:993
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
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
const WCHAR * action
Definition: action.c:7479
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
Definition: database.c:853
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:955
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:1396
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:1128
UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
Definition: install.c:1052
UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, INSTALLSTATE iState)
Definition: install.c:1380
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
Definition: msi.c:82
UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD handler, DWORD filter, void *context, INSTALLUI_HANDLER_RECORD *prev)
Definition: msi.c:4155
BOOL is_wow64
Definition: msi.c:54
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, DWORD dwMessageFilter, void *pvContext)
Definition: msi.c:2309
UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, const char *szProperty, char *szValue, DWORD *pccbValue)
Definition: msi.c:2596
INSTALLSTATE WINAPI MsiGetComponentPathExA(LPCSTR product, LPCSTR comp, LPCSTR usersid, MSIINSTALLCONTEXT ctx, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2866
UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, const WCHAR *szProperty, WCHAR *szValue, DWORD *pccbValue)
Definition: msi.c:2656
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, LPDWORD pcchValueBuf)
Definition: msi.c:1256
UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR szPatchPackages, LPCSTR szProductCode, LPCSTR szPropertiesList)
Definition: msi.c:426
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
Definition: msi.c:3029
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage, INSTALLTYPE eInstallType, LPCSTR szCommandLine)
Definition: msi.c:288
UINT WINAPI MsiEnumComponentCostsA(MSIHANDLE handle, const char *component, DWORD index, INSTALLSTATE state, char *drive, DWORD *buflen, int *cost, int *temp)
Definition: msi.c:1927
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
Definition: package.c:1669
UINT WINAPI MsiSetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
Definition: package.c:2067
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
Definition: package.c:1674
UINT WINAPI MsiGetPropertyW(MSIHANDLE hinst, const WCHAR *name, WCHAR *buf, DWORD *sz)
Definition: package.c:2385
UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz)
Definition: package.c:2313
INT WINAPI MsiProcessMessage(MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, MSIHANDLE hRecord)
Definition: package.c:2017
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:937
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:584
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1222
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:619
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:853
#define assert(x)
Definition: debug.h:53
static unsigned char buff[32768]
Definition: fatten.c:17
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
#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
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:744
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const GUID * guid
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
#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(buf, format,...)
Definition: sprintf.c:55
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2063
static HINSTANCE hkernel32
Definition: process.c:66
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static INT CALLBACK externalui_message_callback(void *context, UINT message, MSIHANDLE hrecord)
Definition: package.c:9055
#define add_install_ui_sequence_entry(hdb, values)
Definition: package.c:809
static void remove_restore_point(DWORD seq_number)
Definition: package.c:1072
static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val)
Definition: package.c:6147
#define add_signature_entry(hdb, values)
Definition: package.c:786
static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
Definition: package.c:951
static UINT create_complocator_table(MSIHANDLE hdb)
Definition: package.c:622
static const struct externalui_message openpackage_nonexistent_sequence[]
Definition: package.c:8922
static UINT create_appsearch_table(MSIHANDLE hdb)
Definition: package.c:495
static const struct externalui_message toplevel_install_ui_sequence[]
Definition: package.c:9417
static void test_removefiles(void)
Definition: package.c:3861
static UINT create_control_table(MSIHANDLE hdb)
Definition: package.c:681
static void test_property_table(void)
Definition: package.c:2369
static void test_formatrecord_tables(void)
Definition: package.c:2747
static UINT create_install_ui_sequence_table(MSIHANDLE hdb)
Definition: package.c:572
static void test_access(void)
Definition: package.c:7749
#define add_install_execute_sequence_entry(hdb, values)
Definition: package.c:805
static void ok_sequence_(const struct externalui_message *expected, const char *context, BOOL todo, const char *file, int line)
Definition: package.c:8822
static void test_doaction(void)
Definition: package.c:1105
static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
Definition: package.c:1060
static const WCHAR msifileW[]
Definition: package.c:38
static void test_controlevent(void)
Definition: package.c:9304
static LPSTR
Definition: package.c:41
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: package.c:212
static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[]
Definition: package.c:9511
static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR usersid)
Definition: package.c:329
#define add_control_entry(hdb, values)
Definition: package.c:842
static const struct externalui_message toplevel_install_sequence[]
Definition: package.c:9380
static char * get_user_sid(void)
Definition: package.c:126
static UINT create_feature_table(MSIHANDLE hdb)
Definition: package.c:436
static const struct externalui_message doaction_custom_cancel_sequence[]
Definition: package.c:8990
static UINT create_reglocator_table(MSIHANDLE hdb)
Definition: package.c:506
static void test_MsiApplyPatch(void)
Definition: package.c:8431
static struct externalui_message * sequence
Definition: package.c:8795
static const struct externalui_message doaction_costinitialize_sequence[]
Definition: package.c:8968
static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case)
Definition: package.c:2140
#define add_component_entry(hdb, values)
Definition: package.c:759
static const struct externalui_message processmessage_actionstart_sequence[]
Definition: package.c:8942
#define add_dialog_entry(hdb, values)
Definition: package.c:838
static UINT create_launchcondition_table(MSIHANDLE hdb)
Definition: package.c:538
static void test_msipackage(void)
Definition: package.c:2562
static const struct access_res create[16]
Definition: package.c:7644
static const struct externalui_message toplevel_msiinstallproduct_sequence[]
Definition: package.c:9486
static void test_installprops(void)
Definition: package.c:5573
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:3033
static const char msifile[]
Definition: package.c:37
static const struct externalui_message doaction_dialog_12345_sequence[]
Definition: package.c:9029
static UINT create_upgrade_table(MSIHANDLE hdb)
Definition: package.c:729
static INT CALLBACK externalui_callback(void *context, UINT message_type, LPCSTR message)
Definition: package.c:8692
static UINT create_feature_components_table(MSIHANDLE hdb)
Definition: package.c:453
static const struct externalui_message processmessage_error_format_sequence[]
Definition: package.c:8963
#define add_actiontext_entry(hdb, values)
Definition: package.c:850
static int externalui_record_ran
Definition: package.c:8699
static int externalui_ran
Definition: package.c:8690
#define add_media_entry(hdb, values)
Definition: package.c:813
static void test_appsearch_reglocator(void)
Definition: package.c:4376
static UINT try_query(MSIHANDLE hdb, LPCSTR szQuery)
Definition: package.c:2523
#define update_ProductCode_property(hdb, value)
Definition: package.c:802
#define add_ccpsearch_entry(hdb, values)
Definition: package.c:818
static const struct externalui_message doaction_dialog_3_sequence[]
Definition: package.c:9021
static UINT create_install_execute_sequence_table(MSIHANDLE hdb)
Definition: package.c:560
static UINT create_controlevent_table(MSIHANDLE hdb)
Definition: package.c:702
static UINT create_inilocator_table(MSIHANDLE hdb)
Definition: package.c:634
static void test_props(void)
Definition: package.c:2153
static void test_complocator(void)
Definition: package.c:5906
static UINT create_component_table(MSIHANDLE hdb)
Definition: package.c:421
static REGSAM
Definition: package.c:43
static void test_MsiDatabaseCommit(void)
Definition: package.c:8645
static void test_appsearch(void)
Definition: package.c:4010
#define ok_sequence(exp, contx, todo)
Definition: package.c:8895
static void test_MsiGetProductProperty(void)
Definition: package.c:7948
#define add_complocator_entry(hdb, values)
Definition: package.c:825
#define add_inilocator_entry(hdb, values)
Definition: package.c:829
static void test_appsearch_drlocator(void)
Definition: package.c:5195
static BOOL create_file_with_version(const CHAR *name, LONG ms, LONG ls)
Definition: package.c:1012
static void test_MsiGetSourcePath(void)
Definition: package.c:6164
#define add_file_entry(hdb, values)
Definition: package.c:777
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:3007
static INT CALLBACK externalui_record_callback(void *context, UINT message_type, MSIHANDLE hrecord)
Definition: package.c:8701
static UINT create_actiontext_table(MSIHANDLE hdb)
Definition: package.c:717
static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, LPCSTR guid, LPSTR usersid, BOOL dir)
Definition: package.c:263
static void test_settargetpath(void)
Definition: package.c:1219
struct _tagVS_VERSIONINFO VS_VERSIONINFO
static const struct externalui_message controlevent_spawn_sequence[]
Definition: package.c:9272
static void test_gettargetpath_bad(void)
Definition: package.c:1135
static int sequence_size
Definition: package.c:8796
static const struct access_res create_close[16]
Definition: package.c:7684
static const struct externalui_message processmessage_internal_error_sequence[]
Definition: package.c:8957
static void flush_sequence(void)
Definition: package.c:8815
static UINT create_drlocator_table(MSIHANDLE hdb)
Definition: package.c:609
static const struct externalui_message processmessage_error_sequence[]
Definition: package.c:8952
static void test_sourcedir(void)
Definition: package.c:7279
static void test_MsiApplyMultiplePatches(void)
Definition: package.c:8387
static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE
Definition: package.c:8900
static BOOL is_root(const char *path)
Definition: package.c:1081
static UINT add_reglocator_entry(MSIHANDLE hdb, const char *sig, UINT root, const char *path, const char *name, UINT type)
Definition: package.c:858
static DWORD
Definition: package.c:43
static char CURR_DIR[MAX_PATH]
Definition: package.c:39
static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
Definition: package.c:7704
static void test_MsiSetProperty(void)
Definition: package.c:8272
static void test_ccpsearch(void)
Definition: package.c:5860
static MSIHANDLE create_package_db(void)
Definition: package.c:921
static PBOOL
Definition: package.c:45
static BOOL is_process_limited(void)
Definition: package.c:71
static void test_createpackage(void)
Definition: package.c:1086
static void test_launchconditions(void)
Definition: package.c:5811
static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
Definition: package.c:1200
static const struct externalui_message toplevel_executeaction_install_sequence[]
Definition: package.c:9429
static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
Definition: package.c:2329
static STATEMGRSTATUS *static void init_functionpointers(void)
Definition: package.c:49
static UINT create_remove_file_table(MSIHANDLE hdb)
Definition: package.c:481
static UINT create_custom_action_table(MSIHANDLE hdb)
Definition: package.c:649
static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
Definition: package.c:383
static void test_emptypackage(void)
Definition: package.c:7783
static UINT try_query_param(MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec)
Definition: package.c:2495
#define add_property_entry(hdb, values)
Definition: package.c:796
#define add_feature_components_entry(hdb, values)
Definition: package.c:773
static void test_featureparents(void)
Definition: package.c:5403
static void test_shortlongsource(void)
Definition: package.c:6945
#define add_drlocator_entry(hdb, values)
Definition: package.c:821
static LPCWSTR
Definition: package.c:44
static UINT create_property_table(MSIHANDLE hdb)
Definition: package.c:549
static void test_condition(void)
Definition: package.c:1387
static void test_appsearch_inilocator(void)
Definition: package.c:4958
static const struct access_res create_commit[16]
Definition: package.c:7664
static UINT run_query(MSIHANDLE hdb, const char *query)
Definition: package.c:405
#define add_feature_entry(hdb, values)
Definition: package.c:768
static const struct externalui_message closehandle_sequence[]
Definition: package.c:9037
static const struct externalui_message toplevel_executeaction_costinitialize_sequence[]
Definition: package.c:9465
static const struct externalui_message empty_sequence[]
Definition: package.c:8918
#define add_launchcondition_entry(hdb, values)
Definition: package.c:792
static void test_costs(void)
Definition: package.c:8442
static void test_appsearch_complocator(void)
Definition: package.c:4127
#define update_ProductVersion_property(hdb, value)
Definition: package.c:799
#define add_controlevent_entry(hdb, values)
Definition: package.c:846
static const struct externalui_message processmessage_info_sequence[]
Definition: package.c:8937
static void set_summary_dword(MSIHANDLE hdb, DWORD pid, DWORD value)
Definition: package.c:2545
static LPDWORD
Definition: package.c:41
static const struct externalui_message doaction_custom_fullui_sequence[]
Definition: package.c:8982
static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
Definition: package.c:146
static const struct externalui_message doaction_dialog_error_sequence[]
Definition: package.c:9014
static const struct externalui_message doaction_custom_sequence[]
Definition: package.c:8975
static const struct externalui_message processmessage_actiondata_sequence[]
Definition: package.c:8947
static MSIINSTALLCONTEXT
Definition: package.c:41
static void create_file_data(LPCSTR name, LPCSTR data)
Definition: package.c:976
#define test_file_access(file, ares)
Definition: package.c:7747
static const struct externalui_message doaction_dialog_nonexistent_sequence[]
Definition: package.c:8995
static UINT set_summary_info(MSIHANDLE hdb)
Definition: package.c:876
#define add_directory_entry(hdb, values)
Definition: package.c:764
static INT CALLBACK externalui_message_string_callback(void *context, UINT message, LPCSTR string)
Definition: package.c:9042
static UINT create_dialog_table(MSIHANDLE hdb)
Definition: package.c:662
static void set_summary_str(MSIHANDLE hdb, DWORD pid, LPCSTR value)
Definition: package.c:2528
static LPCSTR
Definition: package.c:41
static void search_absolute_directory(LPSTR absolute, LPCSTR relative)
Definition: package.c:5165
static void test_top_level_action(void)
Definition: package.c:9532
static void delete_win_ini(LPCSTR file)
Definition: package.c:4947
static int sequence_count
Definition: package.c:8796
static void create_test_file(const CHAR *name)
Definition: package.c:992
static UINT create_signature_table(MSIHANDLE hdb)
Definition: package.c:520
static const struct externalui_message openpackage_sequence[]
Definition: package.c:8928
#define GET_PROC(mod, func)
static void test_externalui_message(void)
Definition: package.c:9090
static const struct externalui_message controlevent_spawn2_sequence[]
Definition: package.c:9288
static UINT create_media_table(MSIHANDLE hdb)
Definition: package.c:584
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: package.c:244
static void test_externalui(void)
Definition: package.c:8714
#define add_upgrade_entry(hdb, values)
Definition: package.c:854
#define roundpos(a, b, r)
Definition: package.c:1010
#define add_appsearch_entry(hdb, values)
Definition: package.c:782
static void test_states(void)
Definition: package.c:3060
static UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
Definition: package.c:745
static const struct externalui_message doaction_dialog_sequence[]
Definition: package.c:9005
static UINT create_file_table(MSIHANDLE hdb)
Definition: package.c:464
static void test_formatrecord2(void)
Definition: package.c:2657
#define add_custom_action_entry(hdb, values)
Definition: package.c:834
static UINT create_ccpsearch_table(MSIHANDLE hdb)
Definition: package.c:599
#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:1719
#define min(a, b)
Definition: monoChain.cc:55
LANGID langid
Definition: msctf.idl:644
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
Definition: action.c:49
#define INSTALLPROPERTY_LOCALPACKAGEA
Definition: msi.h:342
@ 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
@ 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:469
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:518
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1148
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
unsigned int UINT
Definition: ndis.h:50
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
#define BOOL
Definition: nt_native.h:43
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#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:1494
#define L(x)
Definition: ntvdm.h:50
#define VS_VERSION_INFO
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define RT_VERSION
Definition: pedump.c:376
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
#define delete_key(r, p, s)
Definition: reg_test.h:64
static FILE * out
Definition: regtests2xml.c:44
static calc_node_t temp
Definition: rpn_ieee.c:38
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_NEUTRAL
Definition: nls.h:167
int winetest_interactive
#define S(x)
Definition: test.h:217
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI SRSetRestorePointA(PRESTOREPOINTINFOA pRestorePtSpec, PSTATEMGRSTATUS pSMgrStatus)
Definition: sfc.c:54
HRESULT hr
Definition: shlfolder.c:183
DWORD WINAPI SRRemoveRestorePoint(DWORD dwNumber)
Definition: srclient_main.c:71
#define APPLICATION_INSTALL
#define BEGIN_NESTED_SYSTEM_CHANGE
#define END_NESTED_SYSTEM_CHANGE
WCHAR szKey[17]
Definition: fusionpriv.h:382
CHAR szDescription[MAX_DESC]
WORD wProcessorLevel
Definition: winbase.h:1180
WORD wChildren[1]
Definition: package.c:1006
WORD wPadding1[1]
Definition: package.c:1003
VS_FIXEDFILEINFO Value
Definition: package.c:1004
WORD wPadding2[1]
Definition: package.c:1005
WCHAR szKey[1]
Definition: package.c:1002
DWORD lasterr
Definition: package.c:7640
BOOL ignore
Definition: package.c:7641
BOOL gothandle
Definition: package.c:7639
Definition: cookie.c:202
Definition: http.c:7252
char field[4][100]
Definition: package.c:8790
Definition: parser.c:44
Definition: fci.c:127
Definition: copy.c:22
Definition: parser.c:49
Definition: match.c:28
Definition: tftpd.h:60
Definition: name.c:39
Definition: ps.c:97
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
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
Definition: pdh_main.c:94
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetLogicalDrives(void)
Definition: disk.c:110
#define DRIVE_FIXED
Definition: winbase.h:252
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define WINAPI
Definition: msvc.h:6
int INSTALLSTATE
Definition: winemsi.idl:31
int MSICONDITION
Definition: winemsi.idl:29
unsigned long MSIHANDLE
Definition: winemsi.idl:27
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961
#define ERROR_INSTALL_PACKAGE_INVALID
Definition: winerror.h:978
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:960
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define ERROR_INVALID_HANDLE_STATE
Definition: winerror.h:967
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965
#define ERROR_PRODUCT_VERSION
Definition: winerror.h:996
#define ERROR_UNKNOWN_FEATURE
Definition: winerror.h:964
#define ERROR_PATCH_PACKAGE_OPEN_FAILED
Definition: winerror.h:993
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:973
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:984
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeLimited
Definition: winnt_old.h:2488
@ TokenElevationTypeDefault
Definition: winnt_old.h:2486
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define SM_CYSCREEN
Definition: winuser.h:960
#define MB_ICONHAND
Definition: winuser.h:788
#define SM_CXSCREEN
Definition: winuser.h:959
#define MAKEINTRESOURCE
Definition: winuser.h:591
int WINAPI GetSystemMetrics(_In_ int)
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define TOKEN_QUERY
Definition: setypes.h:928
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
@ TokenUser
Definition: setypes.h:966
@ TokenElevationType
Definition: setypes.h:983
#define DOMAIN_ALIAS_RID_POWER_USERS
Definition: setypes.h:655
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
static int insert
Definition: xmllint.c:138
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193