tools: Register the MSI service from wine.inf.
[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_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
2406 {
2407     DWORD val, size, type;
2408     LONG res;
2409
2410     size = sizeof(DWORD);
2411     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2412
2413     if (res != ERROR_SUCCESS || type != REG_DWORD)
2414     {
2415         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2416         return;
2417     }
2418
2419     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
2420                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
2421 }
2422
2423 static void check_reg_dword4(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2424                              DWORD expected4, DWORD line)
2425 {
2426     DWORD val, size, type;
2427     LONG res;
2428
2429     size = sizeof(DWORD);
2430     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2431
2432     if (res != ERROR_SUCCESS || type != REG_DWORD)
2433     {
2434         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2435         return;
2436     }
2437
2438     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4,
2439         "Expected %d, %d or %d or %d, got %d\n", expected1, expected2, expected3, expected4, val);
2440 }
2441
2442 #define CHECK_REG_STR(prodkey, name, expected) \
2443     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2444
2445 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2446     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2447     RegDeleteValueA(prodkey, name);
2448
2449 #define CHECK_REG_ISTR(prodkey, name, expected) \
2450     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2451
2452 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2453     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2454     RegDeleteValueA(prodkey, name);
2455
2456 #define CHECK_REG_DWORD(prodkey, name, expected) \
2457     check_reg_dword(prodkey, name, expected, __LINE__);
2458
2459 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2460     check_reg_dword(prodkey, name, expected, __LINE__); \
2461     RegDeleteValueA(prodkey, name);
2462
2463 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
2464     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
2465
2466 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
2467     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
2468     RegDeleteValueA(prodkey, name);
2469
2470 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
2471     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
2472
2473 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
2474     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
2475     RegDeleteValueA(prodkey, name);
2476
2477 #define CHECK_DEL_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \
2478     check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__); \
2479     RegDeleteValueA(prodkey, name);
2480
2481 static void get_date_str(LPSTR date)
2482 {
2483     SYSTEMTIME systime;
2484
2485     static const char date_fmt[] = "%d%02d%02d";
2486     GetLocalTime(&systime);
2487     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2488 }
2489
2490 static void test_register_product(void)
2491 {
2492     UINT r;
2493     LONG res;
2494     HKEY hkey, props, usage;
2495     LPSTR usersid;
2496     char date[MAX_PATH], temp[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
2497     DWORD size, type;
2498     REGSAM access = KEY_ALL_ACCESS;
2499
2500     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2501                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2502     static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion"
2503                                            "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2504     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2505                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2506     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2507                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2508     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2509                                     "\\51AAE0C44620A5E4788506E91F249BD2";
2510
2511     if (is_process_limited())
2512     {
2513         skip("process is limited\n");
2514         return;
2515     }
2516
2517     if (!(usersid = get_user_sid()))
2518         return;
2519
2520     get_date_str(date);
2521     GetTempPath(MAX_PATH, temp);
2522
2523     CreateDirectoryA("msitest", NULL);
2524     create_file("msitest\\maximus", 500);
2525
2526     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2527
2528     if (is_wow64)
2529         access |= KEY_WOW64_64KEY;
2530
2531     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2532
2533     /* RegisterProduct */
2534     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2535     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2536     {
2537         skip("Not enough rights to perform tests\n");
2538         goto error;
2539     }
2540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2541     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2542     ok(delete_pf("msitest", FALSE), "File not installed\n");
2543
2544     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2545     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2546
2547     if (is_64bit)
2548     {
2549         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2550         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2551     }
2552     else
2553     {
2554         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2555         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2556     }
2557
2558     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2559     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2560     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2561     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2562     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2563     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2564     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2565     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2566     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2567     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2568     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2569     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2570     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2571     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2572     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2573     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2574     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2575     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2576     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2577     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2578     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2579     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2580     todo_wine
2581     {
2582         CHECK_DEL_REG_DWORD4(hkey, "EstimatedSize", 12, -12, 4, 10);
2583     }
2584
2585     delete_key(hkey, "", access);
2586     RegCloseKey(hkey);
2587
2588     sprintf(keypath, userdata, usersid);
2589     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2591
2592     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2594
2595     size = sizeof(path);
2596     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2597     DeleteFileA(path);
2598     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2599
2600     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2601     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2602     CHECK_DEL_REG_STR(props, "InstallDate", date);
2603     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2604     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2605     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2606     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2607     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2608     CHECK_DEL_REG_STR(props, "Comments", NULL);
2609     CHECK_DEL_REG_STR(props, "Contact", NULL);
2610     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2611     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2612     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2613     CHECK_DEL_REG_STR(props, "Readme", NULL);
2614     CHECK_DEL_REG_STR(props, "Size", NULL);
2615     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2616     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2617     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2618     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2619     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2620     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2621     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2622     todo_wine
2623     {
2624         CHECK_DEL_REG_DWORD4(props, "EstimatedSize", 12, -12, 4, 10);
2625     }
2626
2627     delete_key(props, "", access);
2628     RegCloseKey(props);
2629
2630     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2631     todo_wine
2632     {
2633         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2634     }
2635
2636     delete_key(usage, "", access);
2637     RegCloseKey(usage);
2638     delete_key(hkey, "", access);
2639     RegCloseKey(hkey);
2640
2641     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2643
2644     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2645
2646     delete_key(hkey, "", access);
2647     RegCloseKey(hkey);
2648
2649     /* RegisterProduct, machine */
2650     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
2651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2652     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2653     ok(delete_pf("msitest", FALSE), "File not installed\n");
2654
2655     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey);
2656     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2657
2658     if (is_64bit)
2659     {
2660         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2661         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2662     }
2663     else
2664     {
2665         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2666         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2667     }
2668
2669     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2670     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2671     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2672     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2673     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2674     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2675     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2676     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2677     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2678     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2679     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2680     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2681     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2682     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2683     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2684     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2685     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2686     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2687     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2688     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2689     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2690     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2691     todo_wine
2692     {
2693         CHECK_DEL_REG_DWORD4(hkey, "EstimatedSize", 12, -12, 4, 10);
2694     }
2695
2696     delete_key(hkey, "", access);
2697     RegCloseKey(hkey);
2698
2699     sprintf(keypath, userdata, "S-1-5-18");
2700     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2702
2703     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2705
2706     size = sizeof(path);
2707     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2708     DeleteFileA(path);
2709     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2710
2711     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2712     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2713     CHECK_DEL_REG_STR(props, "InstallDate", date);
2714     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2715     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2716     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2717     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2718     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2719     CHECK_DEL_REG_STR(props, "Comments", NULL);
2720     CHECK_DEL_REG_STR(props, "Contact", NULL);
2721     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2722     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2723     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2724     CHECK_DEL_REG_STR(props, "Readme", NULL);
2725     CHECK_DEL_REG_STR(props, "Size", NULL);
2726     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2727     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2728     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2729     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2730     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2731     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2732     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2733     todo_wine
2734     {
2735         CHECK_DEL_REG_DWORD4(props, "EstimatedSize", 12, -12, 4, 10);
2736     }
2737
2738     delete_key(props, "", access);
2739     RegCloseKey(props);
2740
2741     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2742     todo_wine
2743     {
2744         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2745     }
2746
2747     delete_key(usage, "", access);
2748     RegCloseKey(usage);
2749     delete_key(hkey, "", access);
2750     RegCloseKey(hkey);
2751
2752     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2754
2755     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2756
2757     delete_key(hkey, "", access);
2758     RegCloseKey(hkey);
2759
2760 error:
2761     DeleteFile(msifile);
2762     DeleteFile("msitest\\maximus");
2763     RemoveDirectory("msitest");
2764     HeapFree(GetProcessHeap(), 0, usersid);
2765 }
2766
2767 static void test_publish_product(void)
2768 {
2769     UINT r;
2770     LONG res;
2771     LPSTR usersid;
2772     HKEY sourcelist, net, props;
2773     HKEY hkey, patches, media;
2774     CHAR keypath[MAX_PATH];
2775     CHAR temp[MAX_PATH];
2776     CHAR path[MAX_PATH];
2777     BOOL old_installer = FALSE;
2778     REGSAM access = KEY_ALL_ACCESS;
2779
2780     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2781                                    "\\Installer\\UserData\\%s\\Products"
2782                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2783     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
2784                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2785     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2786                                      "\\51AAE0C44620A5E4788506E91F249BD2";
2787     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2788                                   "\\Installer\\Products"
2789                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2790     static const CHAR machprod[] = "Software\\Classes\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2791     static const CHAR machup[] = "Software\\Classes\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2792
2793     if (is_process_limited())
2794     {
2795         skip("process is limited\n");
2796         return;
2797     }
2798
2799     if (!(usersid = get_user_sid()))
2800         return;
2801
2802     GetTempPath(MAX_PATH, temp);
2803
2804     CreateDirectoryA("msitest", NULL);
2805     create_file("msitest\\maximus", 500);
2806
2807     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2808
2809     if (is_wow64)
2810         access |= KEY_WOW64_64KEY;
2811
2812     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2813
2814     /* PublishProduct, current user */
2815     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2816     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2817     {
2818         skip("Not enough rights to perform tests\n");
2819         goto error;
2820     }
2821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2822     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2823     ok(delete_pf("msitest", FALSE), "File not installed\n");
2824
2825     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
2826     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2827
2828     sprintf(keypath, prodpath, usersid);
2829     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2830     if (res == ERROR_FILE_NOT_FOUND)
2831     {
2832         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2833         if (res == ERROR_SUCCESS)
2834         {
2835             win_skip("Windows Installer < 3.0 detected\n");
2836             RegCloseKey(hkey);
2837             old_installer = TRUE;
2838             goto currentuser;
2839         }
2840         else
2841         {
2842             win_skip("Install failed, no need to continue\n");
2843             return;
2844         }
2845     }
2846     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2847
2848     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2849     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2850
2851     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
2852     todo_wine
2853     {
2854         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2855         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2856     }
2857
2858     delete_key(patches, "", access);
2859     RegCloseKey(patches);
2860     delete_key(hkey, "", access);
2861     RegCloseKey(hkey);
2862
2863 currentuser:
2864     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2865     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2866
2867     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2868     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2869     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2870     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2871     if (!old_installer)
2872         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2873     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
2874     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2875     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2876     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2877
2878     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2880
2881     lstrcpyA(path, "n;1;");
2882     lstrcatA(path, temp);
2883     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2884     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2885
2886     res = RegOpenKeyA(sourcelist, "Net", &net);
2887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2888
2889     CHECK_DEL_REG_STR(net, "1", temp);
2890
2891     RegDeleteKeyA(net, "");
2892     RegCloseKey(net);
2893
2894     res = RegOpenKeyA(sourcelist, "Media", &media);
2895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2896
2897     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2898
2899     RegDeleteKeyA(media, "");
2900     RegCloseKey(media);
2901     RegDeleteKeyA(sourcelist, "");
2902     RegCloseKey(sourcelist);
2903     RegDeleteKeyA(hkey, "");
2904     RegCloseKey(hkey);
2905
2906     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
2907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2908
2909     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2910
2911     RegDeleteKeyA(hkey, "");
2912     RegCloseKey(hkey);
2913
2914     /* PublishProduct, machine */
2915     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
2916     if (old_installer)
2917         goto machprod;
2918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2919     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2920     ok(delete_pf("msitest", FALSE), "File not installed\n");
2921
2922     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
2923     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2924
2925     sprintf(keypath, prodpath, "S-1-5-18");
2926     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2928
2929     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2930     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2931
2932     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
2933     todo_wine
2934     {
2935         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2936         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2937     }
2938
2939     delete_key(patches, "", access);
2940     RegCloseKey(patches);
2941     delete_key(hkey, "", access);
2942     RegCloseKey(hkey);
2943
2944 machprod:
2945     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machprod, 0, access, &hkey);
2946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2947
2948     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2949     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2950     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2951     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2952     if (!old_installer)
2953         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2954     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
2955     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2956     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2957     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2958
2959     res = RegOpenKeyExA(hkey, "SourceList", 0, access, &sourcelist);
2960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2961
2962     lstrcpyA(path, "n;1;");
2963     lstrcatA(path, temp);
2964     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2965     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2966
2967     res = RegOpenKeyExA(sourcelist, "Net", 0, access, &net);
2968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2969
2970     CHECK_DEL_REG_STR(net, "1", temp);
2971
2972     res = delete_key(net, "", access);
2973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2974     RegCloseKey(net);
2975
2976     res = RegOpenKeyExA(sourcelist, "Media", 0, access, &media);
2977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2978
2979     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2980
2981     res = delete_key(media, "", access);
2982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2983     RegCloseKey(media);
2984     res = delete_key(sourcelist, "", access);
2985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2986     RegCloseKey(sourcelist);
2987     res = delete_key(hkey, "", access);
2988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2989     RegCloseKey(hkey);
2990
2991     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machup, 0, access, &hkey);
2992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2993
2994     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2995
2996     res = delete_key(hkey, "", access);
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998     RegCloseKey(hkey);
2999
3000 error:
3001     DeleteFile(msifile);
3002     DeleteFile("msitest\\maximus");
3003     RemoveDirectory("msitest");
3004     HeapFree(GetProcessHeap(), 0, usersid);
3005 }
3006
3007 static void test_publish_features(void)
3008 {
3009     UINT r;
3010     LONG res;
3011     HKEY hkey;
3012     LPSTR usersid;
3013     CHAR keypath[MAX_PATH];
3014     REGSAM access = KEY_ALL_ACCESS;
3015
3016     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
3017                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3018     static const CHAR udfeatpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3019                                      "\\Installer\\UserData\\%s\\Products"
3020                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
3021     static const CHAR udpridpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3022                                      "\\Installer\\UserData\\%s\\Products"
3023                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3024     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3025                                   "\\Installer\\Features";
3026     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
3027                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3028
3029     if (is_process_limited())
3030     {
3031         skip("process is limited\n");
3032         return;
3033     }
3034
3035     if (!(usersid = get_user_sid()))
3036         return;
3037
3038     CreateDirectoryA("msitest", NULL);
3039     create_file("msitest\\maximus", 500);
3040
3041     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3042
3043     if (is_wow64)
3044         access |= KEY_WOW64_64KEY;
3045
3046     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3047
3048     /* PublishFeatures, current user */
3049     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3050     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3051     {
3052         skip("Not enough rights to perform tests\n");
3053         goto error;
3054     }
3055     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3056     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3057     ok(delete_pf("msitest", FALSE), "File not installed\n");
3058
3059     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3060     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3061
3062     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3063     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3064
3065     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068     CHECK_REG_STR(hkey, "feature", "");
3069     CHECK_REG_STR(hkey, "montecristo", "");
3070
3071     RegDeleteValueA(hkey, "feature");
3072     RegDeleteValueA(hkey, "montecristo");
3073     delete_key(hkey, "", access);
3074     RegCloseKey(hkey);
3075
3076     sprintf(keypath, udfeatpath, usersid);
3077     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3079
3080     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3081     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3082
3083     RegDeleteValueA(hkey, "feature");
3084     RegDeleteValueA(hkey, "montecristo");
3085     delete_key(hkey, "", access);
3086     RegCloseKey(hkey);
3087     sprintf(keypath, udpridpath, usersid);
3088     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3089
3090     /* PublishFeatures, machine */
3091     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
3092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3093     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3094     ok(delete_pf("msitest", FALSE), "File not installed\n");
3095
3096     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3097     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3098
3099     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3100     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3101     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3103
3104     CHECK_REG_STR(hkey, "feature", "");
3105     CHECK_REG_STR(hkey, "montecristo", "");
3106
3107     RegDeleteValueA(hkey, "feature");
3108     RegDeleteValueA(hkey, "montecristo");
3109     delete_key(hkey, "", access);
3110     RegCloseKey(hkey);
3111
3112     sprintf(keypath, udfeatpath, "S-1-5-18");
3113     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3115
3116     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3117     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3118
3119     RegDeleteValueA(hkey, "feature");
3120     RegDeleteValueA(hkey, "montecristo");
3121     delete_key(hkey, "", access);
3122     RegCloseKey(hkey);
3123     sprintf(keypath, udpridpath, "S-1-5-18");
3124     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3125
3126 error:
3127     DeleteFile(msifile);
3128     DeleteFile("msitest\\maximus");
3129     RemoveDirectory("msitest");
3130     HeapFree(GetProcessHeap(), 0, usersid);
3131 }
3132
3133 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
3134 {
3135     DWORD len = 0;
3136     LPSTR val;
3137     LONG r;
3138
3139     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
3140     if (r != ERROR_SUCCESS)
3141         return NULL;
3142
3143     len += sizeof (WCHAR);
3144     val = HeapAlloc(GetProcessHeap(), 0, len);
3145     if (!val) return NULL;
3146     val[0] = 0;
3147     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
3148     return val;
3149 }
3150
3151 static void get_owner_company(LPSTR *owner, LPSTR *company)
3152 {
3153     LONG res;
3154     HKEY hkey;
3155     REGSAM access = KEY_ALL_ACCESS;
3156
3157     *owner = *company = NULL;
3158
3159     if (is_wow64)
3160         access |= KEY_WOW64_64KEY;
3161
3162     res = RegOpenKeyA(HKEY_CURRENT_USER,
3163                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
3164     if (res == ERROR_SUCCESS)
3165     {
3166         *owner = reg_get_val_str(hkey, "DefName");
3167         *company = reg_get_val_str(hkey, "DefCompany");
3168         RegCloseKey(hkey);
3169     }
3170
3171     if (!*owner || !*company)
3172     {
3173         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3174                             "Software\\Microsoft\\Windows\\CurrentVersion", 0, access, &hkey);
3175         if (res == ERROR_SUCCESS)
3176         {
3177             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3178             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3179             RegCloseKey(hkey);
3180         }
3181     }
3182
3183     if (!*owner || !*company)
3184     {
3185         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3186                             "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey);
3187         if (res == ERROR_SUCCESS)
3188         {
3189             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3190             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3191             RegCloseKey(hkey);
3192         }
3193     }
3194 }
3195
3196 static void test_register_user(void)
3197 {
3198     UINT r;
3199     LONG res;
3200     HKEY props;
3201     LPSTR usersid;
3202     LPSTR owner, company;
3203     CHAR keypath[MAX_PATH];
3204     REGSAM access = KEY_ALL_ACCESS;
3205
3206     static const CHAR keypropsfmt[] =
3207         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3208         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
3209     static const CHAR keypridfmt[] =
3210         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3211         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3212
3213     if (is_process_limited())
3214     {
3215         skip("process is limited\n");
3216         return;
3217     }
3218
3219     if (!(usersid = get_user_sid()))
3220         return;
3221
3222     get_owner_company(&owner, &company);
3223
3224     CreateDirectoryA("msitest", NULL);
3225     create_file("msitest\\maximus", 500);
3226
3227     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3228
3229     if (is_wow64)
3230         access |= KEY_WOW64_64KEY;
3231
3232     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3233
3234     /* RegisterUser, per-user */
3235     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
3236     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3237     {
3238         skip("Not enough rights to perform tests\n");
3239         goto error;
3240     }
3241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3242     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3243     ok(delete_pf("msitest", FALSE), "File not installed\n");
3244
3245     sprintf(keypath, keypropsfmt, usersid);
3246     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3248
3249     CHECK_REG_STR(props, "ProductID", "none");
3250     CHECK_REG_STR(props, "RegCompany", company);
3251     CHECK_REG_STR(props, "RegOwner", owner);
3252
3253     RegDeleteValueA(props, "ProductID");
3254     RegDeleteValueA(props, "RegCompany");
3255     RegDeleteValueA(props, "RegOwner");
3256     delete_key(props, "", access);
3257     RegCloseKey(props);
3258     sprintf(keypath, keypridfmt, usersid);
3259     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3260
3261     /* RegisterUser, machine */
3262     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
3263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3264     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3265     ok(delete_pf("msitest", FALSE), "File not installed\n");
3266
3267     sprintf(keypath, keypropsfmt, "S-1-5-18");
3268     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3270
3271     CHECK_REG_STR(props, "ProductID", "none");
3272     CHECK_REG_STR(props, "RegCompany", company);
3273     CHECK_REG_STR(props, "RegOwner", owner);
3274
3275     RegDeleteValueA(props, "ProductID");
3276     RegDeleteValueA(props, "RegCompany");
3277     RegDeleteValueA(props, "RegOwner");
3278     delete_key(props, "", access);
3279     RegCloseKey(props);
3280     sprintf(keypath, keypridfmt, "S-1-5-18");
3281     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3282
3283 error:
3284     HeapFree(GetProcessHeap(), 0, company);
3285     HeapFree(GetProcessHeap(), 0, owner);
3286
3287     DeleteFile(msifile);
3288     DeleteFile("msitest\\maximus");
3289     RemoveDirectory("msitest");
3290     LocalFree(usersid);
3291 }
3292
3293 static void test_process_components(void)
3294 {
3295     UINT r;
3296     LONG res;
3297     DWORD size;
3298     HKEY comp, hkey;
3299     LPSTR usersid;
3300     CHAR val[MAX_PATH];
3301     CHAR keypath[MAX_PATH];
3302     CHAR program_files_maximus[MAX_PATH];
3303     REGSAM access = KEY_ALL_ACCESS;
3304
3305     static const CHAR keyfmt[] =
3306         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3307         "UserData\\%s\\Components\\%s";
3308     static const CHAR compkey[] =
3309         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3310
3311     if (is_process_limited())
3312     {
3313         skip("process is limited\n");
3314         return;
3315     }
3316
3317     if (!(usersid = get_user_sid()))
3318         return;
3319
3320     CreateDirectoryA("msitest", NULL);
3321     create_file("msitest\\maximus", 500);
3322
3323     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3324
3325     if (is_wow64)
3326         access |= KEY_WOW64_64KEY;
3327
3328     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3329
3330     /* ProcessComponents, per-user */
3331     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3332     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3333     {
3334         skip("Not enough rights to perform tests\n");
3335         goto error;
3336     }
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3339     ok(delete_pf("msitest", FALSE), "File not installed\n");
3340
3341     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3342     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3343     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3344
3345     size = MAX_PATH;
3346     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3347                            NULL, NULL, (LPBYTE)val, &size);
3348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3349
3350     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3351     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3352
3353     ok(!lstrcmpiA(val, program_files_maximus),
3354        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3355
3356     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3357     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3358
3359     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3360     delete_key(comp, "", access);
3361     RegCloseKey(comp);
3362
3363     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
3364     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     size = MAX_PATH;
3368     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3369                            NULL, NULL, (LPBYTE)val, &size);
3370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3371     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3372        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3373
3374     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3375     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3376
3377     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3378     delete_key(comp, "", access);
3379     RegCloseKey(comp);
3380
3381     /* ProcessComponents, machine */
3382     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3385     ok(delete_pf("msitest", FALSE), "File not installed\n");
3386
3387     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
3388     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3390
3391     size = MAX_PATH;
3392     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3393                            NULL, NULL, (LPBYTE)val, &size);
3394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3395     ok(!lstrcmpiA(val, program_files_maximus),
3396        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3397
3398     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3399     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3400
3401     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3402     delete_key(comp, "", access);
3403     RegCloseKey(comp);
3404
3405     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
3406     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3408
3409     size = MAX_PATH;
3410     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3411                            NULL, NULL, (LPBYTE)val, &size);
3412     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3413     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3414        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3415
3416     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3417     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3418
3419     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3420     delete_key(comp, "", access);
3421     RegCloseKey(comp);
3422
3423 error:
3424     DeleteFile(msifile);
3425     DeleteFile("msitest\\maximus");
3426     RemoveDirectory("msitest");
3427     LocalFree(usersid);
3428 }
3429
3430 static void test_publish(void)
3431 {
3432     UINT r;
3433     LONG res;
3434     HKEY uninstall, prodkey, uninstall_32node = NULL;
3435     INSTALLSTATE state;
3436     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3437     char date[MAX_PATH], temp[MAX_PATH];
3438     REGSAM access = KEY_ALL_ACCESS;
3439
3440     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3441     static const CHAR subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3442
3443     if (!pMsiQueryComponentStateA)
3444     {
3445         win_skip("MsiQueryComponentStateA is not available\n");
3446         return;
3447     }
3448     if (is_process_limited())
3449     {
3450         skip("process is limited\n");
3451         return;
3452     }
3453
3454     get_date_str(date);
3455     GetTempPath(MAX_PATH, temp);
3456
3457     if (is_wow64)
3458         access |= KEY_WOW64_64KEY;
3459
3460     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall);
3461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3462
3463     if (is_64bit)
3464     {
3465         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node);
3466         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3467     }
3468
3469     CreateDirectoryA("msitest", NULL);
3470     create_file("msitest\\maximus", 500);
3471
3472     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3473
3474     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3475
3476     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3477     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3478
3479     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3480     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3481
3482     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3483     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3484
3485     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3486                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3487     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3488     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3489
3490     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3491     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3492
3493     /* nothing published */
3494     r = MsiInstallProductA(msifile, NULL);
3495     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3496     {
3497         skip("Not enough rights to perform tests\n");
3498         goto error;
3499     }
3500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3501     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3502     ok(pf_exists("msitest"), "File not installed\n");
3503
3504     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3505     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3506
3507     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3508     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3509
3510     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3511     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3512
3513     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3514                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3515     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3516     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3517
3518     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3519     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3520
3521     /* PublishProduct and RegisterProduct */
3522     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3524     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3525     ok(pf_exists("msitest"), "File not installed\n");
3526
3527     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3528     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3529
3530     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3531     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3532
3533     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3534     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3535
3536     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3537                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3538     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3539     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3540
3541     if (is_64bit)
3542     {
3543         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3544         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3545     }
3546     else
3547     {
3548         res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3549         if (is_wow64 && res == ERROR_FILE_NOT_FOUND) /* XP - Vista, Wow64 */
3550             res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3551         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3552     }
3553
3554     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3555     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3556     CHECK_REG_STR(prodkey, "InstallDate", date);
3557     CHECK_REG_STR(prodkey, "InstallSource", temp);
3558     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3559     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3560     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3561     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3562     CHECK_REG_STR(prodkey, "Comments", NULL);
3563     CHECK_REG_STR(prodkey, "Contact", NULL);
3564     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3565     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3566     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3567     CHECK_REG_STR(prodkey, "Readme", NULL);
3568     CHECK_REG_STR(prodkey, "Size", NULL);
3569     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3570     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3571     CHECK_REG_DWORD(prodkey, "Language", 1033);
3572     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3573     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3574     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3575     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3576     todo_wine
3577     {
3578         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -12, 10);
3579     }
3580
3581     RegCloseKey(prodkey);
3582
3583     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3585     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3586     ok(pf_exists("msitest"), "File deleted\n");
3587
3588     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3589     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3590
3591     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3592     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3593
3594     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3595     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3596
3597     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3598                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3599     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3600     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3601
3602     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3603     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3604
3605     /* complete install */
3606     r = MsiInstallProductA(msifile, "FULL=1");
3607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3609     ok(pf_exists("msitest"), "File not installed\n");
3610
3611     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3612     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3613
3614     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3615     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3616
3617     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3618     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3619
3620     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3621                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3623     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3624
3625     if (is_64bit)
3626     {
3627         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3628         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3629     }
3630     else
3631     {
3632         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3633         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3634     }
3635
3636     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3637     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3638     CHECK_REG_STR(prodkey, "InstallDate", date);
3639     CHECK_REG_STR(prodkey, "InstallSource", temp);
3640     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3641     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3642     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3643     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3644     CHECK_REG_STR(prodkey, "Comments", NULL);
3645     CHECK_REG_STR(prodkey, "Contact", NULL);
3646     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3647     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3648     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3649     CHECK_REG_STR(prodkey, "Readme", NULL);
3650     CHECK_REG_STR(prodkey, "Size", NULL);
3651     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3652     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3653     CHECK_REG_DWORD(prodkey, "Language", 1033);
3654     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3655     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3656     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3657     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3658     todo_wine
3659     {
3660         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -12, 10);
3661     }
3662
3663     RegCloseKey(prodkey);
3664
3665     /* no UnpublishFeatures */
3666     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3669     ok(!pf_exists("msitest"), "Directory not deleted\n");
3670
3671     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3672     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3673
3674     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3675     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3676
3677     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3678     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3679
3680     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3681                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3682     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3683     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3684
3685     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3686     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3687
3688     /* complete install */
3689     r = MsiInstallProductA(msifile, "FULL=1");
3690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3691     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3692     ok(pf_exists("msitest"), "File not installed\n");
3693
3694     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3695     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3696
3697     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3698     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3699
3700     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3701     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3702
3703     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3704                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3707
3708     if (is_64bit)
3709     {
3710         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3711         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3712     }
3713     else
3714     {
3715         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3716         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3717     }
3718
3719     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3720     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3721     CHECK_REG_STR(prodkey, "InstallDate", date);
3722     CHECK_REG_STR(prodkey, "InstallSource", temp);
3723     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3724     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3725     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3726     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3727     CHECK_REG_STR(prodkey, "Comments", NULL);
3728     CHECK_REG_STR(prodkey, "Contact", NULL);
3729     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3730     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3731     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3732     CHECK_REG_STR(prodkey, "Readme", NULL);
3733     CHECK_REG_STR(prodkey, "Size", NULL);
3734     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3735     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3736     CHECK_REG_DWORD(prodkey, "Language", 1033);
3737     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3738     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3739     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3740     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3741     todo_wine
3742     {
3743         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -12, 10);
3744     }
3745
3746     RegCloseKey(prodkey);
3747
3748     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3749     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3751     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3752     ok(pf_exists("msitest"), "Directory deleted\n");
3753
3754     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3755     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3756
3757     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3758     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3759
3760     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3761     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3762
3763     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3764                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3765     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3766     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3767
3768     if (is_64bit)
3769     {
3770         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3771         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3772     }
3773     else
3774     {
3775         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3776         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3777     }
3778
3779     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3780     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3781     CHECK_REG_STR(prodkey, "InstallDate", date);
3782     CHECK_REG_STR(prodkey, "InstallSource", temp);
3783     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3784     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3785     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3786     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3787     CHECK_REG_STR(prodkey, "Comments", NULL);
3788     CHECK_REG_STR(prodkey, "Contact", NULL);
3789     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3790     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3791     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3792     CHECK_REG_STR(prodkey, "Readme", NULL);
3793     CHECK_REG_STR(prodkey, "Size", NULL);
3794     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3795     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3796     CHECK_REG_DWORD(prodkey, "Language", 1033);
3797     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3798     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3799     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3800     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3801     todo_wine
3802     {
3803         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -12, 10);
3804     }
3805
3806     RegCloseKey(prodkey);
3807
3808     /* complete install */
3809     r = MsiInstallProductA(msifile, "FULL=1");
3810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3811     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3812     ok(pf_exists("msitest"), "File not installed\n");
3813
3814     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3815     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3816
3817     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3818     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3819
3820     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3821     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3822
3823     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3824                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3825     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3826     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3827
3828     if (is_64bit)
3829     {
3830         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3831         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3832     }
3833     else
3834     {
3835         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3836         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3837     }
3838
3839     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3840     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3841     CHECK_REG_STR(prodkey, "InstallDate", date);
3842     CHECK_REG_STR(prodkey, "InstallSource", temp);
3843     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3844     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3845     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3846     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3847     CHECK_REG_STR(prodkey, "Comments", NULL);
3848     CHECK_REG_STR(prodkey, "Contact", NULL);
3849     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3850     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3851     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3852     CHECK_REG_STR(prodkey, "Readme", NULL);
3853     CHECK_REG_STR(prodkey, "Size", NULL);
3854     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3855     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3856     CHECK_REG_DWORD(prodkey, "Language", 1033);
3857     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3858     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3859     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3860     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3861     todo_wine
3862     {
3863         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -20, 10);
3864     }
3865
3866     RegCloseKey(prodkey);
3867
3868     /* UnpublishFeatures, both features removed */
3869     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3871     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3872     ok(!pf_exists("msitest"), "Directory not deleted\n");
3873
3874     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3875     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3876
3877     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3878     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3879
3880     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3881     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3882
3883     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3884                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3885     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3886     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3887
3888     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3889     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3890
3891     /* complete install */
3892     r = MsiInstallProductA(msifile, "FULL=1");
3893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3894     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3895     ok(pf_exists("msitest"), "File not installed\n");
3896
3897     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3898     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3899
3900     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3901     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3902
3903     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3904     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3905
3906     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3907                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3908     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3909     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3910
3911     if (is_64bit)
3912     {
3913         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3914         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3915     }
3916     else
3917     {
3918         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3919         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3920     }
3921
3922     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3923     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3924     CHECK_REG_STR(prodkey, "InstallDate", date);
3925     CHECK_REG_STR(prodkey, "InstallSource", temp);
3926     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3927     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3928     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3929     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3930     CHECK_REG_STR(prodkey, "Comments", NULL);
3931     CHECK_REG_STR(prodkey, "Contact", NULL);
3932     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3933     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3934     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3935     CHECK_REG_STR(prodkey, "Readme", NULL);
3936     CHECK_REG_STR(prodkey, "Size", NULL);
3937     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3938     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3939     CHECK_REG_DWORD(prodkey, "Language", 1033);
3940     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3941     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3942     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3943     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3944     todo_wine
3945     {
3946         CHECK_REG_DWORD3(prodkey, "EstimatedSize", 12, -12, 10);
3947     }
3948
3949     RegCloseKey(prodkey);
3950
3951     /* complete uninstall */
3952     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3954     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3955     ok(!pf_exists("msitest"), "Directory not deleted\n");
3956
3957     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3958     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3959
3960     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3961     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3962
3963     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3964     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3965
3966     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3967                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3968     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3969     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3970
3971     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3972     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3973
3974     /* make sure 'Program Files\msitest' is removed */
3975     delete_pfmsitest_files();
3976
3977 error:
3978     RegCloseKey(uninstall);
3979     RegCloseKey(uninstall_32node);
3980     DeleteFile(msifile);
3981     DeleteFile("msitest\\maximus");
3982     RemoveDirectory("msitest");
3983 }
3984
3985 static void test_publish_sourcelist(void)
3986 {
3987     UINT r;
3988     DWORD size;
3989     CHAR value[MAX_PATH];
3990     CHAR path[MAX_PATH];
3991     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3992
3993     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3994     {
3995         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3996         return;
3997     }
3998     if (is_process_limited())
3999     {
4000         skip("process is limited\n");
4001         return;
4002     }
4003
4004     CreateDirectoryA("msitest", NULL);
4005     create_file("msitest\\maximus", 500);
4006
4007     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4008
4009     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4010
4011     r = MsiInstallProductA(msifile, NULL);
4012     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4013     {
4014         skip("Not enough rights to perform tests\n");
4015         goto error;
4016     }
4017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4018     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4019     ok(pf_exists("msitest"), "File not installed\n");
4020
4021     /* nothing published */
4022     size = MAX_PATH;
4023     lstrcpyA(value, "aaa");
4024     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4025                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4026     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4027     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4028     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4029
4030     size = MAX_PATH;
4031     lstrcpyA(value, "aaa");
4032     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4033                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4034     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4035     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4036     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4037
4038     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4040     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4041     ok(pf_exists("msitest"), "File not installed\n");
4042
4043     /* after RegisterProduct */
4044     size = MAX_PATH;
4045     lstrcpyA(value, "aaa");
4046     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4047                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4048     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4049     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4050     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4051
4052     size = MAX_PATH;
4053     lstrcpyA(value, "aaa");
4054     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4055                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4056     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4057     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4058     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4059
4060     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4062     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4063     ok(pf_exists("msitest"), "File not installed\n");
4064
4065     /* after ProcessComponents */
4066     size = MAX_PATH;
4067     lstrcpyA(value, "aaa");
4068     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4069                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4070     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4071     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4072     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4073
4074     size = MAX_PATH;
4075     lstrcpyA(value, "aaa");
4076     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4077                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4078     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4079     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4080     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4081
4082     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4083     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4084     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4085     ok(pf_exists("msitest"), "File not installed\n");
4086
4087     /* after PublishFeatures */
4088     size = MAX_PATH;
4089     lstrcpyA(value, "aaa");
4090     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4091                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4092     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4093     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4094     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4095
4096     size = MAX_PATH;
4097     lstrcpyA(value, "aaa");
4098     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4099                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4100     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4101     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4102     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4103
4104     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4106     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4107     ok(pf_exists("msitest"), "File not installed\n");
4108
4109     /* after PublishProduct */
4110     size = MAX_PATH;
4111     lstrcpyA(value, "aaa");
4112     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4113                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4116     ok(size == 11, "Expected 11, got %d\n", size);
4117
4118     size = MAX_PATH;
4119     lstrcpyA(value, "aaa");
4120     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4121                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
4122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4124     ok(size == 0, "Expected 0, got %d\n", size);
4125
4126     size = MAX_PATH;
4127     lstrcpyA(value, "aaa");
4128     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4129                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
4130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4131     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4132     ok(size == 0, "Expected 0, got %d\n", size);
4133
4134     lstrcpyA(path, CURR_DIR);
4135     lstrcatA(path, "\\");
4136
4137     size = MAX_PATH;
4138     lstrcpyA(value, "aaa");
4139     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4140                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4142     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4143     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4144
4145     size = MAX_PATH;
4146     lstrcpyA(value, "aaa");
4147     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4148                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
4149     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4150     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4151     ok(size == 1, "Expected 1, got %d\n", size);
4152
4153     size = MAX_PATH;
4154     lstrcpyA(value, "aaa");
4155     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4156                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4157     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4158     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4159     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4160
4161     size = MAX_PATH;
4162     lstrcpyA(value, "aaa");
4163     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4164                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4166     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4167     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4168
4169     size = MAX_PATH;
4170     lstrcpyA(value, "aaa");
4171     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4172                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4173     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4174     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4175     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4176
4177     /* complete uninstall */
4178     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4181     ok(!pf_exists("msitest"), "Directory not deleted\n");
4182
4183     /* make sure 'Program Files\msitest' is removed */
4184     delete_pfmsitest_files();
4185
4186 error:
4187     DeleteFile(msifile);
4188     DeleteFile("msitest\\maximus");
4189     RemoveDirectory("msitest");
4190 }
4191
4192 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4193 {
4194     CHAR path[MAX_PATH];
4195
4196     lstrcpyA(path, PROG_FILES_DIR);
4197     lstrcatA(path, "\\");
4198     lstrcatA(path, file);
4199
4200     if (is_file)
4201         create_file_data(path, data, 500);
4202     else
4203         CreateDirectoryA(path, NULL);
4204 }
4205
4206 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4207
4208 static void test_remove_files(void)
4209 {
4210     UINT r;
4211
4212     if (is_process_limited())
4213     {
4214         skip("process is limited\n");
4215         return;
4216     }
4217
4218     CreateDirectoryA("msitest", NULL);
4219     create_file("msitest\\hydrogen", 500);
4220     create_file("msitest\\helium", 500);
4221     create_file("msitest\\lithium", 500);
4222
4223     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4224
4225     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4226
4227     r = MsiInstallProductA(msifile, NULL);
4228     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4229     {
4230         skip("Not enough rights to perform tests\n");
4231         goto error;
4232     }
4233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4234     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4235     ok(!pf_exists("msitest\\helium"), "File installed\n");
4236     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4237     ok(pf_exists("msitest"), "File not installed\n");
4238
4239     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4241     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4242     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4243     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4244     ok(delete_pf("msitest", FALSE), "File deleted\n");
4245
4246     create_pf("msitest", FALSE);
4247     create_pf("msitest\\hydrogen", TRUE);
4248     create_pf("msitest\\helium", TRUE);
4249     create_pf("msitest\\lithium", TRUE);
4250
4251     r = MsiInstallProductA(msifile, NULL);
4252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4253     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4254     ok(pf_exists("msitest\\helium"), "File not installed\n");
4255     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4256     ok(pf_exists("msitest"), "File not installed\n");
4257
4258     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4260     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4261     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4262     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4263     ok(delete_pf("msitest", FALSE), "File deleted\n");
4264
4265     create_pf("msitest", FALSE);
4266     create_pf("msitest\\furlong", TRUE);
4267     create_pf("msitest\\firkin", TRUE);
4268     create_pf("msitest\\fortnight", TRUE);
4269     create_pf("msitest\\becquerel", TRUE);
4270     create_pf("msitest\\dioptre", TRUE);
4271     create_pf("msitest\\attoparsec", TRUE);
4272     create_pf("msitest\\storeys", TRUE);
4273     create_pf("msitest\\block", TRUE);
4274     create_pf("msitest\\siriometer", TRUE);
4275     create_pf("msitest\\cabout", FALSE);
4276     create_pf("msitest\\cabout\\blocker", TRUE);
4277
4278     r = MsiInstallProductA(msifile, NULL);
4279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4280     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4281     ok(!pf_exists("msitest\\helium"), "File installed\n");
4282     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4283     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4284     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4285     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4286     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4287     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4288     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4289     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4290     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4291     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4292     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4293     ok(pf_exists("msitest"), "File not installed\n");
4294
4295     create_pf("msitest\\furlong", TRUE);
4296     create_pf("msitest\\firkin", TRUE);
4297     create_pf("msitest\\fortnight", TRUE);
4298     create_pf("msitest\\storeys", TRUE);
4299     create_pf("msitest\\block", TRUE);
4300     create_pf("msitest\\siriometer", TRUE);
4301
4302     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4304     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4305     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4306     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4307     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4308     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4309     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4310     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4311     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4312     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4313     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4314     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4315     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4316     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4317     ok(pf_exists("msitest"), "Directory deleted\n");
4318
4319     r = MsiInstallProductA(msifile, NULL);
4320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4321     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4322     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4323     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4324     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4325     ok(pf_exists("msitest"), "Directory deleted\n");
4326
4327     delete_pf("msitest\\cabout\\blocker", TRUE);
4328
4329     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4330     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4331     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4332     delete_pf("msitest", FALSE);
4333
4334 error:
4335     DeleteFile(msifile);
4336     DeleteFile("msitest\\hydrogen");
4337     DeleteFile("msitest\\helium");
4338     DeleteFile("msitest\\lithium");
4339     RemoveDirectory("msitest");
4340 }
4341
4342 static void test_move_files(void)
4343 {
4344     UINT r;
4345     char props[MAX_PATH];
4346
4347     if (is_process_limited())
4348     {
4349         skip("process is limited\n");
4350         return;
4351     }
4352
4353     CreateDirectoryA("msitest", NULL);
4354     create_file("msitest\\augustus", 100);
4355     create_file("cameroon", 100);
4356     create_file("djibouti", 100);
4357     create_file("egypt", 100);
4358     create_file("finland", 100);
4359     create_file("gambai", 100);
4360     create_file("honduras", 100);
4361     create_file("msitest\\india", 100);
4362     create_file("japan", 100);
4363     create_file("kenya", 100);
4364     CreateDirectoryA("latvia", NULL);
4365     create_file("nauru", 100);
4366     create_file("peru", 100);
4367     create_file("apple", 100);
4368     create_file("application", 100);
4369     create_file("ape", 100);
4370     create_file("foo", 100);
4371     create_file("fao", 100);
4372     create_file("fbod", 100);
4373     create_file("budding", 100);
4374     create_file("buddy", 100);
4375     create_file("bud", 100);
4376     create_file("bar", 100);
4377     create_file("bur", 100);
4378     create_file("bird", 100);
4379
4380     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4381
4382     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4383
4384     /* if the source or dest property is not a full path,
4385      * windows tries to access it as a network resource
4386      */
4387
4388     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4389             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4390             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4391
4392     r = MsiInstallProductA(msifile, props);
4393     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4394     {
4395         skip("Not enough rights to perform tests\n");
4396         goto error;
4397     }
4398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4399     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4400     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4401     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4402     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4403     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4404     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4405     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4406     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4407     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4408     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4409     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4410     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4411     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4412     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4413     /* either apple or application will be moved depending on directory order */
4414     if (!delete_pf("msitest\\apple", TRUE))
4415         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4416     else
4417         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4418     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4419     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4420     /* either fao or foo will be moved depending on directory order */
4421     if (delete_pf("msitest\\foo", TRUE))
4422         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4423     else
4424         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4425     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4426     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4427     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4428     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4429     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4430     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4431     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4432     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4433     ok(delete_pf("msitest", FALSE), "File not installed\n");
4434     ok(DeleteFileA("cameroon"), "File moved\n");
4435     ok(!DeleteFileA("djibouti"), "File not moved\n");
4436     ok(DeleteFileA("egypt"), "File moved\n");
4437     ok(DeleteFileA("finland"), "File moved\n");
4438     ok(DeleteFileA("gambai"), "File moved\n");
4439     ok(!DeleteFileA("honduras"), "File not moved\n");
4440     ok(DeleteFileA("msitest\\india"), "File moved\n");
4441     ok(DeleteFileA("japan"), "File moved\n");
4442     ok(!DeleteFileA("kenya"), "File not moved\n");
4443     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4444     ok(!DeleteFileA("nauru"), "File not moved\n");
4445     ok(!DeleteFileA("peru"), "File not moved\n");
4446     ok(!DeleteFileA("apple"), "File not moved\n");
4447     ok(!DeleteFileA("application"), "File not moved\n");
4448     ok(DeleteFileA("ape"), "File moved\n");
4449     ok(!DeleteFileA("foo"), "File not moved\n");
4450     ok(!DeleteFileA("fao"), "File not moved\n");
4451     ok(DeleteFileA("fbod"), "File moved\n");
4452     ok(!DeleteFileA("budding"), "File not moved\n");
4453     ok(!DeleteFileA("buddy"), "File not moved\n");
4454     ok(DeleteFileA("bud"), "File moved\n");
4455     ok(!DeleteFileA("bar"), "File not moved\n");
4456     ok(!DeleteFileA("bur"), "File not moved\n");
4457     ok(DeleteFileA("bird"), "File moved\n");
4458
4459 error:
4460     DeleteFile("cameroon");
4461     DeleteFile("djibouti");
4462     DeleteFile("egypt");
4463     DeleteFile("finland");
4464     DeleteFile("gambai");
4465     DeleteFile("honduras");
4466     DeleteFile("japan");
4467     DeleteFile("kenya");
4468     DeleteFile("nauru");
4469     DeleteFile("peru");
4470     DeleteFile("apple");
4471     DeleteFile("application");
4472     DeleteFile("ape");
4473     DeleteFile("foo");
4474     DeleteFile("fao");
4475     DeleteFile("fbod");
4476     DeleteFile("budding");
4477     DeleteFile("buddy");
4478     DeleteFile("bud");
4479     DeleteFile("bar");
4480     DeleteFile("bur");
4481     DeleteFile("bird");
4482     DeleteFile("msitest\\india");
4483     DeleteFile("msitest\\augustus");
4484     RemoveDirectory("latvia");
4485     RemoveDirectory("msitest");
4486     DeleteFile(msifile);
4487 }
4488
4489 static void test_duplicate_files(void)
4490 {
4491     UINT r;
4492
4493     if (is_process_limited())
4494     {
4495         skip("process is limited\n");
4496         return;
4497     }
4498
4499     CreateDirectoryA("msitest", NULL);
4500     create_file("msitest\\maximus", 500);
4501     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4502
4503     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4504
4505     /* fails if the destination folder is not a valid property */
4506
4507     r = MsiInstallProductA(msifile, NULL);
4508     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4509     {
4510         skip("Not enough rights to perform tests\n");
4511         goto error;
4512     }
4513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4514     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4515     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4516     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4517     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4518     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4519     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4520     ok(delete_pf("msitest", FALSE), "File not installed\n");
4521
4522 error:
4523     DeleteFile("msitest\\maximus");
4524     RemoveDirectory("msitest");
4525     DeleteFile(msifile);
4526 }
4527
4528 static void test_write_registry_values(void)
4529 {
4530     UINT r;
4531     LONG res;
4532     HKEY hkey;
4533     DWORD type, size;
4534     CHAR path[MAX_PATH];
4535
4536     if (is_process_limited())
4537     {
4538         skip("process is limited\n");
4539         return;
4540     }
4541
4542     CreateDirectoryA("msitest", NULL);
4543     create_file("msitest\\augustus", 500);
4544
4545     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4546
4547     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4548
4549     r = MsiInstallProductA(msifile, NULL);
4550     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4551     {
4552         skip("Not enough rights to perform tests\n");
4553         goto error;
4554     }
4555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4556     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4557     ok(delete_pf("msitest", FALSE), "File installed\n");
4558
4559     if (is_64bit)
4560         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4561     else
4562         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4564
4565     size = MAX_PATH;
4566     type = REG_MULTI_SZ;
4567     memset(path, 'a', MAX_PATH);
4568     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4570     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4571     ok(size == 15, "Expected 15, got %d\n", size);
4572     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4573
4574     RegDeleteValueA(hkey, "Value");
4575     RegCloseKey(hkey);
4576     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
4577
4578 error:
4579     DeleteFile(msifile);
4580     DeleteFile("msitest\\augustus");
4581     RemoveDirectory("msitest");
4582 }
4583
4584 static void test_envvar(void)
4585 {
4586     static const char *results[] =
4587     {
4588         "1;2",    /* MSITESTVAR11 */
4589         "1",      /* MSITESTVAR12 */
4590         "1;2",    /* MSITESTVAR13 */
4591         ";1;",    /* MSITESTVAR14 */
4592         ";;1;;",  /* MSITESTVAR15 */
4593         " 1 ",    /* MSITESTVAR16 */
4594         ";;2;;1", /* MSITESTVAR17 */
4595         "1;;2;;", /* MSITESTVAR18 */
4596         "1",      /* MSITESTVAR19 */
4597         "1",      /* MSITESTVAR20 */
4598         NULL
4599     };
4600     UINT r;
4601     HKEY env;
4602     LONG res;
4603     DWORD type, size;
4604     char buffer[16];
4605     UINT i;
4606
4607     if (is_process_limited())
4608     {
4609         skip("process is limited\n");
4610         return;
4611     }
4612
4613     create_test_files();
4614     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
4615
4616     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
4617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4618
4619     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
4620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4621
4622     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
4623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4624
4625     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4626
4627     r = MsiInstallProductA(msifile, NULL);
4628     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4629     {
4630         skip("Not enough rights to perform tests\n");
4631         goto error;
4632     }
4633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4634
4635     type = REG_NONE;
4636     size = sizeof(buffer);
4637     buffer[0] = 0;
4638     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
4639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4640     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4641     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4642
4643     res = RegDeleteValueA(env, "MSITESTVAR1");
4644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4645
4646     type = REG_NONE;
4647     size = sizeof(buffer);
4648     buffer[0] = 0;
4649     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
4650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4651     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4652     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4653
4654     res = RegDeleteValueA(env, "MSITESTVAR2");
4655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4656
4657     res = RegDeleteValueA(env, "MSITESTVAR3");
4658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4659
4660     res = RegDeleteValueA(env, "MSITESTVAR4");
4661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4662
4663     res = RegDeleteValueA(env, "MSITESTVAR5");
4664     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4665
4666     res = RegDeleteValueA(env, "MSITESTVAR6");
4667     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4668
4669     res = RegDeleteValueA(env, "MSITESTVAR7");
4670     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4671
4672     res = RegDeleteValueA(env, "MSITESTVAR8");
4673     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4674
4675     res = RegDeleteValueA(env, "MSITESTVAR9");
4676     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4677
4678     res = RegDeleteValueA(env, "MSITESTVAR10");
4679     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4680
4681     i = 11;
4682     while (results[i - 11])
4683     {
4684         char name[20];
4685         sprintf(name, "MSITESTVAR%d", i);
4686
4687         type = REG_NONE;
4688         size = sizeof(buffer);
4689         buffer[0] = 0;
4690         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
4691         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
4692         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
4693         ok(!lstrcmp(buffer, results[i - 11]), "%d: Expected %s, got %s\n", i, results[i - 11], buffer);
4694
4695         res = RegDeleteValueA(env, name);
4696         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
4697         i++;
4698     }
4699
4700     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
4701     delete_pf("msitest\\cabout\\new", FALSE);
4702     delete_pf("msitest\\cabout\\four.txt", TRUE);
4703     delete_pf("msitest\\cabout", FALSE);
4704     delete_pf("msitest\\changed\\three.txt", TRUE);
4705     delete_pf("msitest\\changed", FALSE);
4706     delete_pf("msitest\\first\\two.txt", TRUE);
4707     delete_pf("msitest\\first", FALSE);
4708     delete_pf("msitest\\filename", TRUE);
4709     delete_pf("msitest\\one.txt", TRUE);
4710     delete_pf("msitest\\service.exe", TRUE);
4711     delete_pf("msitest", FALSE);
4712
4713 error:
4714     RegDeleteValueA(env, "MSITESTVAR1");
4715     RegDeleteValueA(env, "MSITESTVAR2");
4716     RegCloseKey(env);
4717
4718     delete_test_files();
4719     DeleteFile(msifile);
4720 }
4721
4722 static void test_create_remove_folder(void)
4723 {
4724     UINT r;
4725
4726     CreateDirectoryA("msitest", NULL);
4727     CreateDirectoryA("msitest\\first", NULL);
4728     CreateDirectoryA("msitest\\second", NULL);
4729     create_file("msitest\\first\\one.txt", 1000);
4730     create_file("msitest\\second\\two.txt", 1000);
4731     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
4732
4733     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4734
4735     r = MsiInstallProductA(msifile, NULL);
4736     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4737     {
4738         skip("Not enough rights to perform tests\n");
4739         goto error;
4740     }
4741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4742
4743     ok(pf_exists("msitest\\first\\one.txt"), "file not installed\n");
4744     ok(pf_exists("msitest\\first"), "directory not created\n");
4745     ok(pf_exists("msitest\\second\\two.txt"), "file not installed\n");
4746     ok(pf_exists("msitest\\second"), "directory not created\n");
4747     ok(pf_exists("msitest\\third"), "directory not created\n");
4748     ok(pf_exists("msitest"), "directory not created\n");
4749
4750     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4752
4753     ok(!pf_exists("msitest\\first\\one.txt"), "file not removed\n");
4754     ok(!pf_exists("msitest\\first"), "directory not removed\n");
4755     ok(!pf_exists("msitest\\second\\two.txt"), "file not removed\n");
4756     ok(!pf_exists("msitest\\second"), "directory not removed\n");
4757     ok(!pf_exists("msitest\\third"), "directory not removed\n");
4758     todo_wine ok(!pf_exists("msitest"), "directory not removed\n");
4759
4760 error:
4761     DeleteFileA("msitest\\first\\one.txt");
4762     DeleteFileA("msitest\\second\\two.txt");
4763     RemoveDirectoryA("msitest\\first");
4764     RemoveDirectoryA("msitest\\second");
4765     RemoveDirectoryA("msitest");
4766     DeleteFile(msifile);
4767 }
4768
4769 static void test_start_services(void)
4770 {
4771     UINT r;
4772     SC_HANDLE scm, service;
4773     BOOL ret;
4774     DWORD error = ERROR_SUCCESS;
4775
4776     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
4777     if (!scm && GetLastError() == ERROR_ACCESS_DENIED)
4778     {
4779         skip("Not enough rights to perform tests\n");
4780         return;
4781     }
4782     ok(scm != NULL, "Failed to open the SC Manager\n");
4783     if (!scm) return;
4784
4785     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
4786     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
4787     {
4788         win_skip("The 'Spooler' service does not exist\n");
4789         CloseServiceHandle(scm);
4790         return;
4791     }
4792     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
4793     if (!service) {
4794         CloseServiceHandle(scm);
4795         return;
4796     }
4797
4798     ret = StartService(service, 0, NULL);
4799     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
4800     {
4801         skip("Terminal service not available, skipping test\n");
4802         CloseServiceHandle(service);
4803         CloseServiceHandle(scm);
4804         return;
4805     }
4806
4807     CloseServiceHandle(service);
4808     CloseServiceHandle(scm);
4809
4810     create_test_files();
4811     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
4812
4813     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4814
4815     r = MsiInstallProductA(msifile, NULL);
4816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4817
4818     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4819     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4820     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4821     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4822     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4823     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4824     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4825     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4826     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4827     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4828     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4829     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4830
4831     delete_test_files();
4832     DeleteFile(msifile);
4833
4834     if (error == ERROR_SUCCESS)
4835     {
4836         SERVICE_STATUS status;
4837
4838         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
4839         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
4840
4841         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
4842         ok(ret, "ControlService failed %u\n", GetLastError());
4843
4844         CloseServiceHandle(service);
4845         CloseServiceHandle(scm);
4846     }
4847 }
4848
4849 static void test_delete_services(void)
4850 {
4851     UINT r;
4852
4853     if (is_process_limited())
4854     {
4855         skip("process is limited\n");
4856         return;
4857     }
4858
4859     create_test_files();
4860     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
4861
4862     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4863
4864     r = MsiInstallProductA(msifile, NULL);
4865     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4866     {
4867         skip("Not enough rights to perform tests\n");
4868         goto error;
4869     }
4870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4871
4872     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4874
4875     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4876     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4877     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4878     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4879     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4880     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4881     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4882     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4883     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4884     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4885     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4886     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4887
4888 error:
4889     delete_test_files();
4890     DeleteFile(msifile);
4891 }
4892
4893 static void test_self_registration(void)
4894 {
4895     UINT r;
4896
4897     if (is_process_limited())
4898     {
4899         skip("process is limited\n");
4900         return;
4901     }
4902
4903     create_test_files();
4904     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
4905
4906     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4907
4908     r = MsiInstallProductA(msifile, NULL);
4909     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4910     {
4911         skip("Not enough rights to perform tests\n");
4912         goto error;
4913     }
4914     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4915
4916     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4917     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4918     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4919     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4920     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
4921     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
4922     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
4923     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
4924     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
4925     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
4926     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
4927     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4928
4929 error:
4930     delete_test_files();
4931     DeleteFile(msifile);
4932 }
4933
4934 static void test_register_font(void)
4935 {
4936     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
4937     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
4938     LONG ret;
4939     HKEY key;
4940     UINT r;
4941     REGSAM access = KEY_ALL_ACCESS;
4942
4943     if (is_process_limited())
4944     {
4945         skip("process is limited\n");
4946         return;
4947     }
4948
4949     create_test_files();
4950     create_file("msitest\\font.ttf", 1000);
4951     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
4952
4953     if (is_wow64)
4954         access |= KEY_WOW64_64KEY;
4955
4956     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4957
4958     r = MsiInstallProductA(msifile, NULL);
4959     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4960     {
4961         skip("Not enough rights to perform tests\n");
4962         goto error;
4963     }
4964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4965
4966     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont1, 0, access, &key);
4967     if (ret)
4968         RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont2, 0, access, &key);
4969
4970     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
4971     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
4972
4973     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4975
4976     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
4977
4978     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
4979     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
4980
4981     RegDeleteValueA(key, "msi test font");
4982     RegCloseKey(key);
4983
4984 error:
4985     DeleteFileA("msitest\\font.ttf");
4986     delete_test_files();
4987     DeleteFile(msifile);
4988 }
4989
4990 static void test_validate_product_id(void)
4991 {
4992     UINT r;
4993
4994     if (is_process_limited())
4995     {
4996         skip("process is limited\n");
4997         return;
4998     }
4999
5000     create_test_files();
5001     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
5002
5003     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5004
5005     r = MsiInstallProductA(msifile, NULL);
5006     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5007     {
5008         skip("Not enough rights to perform tests\n");
5009         goto error;
5010     }
5011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5012
5013     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
5014     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5015
5016     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
5017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5018
5019     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
5020     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5021
5022     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5023     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5024     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5025     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5026     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5027     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5028     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5029     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5030     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5031     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5032     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5033     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5034
5035 error:
5036     delete_test_files();
5037     DeleteFile(msifile);
5038 }
5039
5040 static void test_install_remove_odbc(void)
5041 {
5042     UINT r;
5043
5044     if (is_process_limited())
5045     {
5046         skip("process is limited\n");
5047         return;
5048     }
5049
5050     create_test_files();
5051     create_file("msitest\\ODBCdriver.dll", 1000);
5052     create_file("msitest\\ODBCdriver2.dll", 1000);
5053     create_file("msitest\\ODBCtranslator.dll", 1000);
5054     create_file("msitest\\ODBCtranslator2.dll", 1000);
5055     create_file("msitest\\ODBCsetup.dll", 1000);
5056     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
5057
5058     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5059
5060     r = MsiInstallProductA(msifile, NULL);
5061     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5062     {
5063         skip("Not enough rights to perform tests\n");
5064         goto error;
5065     }
5066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5067
5068     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
5069     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
5070     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
5071     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
5072     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
5073
5074     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5076
5077     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
5078     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
5079     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
5080     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
5081     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
5082     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5083
5084 error:
5085     DeleteFileA("msitest\\ODBCdriver.dll");
5086     DeleteFileA("msitest\\ODBCdriver2.dll");
5087     DeleteFileA("msitest\\ODBCtranslator.dll");
5088     DeleteFileA("msitest\\ODBCtranslator2.dll");
5089     DeleteFileA("msitest\\ODBCsetup.dll");
5090     delete_test_files();
5091     DeleteFile(msifile);
5092 }
5093
5094 static void test_register_typelib(void)
5095 {
5096     UINT r;
5097
5098     if (is_process_limited())
5099     {
5100         skip("process is limited\n");
5101         return;
5102     }
5103
5104     create_test_files();
5105     create_file("msitest\\typelib.dll", 1000);
5106     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
5107
5108     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5109
5110     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
5111     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5112     {
5113         skip("Not enough rights to perform tests\n");
5114         goto error;
5115     }
5116     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5117
5118     r = MsiInstallProductA(msifile, NULL);
5119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5120
5121     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5123
5124     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
5125     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5126
5127 error:
5128     DeleteFileA("msitest\\typelib.dll");
5129     delete_test_files();
5130     DeleteFile(msifile);
5131 }
5132
5133 static void test_create_remove_shortcut(void)
5134 {
5135     UINT r;
5136
5137     if (is_process_limited())
5138     {
5139         skip("process is limited\n");
5140         return;
5141     }
5142
5143     create_test_files();
5144     create_file("msitest\\target.txt", 1000);
5145     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
5146
5147     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5148
5149     r = MsiInstallProductA(msifile, NULL);
5150     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5151     {
5152         skip("Not enough rights to perform tests\n");
5153         goto error;
5154     }
5155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5156
5157     ok(pf_exists("msitest\\target.txt"), "file not created\n");
5158     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
5159
5160     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5162
5163     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
5164     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
5165     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5166
5167 error:
5168     DeleteFileA("msitest\\target.txt");
5169     delete_test_files();
5170     DeleteFile(msifile);
5171 }
5172
5173 static void test_publish_components(void)
5174 {
5175     static char keypath[] =
5176         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
5177
5178     UINT r;
5179     LONG res;
5180     HKEY key;
5181
5182     if (is_process_limited())
5183     {
5184         skip("process is limited\n");
5185         return;
5186     }
5187
5188     create_test_files();
5189     create_file("msitest\\english.txt", 1000);
5190     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
5191
5192     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5193
5194     r = MsiInstallProductA(msifile, NULL);
5195     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5196     {
5197         skip("Not enough rights to perform tests\n");
5198         goto error;
5199     }
5200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5201
5202     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5203     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
5204
5205     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
5206     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
5207     RegCloseKey(key);
5208
5209     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5211
5212     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5213     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
5214
5215     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
5216     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5217
5218 error:
5219     DeleteFileA("msitest\\english.txt");
5220     delete_test_files();
5221     DeleteFile(msifile);
5222 }
5223
5224 static void test_remove_duplicate_files(void)
5225 {
5226     UINT r;
5227
5228     if (is_process_limited())
5229     {
5230         skip("process is limited\n");
5231         return;
5232     }
5233
5234     create_test_files();
5235     create_file("msitest\\original.txt", 1000);
5236     create_file("msitest\\original2.txt", 1000);
5237     create_file("msitest\\original3.txt", 1000);
5238     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
5239
5240     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5241
5242     r = MsiInstallProductA(msifile, NULL);
5243     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5244     {
5245         skip("Not enough rights to perform tests\n");
5246         goto error;
5247     }
5248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5249
5250     ok(pf_exists("msitest\\original.txt"), "file not created\n");
5251     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
5252     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
5253     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
5254     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
5255
5256     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5258
5259     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
5260     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
5261     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
5262     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
5263     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
5264     ok(delete_pf("msitest", FALSE), "directory removed\n");
5265
5266 error:
5267     DeleteFileA("msitest\\original.txt");
5268     DeleteFileA("msitest\\original2.txt");
5269     DeleteFileA("msitest\\original3.txt");
5270     delete_test_files();
5271     DeleteFile(msifile);
5272 }
5273
5274 static void test_remove_registry_values(void)
5275 {
5276     UINT r;
5277     LONG res;
5278     HKEY key;
5279     REGSAM access = KEY_ALL_ACCESS;
5280
5281     if (is_process_limited())
5282     {
5283         skip("process is limited\n");
5284         return;
5285     }
5286
5287     create_test_files();
5288     create_file("msitest\\registry.txt", 1000);
5289     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
5290
5291     if (is_wow64)
5292         access |= KEY_WOW64_64KEY;
5293
5294     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5295
5296     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, NULL, 0, access, NULL, &key, NULL);
5297     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
5298     RegCloseKey(key);
5299
5300     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5301     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
5302     RegCloseKey(key);
5303
5304     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, NULL, 0, access, NULL, &key, NULL);
5305     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5306     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
5307     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5308     RegCloseKey(key);
5309
5310     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, NULL, 0, access, NULL, &key, NULL);
5311     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5312     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5313     RegCloseKey(key);
5314
5315     r = MsiInstallProductA(msifile, NULL);
5316     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5317     {
5318         skip("Not enough rights to perform tests\n");
5319         goto error;
5320     }
5321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5322
5323     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, access, &key);
5324     ok(res == ERROR_SUCCESS, "key removed\n");
5325     RegCloseKey(key);
5326
5327     if (is_64bit)
5328     {
5329         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5330         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5331     }
5332     else
5333     {
5334         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5335         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5336     }
5337
5338     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5340     RegCloseKey(key);
5341
5342     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5344
5345     if (is_64bit)
5346     {
5347         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5348         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5349     }
5350     else
5351     {
5352         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5353         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5354     }
5355
5356     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, access, &key);
5357     ok(res == ERROR_SUCCESS, "key removed\n");
5358     RegCloseKey(key);
5359
5360     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, access, &key);
5361     ok(res == ERROR_SUCCESS, "key removed\n");
5362     RegCloseKey(key);
5363
5364     if (is_64bit)
5365     {
5366         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5367         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5368     }
5369     else
5370     {
5371         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5372         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5373     }
5374
5375     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5376     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5377     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine", access);
5378
5379     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
5380     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5381
5382 error:
5383     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", access);
5384     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5385     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5386     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", access);
5387
5388     DeleteFileA("msitest\\registry.txt");
5389     delete_test_files();
5390     DeleteFile(msifile);
5391 }
5392
5393 static void test_find_related_products(void)
5394 {
5395     UINT r;
5396
5397     if (is_process_limited())
5398     {
5399         skip("process is limited\n");
5400         return;
5401     }
5402
5403     create_test_files();
5404     create_file("msitest\\product.txt", 1000);
5405     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
5406
5407     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5408
5409     r = MsiInstallProductA(msifile, NULL);
5410     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5411     {
5412         skip("Not enough rights to perform tests\n");
5413         goto error;
5414     }
5415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5416
5417     /* install again, so it finds the upgrade code */
5418     r = MsiInstallProductA(msifile, NULL);
5419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5420
5421     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5423
5424     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
5425     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5426
5427 error:
5428     DeleteFileA("msitest\\product.txt");
5429     delete_test_files();
5430     DeleteFile(msifile);
5431 }
5432
5433 static void test_remove_ini_values(void)
5434 {
5435     UINT r;
5436     DWORD len;
5437     char inifile[MAX_PATH], buf[0x10];
5438     HANDLE file;
5439     BOOL ret;
5440
5441     if (is_process_limited())
5442     {
5443         skip("process is limited\n");
5444         return;
5445     }
5446
5447     create_test_files();
5448     create_file("msitest\\inifile.txt", 1000);
5449     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
5450
5451     lstrcpyA(inifile, PROG_FILES_DIR);
5452     lstrcatA(inifile, "\\msitest");
5453     ret = CreateDirectoryA(inifile, NULL);
5454     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
5455     {
5456         skip("Not enough rights to perform tests\n");
5457         goto error;
5458     }
5459     lstrcatA(inifile, "\\test.ini");
5460     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
5461     CloseHandle(file);
5462
5463     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
5464     ok(ret, "failed to write profile string %u\n", GetLastError());
5465
5466     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
5467     ok(ret, "failed to write profile string %u\n", GetLastError());
5468
5469     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5470
5471     r = MsiInstallProductA(msifile, NULL);
5472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5473
5474     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5475     ok(len == 6, "got %u expected 6\n", len);
5476
5477     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5478     ok(!len, "got %u expected 0\n", len);
5479
5480     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5482
5483     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5484     ok(!len, "got %u expected 0\n", len);
5485
5486     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5487     ok(!len, "got %u expected 0\n", len);
5488
5489     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
5490     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
5491     ok(delete_pf("msitest", FALSE), "directory removed\n");
5492
5493 error:
5494     DeleteFileA("msitest\\inifile.txt");
5495     delete_test_files();
5496     DeleteFile(msifile);
5497 }
5498
5499 static void test_remove_env_strings(void)
5500 {
5501     UINT r;
5502     LONG res;
5503     HKEY key;
5504     DWORD type, size;
5505     char buffer[0x10];
5506
5507     if (is_process_limited())
5508     {
5509         skip("process is limited\n");
5510         return;
5511     }
5512
5513     create_test_files();
5514     create_file("msitest\\envvar.txt", 1000);
5515     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
5516
5517     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5518
5519     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5520     ok(!res, "failed to open environment key %d\n", res);
5521
5522     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
5523     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
5524     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
5525     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
5526     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
5527
5528     RegCloseKey(key);
5529
5530     r = MsiInstallProductA(msifile, NULL);
5531     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5532     {
5533         skip("Not enough rights to perform tests\n");
5534         goto error;
5535     }
5536     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5537
5538     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5539     ok(!res, "failed to open environment key %d\n", res);
5540
5541     type = REG_NONE;
5542     buffer[0] = 0;
5543     size = sizeof(buffer);
5544     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
5545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5546     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5547     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5548
5549     type = REG_NONE;
5550     buffer[0] = 0;
5551     size = sizeof(buffer);
5552     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
5553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5554     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5555     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5556
5557     type = REG_NONE;
5558     buffer[0] = 0;
5559     size = sizeof(buffer);
5560     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5562     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5563     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5564
5565     type = REG_NONE;
5566     buffer[0] = 0;
5567     size = sizeof(buffer);
5568     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
5569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5570     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5571     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5572
5573     type = REG_NONE;
5574     buffer[0] = 0;
5575     size = sizeof(buffer);
5576     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5578     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5579     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5580
5581     RegCloseKey(key);
5582
5583     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5585
5586     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5587     ok(!res, "failed to open environment key %d\n", res);
5588
5589     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
5590     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5591
5592     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
5593     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5594
5595     type = REG_NONE;
5596     buffer[0] = 0;
5597     size = sizeof(buffer);
5598     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5600     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5601     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5602     RegDeleteValueA(key, "MSITESTVAR3");
5603
5604     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
5605     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5606
5607     type = REG_NONE;
5608     buffer[0] = 0;
5609     size = sizeof(buffer);
5610     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5612     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5613     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5614     RegDeleteValueA(key, "MSITESTVAR5");
5615
5616     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
5617     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5618
5619 error:
5620     RegDeleteValueA(key, "MSITESTVAR1");
5621     RegDeleteValueA(key, "MSITESTVAR2");
5622     RegDeleteValueA(key, "MSITESTVAR3");
5623     RegDeleteValueA(key, "MSITESTVAR4");
5624     RegDeleteValueA(key, "MSITESTVAR5");
5625     RegCloseKey(key);
5626
5627     DeleteFileA("msitest\\envvar.txt");
5628     delete_test_files();
5629     DeleteFile(msifile);
5630 }
5631
5632 static void test_register_class_info(void)
5633 {
5634     UINT r;
5635     LONG res;
5636     HKEY hkey;
5637
5638     if (is_process_limited())
5639     {
5640         skip("process is limited\n");
5641         return;
5642     }
5643
5644     create_test_files();
5645     create_file("msitest\\class.txt", 1000);
5646     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
5647
5648     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5649
5650     r = MsiInstallProductA(msifile, NULL);
5651     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5652     {
5653         skip("Not enough rights to perform tests\n");
5654         goto error;
5655     }
5656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5657
5658     if (is_64bit)
5659         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5660     else
5661         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5662     ok(res == ERROR_SUCCESS, "key not created\n");
5663     RegCloseKey(hkey);
5664
5665     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{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, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
5670     ok(res == ERROR_SUCCESS, "key not created\n");
5671     RegCloseKey(hkey);
5672
5673     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5674     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5675
5676     if (is_64bit)
5677         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5678     else
5679         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5680     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5681
5682     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
5683     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5684
5685     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
5686     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5687
5688     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
5689     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5690
5691 error:
5692     DeleteFileA("msitest\\class.txt");
5693     delete_test_files();
5694     DeleteFile(msifile);
5695 }
5696
5697 static void test_register_extension_info(void)
5698 {
5699     UINT r;
5700     LONG res;
5701     HKEY hkey;
5702
5703     if (is_process_limited())
5704     {
5705         skip("process is limited\n");
5706         return;
5707     }
5708
5709     create_test_files();
5710     create_file("msitest\\extension.txt", 1000);
5711     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
5712
5713     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5714
5715     r = MsiInstallProductA(msifile, NULL);
5716     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5717     {
5718         skip("Not enough rights to perform tests\n");
5719         goto error;
5720     }
5721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5722
5723     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
5724     ok(res == ERROR_SUCCESS, "key not created\n");
5725     RegCloseKey(hkey);
5726
5727     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
5728     ok(res == ERROR_SUCCESS, "key not created\n");
5729     RegCloseKey(hkey);
5730
5731     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5733
5734     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
5735     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5736
5737     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
5738     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5739
5740     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
5741     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5742
5743 error:
5744     DeleteFileA("msitest\\extension.txt");
5745     delete_test_files();
5746     DeleteFile(msifile);
5747 }
5748
5749 static void test_register_mime_info(void)
5750 {
5751     UINT r;
5752     LONG res;
5753     HKEY hkey;
5754
5755     if (is_process_limited())
5756     {
5757         skip("process is limited\n");
5758         return;
5759     }
5760
5761     create_test_files();
5762     create_file("msitest\\mime.txt", 1000);
5763     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
5764
5765     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5766
5767     r = MsiInstallProductA(msifile, NULL);
5768     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5769     {
5770         skip("Not enough rights to perform tests\n");
5771         goto error;
5772     }
5773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5774
5775     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
5776     ok(res == ERROR_SUCCESS, "key not created\n");
5777     RegCloseKey(hkey);
5778
5779     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5781
5782     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
5783     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5784
5785     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
5786     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5787
5788 error:
5789     DeleteFileA("msitest\\mime.txt");
5790     delete_test_files();
5791     DeleteFile(msifile);
5792 }
5793
5794 static void test_publish_assemblies(void)
5795 {
5796     static const char manifest[] =
5797         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Assembly\" "
5798         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
5799         "processorArchitecture=\"x86\"/>";
5800     static const char manifest_local[] =
5801         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Local.Assembly\" "
5802         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
5803         "processorArchitecture=\"x86\"/>";
5804     static const char classes_path_dotnet[] =
5805         "Installer\\Assemblies\\Global";
5806     static const char classes_path_dotnet_local[] =
5807         "Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
5808     static const char classes_path_dotnet_local_wow64[] =
5809         "Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
5810     static const char classes_path_win32[] =
5811         "Installer\\Win32Assemblies\\Global";
5812     static const char classes_path_win32_local[] =
5813         "Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
5814     static const char classes_path_win32_local_wow64[] =
5815         "Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
5816     static const char path_dotnet[] =
5817         "Software\\Microsoft\\Installer\\Assemblies\\Global";
5818     static const char path_dotnet_local[] =
5819         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
5820     static const char path_dotnet_local_wow64[] =
5821         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
5822     static const char path_win32[] =
5823         "Software\\Microsoft\\Installer\\Win32Assemblies\\Global";
5824     static const char path_win32_local[] =
5825         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
5826     static const char path_win32_local_wow64[] =
5827         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
5828     static const char name_dotnet[] =
5829         "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
5830         "version=\"1.0.0.0\",culture=\"neutral\"";
5831     static const char name_dotnet_local[] =
5832         "Wine.Dotnet.Local.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
5833         "version=\"1.0.0.0\",culture=\"neutral\"";
5834     static const char name_win32[] =
5835         "Wine.Win32.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
5836         "type=\"win32\",version=\"1.0.0.0\"";
5837     static const char name_win32_local[] =
5838         "Wine.Win32.Local.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
5839         "type=\"win32\",version=\"1.0.0.0\"";
5840     UINT r;
5841     LONG res;
5842     HKEY hkey;
5843     const char *path;
5844     int access;
5845
5846     if (is_process_limited())
5847     {
5848         skip("process is limited\n");
5849         return;
5850     }
5851
5852     create_test_files();
5853     create_file("msitest\\win32.txt", 1000);
5854     create_file("msitest\\win32_local.txt", 1000);
5855     create_file("msitest\\dotnet.txt", 1000);
5856     create_file("msitest\\dotnet_local.txt", 1000);
5857     create_file_data("msitest\\manifest.txt", manifest, 0);
5858     create_file_data("msitest\\manifest_local.txt", manifest_local, 0);
5859     create_file("msitest\\application_win32.txt", 1000);
5860     create_file("msitest\\application_dotnet.txt", 1000);
5861     create_database(msifile, pa_tables, sizeof(pa_tables) / sizeof(msi_table));
5862
5863     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5864
5865     r = MsiInstallProductA(msifile, NULL);
5866     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5867     {
5868         skip("Not enough rights to perform tests\n");
5869         goto done;
5870     }
5871     if (r == ERROR_INSTALL_FAILURE)
5872     {
5873         skip("No support for installing side-by-side assemblies\n");
5874         goto done;
5875     }
5876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5877
5878     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
5879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5880     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
5881     RegCloseKey(hkey);
5882
5883     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
5884     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5886     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
5887     RegCloseKey(hkey);
5888
5889     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
5890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5891     CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
5892     RegCloseKey(hkey);
5893
5894     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
5895     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5897     CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
5898     RegCloseKey(hkey);
5899
5900     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5902
5903     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
5904     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5905     if (res == ERROR_SUCCESS)
5906     {
5907         res = RegDeleteValueA(hkey, name_dotnet);
5908         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5909         RegCloseKey(hkey);
5910     }
5911
5912     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
5913     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5914     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5915
5916     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
5917     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5918     if (res == ERROR_SUCCESS)
5919     {
5920         res = RegDeleteValueA(hkey, name_win32);
5921         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5922         RegCloseKey(hkey);
5923     }
5924
5925     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
5926     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
5927     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5928
5929     r = MsiInstallProductA(msifile, "ALLUSERS=1");
5930     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5931
5932     access = KEY_QUERY_VALUE;
5933     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
5934     if (res == ERROR_FILE_NOT_FOUND && is_wow64) /* Vista WOW64 */
5935     {
5936         trace("Using 64-bit registry view for HKCR\\Installer\n");
5937         access = KEY_QUERY_VALUE | KEY_WOW64_64KEY;
5938         res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
5939     }
5940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5941     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
5942     RegCloseKey(hkey);
5943
5944     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
5945     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
5946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5947     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
5948     RegCloseKey(hkey);
5949
5950     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_win32, 0, access, &hkey);
5951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5952     CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
5953     RegCloseKey(hkey);
5954
5955     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
5956     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
5957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5958     CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
5959     RegCloseKey(hkey);
5960
5961     r = MsiInstallProductA(msifile, "REMOVE=ALL ALLUSERS=1");
5962     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5963
5964     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_dotnet, &hkey);
5965     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5966     if (res == ERROR_SUCCESS)
5967     {
5968         res = RegDeleteValueA(hkey, name_dotnet);
5969         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5970         RegCloseKey(hkey);
5971     }
5972
5973     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
5974     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
5975     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5976
5977     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_win32, &hkey);
5978     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
5979     if (res == ERROR_SUCCESS)
5980     {
5981         res = RegDeleteValueA(hkey, name_win32);
5982         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5983         RegCloseKey(hkey);
5984     }
5985
5986     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
5987     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
5988     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5989
5990 done:
5991     DeleteFileA("msitest\\win32.txt");
5992     DeleteFileA("msitest\\win32_local.txt");
5993     DeleteFileA("msitest\\dotnet.txt");
5994     DeleteFileA("msitest\\dotnet_local.txt");
5995     DeleteFileA("msitest\\manifest.txt");
5996     DeleteFileA("msitest\\manifest_local.txt");
5997     DeleteFileA("msitest\\application_win32.txt");
5998     DeleteFileA("msitest\\application_dotnet.txt");
5999     delete_test_files();
6000     DeleteFile(msifile);
6001 }
6002
6003 START_TEST(action)
6004 {
6005     DWORD len;
6006     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6007     STATEMGRSTATUS status;
6008     BOOL ret = FALSE;
6009
6010     init_functionpointers();
6011
6012     if (pIsWow64Process)
6013         pIsWow64Process(GetCurrentProcess(), &is_wow64);
6014
6015     GetCurrentDirectoryA(MAX_PATH, prev_path);
6016     GetTempPath(MAX_PATH, temp_path);
6017     SetCurrentDirectoryA(temp_path);
6018
6019     lstrcpyA(CURR_DIR, temp_path);
6020     len = lstrlenA(CURR_DIR);
6021
6022     if(len && (CURR_DIR[len - 1] == '\\'))
6023         CURR_DIR[len - 1] = 0;
6024
6025     ok(get_system_dirs(), "failed to retrieve system dirs\n");
6026     ok(get_user_dirs(), "failed to retrieve user dirs\n");
6027
6028     /* Create a restore point ourselves so we circumvent the multitude of restore points
6029      * that would have been created by all the installation and removal tests.
6030      *
6031      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
6032      * creation of restore points.
6033      */
6034     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
6035     {
6036         memset(&status, 0, sizeof(status));
6037         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6038     }
6039
6040     /* Create only one log file and don't append. We have to pass something
6041      * for the log mode for this to work. The logfile needs to have an absolute
6042      * path otherwise we still end up with some extra logfiles as some tests
6043      * change the current directory.
6044      */
6045     lstrcpyA(log_file, temp_path);
6046     lstrcatA(log_file, "\\msitest.log");
6047     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6048
6049     test_register_product();
6050     test_publish_product();
6051     test_publish_features();
6052     test_register_user();
6053     test_process_components();
6054     test_publish();
6055     test_publish_sourcelist();
6056     test_remove_files();
6057     test_move_files();
6058     test_duplicate_files();
6059     test_write_registry_values();
6060     test_envvar();
6061     test_create_remove_folder();
6062     test_start_services();
6063     test_delete_services();
6064     test_self_registration();
6065     test_register_font();
6066     test_validate_product_id();
6067     test_install_remove_odbc();
6068     test_register_typelib();
6069     test_create_remove_shortcut();
6070     test_publish_components();
6071     test_remove_duplicate_files();
6072     test_remove_registry_values();
6073     test_find_related_products();
6074     test_remove_ini_values();
6075     test_remove_env_strings();
6076     test_register_class_info();
6077     test_register_extension_info();
6078     test_register_mime_info();
6079     test_publish_assemblies();
6080
6081     DeleteFileA(log_file);
6082
6083     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
6084     {
6085         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6086         if (ret)
6087             remove_restore_point(status.llSequenceNumber);
6088     }
6089     FreeLibrary(hsrclient);
6090
6091     SetCurrentDirectoryA(prev_path);
6092 }