Release 1.4.1.
[wine] / dlls / msi / tests / action.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  * Copyright 2010 Hans Leidekker for CodeWeavers
4  *
5  * Tests concentrating on standard actions
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 _WIN32_MSI 300
23 #include <stdio.h>
24
25 #include <windows.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <fci.h>
30 #include <srrestoreptapi.h>
31
32 #include "wine/test.h"
33
34 static UINT (WINAPI *pMsiQueryComponentStateA)
35     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
36 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
37     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
38 static UINT (WINAPI *pMsiSourceListGetInfoA)
39     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
40 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
41     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
42
43 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *);
44 static BOOL (WINAPI *pGetTokenInformation)(HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD);
45 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE);
46 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
47 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
48
49 static HMODULE hsrclient;
50 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
51 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA *, STATEMGRSTATUS *);
52
53 static BOOL is_wow64;
54 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
55
56 static const char *msifile = "msitest.msi";
57 static CHAR CURR_DIR[MAX_PATH];
58 static CHAR PROG_FILES_DIR[MAX_PATH];
59 static CHAR COMMON_FILES_DIR[MAX_PATH];
60 static CHAR APP_DATA_DIR[MAX_PATH];
61 static CHAR WINDOWS_DIR[MAX_PATH];
62
63 /* msi database data */
64
65 static const char component_dat[] =
66     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
67     "s72\tS38\ts72\ti2\tS255\tS72\n"
68     "Component\tComponent\n"
69     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
70     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
71     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
72     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
73     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
74     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
75     "component\t\tMSITESTDIR\t0\t1\tfile\n"
76     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
77
78 static const char directory_dat[] =
79     "Directory\tDirectory_Parent\tDefaultDir\n"
80     "s72\tS72\tl255\n"
81     "Directory\tDirectory\n"
82     "CABOUTDIR\tMSITESTDIR\tcabout\n"
83     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
84     "FIRSTDIR\tMSITESTDIR\tfirst\n"
85     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
86     "NEWDIR\tCABOUTDIR\tnew\n"
87     "ProgramFilesFolder\tTARGETDIR\t.\n"
88     "TARGETDIR\t\tSourceDir";
89
90 static const char feature_dat[] =
91     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
92     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
93     "Feature\tFeature\n"
94     "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
95     "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
96     "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
97     "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
98     "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
99     "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
100     "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
101
102 static const char feature_comp_dat[] =
103     "Feature_\tComponent_\n"
104     "s38\ts72\n"
105     "FeatureComponents\tFeature_\tComponent_\n"
106     "Five\tFive\n"
107     "Four\tFour\n"
108     "One\tOne\n"
109     "Three\tThree\n"
110     "Two\tTwo\n"
111     "feature\tcomponent\n"
112     "service_feature\tservice_comp\n";
113
114 static const char file_dat[] =
115     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
116     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
117     "File\tFile\n"
118     "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
119     "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
120     "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
121     "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
122     "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
123     "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
124     "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
125
126 static const char install_exec_seq_dat[] =
127     "Action\tCondition\tSequence\n"
128     "s72\tS255\tI2\n"
129     "InstallExecuteSequence\tAction\n"
130     "AllocateRegistrySpace\tNOT Installed\t1550\n"
131     "CostFinalize\t\t1000\n"
132     "CostInitialize\t\t800\n"
133     "FileCost\t\t900\n"
134     "ResolveSource\t\t950\n"
135     "MoveFiles\t\t1700\n"
136     "InstallFiles\t\t4000\n"
137     "DuplicateFiles\t\t4500\n"
138     "WriteEnvironmentStrings\t\t4550\n"
139     "CreateShortcuts\t\t4600\n"
140     "InstallServices\t\t5000\n"
141     "InstallFinalize\t\t6600\n"
142     "InstallInitialize\t\t1500\n"
143     "InstallValidate\t\t1400\n"
144     "LaunchConditions\t\t100\n"
145     "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
146
147 static const char media_dat[] =
148     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
149     "i2\ti4\tL64\tS255\tS32\tS72\n"
150     "Media\tDiskId\n"
151     "1\t3\t\t\tDISK1\t\n"
152     "2\t5\t\tmsitest.cab\tDISK2\t\n";
153
154 static const char property_dat[] =
155     "Property\tValue\n"
156     "s72\tl0\n"
157     "Property\tProperty\n"
158     "DefaultUIFont\tDlgFont8\n"
159     "HASUIRUN\t0\n"
160     "INSTALLLEVEL\t3\n"
161     "InstallMode\tTypical\n"
162     "Manufacturer\tWine\n"
163     "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
164     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
165     "ProductID\tnone\n"
166     "ProductLanguage\t1033\n"
167     "ProductName\tMSITEST\n"
168     "ProductVersion\t1.1.1\n"
169     "PROMPTROLLBACKCOST\tP\n"
170     "Setup\tSetup\n"
171     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
172     "AdminProperties\tPOSTADMIN\n"
173     "ROOTDRIVE\tC:\\\n"
174     "SERVNAME\tTestService\n"
175     "SERVDISP\tTestServiceDisp\n"
176     "MSIFASTINSTALL\t1\n";
177
178 static const char environment_dat[] =
179     "Environment\tName\tValue\tComponent_\n"
180     "s72\tl255\tL255\ts72\n"
181     "Environment\tEnvironment\n"
182     "Var1\t=-MSITESTVAR1\t1\tOne\n"
183     "Var2\tMSITESTVAR2\t1\tOne\n"
184     "Var3\t=-MSITESTVAR3\t1\tOne\n"
185     "Var4\tMSITESTVAR4\t1\tOne\n"
186     "Var5\t-MSITESTVAR5\t\tOne\n"
187     "Var6\tMSITESTVAR6\t\tOne\n"
188     "Var7\t!-MSITESTVAR7\t\tOne\n"
189     "Var8\t!-*MSITESTVAR8\t\tOne\n"
190     "Var9\t=-MSITESTVAR9\t\tOne\n"
191     "Var10\t=MSITESTVAR10\t\tOne\n"
192     "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
193     "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
194     "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
195     "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
196     "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
197     "Var16\t=MSITESTVAR14\t;1;\tOne\n"
198     "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
199     "Var18\t=MSITESTVAR16\t 1 \tOne\n"
200     "Var19\t+-MSITESTVAR17\t1\tOne\n"
201     "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
202     "Var21\t+-MSITESTVAR18\t1\tOne\n"
203     "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
204     "Var23\t+-MSITESTVAR19\t1\tOne\n"
205     "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
206     "Var25\t+-MSITESTVAR20\t1\tOne\n"
207     "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
208
209 static const char service_install_dat[] =
210     "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
211     "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
212     "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
213     "ServiceInstall\tServiceInstall\n"
214     "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription";
215
216 static const char service_control_dat[] =
217     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
218     "s72\tl255\ti2\tL255\tI2\ts72\n"
219     "ServiceControl\tServiceControl\n"
220     "ServiceControl\tTestService\t8\t\t0\tservice_comp";
221
222 static const char sss_service_control_dat[] =
223     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
224     "s72\tl255\ti2\tL255\tI2\ts72\n"
225     "ServiceControl\tServiceControl\n"
226     "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
227
228 static const char sss_install_exec_seq_dat[] =
229     "Action\tCondition\tSequence\n"
230     "s72\tS255\tI2\n"
231     "InstallExecuteSequence\tAction\n"
232     "LaunchConditions\t\t100\n"
233     "CostInitialize\t\t800\n"
234     "FileCost\t\t900\n"
235     "ResolveSource\t\t950\n"
236     "CostFinalize\t\t1000\n"
237     "InstallValidate\t\t1400\n"
238     "InstallInitialize\t\t1500\n"
239     "DeleteServices\t\t5000\n"
240     "MoveFiles\t\t5100\n"
241     "InstallFiles\t\t5200\n"
242     "DuplicateFiles\t\t5300\n"
243     "StartServices\t\t5400\n"
244     "InstallFinalize\t\t6000\n";
245
246 static const char sds_install_exec_seq_dat[] =
247     "Action\tCondition\tSequence\n"
248     "s72\tS255\tI2\n"
249     "InstallExecuteSequence\tAction\n"
250     "LaunchConditions\t\t100\n"
251     "CostInitialize\t\t800\n"
252     "FileCost\t\t900\n"
253     "ResolveSource\t\t950\n"
254     "CostFinalize\t\t1000\n"
255     "InstallValidate\t\t1400\n"
256     "InstallInitialize\t\t1500\n"
257     "DeleteServices\tInstalled\t5000\n"
258     "MoveFiles\t\t5100\n"
259     "InstallFiles\t\t5200\n"
260     "DuplicateFiles\t\t5300\n"
261     "InstallServices\tNOT Installed\t5400\n"
262     "RegisterProduct\t\t5500\n"
263     "PublishFeatures\t\t5600\n"
264     "PublishProduct\t\t5700\n"
265     "InstallFinalize\t\t6000\n";
266
267 static const char rof_component_dat[] =
268     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
269     "s72\tS38\ts72\ti2\tS255\tS72\n"
270     "Component\tComponent\n"
271     "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
272
273 static const char rof_feature_dat[] =
274     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
275     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
276     "Feature\tFeature\n"
277     "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
278     "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
279
280 static const char rof_feature_comp_dat[] =
281     "Feature_\tComponent_\n"
282     "s38\ts72\n"
283     "FeatureComponents\tFeature_\tComponent_\n"
284     "feature\tmaximus\n"
285     "montecristo\tmaximus";
286
287 static const char rof_file_dat[] =
288     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
289     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
290     "File\tFile\n"
291     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
292
293 static const char rof_media_dat[] =
294     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
295     "i2\ti4\tL64\tS255\tS32\tS72\n"
296     "Media\tDiskId\n"
297     "1\t1\t\t\tDISK1\t\n";
298
299 static const char ci2_feature_comp_dat[] =
300     "Feature_\tComponent_\n"
301     "s38\ts72\n"
302     "FeatureComponents\tFeature_\tComponent_\n"
303     "feature\taugustus";
304
305 static const char ci2_file_dat[] =
306     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
307     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
308     "File\tFile\n"
309     "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
310
311 static const char pp_install_exec_seq_dat[] =
312     "Action\tCondition\tSequence\n"
313     "s72\tS255\tI2\n"
314     "InstallExecuteSequence\tAction\n"
315     "ValidateProductID\t\t700\n"
316     "CostInitialize\t\t800\n"
317     "FileCost\t\t900\n"
318     "CostFinalize\t\t1000\n"
319     "InstallValidate\t\t1400\n"
320     "InstallInitialize\t\t1500\n"
321     "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
322     "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
323     "RemoveFiles\t\t3500\n"
324     "InstallFiles\t\t4000\n"
325     "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
326     "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
327     "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
328     "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
329     "InstallFinalize\t\t6600";
330
331 static const char pp_component_dat[] =
332     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
333     "s72\tS38\ts72\ti2\tS255\tS72\n"
334     "Component\tComponent\n"
335     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n";
336
337 static const char ppc_component_dat[] =
338     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
339     "s72\tS38\ts72\ti2\tS255\tS72\n"
340     "Component\tComponent\n"
341     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n"
342     "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
343
344 static const char ppc_file_dat[] =
345     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
346     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
347     "File\tFile\n"
348     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
349     "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
350
351 static const char ppc_media_dat[] =
352     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
353     "i2\ti4\tL64\tS255\tS32\tS72\n"
354     "Media\tDiskId\n"
355     "1\t2\t\t\tDISK1\t\n";
356
357 static const char ppc_feature_comp_dat[] =
358     "Feature_\tComponent_\n"
359     "s38\ts72\n"
360     "FeatureComponents\tFeature_\tComponent_\n"
361     "feature\tmaximus\n"
362     "feature\taugustus\n"
363     "montecristo\tmaximus";
364
365 static const char cwd_component_dat[] =
366     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
367     "s72\tS38\ts72\ti2\tS255\tS72\n"
368     "Component\tComponent\n"
369     "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
370
371 static const char rem_component_dat[] =
372     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
373     "s72\tS38\ts72\ti2\tS255\tS72\n"
374     "Component\tComponent\n"
375     "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
376     "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
377     "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
378
379 static const char rem_feature_comp_dat[] =
380     "Feature_\tComponent_\n"
381     "s38\ts72\n"
382     "FeatureComponents\tFeature_\tComponent_\n"
383     "feature\thydrogen\n"
384     "feature\thelium\n"
385     "feature\tlithium";
386
387 static const char rem_file_dat[] =
388     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
389     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
390     "File\tFile\n"
391     "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
392     "helium\thelium\thelium\t0\t\t\t8192\t1\n"
393     "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
394
395 static const char rem_install_exec_seq_dat[] =
396     "Action\tCondition\tSequence\n"
397     "s72\tS255\tI2\n"
398     "InstallExecuteSequence\tAction\n"
399     "ValidateProductID\t\t700\n"
400     "CostInitialize\t\t800\n"
401     "FileCost\t\t900\n"
402     "CostFinalize\t\t1000\n"
403     "InstallValidate\t\t1400\n"
404     "InstallInitialize\t\t1500\n"
405     "ProcessComponents\t\t1600\n"
406     "UnpublishFeatures\t\t1800\n"
407     "RemoveFiles\t\t3500\n"
408     "InstallFiles\t\t4000\n"
409     "RegisterProduct\t\t6100\n"
410     "PublishFeatures\t\t6300\n"
411     "PublishProduct\t\t6400\n"
412     "InstallFinalize\t\t6600";
413
414 static const char rem_remove_files_dat[] =
415     "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
416     "s72\ts72\tS255\ts72\tI2\n"
417     "RemoveFile\tFileKey\n"
418     "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
419     "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
420     "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
421     "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
422     "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
423     "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
424     "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
425     "block\thelium\tblock\tMSITESTDIR\t3\n"
426     "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
427     "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
428
429 static const char mov_move_file_dat[] =
430     "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
431     "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
432     "MoveFile\tFileKey\n"
433     "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
434     "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
435     "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
436     "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
437     "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
438     "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
439     "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
440     "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
441     "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
442     "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
443     "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
444     "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
445     "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
446     "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
447     "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
448     "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
449     "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
450     "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
451
452 static const char df_directory_dat[] =
453     "Directory\tDirectory_Parent\tDefaultDir\n"
454     "s72\tS72\tl255\n"
455     "Directory\tDirectory\n"
456     "THIS\tMSITESTDIR\tthis\n"
457     "DOESNOT\tTHIS\tdoesnot\n"
458     "NONEXISTENT\tDOESNOT\texist\n"
459     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
460     "ProgramFilesFolder\tTARGETDIR\t.\n"
461     "TARGETDIR\t\tSourceDir";
462
463 static const char df_duplicate_file_dat[] =
464     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
465     "s72\ts72\ts72\tS255\tS72\n"
466     "DuplicateFile\tFileKey\n"
467     "maximus\tmaximus\tmaximus\taugustus\t\n"
468     "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
469     "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
470
471 static const char wrv_component_dat[] =
472     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
473     "s72\tS38\ts72\ti2\tS255\tS72\n"
474     "Component\tComponent\n"
475     "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
476
477 static const char wrv_registry_dat[] =
478     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
479     "s72\ti2\tl255\tL255\tL0\ts72\n"
480     "Registry\tRegistry\n"
481     "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
482
483 static const char cf_directory_dat[] =
484     "Directory\tDirectory_Parent\tDefaultDir\n"
485     "s72\tS72\tl255\n"
486     "Directory\tDirectory\n"
487     "FIRSTDIR\tMSITESTDIR\tfirst\n"
488     "SECONDDIR\tMSITESTDIR\tsecond\n"
489     "THIRDDIR\tMSITESTDIR\tthird\n"
490     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
491     "ProgramFilesFolder\tTARGETDIR\t.\n"
492     "TARGETDIR\t\tSourceDir";
493
494 static const char cf_component_dat[] =
495     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
496     "s72\tS38\ts72\ti2\tS255\tS72\n"
497     "Component\tComponent\n"
498     "One\t{F8CD42AC-9C38-48FE-8664-B35FD121012A}\tFIRSTDIR\t0\t\tone.txt\n"
499     "Two\t{DE2DB02E-2DDF-4E34-8CF6-DCA13E29DF52}\tSECONDDIR\t0\t\ttwo.txt\n";
500
501 static const char cf_feature_dat[] =
502     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
503     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
504     "Feature\tFeature\n"
505     "One\t\tOne\tThe One Feature\t1\t3\tFIRSTDIR\t0\n"
506     "Two\t\tTwo\tThe Two Feature\t1\t3\tSECONDDIR\t0\n";
507
508 static const char cf_feature_comp_dat[] =
509     "Feature_\tComponent_\n"
510     "s38\ts72\n"
511     "FeatureComponents\tFeature_\tComponent_\n"
512     "One\tOne\n"
513     "Two\tTwo\n";
514
515 static const char cf_file_dat[] =
516     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
517     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
518     "File\tFile\n"
519     "one.txt\tOne\tone.txt\t0\t\t\t0\t1\n"
520     "two.txt\tTwo\ttwo.txt\t0\t\t\t0\t2\n";
521
522 static const char cf_create_folders_dat[] =
523     "Directory_\tComponent_\n"
524     "s72\ts72\n"
525     "CreateFolder\tDirectory_\tComponent_\n"
526     "FIRSTDIR\tOne\n"
527     "SECONDDIR\tTwo\n"
528     "THIRDDIR\tTwo\n";
529
530 static const char cf_install_exec_seq_dat[] =
531     "Action\tCondition\tSequence\n"
532     "s72\tS255\tI2\n"
533     "InstallExecuteSequence\tAction\n"
534     "CostFinalize\t\t1000\n"
535     "ValidateProductID\t\t700\n"
536     "CostInitialize\t\t800\n"
537     "FileCost\t\t900\n"
538     "RemoveFiles\t\t3500\n"
539     "CreateFolders\t\t3700\n"
540     "RemoveFolders\t\t3800\n"
541     "InstallFiles\t\t4000\n"
542     "RegisterUser\t\t6000\n"
543     "RegisterProduct\t\t6100\n"
544     "PublishFeatures\t\t6300\n"
545     "PublishProduct\t\t6400\n"
546     "InstallFinalize\t\t6600\n"
547     "InstallInitialize\t\t1500\n"
548     "ProcessComponents\t\t1600\n"
549     "UnpublishFeatures\t\t1800\n"
550     "InstallValidate\t\t1400\n"
551     "LaunchConditions\t\t100\n";
552
553 static const char sr_selfreg_dat[] =
554     "File_\tCost\n"
555     "s72\tI2\n"
556     "SelfReg\tFile_\n"
557     "one.txt\t1\n";
558
559 static const char sr_install_exec_seq_dat[] =
560     "Action\tCondition\tSequence\n"
561     "s72\tS255\tI2\n"
562     "InstallExecuteSequence\tAction\n"
563     "CostFinalize\t\t1000\n"
564     "CostInitialize\t\t800\n"
565     "FileCost\t\t900\n"
566     "ResolveSource\t\t950\n"
567     "MoveFiles\t\t1700\n"
568     "SelfUnregModules\t\t3900\n"
569     "InstallFiles\t\t4000\n"
570     "DuplicateFiles\t\t4500\n"
571     "WriteEnvironmentStrings\t\t4550\n"
572     "CreateShortcuts\t\t4600\n"
573     "InstallFinalize\t\t6600\n"
574     "InstallInitialize\t\t1500\n"
575     "InstallValidate\t\t1400\n"
576     "LaunchConditions\t\t100\n";
577
578 static const char font_media_dat[] =
579     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
580     "i2\ti4\tL64\tS255\tS32\tS72\n"
581     "Media\tDiskId\n"
582     "1\t3\t\t\tDISK1\t\n";
583
584 static const char font_file_dat[] =
585     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
586     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
587     "File\tFile\n"
588     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
589
590 static const char font_feature_dat[] =
591     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
592     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
593     "Feature\tFeature\n"
594     "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
595
596 static const char font_component_dat[] =
597     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
598     "s72\tS38\ts72\ti2\tS255\tS72\n"
599     "Component\tComponent\n"
600     "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
601
602 static const char font_feature_comp_dat[] =
603     "Feature_\tComponent_\n"
604     "s38\ts72\n"
605     "FeatureComponents\tFeature_\tComponent_\n"
606     "fonts\tfonts\n";
607
608 static const char font_dat[] =
609     "File_\tFontTitle\n"
610     "s72\tS128\n"
611     "Font\tFile_\n"
612     "font.ttf\tmsi test font\n";
613
614 static const char font_install_exec_seq_dat[] =
615     "Action\tCondition\tSequence\n"
616     "s72\tS255\tI2\n"
617     "InstallExecuteSequence\tAction\n"
618     "ValidateProductID\t\t700\n"
619     "CostInitialize\t\t800\n"
620     "FileCost\t\t900\n"
621     "CostFinalize\t\t1000\n"
622     "InstallValidate\t\t1400\n"
623     "InstallInitialize\t\t1500\n"
624     "ProcessComponents\t\t1600\n"
625     "UnpublishFeatures\t\t1800\n"
626     "RemoveFiles\t\t3500\n"
627     "InstallFiles\t\t4000\n"
628     "RegisterFonts\t\t4100\n"
629     "UnregisterFonts\t\t4200\n"
630     "RegisterUser\t\t6000\n"
631     "RegisterProduct\t\t6100\n"
632     "PublishFeatures\t\t6300\n"
633     "PublishProduct\t\t6400\n"
634     "InstallFinalize\t\t6600";
635
636 static const char vp_property_dat[] =
637     "Property\tValue\n"
638     "s72\tl0\n"
639     "Property\tProperty\n"
640     "HASUIRUN\t0\n"
641     "INSTALLLEVEL\t3\n"
642     "InstallMode\tTypical\n"
643     "Manufacturer\tWine\n"
644     "PIDTemplate\t###-#######\n"
645     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
646     "ProductLanguage\t1033\n"
647     "ProductName\tMSITEST\n"
648     "ProductVersion\t1.1.1\n"
649     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
650     "MSIFASTINSTALL\t1\n";
651
652 static const char vp_custom_action_dat[] =
653     "Action\tType\tSource\tTarget\tISComments\n"
654     "s72\ti2\tS64\tS0\tS255\n"
655     "CustomAction\tAction\n"
656     "SetProductID1\t51\tProductID\t1\t\n"
657     "SetProductID2\t51\tProductID\t2\t\n"
658     "TestProductID1\t19\t\t\tHalts installation\n"
659     "TestProductID2\t19\t\t\tHalts installation\n";
660
661 static const char vp_install_exec_seq_dat[] =
662     "Action\tCondition\tSequence\n"
663     "s72\tS255\tI2\n"
664     "InstallExecuteSequence\tAction\n"
665     "LaunchConditions\t\t100\n"
666     "CostInitialize\t\t800\n"
667     "FileCost\t\t900\n"
668     "CostFinalize\t\t1000\n"
669     "InstallValidate\t\t1400\n"
670     "InstallInitialize\t\t1500\n"
671     "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
672     "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
673     "ValidateProductID\t\t3200\n"
674     "InstallExecute\t\t3300\n"
675     "TestProductID1\tProductID=1\t3400\n"
676     "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
677     "InstallFiles\t\t4000\n"
678     "InstallFinalize\t\t6000\n";
679
680 static const char odbc_file_dat[] =
681     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
682     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
683     "File\tFile\n"
684     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
685     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
686     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
687     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
688     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
689
690 static const char odbc_feature_dat[] =
691     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
692     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
693     "Feature\tFeature\n"
694     "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
695
696 static const char odbc_feature_comp_dat[] =
697     "Feature_\tComponent_\n"
698     "s38\ts72\n"
699     "FeatureComponents\tFeature_\tComponent_\n"
700     "odbc\todbc\n";
701
702 static const char odbc_component_dat[] =
703     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
704     "s72\tS38\ts72\ti2\tS255\tS72\n"
705     "Component\tComponent\n"
706     "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
707
708 static const char odbc_driver_dat[] =
709     "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
710     "s72\ts72\ts255\ts72\tS72\n"
711     "ODBCDriver\tDriver\n"
712     "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
713     "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
714
715 static const char odbc_translator_dat[] =
716     "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
717     "s72\ts72\ts255\ts72\tS72\n"
718     "ODBCTranslator\tTranslator\n"
719     "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
720     "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
721
722 static const char odbc_datasource_dat[] =
723     "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
724     "s72\ts72\ts255\ts255\ti2\n"
725     "ODBCDataSource\tDataSource\n"
726     "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
727
728 static const char odbc_install_exec_seq_dat[] =
729     "Action\tCondition\tSequence\n"
730     "s72\tS255\tI2\n"
731     "InstallExecuteSequence\tAction\n"
732     "LaunchConditions\t\t100\n"
733     "CostInitialize\t\t800\n"
734     "FileCost\t\t900\n"
735     "CostFinalize\t\t1000\n"
736     "InstallValidate\t\t1400\n"
737     "InstallInitialize\t\t1500\n"
738     "ProcessComponents\t\t1600\n"
739     "InstallODBC\t\t3000\n"
740     "RemoveODBC\t\t3100\n"
741     "RemoveFiles\t\t3900\n"
742     "InstallFiles\t\t4000\n"
743     "RegisterProduct\t\t5000\n"
744     "PublishFeatures\t\t5100\n"
745     "PublishProduct\t\t5200\n"
746     "InstallFinalize\t\t6000\n";
747
748 static const char odbc_media_dat[] =
749     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
750     "i2\ti4\tL64\tS255\tS32\tS72\n"
751     "Media\tDiskId\n"
752     "1\t5\t\t\tDISK1\t\n";
753
754 static const char tl_file_dat[] =
755     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
756     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
757     "File\tFile\n"
758     "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
759
760 static const char tl_feature_dat[] =
761     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
762     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
763     "Feature\tFeature\n"
764     "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
765
766 static const char tl_feature_comp_dat[] =
767     "Feature_\tComponent_\n"
768     "s38\ts72\n"
769     "FeatureComponents\tFeature_\tComponent_\n"
770     "typelib\ttypelib\n";
771
772 static const char tl_component_dat[] =
773     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
774     "s72\tS38\ts72\ti2\tS255\tS72\n"
775     "Component\tComponent\n"
776     "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
777
778 static const char tl_typelib_dat[] =
779     "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
780     "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
781     "TypeLib\tLibID\tLanguage\tComponent_\n"
782     "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
783
784 static const char tl_install_exec_seq_dat[] =
785     "Action\tCondition\tSequence\n"
786     "s72\tS255\tI2\n"
787     "InstallExecuteSequence\tAction\n"
788     "LaunchConditions\t\t100\n"
789     "CostInitialize\t\t800\n"
790     "FileCost\t\t900\n"
791     "CostFinalize\t\t1000\n"
792     "InstallValidate\t\t1400\n"
793     "InstallInitialize\t\t1500\n"
794     "ProcessComponents\t\t1600\n"
795     "RemoveFiles\t\t1700\n"
796     "InstallFiles\t\t2000\n"
797     "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
798     "UnregisterTypeLibraries\t\t3100\n"
799     "RegisterProduct\t\t5100\n"
800     "PublishFeatures\t\t5200\n"
801     "PublishProduct\t\t5300\n"
802     "InstallFinalize\t\t6000\n";
803
804 static const char crs_file_dat[] =
805     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
806     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
807     "File\tFile\n"
808     "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
809
810 static const char crs_feature_dat[] =
811     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
812     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
813     "Feature\tFeature\n"
814     "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
815
816 static const char crs_feature_comp_dat[] =
817     "Feature_\tComponent_\n"
818     "s38\ts72\n"
819     "FeatureComponents\tFeature_\tComponent_\n"
820     "shortcut\tshortcut\n";
821
822 static const char crs_component_dat[] =
823     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
824     "s72\tS38\ts72\ti2\tS255\tS72\n"
825     "Component\tComponent\n"
826     "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
827
828 static const char crs_shortcut_dat[] =
829     "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
830     "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
831     "Shortcut\tShortcut\n"
832     "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
833
834 static const char crs_install_exec_seq_dat[] =
835     "Action\tCondition\tSequence\n"
836     "s72\tS255\tI2\n"
837     "InstallExecuteSequence\tAction\n"
838     "LaunchConditions\t\t100\n"
839     "CostInitialize\t\t800\n"
840     "FileCost\t\t900\n"
841     "CostFinalize\t\t1000\n"
842     "InstallValidate\t\t1400\n"
843     "InstallInitialize\t\t1500\n"
844     "ProcessComponents\t\t1600\n"
845     "RemoveFiles\t\t1700\n"
846     "InstallFiles\t\t2000\n"
847     "RemoveShortcuts\t\t3000\n"
848     "CreateShortcuts\t\t3100\n"
849     "RegisterProduct\t\t5000\n"
850     "PublishFeatures\t\t5100\n"
851     "PublishProduct\t\t5200\n"
852     "InstallFinalize\t\t6000\n";
853
854 static const char pub_file_dat[] =
855     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
856     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
857     "File\tFile\n"
858     "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
859
860 static const char pub_feature_dat[] =
861     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
862     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
863     "Feature\tFeature\n"
864     "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
865
866 static const char pub_feature_comp_dat[] =
867     "Feature_\tComponent_\n"
868     "s38\ts72\n"
869     "FeatureComponents\tFeature_\tComponent_\n"
870     "publish\tpublish\n";
871
872 static const char pub_component_dat[] =
873     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
874     "s72\tS38\ts72\ti2\tS255\tS72\n"
875     "Component\tComponent\n"
876     "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
877
878 static const char pub_publish_component_dat[] =
879     "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
880     "s38\ts255\ts72\tL255\ts38\n"
881     "PublishComponent\tComponentId\tQualifier\tComponent_\n"
882     "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
883
884 static const char pub_install_exec_seq_dat[] =
885     "Action\tCondition\tSequence\n"
886     "s72\tS255\tI2\n"
887     "InstallExecuteSequence\tAction\n"
888     "LaunchConditions\t\t100\n"
889     "CostInitialize\t\t800\n"
890     "FileCost\t\t900\n"
891     "CostFinalize\t\t1000\n"
892     "InstallValidate\t\t1400\n"
893     "InstallInitialize\t\t1500\n"
894     "ProcessComponents\t\t1600\n"
895     "RemoveFiles\t\t1700\n"
896     "InstallFiles\t\t2000\n"
897     "PublishComponents\t\t3000\n"
898     "UnpublishComponents\t\t3100\n"
899     "RegisterProduct\t\t5000\n"
900     "PublishFeatures\t\t5100\n"
901     "PublishProduct\t\t5200\n"
902     "InstallFinalize\t\t6000\n";
903
904 static const char rd_file_dat[] =
905     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
906     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
907     "File\tFile\n"
908     "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
909     "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
910     "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
911
912 static const char rd_feature_dat[] =
913     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
914     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
915     "Feature\tFeature\n"
916     "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
917
918 static const char rd_feature_comp_dat[] =
919     "Feature_\tComponent_\n"
920     "s38\ts72\n"
921     "FeatureComponents\tFeature_\tComponent_\n"
922     "duplicate\tduplicate\n";
923
924 static const char rd_component_dat[] =
925     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
926     "s72\tS38\ts72\ti2\tS255\tS72\n"
927     "Component\tComponent\n"
928     "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
929     "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
930
931 static const char rd_duplicate_file_dat[] =
932     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
933     "s72\ts72\ts72\tS255\tS72\n"
934     "DuplicateFile\tFileKey\n"
935     "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
936     "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
937     "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
938
939 static const char rd_install_exec_seq_dat[] =
940     "Action\tCondition\tSequence\n"
941     "s72\tS255\tI2\n"
942     "InstallExecuteSequence\tAction\n"
943     "LaunchConditions\t\t100\n"
944     "CostInitialize\t\t800\n"
945     "FileCost\t\t900\n"
946     "CostFinalize\t\t1000\n"
947     "InstallValidate\t\t1400\n"
948     "InstallInitialize\t\t1500\n"
949     "ProcessComponents\t\t1600\n"
950     "RemoveDuplicateFiles\t\t1900\n"
951     "InstallFiles\t\t2000\n"
952     "DuplicateFiles\t\t2100\n"
953     "RegisterProduct\t\t5000\n"
954     "PublishFeatures\t\t5100\n"
955     "PublishProduct\t\t5200\n"
956     "InstallFinalize\t\t6000\n";
957
958 static const char rrv_file_dat[] =
959     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
960     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
961     "File\tFile\n"
962     "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
963
964 static const char rrv_feature_dat[] =
965     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
966     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
967     "Feature\tFeature\n"
968     "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
969
970 static const char rrv_feature_comp_dat[] =
971     "Feature_\tComponent_\n"
972     "s38\ts72\n"
973     "FeatureComponents\tFeature_\tComponent_\n"
974     "registry\tregistry\n";
975
976 static const char rrv_component_dat[] =
977     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
978     "s72\tS38\ts72\ti2\tS255\tS72\n"
979     "Component\tComponent\n"
980     "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
981
982 static const char rrv_registry_dat[] =
983     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
984     "s72\ti2\tl255\tL255\tL0\ts72\n"
985     "Registry\tRegistry\n"
986     "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
987     "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
988     "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
989
990 static const char rrv_remove_registry_dat[] =
991     "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
992     "s72\ti2\tl255\tL255\ts72\n"
993     "RemoveRegistry\tRemoveRegistry\n"
994     "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
995     "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
996     "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
997
998 static const char rrv_install_exec_seq_dat[] =
999     "Action\tCondition\tSequence\n"
1000     "s72\tS255\tI2\n"
1001     "InstallExecuteSequence\tAction\n"
1002     "LaunchConditions\t\t100\n"
1003     "CostInitialize\t\t800\n"
1004     "FileCost\t\t900\n"
1005     "CostFinalize\t\t1000\n"
1006     "InstallValidate\t\t1400\n"
1007     "InstallInitialize\t\t1500\n"
1008     "ProcessComponents\t\t1600\n"
1009     "RemoveFiles\t\t1700\n"
1010     "InstallFiles\t\t2000\n"
1011     "RemoveRegistryValues\t\t3000\n"
1012     "RegisterProduct\t\t5000\n"
1013     "PublishFeatures\t\t5100\n"
1014     "PublishProduct\t\t5200\n"
1015     "InstallFinalize\t\t6000\n";
1016
1017 static const char frp_file_dat[] =
1018     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1019     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1020     "File\tFile\n"
1021     "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1022
1023 static const char frp_feature_dat[] =
1024     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1025     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1026     "Feature\tFeature\n"
1027     "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1028
1029 static const char frp_feature_comp_dat[] =
1030     "Feature_\tComponent_\n"
1031     "s38\ts72\n"
1032     "FeatureComponents\tFeature_\tComponent_\n"
1033     "product\tproduct\n";
1034
1035 static const char frp_component_dat[] =
1036     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1037     "s72\tS38\ts72\ti2\tS255\tS72\n"
1038     "Component\tComponent\n"
1039     "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1040
1041 static const char frp_custom_action_dat[] =
1042     "Action\tType\tSource\tTarget\tISComments\n"
1043     "s72\ti2\tS64\tS0\tS255\n"
1044     "CustomAction\tAction\n"
1045     "TestProp\t19\t\t\tPROP set\n";
1046
1047 static const char frp_upgrade_dat[] =
1048     "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1049     "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1050     "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1051     "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1052
1053 static const char frp_install_exec_seq_dat[] =
1054     "Action\tCondition\tSequence\n"
1055     "s72\tS255\tI2\n"
1056     "InstallExecuteSequence\tAction\n"
1057     "FindRelatedProducts\t\t50\n"
1058     "TestProp\tPROP AND NOT REMOVE\t51\n"
1059     "LaunchConditions\t\t100\n"
1060     "CostInitialize\t\t800\n"
1061     "FileCost\t\t900\n"
1062     "CostFinalize\t\t1000\n"
1063     "InstallValidate\t\t1400\n"
1064     "InstallInitialize\t\t1500\n"
1065     "ProcessComponents\t\t1600\n"
1066     "RemoveFiles\t\t1700\n"
1067     "InstallFiles\t\t2000\n"
1068     "RegisterProduct\t\t5000\n"
1069     "PublishFeatures\t\t5100\n"
1070     "PublishProduct\t\t5200\n"
1071     "InstallFinalize\t\t6000\n";
1072
1073 static const char riv_file_dat[] =
1074     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1075     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1076     "File\tFile\n"
1077     "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1078
1079 static const char riv_feature_dat[] =
1080     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1081     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1082     "Feature\tFeature\n"
1083     "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1084
1085 static const char riv_feature_comp_dat[] =
1086     "Feature_\tComponent_\n"
1087     "s38\ts72\n"
1088     "FeatureComponents\tFeature_\tComponent_\n"
1089     "inifile\tinifile\n";
1090
1091 static const char riv_component_dat[] =
1092     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1093     "s72\tS38\ts72\ti2\tS255\tS72\n"
1094     "Component\tComponent\n"
1095     "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1096
1097 static const char riv_ini_file_dat[] =
1098     "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1099     "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1100     "IniFile\tIniFile\n"
1101     "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1102
1103 static const char riv_remove_ini_file_dat[] =
1104     "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1105     "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1106     "RemoveIniFile\tRemoveIniFile\n"
1107     "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1108
1109 static const char riv_install_exec_seq_dat[] =
1110     "Action\tCondition\tSequence\n"
1111     "s72\tS255\tI2\n"
1112     "InstallExecuteSequence\tAction\n"
1113     "LaunchConditions\t\t100\n"
1114     "CostInitialize\t\t800\n"
1115     "FileCost\t\t900\n"
1116     "CostFinalize\t\t1000\n"
1117     "InstallValidate\t\t1400\n"
1118     "InstallInitialize\t\t1500\n"
1119     "ProcessComponents\t\t1600\n"
1120     "RemoveFiles\t\t1700\n"
1121     "InstallFiles\t\t2000\n"
1122     "RemoveIniValues\t\t3000\n"
1123     "RegisterProduct\t\t5000\n"
1124     "PublishFeatures\t\t5100\n"
1125     "PublishProduct\t\t5200\n"
1126     "InstallFinalize\t\t6000\n";
1127
1128 static const char res_file_dat[] =
1129     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1130     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1131     "File\tFile\n"
1132     "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1133
1134 static const char res_feature_dat[] =
1135     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1136     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1137     "Feature\tFeature\n"
1138     "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1139
1140 static const char res_feature_comp_dat[] =
1141     "Feature_\tComponent_\n"
1142     "s38\ts72\n"
1143     "FeatureComponents\tFeature_\tComponent_\n"
1144     "envvar\tenvvar\n";
1145
1146 static const char res_component_dat[] =
1147     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1148     "s72\tS38\ts72\ti2\tS255\tS72\n"
1149     "Component\tComponent\n"
1150     "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1151
1152 static const char res_environment_dat[] =
1153     "Environment\tName\tValue\tComponent_\n"
1154     "s72\tl255\tL255\ts72\n"
1155     "Environment\tEnvironment\n"
1156     "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1157     "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1158     "var3\t=MSITESTVAR3\t1\tenvvar\n"
1159     "var4\t=-MSITESTVAR4\t\tenvvar\n"
1160     "var5\t=MSITESTVAR5\t\tenvvar\n";
1161
1162 static const char res_install_exec_seq_dat[] =
1163     "Action\tCondition\tSequence\n"
1164     "s72\tS255\tI2\n"
1165     "InstallExecuteSequence\tAction\n"
1166     "LaunchConditions\t\t100\n"
1167     "CostInitialize\t\t800\n"
1168     "FileCost\t\t900\n"
1169     "CostFinalize\t\t1000\n"
1170     "InstallValidate\t\t1400\n"
1171     "InstallInitialize\t\t1500\n"
1172     "ProcessComponents\t\t1600\n"
1173     "RemoveFiles\t\t1700\n"
1174     "InstallFiles\t\t2000\n"
1175     "RemoveEnvironmentStrings\t\t3000\n"
1176     "RegisterProduct\t\t5000\n"
1177     "PublishFeatures\t\t5100\n"
1178     "PublishProduct\t\t5200\n"
1179     "InstallFinalize\t\t6000\n";
1180
1181 static const char rci_file_dat[] =
1182     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1183     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1184     "File\tFile\n"
1185     "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n";
1186
1187 static const char rci_feature_dat[] =
1188     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1189     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1190     "Feature\tFeature\n"
1191     "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n";
1192
1193 static const char rci_feature_comp_dat[] =
1194     "Feature_\tComponent_\n"
1195     "s38\ts72\n"
1196     "FeatureComponents\tFeature_\tComponent_\n"
1197     "class\tclass\n";
1198
1199 static const char rci_component_dat[] =
1200     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1201     "s72\tS38\ts72\ti2\tS255\tS72\n"
1202     "Component\tComponent\n"
1203     "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n";
1204
1205 static const char rci_appid_dat[] =
1206     "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1207     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1208     "AppId\tAppId\n"
1209     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1210
1211 static const char rci_class_dat[] =
1212     "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1213     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1214     "Class\tCLSID\tContext\tComponent_\n"
1215     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n";
1216
1217 static const char rci_install_exec_seq_dat[] =
1218     "Action\tCondition\tSequence\n"
1219     "s72\tS255\tI2\n"
1220     "InstallExecuteSequence\tAction\n"
1221     "LaunchConditions\t\t100\n"
1222     "CostInitialize\t\t800\n"
1223     "FileCost\t\t900\n"
1224     "CostFinalize\t\t1000\n"
1225     "InstallValidate\t\t1400\n"
1226     "InstallInitialize\t\t1500\n"
1227     "ProcessComponents\t\t1600\n"
1228     "RemoveFiles\t\t1700\n"
1229     "InstallFiles\t\t2000\n"
1230     "UnregisterClassInfo\t\t3000\n"
1231     "RegisterClassInfo\t\t4000\n"
1232     "RegisterProduct\t\t5000\n"
1233     "PublishFeatures\t\t5100\n"
1234     "PublishProduct\t\t5200\n"
1235     "InstallFinalize\t\t6000\n";
1236
1237 static const char rei_file_dat[] =
1238     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1239     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1240     "File\tFile\n"
1241     "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n";
1242
1243 static const char rei_feature_dat[] =
1244     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1245     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1246     "Feature\tFeature\n"
1247     "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n";
1248
1249 static const char rei_feature_comp_dat[] =
1250     "Feature_\tComponent_\n"
1251     "s38\ts72\n"
1252     "FeatureComponents\tFeature_\tComponent_\n"
1253     "extension\textension\n";
1254
1255 static const char rei_component_dat[] =
1256     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1257     "s72\tS38\ts72\ti2\tS255\tS72\n"
1258     "Component\tComponent\n"
1259     "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n";
1260
1261 static const char rei_extension_dat[] =
1262     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1263     "s255\ts72\tS255\tS64\ts38\n"
1264     "Extension\tExtension\tComponent_\n"
1265     "extension\textension\tProg.Id.1\t\textension\n";
1266
1267 static const char rei_verb_dat[] =
1268     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1269     "s255\ts32\tI2\tL255\tL255\n"
1270     "Verb\tExtension_\tVerb\n"
1271     "extension\tOpen\t1\t&Open\t/argument\n";
1272
1273 static const char rei_progid_dat[] =
1274     "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1275     "s255\tS255\tS38\tL255\tS72\tI2\n"
1276     "ProgId\tProgId\n"
1277     "Prog.Id.1\t\t\tdescription\t\t\n";
1278
1279 static const char rei_install_exec_seq_dat[] =
1280     "Action\tCondition\tSequence\n"
1281     "s72\tS255\tI2\n"
1282     "InstallExecuteSequence\tAction\n"
1283     "LaunchConditions\t\t100\n"
1284     "CostInitialize\t\t800\n"
1285     "FileCost\t\t900\n"
1286     "CostFinalize\t\t1000\n"
1287     "InstallValidate\t\t1400\n"
1288     "InstallInitialize\t\t1500\n"
1289     "ProcessComponents\t\t1600\n"
1290     "RemoveFiles\t\t1700\n"
1291     "InstallFiles\t\t2000\n"
1292     "UnregisterExtensionInfo\t\t3000\n"
1293     "RegisterExtensionInfo\t\t4000\n"
1294     "RegisterProduct\t\t5000\n"
1295     "PublishFeatures\t\t5100\n"
1296     "PublishProduct\t\t5200\n"
1297     "InstallFinalize\t\t6000\n";
1298
1299 static const char rmi_file_dat[] =
1300     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1301     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1302     "File\tFile\n"
1303     "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n";
1304
1305 static const char rmi_feature_dat[] =
1306     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1307     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1308     "Feature\tFeature\n"
1309     "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n";
1310
1311 static const char rmi_feature_comp_dat[] =
1312     "Feature_\tComponent_\n"
1313     "s38\ts72\n"
1314     "FeatureComponents\tFeature_\tComponent_\n"
1315     "mime\tmime\n";
1316
1317 static const char rmi_component_dat[] =
1318     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1319     "s72\tS38\ts72\ti2\tS255\tS72\n"
1320     "Component\tComponent\n"
1321     "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n";
1322
1323 static const char rmi_extension_dat[] =
1324     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1325     "s255\ts72\tS255\tS64\ts38\n"
1326     "Extension\tExtension\tComponent_\n"
1327     "mime\tmime\t\tmime/type\tmime\n";
1328
1329 static const char rmi_verb_dat[] =
1330     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1331     "s255\ts32\tI2\tL255\tL255\n"
1332     "Verb\tExtension_\tVerb\n"
1333     "mime\tOpen\t1\t&Open\t/argument\n";
1334
1335 static const char rmi_mime_dat[] =
1336     "ContentType\tExtension_\tCLSID\n"
1337     "s64\ts255\tS38\n"
1338     "MIME\tContentType\n"
1339     "mime/type\tmime\t\n";
1340
1341 static const char rmi_install_exec_seq_dat[] =
1342     "Action\tCondition\tSequence\n"
1343     "s72\tS255\tI2\n"
1344     "InstallExecuteSequence\tAction\n"
1345     "LaunchConditions\t\t100\n"
1346     "CostInitialize\t\t800\n"
1347     "FileCost\t\t900\n"
1348     "CostFinalize\t\t1000\n"
1349     "InstallValidate\t\t1400\n"
1350     "InstallInitialize\t\t1500\n"
1351     "ProcessComponents\t\t1600\n"
1352     "RemoveFiles\t\t1700\n"
1353     "InstallFiles\t\t2000\n"
1354     "UnregisterExtensionInfo\t\t3000\n"
1355     "UnregisterMIMEInfo\t\t3500\n"
1356     "RegisterExtensionInfo\t\t4000\n"
1357     "RegisterMIMEInfo\t\t4500\n"
1358     "RegisterProduct\t\t5000\n"
1359     "PublishFeatures\t\t5100\n"
1360     "PublishProduct\t\t5200\n"
1361     "InstallFinalize\t\t6000\n";
1362
1363 static const char pa_file_dat[] =
1364     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1365     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1366     "File\tFile\n"
1367     "win32.txt\twin32\twin32.txt\t1000\t\t\t8192\t1\n"
1368     "manifest.txt\twin32\tmanifest.txt\t1000\t\t\t8192\t1\n"
1369     "win32_local.txt\twin32_local\twin32_local.txt\t1000\t\t\t8192\t1\n"
1370     "manifest_local.txt\twin32_local\tmanifest_local.txt\t1000\t\t\t8192\t1\n"
1371     "dotnet.txt\tdotnet\tdotnet.txt\t1000\t\t\t8192\t1\n"
1372     "dotnet_local.txt\tdotnet_local\tdotnet_local.txt\t1000\t\t\t8192\t1\n"
1373     "application_win32.txt\twin32_local\tapplication_win32.txt\t1000\t\t\t8192\t1\n"
1374     "application_dotnet.txt\tdotnet_local\tapplication_dotnet.txt\t1000\t\t\t8192\t1\n";
1375
1376 static const char pa_feature_dat[] =
1377     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1378     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1379     "Feature\tFeature\n"
1380     "assembly\t\t\tassembly feature\t1\t2\tMSITESTDIR\t0\n";
1381
1382 static const char pa_feature_comp_dat[] =
1383     "Feature_\tComponent_\n"
1384     "s38\ts72\n"
1385     "FeatureComponents\tFeature_\tComponent_\n"
1386     "assembly\twin32\n"
1387     "assembly\twin32_local\n"
1388     "assembly\tdotnet\n"
1389     "assembly\tdotnet_local\n";
1390
1391 static const char pa_component_dat[] =
1392     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1393     "s72\tS38\ts72\ti2\tS255\tS72\n"
1394     "Component\tComponent\n"
1395     "win32\t{F515549E-7E61-425D-AAC1-9BEF2E066D06}\tMSITESTDIR\t0\t\twin32.txt\n"
1396     "win32_local\t{D34D3FBA-6789-4E57-AD1A-1281297DC201}\tMSITESTDIR\t0\t\twin32_local.txt\n"
1397     "dotnet\t{8943164F-2B31-4C09-A894-493A8CBDE0A4}\tMSITESTDIR\t0\t\tdotnet.txt\n"
1398     "dotnet_local\t{4E8567E8-8EAE-4E36-90F1-B99D33C663F8}\tMSITESTDIR\t0\t\tdotnet_local.txt\n";
1399
1400 static const char pa_msi_assembly_dat[] =
1401     "Component_\tFeature_\tFile_Manifest\tFile_Application\tAttributes\n"
1402     "s72\ts38\tS72\tS72\tI2\n"
1403     "MsiAssembly\tComponent_\n"
1404     "win32\tassembly\tmanifest.txt\t\t1\n"
1405     "win32_local\tassembly\tmanifest_local.txt\tapplication_win32.txt\t1\n"
1406     "dotnet\tassembly\t\t\t0\n"
1407     "dotnet_local\tassembly\t\tapplication_dotnet.txt\t0\n";
1408
1409 static const char pa_msi_assembly_name_dat[] =
1410     "Component_\tName\tValue\n"
1411     "s72\ts255\ts255\n"
1412     "MsiAssemblyName\tComponent_\tName\n"
1413     "win32\tName\tWine.Win32.Assembly\n"
1414     "win32\tprocessorArchitecture\tx86\n"
1415     "win32\tpublicKeyToken\tabcdef0123456789\n"
1416     "win32\ttype\twin32\n"
1417     "win32\tversion\t1.0.0.0\n"
1418     "win32_local\tName\tWine.Win32.Local.Assembly\n"
1419     "win32_local\tprocessorArchitecture\tx86\n"
1420     "win32_local\tpublicKeyToken\tabcdef0123456789\n"
1421     "win32_local\ttype\twin32\n"
1422     "win32_local\tversion\t1.0.0.0\n"
1423     "dotnet\tName\tWine.Dotnet.Assembly\n"
1424     "dotnet\tprocessorArchitecture\tMSIL\n"
1425     "dotnet\tpublicKeyToken\tabcdef0123456789\n"
1426     "dotnet\tculture\tneutral\n"
1427     "dotnet\tversion\t1.0.0.0\n"
1428     "dotnet_local\tName\tWine.Dotnet.Local.Assembly\n"
1429     "dotnet_local\tprocessorArchitecture\tMSIL\n"
1430     "dotnet_local\tpublicKeyToken\tabcdef0123456789\n"
1431     "dotnet_local\tculture\tneutral\n"
1432     "dotnet_local\tversion\t1.0.0.0\n";
1433
1434 static const char pa_install_exec_seq_dat[] =
1435     "Action\tCondition\tSequence\n"
1436     "s72\tS255\tI2\n"
1437     "InstallExecuteSequence\tAction\n"
1438     "LaunchConditions\t\t100\n"
1439     "CostInitialize\t\t800\n"
1440     "FileCost\t\t900\n"
1441     "CostFinalize\t\t1000\n"
1442     "InstallValidate\t\t1400\n"
1443     "InstallInitialize\t\t1500\n"
1444     "ProcessComponents\t\t1600\n"
1445     "MsiPublishAssemblies\t\t3000\n"
1446     "MsiUnpublishAssemblies\t\t4000\n"
1447     "RegisterProduct\t\t5000\n"
1448     "PublishFeatures\t\t5100\n"
1449     "PublishProduct\t\t5200\n"
1450     "InstallFinalize\t\t6000\n";
1451
1452 typedef struct _msi_table
1453 {
1454     const char *filename;
1455     const char *data;
1456     unsigned int size;
1457 } msi_table;
1458
1459 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1460
1461 static const msi_table env_tables[] =
1462 {
1463     ADD_TABLE(component),
1464     ADD_TABLE(directory),
1465     ADD_TABLE(feature),
1466     ADD_TABLE(feature_comp),
1467     ADD_TABLE(file),
1468     ADD_TABLE(install_exec_seq),
1469     ADD_TABLE(media),
1470     ADD_TABLE(property),
1471     ADD_TABLE(environment)
1472 };
1473
1474 static const msi_table pp_tables[] =
1475 {
1476     ADD_TABLE(pp_component),
1477     ADD_TABLE(directory),
1478     ADD_TABLE(rof_feature),
1479     ADD_TABLE(rof_feature_comp),
1480     ADD_TABLE(rof_file),
1481     ADD_TABLE(pp_install_exec_seq),
1482     ADD_TABLE(rof_media),
1483     ADD_TABLE(property),
1484 };
1485
1486 static const msi_table ppc_tables[] =
1487 {
1488     ADD_TABLE(ppc_component),
1489     ADD_TABLE(directory),
1490     ADD_TABLE(rof_feature),
1491     ADD_TABLE(ppc_feature_comp),
1492     ADD_TABLE(ppc_file),
1493     ADD_TABLE(pp_install_exec_seq),
1494     ADD_TABLE(ppc_media),
1495     ADD_TABLE(property),
1496 };
1497
1498 static const msi_table rem_tables[] =
1499 {
1500     ADD_TABLE(rem_component),
1501     ADD_TABLE(directory),
1502     ADD_TABLE(rof_feature),
1503     ADD_TABLE(rem_feature_comp),
1504     ADD_TABLE(rem_file),
1505     ADD_TABLE(rem_install_exec_seq),
1506     ADD_TABLE(rof_media),
1507     ADD_TABLE(property),
1508     ADD_TABLE(rem_remove_files),
1509 };
1510
1511 static const msi_table mov_tables[] =
1512 {
1513     ADD_TABLE(cwd_component),
1514     ADD_TABLE(directory),
1515     ADD_TABLE(rof_feature),
1516     ADD_TABLE(ci2_feature_comp),
1517     ADD_TABLE(ci2_file),
1518     ADD_TABLE(install_exec_seq),
1519     ADD_TABLE(rof_media),
1520     ADD_TABLE(property),
1521     ADD_TABLE(mov_move_file),
1522 };
1523
1524 static const msi_table df_tables[] =
1525 {
1526     ADD_TABLE(rof_component),
1527     ADD_TABLE(df_directory),
1528     ADD_TABLE(rof_feature),
1529     ADD_TABLE(rof_feature_comp),
1530     ADD_TABLE(rof_file),
1531     ADD_TABLE(install_exec_seq),
1532     ADD_TABLE(rof_media),
1533     ADD_TABLE(property),
1534     ADD_TABLE(df_duplicate_file),
1535 };
1536
1537 static const msi_table wrv_tables[] =
1538 {
1539     ADD_TABLE(wrv_component),
1540     ADD_TABLE(directory),
1541     ADD_TABLE(rof_feature),
1542     ADD_TABLE(ci2_feature_comp),
1543     ADD_TABLE(ci2_file),
1544     ADD_TABLE(install_exec_seq),
1545     ADD_TABLE(rof_media),
1546     ADD_TABLE(property),
1547     ADD_TABLE(wrv_registry),
1548 };
1549
1550 static const msi_table cf_tables[] =
1551 {
1552     ADD_TABLE(cf_component),
1553     ADD_TABLE(cf_directory),
1554     ADD_TABLE(cf_feature),
1555     ADD_TABLE(cf_feature_comp),
1556     ADD_TABLE(cf_file),
1557     ADD_TABLE(cf_create_folders),
1558     ADD_TABLE(cf_install_exec_seq),
1559     ADD_TABLE(media),
1560     ADD_TABLE(property)
1561 };
1562
1563 static const msi_table sss_tables[] =
1564 {
1565     ADD_TABLE(component),
1566     ADD_TABLE(directory),
1567     ADD_TABLE(feature),
1568     ADD_TABLE(feature_comp),
1569     ADD_TABLE(file),
1570     ADD_TABLE(sss_install_exec_seq),
1571     ADD_TABLE(sss_service_control),
1572     ADD_TABLE(media),
1573     ADD_TABLE(property)
1574 };
1575
1576 static const msi_table sds_tables[] =
1577 {
1578     ADD_TABLE(component),
1579     ADD_TABLE(directory),
1580     ADD_TABLE(feature),
1581     ADD_TABLE(feature_comp),
1582     ADD_TABLE(file),
1583     ADD_TABLE(sds_install_exec_seq),
1584     ADD_TABLE(service_control),
1585     ADD_TABLE(service_install),
1586     ADD_TABLE(media),
1587     ADD_TABLE(property)
1588 };
1589
1590 static const msi_table sr_tables[] =
1591 {
1592     ADD_TABLE(component),
1593     ADD_TABLE(directory),
1594     ADD_TABLE(feature),
1595     ADD_TABLE(feature_comp),
1596     ADD_TABLE(file),
1597     ADD_TABLE(sr_selfreg),
1598     ADD_TABLE(sr_install_exec_seq),
1599     ADD_TABLE(media),
1600     ADD_TABLE(property)
1601 };
1602
1603 static const msi_table font_tables[] =
1604 {
1605     ADD_TABLE(font_component),
1606     ADD_TABLE(directory),
1607     ADD_TABLE(font_feature),
1608     ADD_TABLE(font_feature_comp),
1609     ADD_TABLE(font_file),
1610     ADD_TABLE(font),
1611     ADD_TABLE(font_install_exec_seq),
1612     ADD_TABLE(font_media),
1613     ADD_TABLE(property)
1614 };
1615
1616 static const msi_table vp_tables[] =
1617 {
1618     ADD_TABLE(component),
1619     ADD_TABLE(directory),
1620     ADD_TABLE(feature),
1621     ADD_TABLE(feature_comp),
1622     ADD_TABLE(file),
1623     ADD_TABLE(vp_custom_action),
1624     ADD_TABLE(vp_install_exec_seq),
1625     ADD_TABLE(media),
1626     ADD_TABLE(vp_property)
1627 };
1628
1629 static const msi_table odbc_tables[] =
1630 {
1631     ADD_TABLE(odbc_component),
1632     ADD_TABLE(directory),
1633     ADD_TABLE(odbc_feature),
1634     ADD_TABLE(odbc_feature_comp),
1635     ADD_TABLE(odbc_file),
1636     ADD_TABLE(odbc_driver),
1637     ADD_TABLE(odbc_translator),
1638     ADD_TABLE(odbc_datasource),
1639     ADD_TABLE(odbc_install_exec_seq),
1640     ADD_TABLE(odbc_media),
1641     ADD_TABLE(property)
1642 };
1643
1644 static const msi_table tl_tables[] =
1645 {
1646     ADD_TABLE(tl_component),
1647     ADD_TABLE(directory),
1648     ADD_TABLE(tl_feature),
1649     ADD_TABLE(tl_feature_comp),
1650     ADD_TABLE(tl_file),
1651     ADD_TABLE(tl_typelib),
1652     ADD_TABLE(tl_install_exec_seq),
1653     ADD_TABLE(media),
1654     ADD_TABLE(property)
1655 };
1656
1657 static const msi_table crs_tables[] =
1658 {
1659     ADD_TABLE(crs_component),
1660     ADD_TABLE(directory),
1661     ADD_TABLE(crs_feature),
1662     ADD_TABLE(crs_feature_comp),
1663     ADD_TABLE(crs_file),
1664     ADD_TABLE(crs_shortcut),
1665     ADD_TABLE(crs_install_exec_seq),
1666     ADD_TABLE(media),
1667     ADD_TABLE(property)
1668 };
1669
1670 static const msi_table pub_tables[] =
1671 {
1672     ADD_TABLE(directory),
1673     ADD_TABLE(pub_component),
1674     ADD_TABLE(pub_feature),
1675     ADD_TABLE(pub_feature_comp),
1676     ADD_TABLE(pub_file),
1677     ADD_TABLE(pub_publish_component),
1678     ADD_TABLE(pub_install_exec_seq),
1679     ADD_TABLE(media),
1680     ADD_TABLE(property)
1681 };
1682
1683 static const msi_table rd_tables[] =
1684 {
1685     ADD_TABLE(directory),
1686     ADD_TABLE(rd_component),
1687     ADD_TABLE(rd_feature),
1688     ADD_TABLE(rd_feature_comp),
1689     ADD_TABLE(rd_file),
1690     ADD_TABLE(rd_duplicate_file),
1691     ADD_TABLE(rd_install_exec_seq),
1692     ADD_TABLE(media),
1693     ADD_TABLE(property)
1694 };
1695
1696 static const msi_table rrv_tables[] =
1697 {
1698     ADD_TABLE(directory),
1699     ADD_TABLE(rrv_component),
1700     ADD_TABLE(rrv_feature),
1701     ADD_TABLE(rrv_feature_comp),
1702     ADD_TABLE(rrv_file),
1703     ADD_TABLE(rrv_registry),
1704     ADD_TABLE(rrv_remove_registry),
1705     ADD_TABLE(rrv_install_exec_seq),
1706     ADD_TABLE(media),
1707     ADD_TABLE(property)
1708 };
1709
1710 static const msi_table frp_tables[] =
1711 {
1712     ADD_TABLE(directory),
1713     ADD_TABLE(frp_component),
1714     ADD_TABLE(frp_feature),
1715     ADD_TABLE(frp_feature_comp),
1716     ADD_TABLE(frp_file),
1717     ADD_TABLE(frp_upgrade),
1718     ADD_TABLE(frp_custom_action),
1719     ADD_TABLE(frp_install_exec_seq),
1720     ADD_TABLE(media),
1721     ADD_TABLE(property)
1722 };
1723
1724 static const msi_table riv_tables[] =
1725 {
1726     ADD_TABLE(directory),
1727     ADD_TABLE(riv_component),
1728     ADD_TABLE(riv_feature),
1729     ADD_TABLE(riv_feature_comp),
1730     ADD_TABLE(riv_file),
1731     ADD_TABLE(riv_ini_file),
1732     ADD_TABLE(riv_remove_ini_file),
1733     ADD_TABLE(riv_install_exec_seq),
1734     ADD_TABLE(media),
1735     ADD_TABLE(property)
1736 };
1737
1738 static const msi_table res_tables[] =
1739 {
1740     ADD_TABLE(directory),
1741     ADD_TABLE(res_component),
1742     ADD_TABLE(res_feature),
1743     ADD_TABLE(res_feature_comp),
1744     ADD_TABLE(res_file),
1745     ADD_TABLE(res_environment),
1746     ADD_TABLE(res_install_exec_seq),
1747     ADD_TABLE(media),
1748     ADD_TABLE(property)
1749 };
1750
1751 static const msi_table rci_tables[] =
1752 {
1753     ADD_TABLE(directory),
1754     ADD_TABLE(rci_component),
1755     ADD_TABLE(rci_feature),
1756     ADD_TABLE(rci_feature_comp),
1757     ADD_TABLE(rci_file),
1758     ADD_TABLE(rci_appid),
1759     ADD_TABLE(rci_class),
1760     ADD_TABLE(rci_install_exec_seq),
1761     ADD_TABLE(media),
1762     ADD_TABLE(property)
1763 };
1764
1765 static const msi_table rei_tables[] =
1766 {
1767     ADD_TABLE(directory),
1768     ADD_TABLE(rei_component),
1769     ADD_TABLE(rei_feature),
1770     ADD_TABLE(rei_feature_comp),
1771     ADD_TABLE(rei_file),
1772     ADD_TABLE(rei_extension),
1773     ADD_TABLE(rei_verb),
1774     ADD_TABLE(rei_progid),
1775     ADD_TABLE(rei_install_exec_seq),
1776     ADD_TABLE(media),
1777     ADD_TABLE(property)
1778 };
1779
1780 static const msi_table rmi_tables[] =
1781 {
1782     ADD_TABLE(directory),
1783     ADD_TABLE(rmi_component),
1784     ADD_TABLE(rmi_feature),
1785     ADD_TABLE(rmi_feature_comp),
1786     ADD_TABLE(rmi_file),
1787     ADD_TABLE(rmi_extension),
1788     ADD_TABLE(rmi_verb),
1789     ADD_TABLE(rmi_mime),
1790     ADD_TABLE(rmi_install_exec_seq),
1791     ADD_TABLE(media),
1792     ADD_TABLE(property)
1793 };
1794
1795 static const msi_table pa_tables[] =
1796 {
1797     ADD_TABLE(directory),
1798     ADD_TABLE(pa_component),
1799     ADD_TABLE(pa_feature),
1800     ADD_TABLE(pa_feature_comp),
1801     ADD_TABLE(pa_file),
1802     ADD_TABLE(pa_msi_assembly),
1803     ADD_TABLE(pa_msi_assembly_name),
1804     ADD_TABLE(pa_install_exec_seq),
1805     ADD_TABLE(media),
1806     ADD_TABLE(property)
1807 };
1808
1809 /* cabinet definitions */
1810
1811 /* make the max size large so there is only one cab file */
1812 #define MEDIA_SIZE          0x7FFFFFFF
1813 #define FOLDER_THRESHOLD    900000
1814
1815 /* the FCI callbacks */
1816
1817 static void * CDECL mem_alloc(ULONG cb)
1818 {
1819     return HeapAlloc(GetProcessHeap(), 0, cb);
1820 }
1821
1822 static void CDECL mem_free(void *memory)
1823 {
1824     HeapFree(GetProcessHeap(), 0, memory);
1825 }
1826
1827 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
1828 {
1829     sprintf(pccab->szCab, pv, pccab->iCab);
1830     return TRUE;
1831 }
1832
1833 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
1834 {
1835     return 0;
1836 }
1837
1838 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
1839                              BOOL fContinuation, void *pv)
1840 {
1841     return 0;
1842 }
1843
1844 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
1845 {
1846     HANDLE handle;
1847     DWORD dwAccess = 0;
1848     DWORD dwShareMode = 0;
1849     DWORD dwCreateDisposition = OPEN_EXISTING;
1850
1851     dwAccess = GENERIC_READ | GENERIC_WRITE;
1852     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
1853
1854     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
1855         dwCreateDisposition = OPEN_EXISTING;
1856     else
1857         dwCreateDisposition = CREATE_NEW;
1858
1859     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
1860                          dwCreateDisposition, 0, NULL);
1861
1862     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
1863
1864     return (INT_PTR)handle;
1865 }
1866
1867 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1868 {
1869     HANDLE handle = (HANDLE)hf;
1870     DWORD dwRead;
1871     BOOL res;
1872
1873     res = ReadFile(handle, memory, cb, &dwRead, NULL);
1874     ok(res, "Failed to ReadFile\n");
1875
1876     return dwRead;
1877 }
1878
1879 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1880 {
1881     HANDLE handle = (HANDLE)hf;
1882     DWORD dwWritten;
1883     BOOL res;
1884
1885     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
1886     ok(res, "Failed to WriteFile\n");
1887
1888     return dwWritten;
1889 }
1890
1891 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
1892 {
1893     HANDLE handle = (HANDLE)hf;
1894     ok(CloseHandle(handle), "Failed to CloseHandle\n");
1895
1896     return 0;
1897 }
1898
1899 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
1900 {
1901     HANDLE handle = (HANDLE)hf;
1902     DWORD ret;
1903
1904     ret = SetFilePointer(handle, dist, NULL, seektype);
1905     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
1906
1907     return ret;
1908 }
1909
1910 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
1911 {
1912     BOOL ret = DeleteFileA(pszFile);
1913     ok(ret, "Failed to DeleteFile %s\n", pszFile);
1914
1915     return 0;
1916 }
1917
1918 static void init_functionpointers(void)
1919 {
1920     HMODULE hmsi = GetModuleHandleA("msi.dll");
1921     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
1922     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
1923
1924 #define GET_PROC(mod, func) \
1925     p ## func = (void*)GetProcAddress(mod, #func); \
1926     if(!p ## func) \
1927       trace("GetProcAddress(%s) failed\n", #func);
1928
1929     GET_PROC(hmsi, MsiQueryComponentStateA);
1930     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
1931     GET_PROC(hmsi, MsiSourceListGetInfoA);
1932     GET_PROC(hmsi, MsiGetComponentPathExA);
1933
1934     GET_PROC(hadvapi32, ConvertSidToStringSidA);
1935     GET_PROC(hadvapi32, GetTokenInformation);
1936     GET_PROC(hadvapi32, OpenProcessToken);
1937     GET_PROC(hadvapi32, RegDeleteKeyExA)
1938     GET_PROC(hkernel32, IsWow64Process)
1939
1940     hsrclient = LoadLibraryA("srclient.dll");
1941     GET_PROC(hsrclient, SRRemoveRestorePoint);
1942     GET_PROC(hsrclient, SRSetRestorePointA);
1943
1944 #undef GET_PROC
1945 }
1946
1947 static BOOL is_process_limited(void)
1948 {
1949     HANDLE token;
1950
1951     if (!pOpenProcessToken || !pGetTokenInformation) return FALSE;
1952
1953     if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
1954     {
1955         BOOL ret;
1956         TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
1957         DWORD size;
1958
1959         ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
1960         CloseHandle(token);
1961         return (ret && type == TokenElevationTypeLimited);
1962     }
1963     return FALSE;
1964 }
1965
1966 static char *get_user_sid(void)
1967 {
1968     HANDLE token;
1969     DWORD size = 0;
1970     TOKEN_USER *user;
1971     char *usersid = NULL;
1972
1973     if (!pConvertSidToStringSidA)
1974     {
1975         win_skip("ConvertSidToStringSidA is not available\n");
1976         return NULL;
1977     }
1978     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1979     GetTokenInformation(token, TokenUser, NULL, size, &size);
1980
1981     user = HeapAlloc(GetProcessHeap(), 0, size);
1982     GetTokenInformation(token, TokenUser, user, size, &size);
1983     pConvertSidToStringSidA(user->User.Sid, &usersid);
1984     HeapFree(GetProcessHeap(), 0, user);
1985
1986     CloseHandle(token);
1987     return usersid;
1988 }
1989
1990 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1991 {
1992     LPSTR tempname;
1993
1994     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1995     GetTempFileNameA(".", "xx", 0, tempname);
1996
1997     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1998     {
1999         lstrcpyA(pszTempName, tempname);
2000         HeapFree(GetProcessHeap(), 0, tempname);
2001         return TRUE;
2002     }
2003
2004     HeapFree(GetProcessHeap(), 0, tempname);
2005
2006     return FALSE;
2007 }
2008
2009 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2010                                    USHORT *pattribs, int *err, void *pv)
2011 {
2012     BY_HANDLE_FILE_INFORMATION finfo;
2013     FILETIME filetime;
2014     HANDLE handle;
2015     DWORD attrs;
2016     BOOL res;
2017
2018     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2019                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2020
2021     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2022
2023     res = GetFileInformationByHandle(handle, &finfo);
2024     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2025
2026     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2027     FileTimeToDosDateTime(&filetime, pdate, ptime);
2028
2029     attrs = GetFileAttributes(pszName);
2030     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2031
2032     return (INT_PTR)handle;
2033 }
2034
2035 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2036 {
2037     char path[MAX_PATH];
2038     char filename[MAX_PATH];
2039
2040     lstrcpyA(path, CURR_DIR);
2041     lstrcatA(path, "\\");
2042     lstrcatA(path, file);
2043
2044     lstrcpyA(filename, file);
2045
2046     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2047                       progress, get_open_info, compress);
2048 }
2049
2050 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2051 {
2052     ZeroMemory(pCabParams, sizeof(CCAB));
2053
2054     pCabParams->cb = max_size;
2055     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2056     pCabParams->setID = 0xbeef;
2057     pCabParams->iCab = 1;
2058     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2059     lstrcatA(pCabParams->szCabPath, "\\");
2060     lstrcpyA(pCabParams->szCab, name);
2061 }
2062
2063 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2064 {
2065     CCAB cabParams;
2066     LPCSTR ptr;
2067     HFCI hfci;
2068     ERF erf;
2069     BOOL res;
2070
2071     set_cab_parameters(&cabParams, name, max_size);
2072
2073     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2074                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2075                       get_temp_file, &cabParams, NULL);
2076
2077     ok(hfci != NULL, "Failed to create an FCI context\n");
2078
2079     ptr = files;
2080     while (*ptr)
2081     {
2082         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2083         ok(res, "Failed to add file: %s\n", ptr);
2084         ptr += lstrlen(ptr) + 1;
2085     }
2086
2087     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2088     ok(res, "Failed to flush the cabinet\n");
2089
2090     res = FCIDestroy(hfci);
2091     ok(res, "Failed to destroy the cabinet\n");
2092 }
2093
2094 static BOOL get_user_dirs(void)
2095 {
2096     HKEY hkey;
2097     DWORD type, size;
2098
2099     if (RegOpenKey(HKEY_CURRENT_USER,
2100                    "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hkey))
2101         return FALSE;
2102
2103     size = MAX_PATH;
2104     if (RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size))
2105     {
2106         RegCloseKey(hkey);
2107         return FALSE;
2108     }
2109
2110     RegCloseKey(hkey);
2111     return TRUE;
2112 }
2113
2114 static BOOL get_system_dirs(void)
2115 {
2116     HKEY hkey;
2117     DWORD type, size;
2118
2119     if (RegOpenKey(HKEY_LOCAL_MACHINE,
2120                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
2121         return FALSE;
2122
2123     size = MAX_PATH;
2124     if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
2125         RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
2126     {
2127         RegCloseKey(hkey);
2128         return FALSE;
2129     }
2130
2131     size = MAX_PATH;
2132     if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
2133         RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
2134     {
2135         RegCloseKey(hkey);
2136         return FALSE;
2137     }
2138
2139     RegCloseKey(hkey);
2140
2141     if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH))
2142         return FALSE;
2143
2144     return TRUE;
2145 }
2146
2147 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2148 {
2149     HANDLE file;
2150     DWORD written;
2151
2152     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2153     if (file == INVALID_HANDLE_VALUE)
2154         return;
2155
2156     WriteFile(file, data, strlen(data), &written, NULL);
2157
2158     if (size)
2159     {
2160         SetFilePointer(file, size, NULL, FILE_BEGIN);
2161         SetEndOfFile(file);
2162     }
2163
2164     CloseHandle(file);
2165 }
2166
2167 #define create_file(name, size) create_file_data(name, name, size)
2168
2169 static void create_test_files(void)
2170 {
2171     CreateDirectoryA("msitest", NULL);
2172     create_file("msitest\\one.txt", 100);
2173     CreateDirectoryA("msitest\\first", NULL);
2174     create_file("msitest\\first\\two.txt", 100);
2175     CreateDirectoryA("msitest\\second", NULL);
2176     create_file("msitest\\second\\three.txt", 100);
2177
2178     create_file("four.txt", 100);
2179     create_file("five.txt", 100);
2180     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2181
2182     create_file("msitest\\filename", 100);
2183     create_file("msitest\\service.exe", 100);
2184
2185     DeleteFileA("four.txt");
2186     DeleteFileA("five.txt");
2187 }
2188
2189 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2190 {
2191     CHAR path[MAX_PATH];
2192
2193     lstrcpyA(path, PROG_FILES_DIR);
2194     lstrcatA(path, "\\");
2195     lstrcatA(path, rel_path);
2196
2197     if (is_file)
2198         return DeleteFileA(path);
2199     else
2200         return RemoveDirectoryA(path);
2201 }
2202
2203 static void delete_test_files(void)
2204 {
2205     DeleteFileA("msitest.msi");
2206     DeleteFileA("msitest.cab");
2207     DeleteFileA("msitest\\second\\three.txt");
2208     DeleteFileA("msitest\\first\\two.txt");
2209     DeleteFileA("msitest\\one.txt");
2210     DeleteFileA("msitest\\service.exe");
2211     DeleteFileA("msitest\\filename");
2212     RemoveDirectoryA("msitest\\second");
2213     RemoveDirectoryA("msitest\\first");
2214     RemoveDirectoryA("msitest");
2215 }
2216
2217 static void write_file(const CHAR *filename, const char *data, int data_size)
2218 {
2219     DWORD size;
2220     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2221     WriteFile(hf, data, data_size, &size, NULL);
2222     CloseHandle(hf);
2223 }
2224
2225 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
2226 {
2227     MSIHANDLE summary;
2228     UINT r;
2229
2230     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2232
2233     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
2234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2235
2236     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2237                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
2238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2239
2240     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
2241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2242
2243     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2245
2246     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2248
2249     /* write the summary changes back to the stream */
2250     r = MsiSummaryInfoPersist(summary);
2251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2252
2253     MsiCloseHandle(summary);
2254 }
2255
2256 #define create_database(name, tables, num_tables) \
2257     create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
2258
2259 #define create_database_template(name, tables, num_tables, version, template) \
2260     create_database_wordcount(name, tables, num_tables, version, 0, template);
2261
2262 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
2263                                       int num_tables, INT version, INT wordcount,
2264                                       const char *template)
2265 {
2266     MSIHANDLE db;
2267     UINT r;
2268     int j;
2269
2270     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
2271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2272
2273     /* import the tables into the database */
2274     for (j = 0; j < num_tables; j++)
2275     {
2276         const msi_table *table = &tables[j];
2277
2278         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2279
2280         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2281         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2282
2283         DeleteFileA(table->filename);
2284     }
2285
2286     write_msi_summary_info(db, version, wordcount, template);
2287
2288     r = MsiDatabaseCommit(db);
2289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2290
2291     MsiCloseHandle(db);
2292 }
2293
2294 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
2295 {
2296     RESTOREPOINTINFOA spec;
2297
2298     spec.dwEventType = event_type;
2299     spec.dwRestorePtType = APPLICATION_INSTALL;
2300     spec.llSequenceNumber = status->llSequenceNumber;
2301     lstrcpyA(spec.szDescription, "msitest restore point");
2302
2303     return pSRSetRestorePointA(&spec, status);
2304 }
2305
2306 static void remove_restore_point(DWORD seq_number)
2307 {
2308     DWORD res;
2309
2310     res = pSRRemoveRestorePoint(seq_number);
2311     if (res != ERROR_SUCCESS)
2312         trace("Failed to remove the restore point : %08x\n", res);
2313 }
2314
2315 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
2316 {
2317     if (pRegDeleteKeyExA)
2318         return pRegDeleteKeyExA( key, subkey, access, 0 );
2319     return RegDeleteKeyA( key, subkey );
2320 }
2321
2322 static BOOL file_exists(LPCSTR file)
2323 {
2324     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2325 }
2326
2327 static BOOL pf_exists(LPCSTR file)
2328 {
2329     CHAR path[MAX_PATH];
2330
2331     lstrcpyA(path, PROG_FILES_DIR);
2332     lstrcatA(path, "\\");
2333     lstrcatA(path, file);
2334
2335     return file_exists(path);
2336 }
2337
2338 static void delete_pfmsitest_files(void)
2339 {
2340     SHFILEOPSTRUCT shfl;
2341     CHAR path[MAX_PATH+11];
2342
2343     lstrcpyA(path, PROG_FILES_DIR);
2344     lstrcatA(path, "\\msitest\\*");
2345     path[strlen(path) + 1] = '\0';
2346
2347     shfl.hwnd = NULL;
2348     shfl.wFunc = FO_DELETE;
2349     shfl.pFrom = path;
2350     shfl.pTo = NULL;
2351     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI;
2352
2353     SHFileOperation(&shfl);
2354
2355     lstrcpyA(path, PROG_FILES_DIR);
2356     lstrcatA(path, "\\msitest");
2357     RemoveDirectoryA(path);
2358 }
2359
2360 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2361 {
2362     char val[MAX_PATH];
2363     DWORD size, type;
2364     LONG res;
2365
2366     size = MAX_PATH;
2367     val[0] = '\0';
2368     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2369
2370     if (res != ERROR_SUCCESS ||
2371         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
2372     {
2373         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2374         return;
2375     }
2376
2377     if (!expected)
2378         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2379     else
2380     {
2381         if (bcase)
2382             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2383         else
2384             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2385     }
2386 }
2387
2388 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2389 {
2390     DWORD val, size, type;
2391     LONG res;
2392
2393     size = sizeof(DWORD);
2394     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2395
2396     if (res != ERROR_SUCCESS || type != REG_DWORD)
2397     {
2398         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2399         return;
2400     }
2401
2402     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2403 }
2404
2405 static void check_reg_dword4(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2406                              DWORD expected4, DWORD line)
2407 {
2408     DWORD val, size, type;
2409     LONG res;
2410
2411     size = sizeof(DWORD);
2412     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2413
2414     if (res != ERROR_SUCCESS || type != REG_DWORD)
2415     {
2416         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2417         return;
2418     }
2419
2420     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4,
2421         "Expected %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, val);
2422 }
2423
2424 static void check_reg_dword5(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2425                              DWORD expected4, DWORD expected5, DWORD line)
2426 {
2427     DWORD val, size, type;
2428     LONG res;
2429
2430     size = sizeof(DWORD);
2431     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2432
2433     if (res != ERROR_SUCCESS || type != REG_DWORD)
2434     {
2435         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2436         return;
2437     }
2438
2439     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4 ||
2440         val == expected5,
2441         "Expected %d, %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, expected5, val);
2442 }
2443
2444 #define CHECK_REG_STR(prodkey, name, expected) \
2445     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2446
2447 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2448     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2449     RegDeleteValueA(prodkey, name);
2450
2451 #define CHECK_REG_ISTR(prodkey, name, expected) \
2452     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2453
2454 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2455     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2456     RegDeleteValueA(prodkey, name);
2457
2458 #define CHECK_REG_DWORD(prodkey, name, expected) \
2459     check_reg_dword(prodkey, name, expected, __LINE__);
2460
2461 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2462     check_reg_dword(prodkey, name, expected, __LINE__); \
2463     RegDeleteValueA(prodkey, name);
2464
2465 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
2466     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
2467
2468 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
2469     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
2470     RegDeleteValueA(prodkey, name);
2471
2472 #define CHECK_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \
2473     check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__);
2474
2475 #define CHECK_DEL_REG_DWORD5(prodkey, name, expected1, expected2, expected3, expected4 ,expected5) \
2476     check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \
2477     RegDeleteValueA(prodkey, name);
2478
2479 static void get_date_str(LPSTR date)
2480 {
2481     SYSTEMTIME systime;
2482
2483     static const char date_fmt[] = "%d%02d%02d";
2484     GetLocalTime(&systime);
2485     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2486 }
2487
2488 static void test_register_product(void)
2489 {
2490     UINT r;
2491     LONG res;
2492     HKEY hkey, props, usage;
2493     LPSTR usersid;
2494     char date[MAX_PATH], temp[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
2495     DWORD size, type;
2496     REGSAM access = KEY_ALL_ACCESS;
2497
2498     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2499                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2500     static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion"
2501                                            "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2502     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2503                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2504     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2505                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2506     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2507                                     "\\51AAE0C44620A5E4788506E91F249BD2";
2508
2509     if (is_process_limited())
2510     {
2511         skip("process is limited\n");
2512         return;
2513     }
2514
2515     if (!(usersid = get_user_sid()))
2516         return;
2517
2518     get_date_str(date);
2519     GetTempPath(MAX_PATH, temp);
2520
2521     CreateDirectoryA("msitest", NULL);
2522     create_file("msitest\\maximus", 500);
2523
2524     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2525
2526     if (is_wow64)
2527         access |= KEY_WOW64_64KEY;
2528
2529     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2530
2531     /* RegisterProduct */
2532     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2533     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2534     {
2535         skip("Not enough rights to perform tests\n");
2536         goto error;
2537     }
2538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2539     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2540     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2541
2542     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2543     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2544
2545     if (is_64bit)
2546     {
2547         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2548         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2549     }
2550     else
2551     {
2552         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2553         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2554     }
2555
2556     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2557     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2558     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2559     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2560     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2561     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2562     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2563     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2564     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2565     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2566     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2567     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2568     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2569     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2570     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2571     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2572     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2573     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2574     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2575     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2576     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2577     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2578     todo_wine
2579     {
2580         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
2581     }
2582
2583     delete_key(hkey, "", access);
2584     RegCloseKey(hkey);
2585
2586     sprintf(keypath, userdata, usersid);
2587     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2589
2590     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2592
2593     size = sizeof(path);
2594     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2595     DeleteFileA(path);
2596     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2597
2598     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2599     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2600     CHECK_DEL_REG_STR(props, "InstallDate", date);
2601     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2602     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2603     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2604     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2605     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2606     CHECK_DEL_REG_STR(props, "Comments", NULL);
2607     CHECK_DEL_REG_STR(props, "Contact", NULL);
2608     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2609     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2610     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2611     CHECK_DEL_REG_STR(props, "Readme", NULL);
2612     CHECK_DEL_REG_STR(props, "Size", NULL);
2613     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2614     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2615     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2616     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2617     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2618     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2619     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2620     todo_wine
2621     {
2622         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
2623     }
2624
2625     delete_key(props, "", access);
2626     RegCloseKey(props);
2627
2628     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2629     todo_wine
2630     {
2631         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2632     }
2633
2634     delete_key(usage, "", access);
2635     RegCloseKey(usage);
2636     delete_key(hkey, "", access);
2637     RegCloseKey(hkey);
2638
2639     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641
2642     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2643
2644     delete_key(hkey, "", access);
2645     RegCloseKey(hkey);
2646
2647     /* RegisterProduct, machine */
2648     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
2649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2650     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2651     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2652
2653     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey);
2654     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2655
2656     if (is_64bit)
2657     {
2658         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2659         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2660     }
2661     else
2662     {
2663         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2664         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2665     }
2666
2667     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2668     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2669     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2670     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2671     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2672     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2673     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2674     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2675     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2676     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2677     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2678     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2679     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2680     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2681     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2682     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2683     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2684     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2685     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2686     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2687     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2688     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2689     todo_wine
2690     {
2691         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
2692     }
2693
2694     delete_key(hkey, "", access);
2695     RegCloseKey(hkey);
2696
2697     sprintf(keypath, userdata, "S-1-5-18");
2698     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2700
2701     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2703
2704     size = sizeof(path);
2705     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2706     DeleteFileA(path);
2707     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2708
2709     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2710     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2711     CHECK_DEL_REG_STR(props, "InstallDate", date);
2712     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2713     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2714     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2715     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2716     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2717     CHECK_DEL_REG_STR(props, "Comments", NULL);
2718     CHECK_DEL_REG_STR(props, "Contact", NULL);
2719     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2720     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2721     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2722     CHECK_DEL_REG_STR(props, "Readme", NULL);
2723     CHECK_DEL_REG_STR(props, "Size", NULL);
2724     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2725     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2726     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2727     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2728     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2729     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2730     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2731     todo_wine
2732     {
2733         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
2734     }
2735
2736     delete_key(props, "", access);
2737     RegCloseKey(props);
2738
2739     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2740     todo_wine
2741     {
2742         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2743     }
2744
2745     delete_key(usage, "", access);
2746     RegCloseKey(usage);
2747     delete_key(hkey, "", access);
2748     RegCloseKey(hkey);
2749
2750     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2752
2753     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2754
2755     delete_key(hkey, "", access);
2756     RegCloseKey(hkey);
2757
2758 error:
2759     DeleteFile(msifile);
2760     DeleteFile("msitest\\maximus");
2761     RemoveDirectory("msitest");
2762     HeapFree(GetProcessHeap(), 0, usersid);
2763 }
2764
2765 static void test_publish_product(void)
2766 {
2767     UINT r;
2768     LONG res;
2769     LPSTR usersid;
2770     HKEY sourcelist, net, props;
2771     HKEY hkey, patches, media;
2772     CHAR keypath[MAX_PATH];
2773     CHAR temp[MAX_PATH];
2774     CHAR path[MAX_PATH];
2775     BOOL old_installer = FALSE;
2776     REGSAM access = KEY_ALL_ACCESS;
2777
2778     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2779                                    "\\Installer\\UserData\\%s\\Products"
2780                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2781     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
2782                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2783     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2784                                      "\\51AAE0C44620A5E4788506E91F249BD2";
2785     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2786                                   "\\Installer\\Products"
2787                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2788     static const CHAR machprod[] = "Software\\Classes\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2789     static const CHAR machup[] = "Software\\Classes\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2790
2791     if (is_process_limited())
2792     {
2793         skip("process is limited\n");
2794         return;
2795     }
2796
2797     if (!(usersid = get_user_sid()))
2798         return;
2799
2800     GetTempPath(MAX_PATH, temp);
2801
2802     CreateDirectoryA("msitest", NULL);
2803     create_file("msitest\\maximus", 500);
2804
2805     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2806
2807     if (is_wow64)
2808         access |= KEY_WOW64_64KEY;
2809
2810     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2811
2812     /* PublishProduct, current user */
2813     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2814     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2815     {
2816         skip("Not enough rights to perform tests\n");
2817         goto error;
2818     }
2819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2820     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2821     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2822
2823     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
2824     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2825
2826     sprintf(keypath, prodpath, usersid);
2827     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2828     if (res == ERROR_FILE_NOT_FOUND)
2829     {
2830         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2831         if (res == ERROR_SUCCESS)
2832         {
2833             win_skip("Windows Installer < 3.0 detected\n");
2834             RegCloseKey(hkey);
2835             old_installer = TRUE;
2836             goto currentuser;
2837         }
2838         else
2839         {
2840             win_skip("Install failed, no need to continue\n");
2841             return;
2842         }
2843     }
2844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2845
2846     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2847     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2848
2849     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
2850     todo_wine
2851     {
2852         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2853         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2854     }
2855
2856     delete_key(patches, "", access);
2857     RegCloseKey(patches);
2858     delete_key(hkey, "", access);
2859     RegCloseKey(hkey);
2860
2861 currentuser:
2862     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2864
2865     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2866     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2867     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2868     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2869     if (!old_installer)
2870         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2871     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
2872     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2873     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2874     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2875
2876     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2878
2879     lstrcpyA(path, "n;1;");
2880     lstrcatA(path, temp);
2881     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2882     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2883
2884     res = RegOpenKeyA(sourcelist, "Net", &net);
2885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2886
2887     CHECK_DEL_REG_STR(net, "1", temp);
2888
2889     RegDeleteKeyA(net, "");
2890     RegCloseKey(net);
2891
2892     res = RegOpenKeyA(sourcelist, "Media", &media);
2893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2894
2895     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2896
2897     RegDeleteKeyA(media, "");
2898     RegCloseKey(media);
2899     RegDeleteKeyA(sourcelist, "");
2900     RegCloseKey(sourcelist);
2901     RegDeleteKeyA(hkey, "");
2902     RegCloseKey(hkey);
2903
2904     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2908
2909     RegDeleteKeyA(hkey, "");
2910     RegCloseKey(hkey);
2911
2912     /* PublishProduct, machine */
2913     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
2914     if (old_installer)
2915         goto machprod;
2916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2917     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2918     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2919
2920     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
2921     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2922
2923     sprintf(keypath, prodpath, "S-1-5-18");
2924     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2926
2927     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2928     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2929
2930     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
2931     todo_wine
2932     {
2933         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2934         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2935     }
2936
2937     delete_key(patches, "", access);
2938     RegCloseKey(patches);
2939     delete_key(hkey, "", access);
2940     RegCloseKey(hkey);
2941
2942 machprod:
2943     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machprod, 0, access, &hkey);
2944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2945
2946     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2947     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2948     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2949     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2950     if (!old_installer)
2951         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2952     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
2953     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2954     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2955     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2956
2957     res = RegOpenKeyExA(hkey, "SourceList", 0, access, &sourcelist);
2958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2959
2960     lstrcpyA(path, "n;1;");
2961     lstrcatA(path, temp);
2962     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2963     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2964
2965     res = RegOpenKeyExA(sourcelist, "Net", 0, access, &net);
2966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2967
2968     CHECK_DEL_REG_STR(net, "1", temp);
2969
2970     res = delete_key(net, "", access);
2971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2972     RegCloseKey(net);
2973
2974     res = RegOpenKeyExA(sourcelist, "Media", 0, access, &media);
2975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2976
2977     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2978
2979     res = delete_key(media, "", access);
2980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2981     RegCloseKey(media);
2982     res = delete_key(sourcelist, "", access);
2983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2984     RegCloseKey(sourcelist);
2985     res = delete_key(hkey, "", access);
2986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2987     RegCloseKey(hkey);
2988
2989     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machup, 0, access, &hkey);
2990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2991
2992     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2993
2994     res = delete_key(hkey, "", access);
2995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2996     RegCloseKey(hkey);
2997
2998 error:
2999     DeleteFile(msifile);
3000     DeleteFile("msitest\\maximus");
3001     RemoveDirectory("msitest");
3002     HeapFree(GetProcessHeap(), 0, usersid);
3003 }
3004
3005 static void test_publish_features(void)
3006 {
3007     UINT r;
3008     LONG res;
3009     HKEY hkey;
3010     LPSTR usersid;
3011     CHAR keypath[MAX_PATH];
3012     REGSAM access = KEY_ALL_ACCESS;
3013
3014     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
3015                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3016     static const CHAR udfeatpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3017                                      "\\Installer\\UserData\\%s\\Products"
3018                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
3019     static const CHAR udpridpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3020                                      "\\Installer\\UserData\\%s\\Products"
3021                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3022     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3023                                   "\\Installer\\Features";
3024     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
3025                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3026
3027     if (is_process_limited())
3028     {
3029         skip("process is limited\n");
3030         return;
3031     }
3032
3033     if (!(usersid = get_user_sid()))
3034         return;
3035
3036     CreateDirectoryA("msitest", NULL);
3037     create_file("msitest\\maximus", 500);
3038
3039     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3040
3041     if (is_wow64)
3042         access |= KEY_WOW64_64KEY;
3043
3044     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3045
3046     /* PublishFeatures, current user */
3047     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3048     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3049     {
3050         skip("Not enough rights to perform tests\n");
3051         goto error;
3052     }
3053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3054     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3055     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3056
3057     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3058     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3059
3060     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3061     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3062
3063     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3065
3066     CHECK_REG_STR(hkey, "feature", "");
3067     CHECK_REG_STR(hkey, "montecristo", "");
3068
3069     RegDeleteValueA(hkey, "feature");
3070     RegDeleteValueA(hkey, "montecristo");
3071     delete_key(hkey, "", access);
3072     RegCloseKey(hkey);
3073
3074     sprintf(keypath, udfeatpath, usersid);
3075     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3076     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3077
3078     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3079     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3080
3081     RegDeleteValueA(hkey, "feature");
3082     RegDeleteValueA(hkey, "montecristo");
3083     delete_key(hkey, "", access);
3084     RegCloseKey(hkey);
3085     sprintf(keypath, udpridpath, usersid);
3086     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3087
3088     /* PublishFeatures, machine */
3089     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
3090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3091     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3092     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3093
3094     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3095     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3096
3097     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3098     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3099     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3101
3102     CHECK_REG_STR(hkey, "feature", "");
3103     CHECK_REG_STR(hkey, "montecristo", "");
3104
3105     RegDeleteValueA(hkey, "feature");
3106     RegDeleteValueA(hkey, "montecristo");
3107     delete_key(hkey, "", access);
3108     RegCloseKey(hkey);
3109
3110     sprintf(keypath, udfeatpath, "S-1-5-18");
3111     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3115     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3116
3117     RegDeleteValueA(hkey, "feature");
3118     RegDeleteValueA(hkey, "montecristo");
3119     delete_key(hkey, "", access);
3120     RegCloseKey(hkey);
3121     sprintf(keypath, udpridpath, "S-1-5-18");
3122     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3123
3124 error:
3125     DeleteFile(msifile);
3126     DeleteFile("msitest\\maximus");
3127     RemoveDirectory("msitest");
3128     HeapFree(GetProcessHeap(), 0, usersid);
3129 }
3130
3131 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
3132 {
3133     DWORD len = 0;
3134     LPSTR val;
3135     LONG r;
3136
3137     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
3138     if (r != ERROR_SUCCESS)
3139         return NULL;
3140
3141     len += sizeof (WCHAR);
3142     val = HeapAlloc(GetProcessHeap(), 0, len);
3143     if (!val) return NULL;
3144     val[0] = 0;
3145     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
3146     return val;
3147 }
3148
3149 static void get_owner_company(LPSTR *owner, LPSTR *company)
3150 {
3151     LONG res;
3152     HKEY hkey;
3153     REGSAM access = KEY_ALL_ACCESS;
3154
3155     *owner = *company = NULL;
3156
3157     if (is_wow64)
3158         access |= KEY_WOW64_64KEY;
3159
3160     res = RegOpenKeyA(HKEY_CURRENT_USER,
3161                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
3162     if (res == ERROR_SUCCESS)
3163     {
3164         *owner = reg_get_val_str(hkey, "DefName");
3165         *company = reg_get_val_str(hkey, "DefCompany");
3166         RegCloseKey(hkey);
3167     }
3168
3169     if (!*owner || !*company)
3170     {
3171         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3172                             "Software\\Microsoft\\Windows\\CurrentVersion", 0, access, &hkey);
3173         if (res == ERROR_SUCCESS)
3174         {
3175             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3176             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3177             RegCloseKey(hkey);
3178         }
3179     }
3180
3181     if (!*owner || !*company)
3182     {
3183         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3184                             "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey);
3185         if (res == ERROR_SUCCESS)
3186         {
3187             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3188             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3189             RegCloseKey(hkey);
3190         }
3191     }
3192 }
3193
3194 static void test_register_user(void)
3195 {
3196     UINT r;
3197     LONG res;
3198     HKEY props;
3199     LPSTR usersid;
3200     LPSTR owner, company;
3201     CHAR keypath[MAX_PATH];
3202     REGSAM access = KEY_ALL_ACCESS;
3203
3204     static const CHAR keypropsfmt[] =
3205         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3206         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
3207     static const CHAR keypridfmt[] =
3208         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3209         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3210
3211     if (is_process_limited())
3212     {
3213         skip("process is limited\n");
3214         return;
3215     }
3216
3217     if (!(usersid = get_user_sid()))
3218         return;
3219
3220     get_owner_company(&owner, &company);
3221
3222     CreateDirectoryA("msitest", NULL);
3223     create_file("msitest\\maximus", 500);
3224
3225     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3226
3227     if (is_wow64)
3228         access |= KEY_WOW64_64KEY;
3229
3230     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3231
3232     /* RegisterUser, per-user */
3233     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
3234     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3235     {
3236         skip("Not enough rights to perform tests\n");
3237         goto error;
3238     }
3239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3240     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3241     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3242
3243     sprintf(keypath, keypropsfmt, usersid);
3244     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3246
3247     CHECK_REG_STR(props, "ProductID", "none");
3248     CHECK_REG_STR(props, "RegCompany", company);
3249     CHECK_REG_STR(props, "RegOwner", owner);
3250
3251     RegDeleteValueA(props, "ProductID");
3252     RegDeleteValueA(props, "RegCompany");
3253     RegDeleteValueA(props, "RegOwner");
3254     delete_key(props, "", access);
3255     RegCloseKey(props);
3256     sprintf(keypath, keypridfmt, usersid);
3257     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3258
3259     /* RegisterUser, machine */
3260     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
3261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3262     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3263     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3264
3265     sprintf(keypath, keypropsfmt, "S-1-5-18");
3266     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3268
3269     CHECK_REG_STR(props, "ProductID", "none");
3270     CHECK_REG_STR(props, "RegCompany", company);
3271     CHECK_REG_STR(props, "RegOwner", owner);
3272
3273     RegDeleteValueA(props, "ProductID");
3274     RegDeleteValueA(props, "RegCompany");
3275     RegDeleteValueA(props, "RegOwner");
3276     delete_key(props, "", access);
3277     RegCloseKey(props);
3278     sprintf(keypath, keypridfmt, "S-1-5-18");
3279     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3280
3281 error:
3282     HeapFree(GetProcessHeap(), 0, company);
3283     HeapFree(GetProcessHeap(), 0, owner);
3284
3285     DeleteFile(msifile);
3286     DeleteFile("msitest\\maximus");
3287     RemoveDirectory("msitest");
3288     LocalFree(usersid);
3289 }
3290
3291 static void test_process_components(void)
3292 {
3293     UINT r;
3294     LONG res;
3295     DWORD size;
3296     HKEY comp, hkey;
3297     LPSTR usersid;
3298     CHAR val[MAX_PATH];
3299     CHAR keypath[MAX_PATH];
3300     CHAR program_files_maximus[MAX_PATH];
3301     REGSAM access = KEY_ALL_ACCESS;
3302
3303     static const CHAR keyfmt[] =
3304         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3305         "UserData\\%s\\Components\\%s";
3306     static const CHAR compkey[] =
3307         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3308
3309     if (is_process_limited())
3310     {
3311         skip("process is limited\n");
3312         return;
3313     }
3314
3315     if (!(usersid = get_user_sid()))
3316         return;
3317
3318     CreateDirectoryA("msitest", NULL);
3319     create_file("msitest\\maximus", 500);
3320
3321     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3322
3323     if (is_wow64)
3324         access |= KEY_WOW64_64KEY;
3325
3326     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3327
3328     /* ProcessComponents, per-user */
3329     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3330     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3331     {
3332         skip("Not enough rights to perform tests\n");
3333         goto error;
3334     }
3335     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3336     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3337     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3338
3339     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3340     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3342
3343     size = MAX_PATH;
3344     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3345                            NULL, NULL, (LPBYTE)val, &size);
3346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3347
3348     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3349     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3350
3351     ok(!lstrcmpiA(val, program_files_maximus),
3352        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3353
3354     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3355     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3356
3357     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3358     delete_key(comp, "", access);
3359     RegCloseKey(comp);
3360
3361     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
3362     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3364
3365     size = MAX_PATH;
3366     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3367                            NULL, NULL, (LPBYTE)val, &size);
3368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3369     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3370        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3371
3372     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3373     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3374
3375     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3376     delete_key(comp, "", access);
3377     RegCloseKey(comp);
3378
3379     /* ProcessComponents, machine */
3380     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
3381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3382     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3383     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3384
3385     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
3386     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3388
3389     size = MAX_PATH;
3390     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3391                            NULL, NULL, (LPBYTE)val, &size);
3392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3393     ok(!lstrcmpiA(val, program_files_maximus),
3394        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3395
3396     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3397     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3398
3399     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3400     delete_key(comp, "", access);
3401     RegCloseKey(comp);
3402
3403     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
3404     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3406
3407     size = MAX_PATH;
3408     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3409                            NULL, NULL, (LPBYTE)val, &size);
3410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3411     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3412        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3413
3414     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3415     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3416
3417     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3418     delete_key(comp, "", access);
3419     RegCloseKey(comp);
3420
3421 error:
3422     DeleteFile(msifile);
3423     DeleteFile("msitest\\maximus");
3424     RemoveDirectory("msitest");
3425     LocalFree(usersid);
3426 }
3427
3428 static void test_publish(void)
3429 {
3430     UINT r;
3431     LONG res;
3432     HKEY uninstall, prodkey, uninstall_32node = NULL;
3433     INSTALLSTATE state;
3434     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3435     char date[MAX_PATH], temp[MAX_PATH];
3436     REGSAM access = KEY_ALL_ACCESS;
3437
3438     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3439     static const CHAR subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3440
3441     if (!pMsiQueryComponentStateA)
3442     {
3443         win_skip("MsiQueryComponentStateA is not available\n");
3444         return;
3445     }
3446     if (is_process_limited())
3447     {
3448         skip("process is limited\n");
3449         return;
3450     }
3451
3452     get_date_str(date);
3453     GetTempPath(MAX_PATH, temp);
3454
3455     if (is_wow64)
3456         access |= KEY_WOW64_64KEY;
3457
3458     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall);
3459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3460
3461     if (is_64bit)
3462     {
3463         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node);
3464         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3465     }
3466
3467     CreateDirectoryA("msitest", NULL);
3468     create_file("msitest\\maximus", 500);
3469
3470     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3471
3472     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3473
3474     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3475     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3476
3477     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3478     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3479
3480     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3481     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3482
3483     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3484                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3485     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3486     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3487
3488     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3489     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3490
3491     /* nothing published */
3492     r = MsiInstallProductA(msifile, NULL);
3493     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3494     {
3495         skip("Not enough rights to perform tests\n");
3496         goto error;
3497     }
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3499     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3500     ok(pf_exists("msitest"), "File not installed\n");
3501
3502     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3503     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3504
3505     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3506     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3507
3508     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3509     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3510
3511     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3512                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3513     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3514     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3515
3516     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3517     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3518
3519     /* PublishProduct and RegisterProduct */
3520     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3523     ok(pf_exists("msitest"), "File not installed\n");
3524
3525     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3526     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3527
3528     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3529     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3530
3531     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3532     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3533
3534     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3535                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3536     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3537     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3538
3539     if (is_64bit)
3540     {
3541         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3542         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3543     }
3544     else
3545     {
3546         res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3547         if (is_wow64 && res == ERROR_FILE_NOT_FOUND) /* XP - Vista, Wow64 */
3548             res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3549         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3550     }
3551
3552     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3553     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3554     CHECK_REG_STR(prodkey, "InstallDate", date);
3555     CHECK_REG_STR(prodkey, "InstallSource", temp);
3556     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3557     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3558     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3559     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3560     CHECK_REG_STR(prodkey, "Comments", NULL);
3561     CHECK_REG_STR(prodkey, "Contact", NULL);
3562     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3563     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3564     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3565     CHECK_REG_STR(prodkey, "Readme", NULL);
3566     CHECK_REG_STR(prodkey, "Size", NULL);
3567     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3568     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3569     CHECK_REG_DWORD(prodkey, "Language", 1033);
3570     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3571     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3572     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3573     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3574     todo_wine
3575     {
3576         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3577     }
3578
3579     RegCloseKey(prodkey);
3580
3581     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3583     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3584     ok(pf_exists("msitest"), "File deleted\n");
3585
3586     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3587     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3588
3589     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3590     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3591
3592     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3593     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3594
3595     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3596                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3597     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3598     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3599
3600     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3601     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3602
3603     /* complete install */
3604     r = MsiInstallProductA(msifile, "FULL=1");
3605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3606     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3607     ok(pf_exists("msitest"), "File not installed\n");
3608
3609     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3610     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3611
3612     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3613     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3614
3615     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3616     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3617
3618     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3619                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3621     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3622
3623     if (is_64bit)
3624     {
3625         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3626         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3627     }
3628     else
3629     {
3630         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3631         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3632     }
3633
3634     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3635     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3636     CHECK_REG_STR(prodkey, "InstallDate", date);
3637     CHECK_REG_STR(prodkey, "InstallSource", temp);
3638     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3639     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3640     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3641     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3642     CHECK_REG_STR(prodkey, "Comments", NULL);
3643     CHECK_REG_STR(prodkey, "Contact", NULL);
3644     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3645     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3646     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3647     CHECK_REG_STR(prodkey, "Readme", NULL);
3648     CHECK_REG_STR(prodkey, "Size", NULL);
3649     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3650     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3651     CHECK_REG_DWORD(prodkey, "Language", 1033);
3652     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3653     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3654     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3655     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3656     todo_wine
3657     {
3658         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3659     }
3660
3661     RegCloseKey(prodkey);
3662
3663     /* no UnpublishFeatures */
3664     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3665     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3666     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3667     ok(!pf_exists("msitest"), "Directory not deleted\n");
3668
3669     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3670     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3671
3672     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3673     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3674
3675     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3676     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3677
3678     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3679                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3680     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3681     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3682
3683     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3684     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3685
3686     /* complete install */
3687     r = MsiInstallProductA(msifile, "FULL=1");
3688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3689     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3690     ok(pf_exists("msitest"), "File not installed\n");
3691
3692     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3693     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3694
3695     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3696     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3697
3698     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3699     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3700
3701     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3702                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3704     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3705
3706     if (is_64bit)
3707     {
3708         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3709         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3710     }
3711     else
3712     {
3713         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3714         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3715     }
3716
3717     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3718     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3719     CHECK_REG_STR(prodkey, "InstallDate", date);
3720     CHECK_REG_STR(prodkey, "InstallSource", temp);
3721     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3722     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3723     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3724     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3725     CHECK_REG_STR(prodkey, "Comments", NULL);
3726     CHECK_REG_STR(prodkey, "Contact", NULL);
3727     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3728     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3729     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3730     CHECK_REG_STR(prodkey, "Readme", NULL);
3731     CHECK_REG_STR(prodkey, "Size", NULL);
3732     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3733     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3734     CHECK_REG_DWORD(prodkey, "Language", 1033);
3735     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3736     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3737     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3738     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3739     todo_wine
3740     {
3741         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3742     }
3743
3744     RegCloseKey(prodkey);
3745
3746     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3747     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3749     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3750     ok(pf_exists("msitest"), "Directory deleted\n");
3751
3752     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3753     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3754
3755     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3756     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3757
3758     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3759     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3760
3761     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3762                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3763     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3764     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3765
3766     if (is_64bit)
3767     {
3768         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3769         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3770     }
3771     else
3772     {
3773         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3774         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3775     }
3776
3777     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3778     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3779     CHECK_REG_STR(prodkey, "InstallDate", date);
3780     CHECK_REG_STR(prodkey, "InstallSource", temp);
3781     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3782     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3783     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3784     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3785     CHECK_REG_STR(prodkey, "Comments", NULL);
3786     CHECK_REG_STR(prodkey, "Contact", NULL);
3787     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3788     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3789     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3790     CHECK_REG_STR(prodkey, "Readme", NULL);
3791     CHECK_REG_STR(prodkey, "Size", NULL);
3792     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3793     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3794     CHECK_REG_DWORD(prodkey, "Language", 1033);
3795     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3796     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3797     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3798     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3799     todo_wine
3800     {
3801         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3802     }
3803
3804     RegCloseKey(prodkey);
3805
3806     /* complete install */
3807     r = MsiInstallProductA(msifile, "FULL=1");
3808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3809     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3810     ok(pf_exists("msitest"), "File not installed\n");
3811
3812     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3813     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3814
3815     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3816     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3817
3818     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3819     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3820
3821     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3822                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3824     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3825
3826     if (is_64bit)
3827     {
3828         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3829         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3830     }
3831     else
3832     {
3833         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3834         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3835     }
3836
3837     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3838     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3839     CHECK_REG_STR(prodkey, "InstallDate", date);
3840     CHECK_REG_STR(prodkey, "InstallSource", temp);
3841     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3842     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3843     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3844     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3845     CHECK_REG_STR(prodkey, "Comments", NULL);
3846     CHECK_REG_STR(prodkey, "Contact", NULL);
3847     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3848     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3849     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3850     CHECK_REG_STR(prodkey, "Readme", NULL);
3851     CHECK_REG_STR(prodkey, "Size", NULL);
3852     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3853     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3854     CHECK_REG_DWORD(prodkey, "Language", 1033);
3855     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3856     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3857     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3858     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3859     todo_wine
3860     {
3861         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -20, 10, 24);
3862     }
3863
3864     RegCloseKey(prodkey);
3865
3866     /* UnpublishFeatures, both features removed */
3867     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3868     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3869     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3870     ok(!pf_exists("msitest"), "Directory not deleted\n");
3871
3872     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3873     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3874
3875     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3876     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3877
3878     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3879     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3880
3881     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3882                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3883     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3884     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3885
3886     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3887     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3888
3889     /* complete install */
3890     r = MsiInstallProductA(msifile, "FULL=1");
3891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3892     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3893     ok(pf_exists("msitest"), "File not installed\n");
3894
3895     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3896     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3897
3898     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3899     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3900
3901     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3902     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3903
3904     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3905                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3907     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3908
3909     if (is_64bit)
3910     {
3911         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3912         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3913     }
3914     else
3915     {
3916         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3917         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3918     }
3919
3920     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3921     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3922     CHECK_REG_STR(prodkey, "InstallDate", date);
3923     CHECK_REG_STR(prodkey, "InstallSource", temp);
3924     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3925     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3926     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3927     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3928     CHECK_REG_STR(prodkey, "Comments", NULL);
3929     CHECK_REG_STR(prodkey, "Contact", NULL);
3930     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3931     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3932     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3933     CHECK_REG_STR(prodkey, "Readme", NULL);
3934     CHECK_REG_STR(prodkey, "Size", NULL);
3935     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3936     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3937     CHECK_REG_DWORD(prodkey, "Language", 1033);
3938     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3939     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3940     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3941     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3942     todo_wine
3943     {
3944         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3945     }
3946
3947     RegCloseKey(prodkey);
3948
3949     /* complete uninstall */
3950     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3952     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3953     ok(!pf_exists("msitest"), "Directory not deleted\n");
3954
3955     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3956     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3957
3958     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3959     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3960
3961     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3962     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3963
3964     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3965                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3966     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3967     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3968
3969     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3970     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3971
3972     /* make sure 'Program Files\msitest' is removed */
3973     delete_pfmsitest_files();
3974
3975 error:
3976     RegCloseKey(uninstall);
3977     RegCloseKey(uninstall_32node);
3978     DeleteFile(msifile);
3979     DeleteFile("msitest\\maximus");
3980     RemoveDirectory("msitest");
3981 }
3982
3983 static void test_publish_sourcelist(void)
3984 {
3985     UINT r;
3986     DWORD size;
3987     CHAR value[MAX_PATH];
3988     CHAR path[MAX_PATH];
3989     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3990
3991     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3992     {
3993         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3994         return;
3995     }
3996     if (is_process_limited())
3997     {
3998         skip("process is limited\n");
3999         return;
4000     }
4001
4002     CreateDirectoryA("msitest", NULL);
4003     create_file("msitest\\maximus", 500);
4004
4005     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4006
4007     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4008
4009     r = MsiInstallProductA(msifile, NULL);
4010     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4011     {
4012         skip("Not enough rights to perform tests\n");
4013         goto error;
4014     }
4015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4016     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4017     ok(pf_exists("msitest"), "File not installed\n");
4018
4019     /* nothing published */
4020     size = MAX_PATH;
4021     lstrcpyA(value, "aaa");
4022     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4023                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4024     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4025     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4026     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4027
4028     size = MAX_PATH;
4029     lstrcpyA(value, "aaa");
4030     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4031                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4032     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4033     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4034     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4035
4036     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4038     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4039     ok(pf_exists("msitest"), "File not installed\n");
4040
4041     /* after RegisterProduct */
4042     size = MAX_PATH;
4043     lstrcpyA(value, "aaa");
4044     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4045                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4046     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4047     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4048     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4049
4050     size = MAX_PATH;
4051     lstrcpyA(value, "aaa");
4052     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4053                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4054     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4055     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4056     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4057
4058     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4060     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4061     ok(pf_exists("msitest"), "File not installed\n");
4062
4063     /* after ProcessComponents */
4064     size = MAX_PATH;
4065     lstrcpyA(value, "aaa");
4066     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4067                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4068     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4069     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4070     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4071
4072     size = MAX_PATH;
4073     lstrcpyA(value, "aaa");
4074     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4075                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4076     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4077     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4078     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4079
4080     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4082     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4083     ok(pf_exists("msitest"), "File not installed\n");
4084
4085     /* after PublishFeatures */
4086     size = MAX_PATH;
4087     lstrcpyA(value, "aaa");
4088     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4089                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4090     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4091     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4092     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4093
4094     size = MAX_PATH;
4095     lstrcpyA(value, "aaa");
4096     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4097                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4098     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4099     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4100     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4101
4102     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4104     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4105     ok(pf_exists("msitest"), "File not installed\n");
4106
4107     /* after PublishProduct */
4108     size = MAX_PATH;
4109     lstrcpyA(value, "aaa");
4110     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4111                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4113     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4114     ok(size == 11, "Expected 11, got %d\n", size);
4115
4116     size = MAX_PATH;
4117     lstrcpyA(value, "aaa");
4118     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4119                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
4120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4121     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4122     ok(size == 0, "Expected 0, got %d\n", size);
4123
4124     size = MAX_PATH;
4125     lstrcpyA(value, "aaa");
4126     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4127                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
4128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4129     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4130     ok(size == 0, "Expected 0, got %d\n", size);
4131
4132     lstrcpyA(path, CURR_DIR);
4133     lstrcatA(path, "\\");
4134
4135     size = MAX_PATH;
4136     lstrcpyA(value, "aaa");
4137     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4138                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4140     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4141     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4142
4143     size = MAX_PATH;
4144     lstrcpyA(value, "aaa");
4145     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4146                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
4147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4148     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4149     ok(size == 1, "Expected 1, got %d\n", size);
4150
4151     size = MAX_PATH;
4152     lstrcpyA(value, "aaa");
4153     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4154                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4155     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4156     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4157     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4158
4159     size = MAX_PATH;
4160     lstrcpyA(value, "aaa");
4161     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4162                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4163     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4164     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4165     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4166
4167     size = MAX_PATH;
4168     lstrcpyA(value, "aaa");
4169     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4170                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4171     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4172     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4173     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4174
4175     /* complete uninstall */
4176     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4178     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4179     ok(!pf_exists("msitest"), "Directory not deleted\n");
4180
4181     /* make sure 'Program Files\msitest' is removed */
4182     delete_pfmsitest_files();
4183
4184 error:
4185     DeleteFile(msifile);
4186     DeleteFile("msitest\\maximus");
4187     RemoveDirectory("msitest");
4188 }
4189
4190 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4191 {
4192     CHAR path[MAX_PATH];
4193
4194     lstrcpyA(path, PROG_FILES_DIR);
4195     lstrcatA(path, "\\");
4196     lstrcatA(path, file);
4197
4198     if (is_file)
4199         create_file_data(path, data, 500);
4200     else
4201         CreateDirectoryA(path, NULL);
4202 }
4203
4204 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4205
4206 static void test_remove_files(void)
4207 {
4208     UINT r;
4209
4210     if (is_process_limited())
4211     {
4212         skip("process is limited\n");
4213         return;
4214     }
4215
4216     CreateDirectoryA("msitest", NULL);
4217     create_file("msitest\\hydrogen", 500);
4218     create_file("msitest\\helium", 500);
4219     create_file("msitest\\lithium", 500);
4220
4221     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4222
4223     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4224
4225     r = MsiInstallProductA(msifile, NULL);
4226     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4227     {
4228         skip("Not enough rights to perform tests\n");
4229         goto error;
4230     }
4231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4232     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4233     ok(!pf_exists("msitest\\helium"), "File installed\n");
4234     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4235     ok(pf_exists("msitest"), "File not installed\n");
4236
4237     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4239     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4240     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4241     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4242     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4243
4244     create_pf("msitest", FALSE);
4245     create_pf("msitest\\hydrogen", TRUE);
4246     create_pf("msitest\\helium", TRUE);
4247     create_pf("msitest\\lithium", TRUE);
4248
4249     r = MsiInstallProductA(msifile, NULL);
4250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4251     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4252     ok(pf_exists("msitest\\helium"), "File not installed\n");
4253     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4254     ok(pf_exists("msitest"), "File not installed\n");
4255
4256     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4258     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4259     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4260     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4261     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4262
4263     create_pf("msitest", FALSE);
4264     create_pf("msitest\\furlong", TRUE);
4265     create_pf("msitest\\firkin", TRUE);
4266     create_pf("msitest\\fortnight", TRUE);
4267     create_pf("msitest\\becquerel", TRUE);
4268     create_pf("msitest\\dioptre", TRUE);
4269     create_pf("msitest\\attoparsec", TRUE);
4270     create_pf("msitest\\storeys", TRUE);
4271     create_pf("msitest\\block", TRUE);
4272     create_pf("msitest\\siriometer", TRUE);
4273     create_pf("msitest\\cabout", FALSE);
4274     create_pf("msitest\\cabout\\blocker", TRUE);
4275
4276     r = MsiInstallProductA(msifile, NULL);
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4278     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4279     ok(!pf_exists("msitest\\helium"), "File installed\n");
4280     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4281     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4282     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4283     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4284     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4285     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4286     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4287     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4288     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4289     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4290     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4291     ok(pf_exists("msitest"), "File not installed\n");
4292
4293     create_pf("msitest\\furlong", TRUE);
4294     create_pf("msitest\\firkin", TRUE);
4295     create_pf("msitest\\fortnight", TRUE);
4296     create_pf("msitest\\storeys", TRUE);
4297     create_pf("msitest\\block", TRUE);
4298     create_pf("msitest\\siriometer", TRUE);
4299
4300     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4302     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4303     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4304     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4305     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4306     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4307     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4308     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4309     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4310     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4311     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4312     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4313     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4314     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4315     ok(pf_exists("msitest"), "Directory deleted\n");
4316
4317     r = MsiInstallProductA(msifile, NULL);
4318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4319     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4320     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4321     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4322     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4323     ok(pf_exists("msitest"), "Directory deleted\n");
4324
4325     delete_pf("msitest\\cabout\\blocker", TRUE);
4326
4327     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4329     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4330     delete_pf("msitest", FALSE);
4331
4332 error:
4333     DeleteFile(msifile);
4334     DeleteFile("msitest\\hydrogen");
4335     DeleteFile("msitest\\helium");
4336     DeleteFile("msitest\\lithium");
4337     RemoveDirectory("msitest");
4338 }
4339
4340 static void test_move_files(void)
4341 {
4342     UINT r;
4343     char props[MAX_PATH];
4344
4345     if (is_process_limited())
4346     {
4347         skip("process is limited\n");
4348         return;
4349     }
4350
4351     CreateDirectoryA("msitest", NULL);
4352     create_file("msitest\\augustus", 100);
4353     create_file("cameroon", 100);
4354     create_file("djibouti", 100);
4355     create_file("egypt", 100);
4356     create_file("finland", 100);
4357     create_file("gambai", 100);
4358     create_file("honduras", 100);
4359     create_file("msitest\\india", 100);
4360     create_file("japan", 100);
4361     create_file("kenya", 100);
4362     CreateDirectoryA("latvia", NULL);
4363     create_file("nauru", 100);
4364     create_file("peru", 100);
4365     create_file("apple", 100);
4366     create_file("application", 100);
4367     create_file("ape", 100);
4368     create_file("foo", 100);
4369     create_file("fao", 100);
4370     create_file("fbod", 100);
4371     create_file("budding", 100);
4372     create_file("buddy", 100);
4373     create_file("bud", 100);
4374     create_file("bar", 100);
4375     create_file("bur", 100);
4376     create_file("bird", 100);
4377
4378     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4379
4380     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4381
4382     /* if the source or dest property is not a full path,
4383      * windows tries to access it as a network resource
4384      */
4385
4386     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4387             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4388             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4389
4390     r = MsiInstallProductA(msifile, props);
4391     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4392     {
4393         skip("Not enough rights to perform tests\n");
4394         goto error;
4395     }
4396     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4397     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4398     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4399     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4400     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4401     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4402     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4403     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4404     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4405     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4406     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4407     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4408     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4409     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4410     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4411     /* either apple or application will be moved depending on directory order */
4412     if (!delete_pf("msitest\\apple", TRUE))
4413         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4414     else
4415         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4416     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4417     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4418     /* either fao or foo will be moved depending on directory order */
4419     if (delete_pf("msitest\\foo", TRUE))
4420         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4421     else
4422         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4423     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4424     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4425     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4426     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4427     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4428     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4429     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4430     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4431     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4432     ok(DeleteFileA("cameroon"), "File moved\n");
4433     ok(!DeleteFileA("djibouti"), "File not moved\n");
4434     ok(DeleteFileA("egypt"), "File moved\n");
4435     ok(DeleteFileA("finland"), "File moved\n");
4436     ok(DeleteFileA("gambai"), "File moved\n");
4437     ok(!DeleteFileA("honduras"), "File not moved\n");
4438     ok(DeleteFileA("msitest\\india"), "File moved\n");
4439     ok(DeleteFileA("japan"), "File moved\n");
4440     ok(!DeleteFileA("kenya"), "File not moved\n");
4441     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4442     ok(!DeleteFileA("nauru"), "File not moved\n");
4443     ok(!DeleteFileA("peru"), "File not moved\n");
4444     ok(!DeleteFileA("apple"), "File not moved\n");
4445     ok(!DeleteFileA("application"), "File not moved\n");
4446     ok(DeleteFileA("ape"), "File moved\n");
4447     ok(!DeleteFileA("foo"), "File not moved\n");
4448     ok(!DeleteFileA("fao"), "File not moved\n");
4449     ok(DeleteFileA("fbod"), "File moved\n");
4450     ok(!DeleteFileA("budding"), "File not moved\n");
4451     ok(!DeleteFileA("buddy"), "File not moved\n");
4452     ok(DeleteFileA("bud"), "File moved\n");
4453     ok(!DeleteFileA("bar"), "File not moved\n");
4454     ok(!DeleteFileA("bur"), "File not moved\n");
4455     ok(DeleteFileA("bird"), "File moved\n");
4456
4457 error:
4458     DeleteFile("cameroon");
4459     DeleteFile("djibouti");
4460     DeleteFile("egypt");
4461     DeleteFile("finland");
4462     DeleteFile("gambai");
4463     DeleteFile("honduras");
4464     DeleteFile("japan");
4465     DeleteFile("kenya");
4466     DeleteFile("nauru");
4467     DeleteFile("peru");
4468     DeleteFile("apple");
4469     DeleteFile("application");
4470     DeleteFile("ape");
4471     DeleteFile("foo");
4472     DeleteFile("fao");
4473     DeleteFile("fbod");
4474     DeleteFile("budding");
4475     DeleteFile("buddy");
4476     DeleteFile("bud");
4477     DeleteFile("bar");
4478     DeleteFile("bur");
4479     DeleteFile("bird");
4480     DeleteFile("msitest\\india");
4481     DeleteFile("msitest\\augustus");
4482     RemoveDirectory("latvia");
4483     RemoveDirectory("msitest");
4484     DeleteFile(msifile);
4485 }
4486
4487 static void test_duplicate_files(void)
4488 {
4489     UINT r;
4490
4491     if (is_process_limited())
4492     {
4493         skip("process is limited\n");
4494         return;
4495     }
4496
4497     CreateDirectoryA("msitest", NULL);
4498     create_file("msitest\\maximus", 500);
4499     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4500
4501     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4502
4503     /* fails if the destination folder is not a valid property */
4504
4505     r = MsiInstallProductA(msifile, NULL);
4506     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4507     {
4508         skip("Not enough rights to perform tests\n");
4509         goto error;
4510     }
4511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4512     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4513     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4514     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4515     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "Directory not created\n");
4516     ok(delete_pf("msitest\\this\\doesnot", FALSE), "Directory not created\n");
4517     ok(delete_pf("msitest\\this", FALSE), "Directory not created\n");
4518     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4519
4520 error:
4521     DeleteFile("msitest\\maximus");
4522     RemoveDirectory("msitest");
4523     DeleteFile(msifile);
4524 }
4525
4526 static void test_write_registry_values(void)
4527 {
4528     UINT r;
4529     LONG res;
4530     HKEY hkey;
4531     DWORD type, size;
4532     CHAR path[MAX_PATH];
4533
4534     if (is_process_limited())
4535     {
4536         skip("process is limited\n");
4537         return;
4538     }
4539
4540     CreateDirectoryA("msitest", NULL);
4541     create_file("msitest\\augustus", 500);
4542
4543     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4544
4545     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4546
4547     r = MsiInstallProductA(msifile, NULL);
4548     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4549     {
4550         skip("Not enough rights to perform tests\n");
4551         goto error;
4552     }
4553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4554     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4555     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4556
4557     if (is_64bit)
4558         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4559     else
4560         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4562
4563     size = MAX_PATH;
4564     type = REG_MULTI_SZ;
4565     memset(path, 'a', MAX_PATH);
4566     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4568     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4569     ok(size == 15, "Expected 15, got %d\n", size);
4570     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4571
4572     RegDeleteValueA(hkey, "Value");
4573     RegCloseKey(hkey);
4574     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
4575
4576 error:
4577     DeleteFile(msifile);
4578     DeleteFile("msitest\\augustus");
4579     RemoveDirectory("msitest");
4580 }
4581
4582 static void test_envvar(void)
4583 {
4584     static const char *results[] =
4585     {
4586         "1;2",    /* MSITESTVAR11 */
4587         "1",      /* MSITESTVAR12 */
4588         "1;2",    /* MSITESTVAR13 */
4589         ";1;",    /* MSITESTVAR14 */
4590         ";;1;;",  /* MSITESTVAR15 */
4591         " 1 ",    /* MSITESTVAR16 */
4592         ";;2;;1", /* MSITESTVAR17 */
4593         "1;;2;;", /* MSITESTVAR18 */
4594         "1",      /* MSITESTVAR19 */
4595         "1",      /* MSITESTVAR20 */
4596         NULL
4597     };
4598     UINT r;
4599     HKEY env;
4600     LONG res;
4601     DWORD type, size;
4602     char buffer[16];
4603     UINT i;
4604
4605     if (is_process_limited())
4606     {
4607         skip("process is limited\n");
4608         return;
4609     }
4610
4611     create_test_files();
4612     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
4613
4614     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
4615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4616
4617     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
4618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4619
4620     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
4621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4622
4623     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4624
4625     r = MsiInstallProductA(msifile, NULL);
4626     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4627     {
4628         skip("Not enough rights to perform tests\n");
4629         goto error;
4630     }
4631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4632
4633     type = REG_NONE;
4634     size = sizeof(buffer);
4635     buffer[0] = 0;
4636     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
4637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4638     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4639     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4640
4641     res = RegDeleteValueA(env, "MSITESTVAR1");
4642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4643
4644     type = REG_NONE;
4645     size = sizeof(buffer);
4646     buffer[0] = 0;
4647     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
4648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4649     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4650     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4651
4652     res = RegDeleteValueA(env, "MSITESTVAR2");
4653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4654
4655     res = RegDeleteValueA(env, "MSITESTVAR3");
4656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4657
4658     res = RegDeleteValueA(env, "MSITESTVAR4");
4659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4660
4661     res = RegDeleteValueA(env, "MSITESTVAR5");
4662     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4663
4664     res = RegDeleteValueA(env, "MSITESTVAR6");
4665     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4666
4667     res = RegDeleteValueA(env, "MSITESTVAR7");
4668     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4669
4670     res = RegDeleteValueA(env, "MSITESTVAR8");
4671     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4672
4673     res = RegDeleteValueA(env, "MSITESTVAR9");
4674     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4675
4676     res = RegDeleteValueA(env, "MSITESTVAR10");
4677     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4678
4679     i = 11;
4680     while (results[i - 11])
4681     {
4682         char name[20];
4683         sprintf(name, "MSITESTVAR%d", i);
4684
4685         type = REG_NONE;
4686         size = sizeof(buffer);
4687         buffer[0] = 0;
4688         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
4689         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
4690         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
4691         ok(!lstrcmp(buffer, results[i - 11]), "%d: Expected %s, got %s\n", i, results[i - 11], buffer);
4692
4693         res = RegDeleteValueA(env, name);
4694         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
4695         i++;
4696     }
4697
4698     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
4699     delete_pf("msitest\\cabout\\new", FALSE);
4700     delete_pf("msitest\\cabout\\four.txt", TRUE);
4701     delete_pf("msitest\\cabout", FALSE);
4702     delete_pf("msitest\\changed\\three.txt", TRUE);
4703     delete_pf("msitest\\changed", FALSE);
4704     delete_pf("msitest\\first\\two.txt", TRUE);
4705     delete_pf("msitest\\first", FALSE);
4706     delete_pf("msitest\\filename", TRUE);
4707     delete_pf("msitest\\one.txt", TRUE);
4708     delete_pf("msitest\\service.exe", TRUE);
4709     delete_pf("msitest", FALSE);
4710
4711 error:
4712     RegDeleteValueA(env, "MSITESTVAR1");
4713     RegDeleteValueA(env, "MSITESTVAR2");
4714     RegCloseKey(env);
4715
4716     delete_test_files();
4717     DeleteFile(msifile);
4718 }
4719
4720 static void test_create_remove_folder(void)
4721 {
4722     UINT r;
4723
4724     if (is_process_limited())
4725     {
4726         skip("process is limited\n");
4727         return;
4728     }
4729
4730     CreateDirectoryA("msitest", NULL);
4731     CreateDirectoryA("msitest\\first", NULL);
4732     CreateDirectoryA("msitest\\second", NULL);
4733     create_file("msitest\\first\\one.txt", 1000);
4734     create_file("msitest\\second\\two.txt", 1000);
4735     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
4736
4737     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4738
4739     r = MsiInstallProductA(msifile, NULL);
4740     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4741     {
4742         skip("Not enough rights to perform tests\n");
4743         goto error;
4744     }
4745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4746
4747     ok(pf_exists("msitest\\first\\one.txt"), "file not installed\n");
4748     ok(pf_exists("msitest\\first"), "directory not created\n");
4749     ok(pf_exists("msitest\\second\\two.txt"), "file not installed\n");
4750     ok(pf_exists("msitest\\second"), "directory not created\n");
4751     ok(pf_exists("msitest\\third"), "directory not created\n");
4752     ok(pf_exists("msitest"), "directory not created\n");
4753
4754     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4756
4757     ok(!pf_exists("msitest\\first\\one.txt"), "file not removed\n");
4758     ok(!pf_exists("msitest\\first"), "directory not removed\n");
4759     ok(!pf_exists("msitest\\second\\two.txt"), "file not removed\n");
4760     ok(!pf_exists("msitest\\second"), "directory not removed\n");
4761     ok(!pf_exists("msitest\\third"), "directory not removed\n");
4762     todo_wine ok(!pf_exists("msitest"), "directory not removed\n");
4763
4764 error:
4765     DeleteFileA("msitest\\first\\one.txt");
4766     DeleteFileA("msitest\\second\\two.txt");
4767     RemoveDirectoryA("msitest\\first");
4768     RemoveDirectoryA("msitest\\second");
4769     RemoveDirectoryA("msitest");
4770     DeleteFile(msifile);
4771 }
4772
4773 static void test_start_services(void)
4774 {
4775     UINT r;
4776     SC_HANDLE scm, service;
4777     BOOL ret;
4778     DWORD error = ERROR_SUCCESS;
4779
4780     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
4781     if (!scm && GetLastError() == ERROR_ACCESS_DENIED)
4782     {
4783         skip("Not enough rights to perform tests\n");
4784         return;
4785     }
4786     ok(scm != NULL, "Failed to open the SC Manager\n");
4787     if (!scm) return;
4788
4789     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
4790     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
4791     {
4792         win_skip("The 'Spooler' service does not exist\n");
4793         CloseServiceHandle(scm);
4794         return;
4795     }
4796     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
4797     if (!service) {
4798         CloseServiceHandle(scm);
4799         return;
4800     }
4801
4802     ret = StartService(service, 0, NULL);
4803     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
4804     {
4805         skip("Spooler service not available, skipping test\n");
4806         CloseServiceHandle(service);
4807         CloseServiceHandle(scm);
4808         return;
4809     }
4810
4811     CloseServiceHandle(service);
4812     CloseServiceHandle(scm);
4813
4814     create_test_files();
4815     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
4816
4817     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4818
4819     r = MsiInstallProductA(msifile, NULL);
4820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4821
4822     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4823     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4824     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4825     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4826     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4827     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4828     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4829     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4830     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4831     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4832     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4833     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4834
4835     delete_test_files();
4836     DeleteFile(msifile);
4837
4838     if (error == ERROR_SUCCESS)
4839     {
4840         SERVICE_STATUS status;
4841
4842         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
4843         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
4844
4845         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
4846         ok(ret, "ControlService failed %u\n", GetLastError());
4847
4848         CloseServiceHandle(service);
4849         CloseServiceHandle(scm);
4850     }
4851 }
4852
4853 static void test_delete_services(void)
4854 {
4855     UINT r;
4856
4857     if (is_process_limited())
4858     {
4859         skip("process is limited\n");
4860         return;
4861     }
4862
4863     create_test_files();
4864     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
4865
4866     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4867
4868     r = MsiInstallProductA(msifile, NULL);
4869     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4870     {
4871         skip("Not enough rights to perform tests\n");
4872         goto error;
4873     }
4874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4875
4876     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4877     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4878
4879     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4880     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4881     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4882     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4883     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4884     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4885     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4886     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4887     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4888     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4889     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4890     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4891
4892 error:
4893     delete_test_files();
4894     DeleteFile(msifile);
4895 }
4896
4897 static void test_self_registration(void)
4898 {
4899     UINT r;
4900
4901     if (is_process_limited())
4902     {
4903         skip("process is limited\n");
4904         return;
4905     }
4906
4907     create_test_files();
4908     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
4909
4910     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4911
4912     r = MsiInstallProductA(msifile, NULL);
4913     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4914     {
4915         skip("Not enough rights to perform tests\n");
4916         goto error;
4917     }
4918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4919
4920     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4921     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4922     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4923     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4924     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4925     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4926     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4927     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4928     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4929     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4930     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4931     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4932
4933 error:
4934     delete_test_files();
4935     DeleteFile(msifile);
4936 }
4937
4938 static void test_register_font(void)
4939 {
4940     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
4941     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
4942     LONG ret;
4943     HKEY key;
4944     UINT r;
4945     REGSAM access = KEY_ALL_ACCESS;
4946
4947     if (is_process_limited())
4948     {
4949         skip("process is limited\n");
4950         return;
4951     }
4952
4953     create_test_files();
4954     create_file("msitest\\font.ttf", 1000);
4955     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
4956
4957     if (is_wow64)
4958         access |= KEY_WOW64_64KEY;
4959
4960     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4961
4962     r = MsiInstallProductA(msifile, NULL);
4963     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4964     {
4965         skip("Not enough rights to perform tests\n");
4966         goto error;
4967     }
4968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4969
4970     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont1, 0, access, &key);
4971     if (ret)
4972         RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont2, 0, access, &key);
4973
4974     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
4975     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
4976
4977     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4979
4980     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
4981
4982     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
4983     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
4984
4985     RegDeleteValueA(key, "msi test font");
4986     RegCloseKey(key);
4987
4988 error:
4989     DeleteFileA("msitest\\font.ttf");
4990     delete_test_files();
4991     DeleteFile(msifile);
4992 }
4993
4994 static void test_validate_product_id(void)
4995 {
4996     UINT r;
4997
4998     if (is_process_limited())
4999     {
5000         skip("process is limited\n");
5001         return;
5002     }
5003
5004     create_test_files();
5005     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
5006
5007     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5008
5009     r = MsiInstallProductA(msifile, NULL);
5010     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5011     {
5012         skip("Not enough rights to perform tests\n");
5013         goto error;
5014     }
5015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5016
5017     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
5018     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5019
5020     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
5021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5022
5023     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
5024     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5025
5026     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5027     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5028     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5029     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5030     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5031     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5032     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5033     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5034     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5035     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5036     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5037     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5038
5039 error:
5040     delete_test_files();
5041     DeleteFile(msifile);
5042 }
5043
5044 static void test_install_remove_odbc(void)
5045 {
5046     UINT r;
5047
5048     if (is_process_limited())
5049     {
5050         skip("process is limited\n");
5051         return;
5052     }
5053
5054     create_test_files();
5055     create_file("msitest\\ODBCdriver.dll", 1000);
5056     create_file("msitest\\ODBCdriver2.dll", 1000);
5057     create_file("msitest\\ODBCtranslator.dll", 1000);
5058     create_file("msitest\\ODBCtranslator2.dll", 1000);
5059     create_file("msitest\\ODBCsetup.dll", 1000);
5060     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
5061
5062     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5063
5064     r = MsiInstallProductA(msifile, NULL);
5065     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5066     {
5067         skip("Not enough rights to perform tests\n");
5068         goto error;
5069     }
5070     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5071
5072     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
5073     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
5074     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
5075     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
5076     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
5077
5078     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5080
5081     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
5082     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
5083     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
5084     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
5085     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
5086     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5087
5088 error:
5089     DeleteFileA("msitest\\ODBCdriver.dll");
5090     DeleteFileA("msitest\\ODBCdriver2.dll");
5091     DeleteFileA("msitest\\ODBCtranslator.dll");
5092     DeleteFileA("msitest\\ODBCtranslator2.dll");
5093     DeleteFileA("msitest\\ODBCsetup.dll");
5094     delete_test_files();
5095     DeleteFile(msifile);
5096 }
5097
5098 static void test_register_typelib(void)
5099 {
5100     UINT r;
5101
5102     if (is_process_limited())
5103     {
5104         skip("process is limited\n");
5105         return;
5106     }
5107
5108     create_test_files();
5109     create_file("msitest\\typelib.dll", 1000);
5110     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
5111
5112     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5113
5114     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
5115     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5116     {
5117         skip("Not enough rights to perform tests\n");
5118         goto error;
5119     }
5120     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5121
5122     r = MsiInstallProductA(msifile, NULL);
5123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5124
5125     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5127
5128     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
5129     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5130
5131 error:
5132     DeleteFileA("msitest\\typelib.dll");
5133     delete_test_files();
5134     DeleteFile(msifile);
5135 }
5136
5137 static void test_create_remove_shortcut(void)
5138 {
5139     UINT r;
5140
5141     if (is_process_limited())
5142     {
5143         skip("process is limited\n");
5144         return;
5145     }
5146
5147     create_test_files();
5148     create_file("msitest\\target.txt", 1000);
5149     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
5150
5151     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5152
5153     r = MsiInstallProductA(msifile, NULL);
5154     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5155     {
5156         skip("Not enough rights to perform tests\n");
5157         goto error;
5158     }
5159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5160
5161     ok(pf_exists("msitest\\target.txt"), "file not created\n");
5162     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
5163
5164     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5166
5167     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
5168     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
5169     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5170
5171 error:
5172     DeleteFileA("msitest\\target.txt");
5173     delete_test_files();
5174     DeleteFile(msifile);
5175 }
5176
5177 static void test_publish_components(void)
5178 {
5179     static char keypath[] =
5180         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
5181
5182     UINT r;
5183     LONG res;
5184     HKEY key;
5185
5186     if (is_process_limited())
5187     {
5188         skip("process is limited\n");
5189         return;
5190     }
5191
5192     create_test_files();
5193     create_file("msitest\\english.txt", 1000);
5194     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
5195
5196     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5197
5198     r = MsiInstallProductA(msifile, NULL);
5199     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5200     {
5201         skip("Not enough rights to perform tests\n");
5202         goto error;
5203     }
5204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5205
5206     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5207     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
5208
5209     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
5210     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
5211     RegCloseKey(key);
5212
5213     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5215
5216     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5217     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
5218
5219     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
5220     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5221
5222 error:
5223     DeleteFileA("msitest\\english.txt");
5224     delete_test_files();
5225     DeleteFile(msifile);
5226 }
5227
5228 static void test_remove_duplicate_files(void)
5229 {
5230     UINT r;
5231
5232     if (is_process_limited())
5233     {
5234         skip("process is limited\n");
5235         return;
5236     }
5237
5238     create_test_files();
5239     create_file("msitest\\original.txt", 1000);
5240     create_file("msitest\\original2.txt", 1000);
5241     create_file("msitest\\original3.txt", 1000);
5242     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
5243
5244     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5245
5246     r = MsiInstallProductA(msifile, NULL);
5247     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5248     {
5249         skip("Not enough rights to perform tests\n");
5250         goto error;
5251     }
5252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5253
5254     ok(pf_exists("msitest\\original.txt"), "file not created\n");
5255     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
5256     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
5257     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
5258     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
5259
5260     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5262
5263     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
5264     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
5265     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
5266     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
5267     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
5268     ok(delete_pf("msitest", FALSE), "directory removed\n");
5269
5270 error:
5271     DeleteFileA("msitest\\original.txt");
5272     DeleteFileA("msitest\\original2.txt");
5273     DeleteFileA("msitest\\original3.txt");
5274     delete_test_files();
5275     DeleteFile(msifile);
5276 }
5277
5278 static void test_remove_registry_values(void)
5279 {
5280     UINT r;
5281     LONG res;
5282     HKEY key;
5283     REGSAM access = KEY_ALL_ACCESS;
5284
5285     if (is_process_limited())
5286     {
5287         skip("process is limited\n");
5288         return;
5289     }
5290
5291     create_test_files();
5292     create_file("msitest\\registry.txt", 1000);
5293     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
5294
5295     if (is_wow64)
5296         access |= KEY_WOW64_64KEY;
5297
5298     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5299
5300     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, NULL, 0, access, NULL, &key, NULL);
5301     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
5302     RegCloseKey(key);
5303
5304     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5305     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
5306     RegCloseKey(key);
5307
5308     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, NULL, 0, access, NULL, &key, NULL);
5309     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5310     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
5311     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5312     RegCloseKey(key);
5313
5314     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, NULL, 0, access, NULL, &key, NULL);
5315     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5316     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5317     RegCloseKey(key);
5318
5319     r = MsiInstallProductA(msifile, NULL);
5320     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5321     {
5322         skip("Not enough rights to perform tests\n");
5323         goto error;
5324     }
5325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5326
5327     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, access, &key);
5328     ok(res == ERROR_SUCCESS, "key removed\n");
5329     RegCloseKey(key);
5330
5331     if (is_64bit)
5332     {
5333         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5334         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5335     }
5336     else
5337     {
5338         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5339         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5340     }
5341
5342     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5343     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5344     RegCloseKey(key);
5345
5346     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5348
5349     if (is_64bit)
5350     {
5351         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5352         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5353     }
5354     else
5355     {
5356         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5357         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5358     }
5359
5360     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, access, &key);
5361     ok(res == ERROR_SUCCESS, "key removed\n");
5362     RegCloseKey(key);
5363
5364     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, access, &key);
5365     ok(res == ERROR_SUCCESS, "key removed\n");
5366     RegCloseKey(key);
5367
5368     if (is_64bit)
5369     {
5370         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5371         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5372     }
5373     else
5374     {
5375         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5376         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5377     }
5378
5379     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5380     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5381     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine", access);
5382
5383     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
5384     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5385
5386 error:
5387     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", access);
5388     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5389     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5390     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", access);
5391
5392     DeleteFileA("msitest\\registry.txt");
5393     delete_test_files();
5394     DeleteFile(msifile);
5395 }
5396
5397 static void test_find_related_products(void)
5398 {
5399     UINT r;
5400
5401     if (is_process_limited())
5402     {
5403         skip("process is limited\n");
5404         return;
5405     }
5406
5407     create_test_files();
5408     create_file("msitest\\product.txt", 1000);
5409     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
5410
5411     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5412
5413     r = MsiInstallProductA(msifile, NULL);
5414     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5415     {
5416         skip("Not enough rights to perform tests\n");
5417         goto error;
5418     }
5419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5420
5421     /* install again, so it finds the upgrade code */
5422     r = MsiInstallProductA(msifile, NULL);
5423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5424
5425     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5427
5428     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
5429     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5430
5431 error:
5432     DeleteFileA("msitest\\product.txt");
5433     delete_test_files();
5434     DeleteFile(msifile);
5435 }
5436
5437 static void test_remove_ini_values(void)
5438 {
5439     UINT r;
5440     DWORD len;
5441     char inifile[MAX_PATH], buf[0x10];
5442     HANDLE file;
5443     BOOL ret;
5444
5445     if (is_process_limited())
5446     {
5447         skip("process is limited\n");
5448         return;
5449     }
5450
5451     create_test_files();
5452     create_file("msitest\\inifile.txt", 1000);
5453     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
5454
5455     lstrcpyA(inifile, PROG_FILES_DIR);
5456     lstrcatA(inifile, "\\msitest");
5457     ret = CreateDirectoryA(inifile, NULL);
5458     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
5459     {
5460         skip("Not enough rights to perform tests\n");
5461         goto error;
5462     }
5463     lstrcatA(inifile, "\\test.ini");
5464     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
5465     CloseHandle(file);
5466
5467     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
5468     ok(ret, "failed to write profile string %u\n", GetLastError());
5469
5470     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
5471     ok(ret, "failed to write profile string %u\n", GetLastError());
5472
5473     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5474
5475     r = MsiInstallProductA(msifile, NULL);
5476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5477
5478     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5479     ok(len == 6, "got %u expected 6\n", len);
5480
5481     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5482     ok(!len, "got %u expected 0\n", len);
5483
5484     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5486
5487     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5488     ok(!len, "got %u expected 0\n", len);
5489
5490     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5491     ok(!len, "got %u expected 0\n", len);
5492
5493     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
5494     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
5495     ok(delete_pf("msitest", FALSE), "directory removed\n");
5496
5497 error:
5498     DeleteFileA("msitest\\inifile.txt");
5499     delete_test_files();
5500     DeleteFile(msifile);
5501 }
5502
5503 static void test_remove_env_strings(void)
5504 {
5505     UINT r;
5506     LONG res;
5507     HKEY key;
5508     DWORD type, size;
5509     char buffer[0x10];
5510
5511     if (is_process_limited())
5512     {
5513         skip("process is limited\n");
5514         return;
5515     }
5516
5517     create_test_files();
5518     create_file("msitest\\envvar.txt", 1000);
5519     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
5520
5521     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5522
5523     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5524     ok(!res, "failed to open environment key %d\n", res);
5525
5526     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
5527     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
5528     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
5529     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
5530     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
5531
5532     RegCloseKey(key);
5533
5534     r = MsiInstallProductA(msifile, NULL);
5535     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5536     {
5537         skip("Not enough rights to perform tests\n");
5538         goto error;
5539     }
5540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5541
5542     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5543     ok(!res, "failed to open environment key %d\n", res);
5544
5545     type = REG_NONE;
5546     buffer[0] = 0;
5547     size = sizeof(buffer);
5548     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
5549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5550     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5551     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5552
5553     type = REG_NONE;
5554     buffer[0] = 0;
5555     size = sizeof(buffer);
5556     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
5557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5558     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5559     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5560
5561     type = REG_NONE;
5562     buffer[0] = 0;
5563     size = sizeof(buffer);
5564     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5566     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5567     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5568
5569     type = REG_NONE;
5570     buffer[0] = 0;
5571     size = sizeof(buffer);
5572     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
5573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5574     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5575     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5576
5577     type = REG_NONE;
5578     buffer[0] = 0;
5579     size = sizeof(buffer);
5580     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5582     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5583     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5584
5585     RegCloseKey(key);
5586
5587     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5589
5590     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5591     ok(!res, "failed to open environment key %d\n", res);
5592
5593     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
5594     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5595
5596     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
5597     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5598
5599     type = REG_NONE;
5600     buffer[0] = 0;
5601     size = sizeof(buffer);
5602     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5604     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5605     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5606     RegDeleteValueA(key, "MSITESTVAR3");
5607
5608     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
5609     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5610
5611     type = REG_NONE;
5612     buffer[0] = 0;
5613     size = sizeof(buffer);
5614     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5616     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5617     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5618     RegDeleteValueA(key, "MSITESTVAR5");
5619
5620     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
5621     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5622
5623 error:
5624     RegDeleteValueA(key, "MSITESTVAR1");
5625     RegDeleteValueA(key, "MSITESTVAR2");
5626     RegDeleteValueA(key, "MSITESTVAR3");
5627     RegDeleteValueA(key, "MSITESTVAR4");
5628     RegDeleteValueA(key, "MSITESTVAR5");
5629     RegCloseKey(key);
5630
5631     DeleteFileA("msitest\\envvar.txt");
5632     delete_test_files();
5633     DeleteFile(msifile);
5634 }
5635
5636 static void test_register_class_info(void)
5637 {
5638     UINT r;
5639     LONG res;
5640     HKEY hkey;
5641
5642     if (is_process_limited())
5643     {
5644         skip("process is limited\n");
5645         return;
5646     }
5647
5648     create_test_files();
5649     create_file("msitest\\class.txt", 1000);
5650     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
5651
5652     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5653
5654     r = MsiInstallProductA(msifile, NULL);
5655     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5656     {
5657         skip("Not enough rights to perform tests\n");
5658         goto error;
5659     }
5660     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5661
5662     if (is_64bit)
5663         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5664     else
5665         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5666     ok(res == ERROR_SUCCESS, "key not created\n");
5667     RegCloseKey(hkey);
5668
5669     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5670     ok(res == ERROR_SUCCESS, "key not created\n");
5671     RegCloseKey(hkey);
5672
5673     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
5674     ok(res == ERROR_SUCCESS, "key not created\n");
5675     RegCloseKey(hkey);
5676
5677     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5678     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5679
5680     if (is_64bit)
5681         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5682     else
5683         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5684     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5685
5686     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5687     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5688
5689     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
5690     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5691
5692     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
5693     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5694
5695 error:
5696     DeleteFileA("msitest\\class.txt");
5697     delete_test_files();
5698     DeleteFile(msifile);
5699 }
5700
5701 static void test_register_extension_info(void)
5702 {
5703     UINT r;
5704     LONG res;
5705     HKEY hkey;
5706
5707     if (is_process_limited())
5708     {
5709         skip("process is limited\n");
5710         return;
5711     }
5712
5713     create_test_files();
5714     create_file("msitest\\extension.txt", 1000);
5715     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
5716
5717     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5718
5719     r = MsiInstallProductA(msifile, NULL);
5720     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5721     {
5722         skip("Not enough rights to perform tests\n");
5723         goto error;
5724     }
5725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5726
5727     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
5728     ok(res == ERROR_SUCCESS, "key not created\n");
5729     RegCloseKey(hkey);
5730
5731     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
5732     ok(res == ERROR_SUCCESS, "key not created\n");
5733     RegCloseKey(hkey);
5734
5735     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5737
5738     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
5739     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5740
5741     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
5742     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5743
5744     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
5745     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5746
5747 error:
5748     DeleteFileA("msitest\\extension.txt");
5749     delete_test_files();
5750     DeleteFile(msifile);
5751 }
5752
5753 static void test_register_mime_info(void)
5754 {
5755     UINT r;
5756     LONG res;
5757     HKEY hkey;
5758
5759     if (is_process_limited())
5760     {
5761         skip("process is limited\n");
5762         return;
5763     }
5764
5765     create_test_files();
5766     create_file("msitest\\mime.txt", 1000);
5767     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
5768
5769     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5770
5771     r = MsiInstallProductA(msifile, NULL);
5772     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5773     {
5774         skip("Not enough rights to perform tests\n");
5775         goto error;
5776     }
5777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5778
5779     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
5780     ok(res == ERROR_SUCCESS, "key not created\n");
5781     RegCloseKey(hkey);
5782
5783     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5784     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5785
5786     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
5787     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5788
5789     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
5790     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5791
5792 error:
5793     DeleteFileA("msitest\\mime.txt");
5794     delete_test_files();
5795     DeleteFile(msifile);
5796 }
5797
5798 static void test_publish_assemblies(void)
5799 {
5800     static const char manifest[] =
5801         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Assembly\" "
5802         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
5803         "processorArchitecture=\"x86\"/>";
5804     static const char manifest_local[] =
5805         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Local.Assembly\" "
5806         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
5807         "processorArchitecture=\"x86\"/>";
5808     static const char classes_path_dotnet[] =
5809         "Installer\\Assemblies\\Global";
5810     static const char classes_path_dotnet_local[] =
5811         "Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
5812     static const char classes_path_dotnet_local_wow64[] =
5813         "Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
5814     static const char classes_path_win32[] =
5815         "Installer\\Win32Assemblies\\Global";
5816     static const char classes_path_win32_local[] =
5817         "Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
5818     static const char classes_path_win32_local_wow64[] =
5819         "Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
5820     static const char path_dotnet[] =
5821         "Software\\Microsoft\\Installer\\Assemblies\\Global";
5822     static const char path_dotnet_local[] =
5823         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
5824     static const char path_dotnet_local_wow64[] =
5825         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
5826     static const char path_win32[] =
5827         "Software\\Microsoft\\Installer\\Win32Assemblies\\Global";
5828     static const char path_win32_local[] =
5829         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
5830     static const char path_win32_local_wow64[] =
5831         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
5832     static const char name_dotnet[] =
5833         "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
5834         "version=\"1.0.0.0\",culture=\"neutral\"";
5835     static const char name_dotnet_local[] =
5836         "Wine.Dotnet.Local.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
5837         "version=\"1.0.0.0\",culture=\"neutral\"";
5838     static const char name_win32[] =
5839         "Wine.Win32.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
5840         "type=\"win32\",version=\"1.0.0.0\"";
5841     static const char name_win32_local[] =
5842         "Wine.Win32.Local.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
5843         "type=\"win32\",version=\"1.0.0.0\"";
5844     UINT r;
5845     LONG res;
5846     HKEY hkey;
5847     const char *path;
5848     int access;
5849
5850     if (is_process_limited())
5851     {
5852         skip("process is limited\n");
5853         return;
5854     }
5855
5856     create_test_files();
5857     create_file("msitest\\win32.txt", 1000);
5858     create_file("msitest\\win32_local.txt", 1000);
5859     create_file("msitest\\dotnet.txt", 1000);
5860     create_file("msitest\\dotnet_local.txt", 1000);
5861     create_file_data("msitest\\manifest.txt", manifest, 0);
5862     create_file_data("msitest\\manifest_local.txt", manifest_local, 0);
5863     create_file("msitest\\application_win32.txt", 1000);
5864     create_file("msitest\\application_dotnet.txt", 1000);
5865     create_database(msifile, pa_tables, sizeof(pa_tables) / sizeof(msi_table));
5866
5867     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5868
5869     r = MsiInstallProductA(msifile, NULL);
5870     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5871     {
5872         skip("Not enough rights to perform tests\n");
5873         goto done;
5874     }
5875     if (r == ERROR_INSTALL_FAILURE)
5876     {
5877         skip("No support for installing side-by-side assemblies\n");
5878         goto done;
5879     }
5880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5881
5882     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
5883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5884     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
5885     RegCloseKey(hkey);
5886
5887     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
5888     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5890     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
5891     RegCloseKey(hkey);
5892
5893     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
5894     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
5895        "Expected ERROR_SUCCESS, got %d\n", res);
5896     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
5897     RegCloseKey(hkey);
5898
5899     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
5900     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5901     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
5902        "Expected ERROR_SUCCESS, got %d\n", res);
5903     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
5904     RegCloseKey(hkey);
5905
5906     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5908
5909     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
5910     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5911     if (res == ERROR_SUCCESS)
5912     {
5913         res = RegDeleteValueA(hkey, name_dotnet);
5914         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5915         RegCloseKey(hkey);
5916     }
5917
5918     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
5919     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5920     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5921
5922     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
5923     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5924     if (res == ERROR_SUCCESS)
5925     {
5926         res = RegDeleteValueA(hkey, name_win32);
5927         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5928         RegCloseKey(hkey);
5929     }
5930
5931     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
5932     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5933     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5934
5935     r = MsiInstallProductA(msifile, "ALLUSERS=1");
5936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5937
5938     access = KEY_QUERY_VALUE;
5939     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
5940     if (res == ERROR_FILE_NOT_FOUND && is_wow64) /* Vista WOW64 */
5941     {
5942         trace("Using 64-bit registry view for HKCR\\Installer\n");
5943         access = KEY_QUERY_VALUE | KEY_WOW64_64KEY;
5944         res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
5945     }
5946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5947     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
5948     RegCloseKey(hkey);
5949
5950     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
5951     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
5952     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5953     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
5954     RegCloseKey(hkey);
5955
5956     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_win32, 0, access, &hkey);
5957     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
5958        "Expected ERROR_SUCCESS, got %d\n", res);
5959     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
5960     RegCloseKey(hkey);
5961
5962     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
5963     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
5964     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
5965        "Expected ERROR_SUCCESS, got %d\n", res);
5966     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
5967     RegCloseKey(hkey);
5968
5969     r = MsiInstallProductA(msifile, "REMOVE=ALL ALLUSERS=1");
5970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5971
5972     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_dotnet, &hkey);
5973     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5974     if (res == ERROR_SUCCESS)
5975     {
5976         res = RegDeleteValueA(hkey, name_dotnet);
5977         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5978         RegCloseKey(hkey);
5979     }
5980
5981     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
5982     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
5983     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5984
5985     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_win32, &hkey);
5986     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5987     if (res == ERROR_SUCCESS)
5988     {
5989         res = RegDeleteValueA(hkey, name_win32);
5990         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5991         RegCloseKey(hkey);
5992     }
5993
5994     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
5995     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
5996     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5997
5998 done:
5999     DeleteFileA("msitest\\win32.txt");
6000     DeleteFileA("msitest\\win32_local.txt");
6001     DeleteFileA("msitest\\dotnet.txt");
6002     DeleteFileA("msitest\\dotnet_local.txt");
6003     DeleteFileA("msitest\\manifest.txt");
6004     DeleteFileA("msitest\\manifest_local.txt");
6005     DeleteFileA("msitest\\application_win32.txt");
6006     DeleteFileA("msitest\\application_dotnet.txt");
6007     delete_test_files();
6008     DeleteFile(msifile);
6009 }
6010
6011 START_TEST(action)
6012 {
6013     DWORD len;
6014     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6015     STATEMGRSTATUS status;
6016     BOOL ret = FALSE;
6017
6018     init_functionpointers();
6019
6020     if (pIsWow64Process)
6021         pIsWow64Process(GetCurrentProcess(), &is_wow64);
6022
6023     GetCurrentDirectoryA(MAX_PATH, prev_path);
6024     GetTempPath(MAX_PATH, temp_path);
6025     SetCurrentDirectoryA(temp_path);
6026
6027     lstrcpyA(CURR_DIR, temp_path);
6028     len = lstrlenA(CURR_DIR);
6029
6030     if(len && (CURR_DIR[len - 1] == '\\'))
6031         CURR_DIR[len - 1] = 0;
6032
6033     ok(get_system_dirs(), "failed to retrieve system dirs\n");
6034     ok(get_user_dirs(), "failed to retrieve user dirs\n");
6035
6036     /* Create a restore point ourselves so we circumvent the multitude of restore points
6037      * that would have been created by all the installation and removal tests.
6038      *
6039      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
6040      * creation of restore points.
6041      */
6042     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
6043     {
6044         memset(&status, 0, sizeof(status));
6045         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6046     }
6047
6048     /* Create only one log file and don't append. We have to pass something
6049      * for the log mode for this to work. The logfile needs to have an absolute
6050      * path otherwise we still end up with some extra logfiles as some tests
6051      * change the current directory.
6052      */
6053     lstrcpyA(log_file, temp_path);
6054     lstrcatA(log_file, "\\msitest.log");
6055     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6056
6057     test_register_product();
6058     test_publish_product();
6059     test_publish_features();
6060     test_register_user();
6061     test_process_components();
6062     test_publish();
6063     test_publish_sourcelist();
6064     test_remove_files();
6065     test_move_files();
6066     test_duplicate_files();
6067     test_write_registry_values();
6068     test_envvar();
6069     test_create_remove_folder();
6070     test_start_services();
6071     test_delete_services();
6072     test_self_registration();
6073     test_register_font();
6074     test_validate_product_id();
6075     test_install_remove_odbc();
6076     test_register_typelib();
6077     test_create_remove_shortcut();
6078     test_publish_components();
6079     test_remove_duplicate_files();
6080     test_remove_registry_values();
6081     test_find_related_products();
6082     test_remove_ini_values();
6083     test_remove_env_strings();
6084     test_register_class_info();
6085     test_register_extension_info();
6086     test_register_mime_info();
6087     test_publish_assemblies();
6088
6089     DeleteFileA(log_file);
6090
6091     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
6092     {
6093         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6094         if (ret)
6095             remove_restore_point(status.llSequenceNumber);
6096     }
6097     FreeLibrary(hsrclient);
6098
6099     SetCurrentDirectoryA(prev_path);
6100 }