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