ReactOS 0.4.16-dev-197-g92996da
msi.c
Go to the documentation of this file.
1/*
2 * tests for Microsoft Installer functionality
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define _WIN32_MSI 300
22#define COBJMACROS
23
24#include <stdio.h>
25#include <windows.h>
26#include <msi.h>
27#include <msiquery.h>
28#include <msidefs.h>
29#include <sddl.h>
30#include <fci.h>
31#include <shellapi.h>
32#include <objidl.h>
33
34#include "wine/test.h"
35#include "utils.h"
36
37#define GUID_SIZE (39)
38#define SQUASHED_GUID_SIZE (33)
39
41static const char msifile[] = "winetest.msi";
42static const WCHAR msifileW[] = L"winetest.msi";
43
44/* cabinet definitions */
45
46/* make the max size large so there is only one cab file */
47#define MEDIA_SIZE 0x7FFFFFFF
48#define FOLDER_THRESHOLD 900000
49
51{
52 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
53 IStorage *stg;
54 IStream *stm;
55 HRESULT hr;
57
58 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
60 if (FAILED(hr))
61 return FALSE;
62
63 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
64 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
65 if (FAILED(hr))
66 {
67 IStorage_Release(stg);
68 return FALSE;
69 }
70
73 {
75 char buffer[1024];
76 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
77 IStream_Write(stm, buffer, count, &count);
79 }
80
81 IStream_Release(stm);
82 IStorage_Release(stg);
83
84 return TRUE;
85}
86
87/* msi database data */
88
89static const char directory_dat[] =
90 "Directory\tDirectory_Parent\tDefaultDir\n"
91 "s72\tS72\tl255\n"
92 "Directory\tDirectory\n"
93 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
94 "ProgramFilesFolder\tTARGETDIR\t.\n"
95 "TARGETDIR\t\tSourceDir";
96
97static const char component_dat[] =
98 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
99 "s72\tS38\ts72\ti2\tS255\tS72\n"
100 "Component\tComponent\n"
101 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
102
103static const char feature_dat[] =
104 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
105 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
106 "Feature\tFeature\n"
107 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
108 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
109
110static const char feature_comp_dat[] =
111 "Feature_\tComponent_\n"
112 "s38\ts72\n"
113 "FeatureComponents\tFeature_\tComponent_\n"
114 "One\tOne\n";
115
116static const char file_dat[] =
117 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
118 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
119 "File\tFile\n"
120 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
121
122static const char install_exec_seq_dat[] =
123 "Action\tCondition\tSequence\n"
124 "s72\tS255\tI2\n"
125 "InstallExecuteSequence\tAction\n"
126 "ValidateProductID\t\t700\n"
127 "CostInitialize\t\t800\n"
128 "FileCost\t\t900\n"
129 "CostFinalize\t\t1000\n"
130 "InstallValidate\t\t1400\n"
131 "InstallInitialize\t\t1500\n"
132 "ProcessComponents\t\t1600\n"
133 "UnpublishFeatures\t\t1800\n"
134 "RemoveFiles\t\t3500\n"
135 "InstallFiles\t\t4000\n"
136 "RegisterProduct\t\t6100\n"
137 "PublishFeatures\t\t6300\n"
138 "PublishProduct\t\t6400\n"
139 "InstallFinalize\t\t6600";
140
141static const char media_dat[] =
142 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
143 "i2\ti4\tL64\tS255\tS32\tS72\n"
144 "Media\tDiskId\n"
145 "1\t1\t\t\tDISK1\t\n";
146
147static const char property_dat[] =
148 "Property\tValue\n"
149 "s72\tl0\n"
150 "Property\tProperty\n"
151 "INSTALLLEVEL\t3\n"
152 "Manufacturer\tWine\n"
153 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
154 "ProductName\tMSITEST\n"
155 "ProductVersion\t1.1.1\n"
156 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
157 "MSIFASTINSTALL\t1\n";
158
159static const char ci2_property_dat[] =
160 "Property\tValue\n"
161 "s72\tl0\n"
162 "Property\tProperty\n"
163 "INSTALLLEVEL\t3\n"
164 "Manufacturer\tWine\n"
165 "ProductCode\t{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}\n"
166 "ProductName\tMSITEST2\n"
167 "ProductVersion\t1.1.1\n"
168 "UpgradeCode\t{6B60C3CA-B8CA-4FB7-A395-092D98FF5D2A}\n"
169 "MSIFASTINSTALL\t1\n";
170
171static const char mcp_component_dat[] =
172 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
173 "s72\tS38\ts72\ti2\tS255\tS72\n"
174 "Component\tComponent\n"
175 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
176 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
177 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
178
179static const char mcp_feature_dat[] =
180 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
181 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
182 "Feature\tFeature\n"
183 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
184 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
185 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
186
187static const char mcp_feature_comp_dat[] =
188 "Feature_\tComponent_\n"
189 "s38\ts72\n"
190 "FeatureComponents\tFeature_\tComponent_\n"
191 "hydroxyl\thydrogen\n"
192 "heliox\thelium\n"
193 "lithia\tlithium";
194
195static const char mcp_file_dat[] =
196 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
197 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
198 "File\tFile\n"
199 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
200 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
201 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
202
203static const char lus_component_dat[] =
204 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
205 "s72\tS38\ts72\ti2\tS255\tS72\n"
206 "Component\tComponent\n"
207 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
208
209static const char lus_feature_dat[] =
210 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
211 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
212 "Feature\tFeature\n"
213 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
214 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
215
216static const char lus_file_dat[] =
217 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
218 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
219 "File\tFile\n"
220 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
221
222static const char lus_feature_comp_dat[] =
223 "Feature_\tComponent_\n"
224 "s38\ts72\n"
225 "FeatureComponents\tFeature_\tComponent_\n"
226 "feature\tmaximus\n"
227 "montecristo\tmaximus";
228
229static const char lus_install_exec_seq_dat[] =
230 "Action\tCondition\tSequence\n"
231 "s72\tS255\tI2\n"
232 "InstallExecuteSequence\tAction\n"
233 "ValidateProductID\t\t700\n"
234 "CostInitialize\t\t800\n"
235 "FileCost\t\t900\n"
236 "CostFinalize\t\t1000\n"
237 "InstallValidate\t\t1400\n"
238 "InstallInitialize\t\t1500\n"
239 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
240 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
241 "RemoveFiles\t\t3500\n"
242 "InstallFiles\t\t4000\n"
243 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
244 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
245 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
246 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
247 "InstallFinalize\t\t6600";
248
249static const char lus0_media_dat[] =
250 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
251 "i2\ti4\tL64\tS255\tS32\tS72\n"
252 "Media\tDiskId\n"
253 "1\t1\t\t\tDISK1\t\n";
254
255static const char lus1_media_dat[] =
256 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
257 "i2\ti4\tL64\tS255\tS32\tS72\n"
258 "Media\tDiskId\n"
259 "1\t1\t\ttest1.cab\tDISK1\t\n";
260
261static const char lus2_media_dat[] =
262 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
263 "i2\ti4\tL64\tS255\tS32\tS72\n"
264 "Media\tDiskId\n"
265 "1\t1\t\t#test1.cab\tDISK1\t\n";
266
267static const char spf_custom_action_dat[] =
268 "Action\tType\tSource\tTarget\tISComments\n"
269 "s72\ti2\tS64\tS0\tS255\n"
270 "CustomAction\tAction\n"
271 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n"
272 "SetFolderProp2\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\\added2\t\n";
273
274static const char spf_install_exec_seq_dat[] =
275 "Action\tCondition\tSequence\n"
276 "s72\tS255\tI2\n"
277 "InstallExecuteSequence\tAction\n"
278 "CostInitialize\t\t800\n"
279 "FileCost\t\t900\n"
280 "SetFolderProp\t\t950\n"
281 "SetFolderProp2\t\t960\n"
282 "CostFinalize\t\t1000\n"
283 "InstallValidate\t\t1400\n"
284 "InstallInitialize\t\t1500\n"
285 "InstallFiles\t\t4000\n"
286 "InstallServices\t\t5000\n"
287 "InstallFinalize\t\t6600\n";
288
289static const char spf_install_ui_seq_dat[] =
290 "Action\tCondition\tSequence\n"
291 "s72\tS255\tI2\n"
292 "InstallUISequence\tAction\n"
293 "CostInitialize\t\t800\n"
294 "FileCost\t\t900\n"
295 "CostFinalize\t\t1000\n"
296 "ExecuteAction\t\t1100\n";
297
298static const char spf_directory_dat[] =
299 "Directory\tDirectory_Parent\tDefaultDir\n"
300 "s72\tS72\tl255\n"
301 "Directory\tDirectory\n"
302 "PARENTDIR\tTARGETDIR\tparent\n"
303 "CHILDDIR\tPARENTDIR\tchild\n"
304 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
305 "ProgramFilesFolder\tTARGETDIR\t.\n"
306 "TARGETDIR\t\tSourceDir";
307
308static const char spf_component_dat[] =
309 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
310 "s72\tS38\ts72\ti2\tS255\tS72\n"
311 "Component\tComponent\n"
312 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
313
314static const char spf2_install_exec_seq_dat[] =
315 "Action\tCondition\tSequence\n"
316 "s72\tS255\tI2\n"
317 "InstallExecuteSequence\tAction\n"
318 "CostInitialize\t\t800\n"
319 "FileCost\t\t900\n"
320 "FormatParentFolderCheck\t\t910\n"
321 "FormatChildFolderCheck\t\t920\n"
322 "CheckParentFolder\tNOT PARENTDIR=PARENTDIRCHECK\t930\n"
323 "CheckChildFolder\tNOT CHILDDIR=CHILDDIRCHECK\t940\n"
324 "FormatParentFolderCheck2\t\t945\n"
325 "SetParentFolder\t\t950\n"
326 "CheckParentFolder2\tNOT PARENTDIR=PARENTDIRCHECK\t960\n"
327 "CheckChildFolder2\tNOT CHILDDIR=CHILDDIRCHECK\t970\n"
328 "CostFinalize\t\t1000\n"
329 "FormatParentFolderCheck3\t\t1005\n"
330 "CheckParentFolder3\tNOT PARENTDIR=PARENTDIRCHECK\t1010\n"
331 "CheckChildFolder3\tNOT CHILDDIR=CHILDDIRCHECK\t1020\n"
332 "InstallValidate\t\t1400\n"
333 "InstallInitialize\t\t1500\n"
334 "InstallFiles\t\t4000\n"
335 "CreateShortcuts\t\t4100\n"
336 "InstallFinalize\t\t6600\n";
337
338static const char spf2_custom_action_dat[] =
339 "Action\tType\tSource\tTarget\tISComments\n"
340 "s72\ti2\tS64\tS0\tS255\n"
341 "CustomAction\tAction\n"
342 "FormatParentFolderCheck\t51\tPARENTDIRCHECK\t[TARGETDIR]parent\\\t\n"
343 "FormatChildFolderCheck\t51\tCHILDDIRCHECK\t[TARGETDIR]parent\\child\\\t\n"
344 "CheckParentFolder\t19\tPARENTDIR\tparent prop wrong before set: [PARENTDIR]\t\n"
345 "CheckChildFolder\t19\tCHILDDIR\tchild prop wrong before set: [CHILDDIR]\t\n"
346 "FormatParentFolderCheck2\t51\tPARENTDIRCHECK\t[ProgramFilesFolder]msitest\\parent\t\n"
347 "SetParentFolder\t51\tPARENTDIR\t[PARENTDIRCHECK]\t\n"
348 "CheckParentFolder2\t19\tPARENTDIR\tparent prop wrong after set: [PARENTDIR]\t\n"
349 "CheckChildFolder2\t19\tCHILDDIR\tchild prop wrong after set: [CHILDDIR]\t\n"
350 "FormatParentFolderCheck3\t51\tPARENTDIRCHECK\t[ProgramFilesFolder]msitest\\parent\\\t\n"
351 "CheckParentFolder3\t19\tPARENTDIR\tparent prop wrong after CostFinalize: [PARENTDIR]\t\n"
352 "CheckChildFolder3\t19\tCHILDDIR\tchild prop wrong after CostFinalize: [CHILDDIR]\t\n";
353
354static const char shortcut_dat[] =
355 "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
356 "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
357 "Shortcut\tShortcut\n"
358 "Shortcut\tCHILDDIR\tShortcut\tmaximus\t[#maximus]\t\tShortcut\t\t\t\t\tMSITESTDIR\n";
359
360static const char sd_file_dat[] =
361 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
362 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
363 "File\tFile\n"
364 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
365
366static const char sd_feature_dat[] =
367 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
368 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
369 "Feature\tFeature\n"
370 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
371
372static const char sd_feature_comp_dat[] =
373 "Feature_\tComponent_\n"
374 "s38\ts72\n"
375 "FeatureComponents\tFeature_\tComponent_\n"
376 "sourcedir\tsourcedir\n";
377
378static const char sd_component_dat[] =
379 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
380 "s72\tS38\ts72\ti2\tS255\tS72\n"
381 "Component\tComponent\n"
382 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
383
384static const char sd_install_ui_seq_dat[] =
385 "Action\tCondition\tSequence\n"
386 "s72\tS255\tI2\n"
387 "InstallUISequence\tAction\n"
388 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
389 "AppSearch\t\t100\n"
390 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
391 "LaunchConditions\tnot Installed \t110\n"
392 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
393 "FindRelatedProducts\t\t120\n"
394 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
395 "CCPSearch\t\t130\n"
396 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
397 "RMCCPSearch\t\t140\n"
398 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
399 "ValidateProductID\t\t150\n"
400 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
401 "CostInitialize\t\t800\n"
402 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
403 "FileCost\t\t900\n"
404 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
405 "IsolateComponents\t\t1000\n"
406 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
407 "CostFinalize\t\t1100\n"
408 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
409 "MigrateFeatureStates\t\t1200\n"
410 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
411 "ExecuteAction\t\t1300\n"
412 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
413
414static const char sd_install_exec_seq_dat[] =
415 "Action\tCondition\tSequence\n"
416 "s72\tS255\tI2\n"
417 "InstallExecuteSequence\tAction\n"
418 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
419 "LaunchConditions\t\t100\n"
420 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
421 "ValidateProductID\t\t700\n"
422 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
423 "CostInitialize\t\t800\n"
424 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
425 "ResolveSource\tResolveSource and not Installed\t850\n"
426 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
427 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
428 "FileCost\t\t900\n"
429 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
430 "IsolateComponents\t\t1000\n"
431 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
432 "CostFinalize\t\t1100\n"
433 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
434 "MigrateFeatureStates\t\t1200\n"
435 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
436 "InstallValidate\t\t1400\n"
437 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
438 "InstallInitialize\t\t1500\n"
439 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
440 "ProcessComponents\t\t1600\n"
441 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
442 "UnpublishFeatures\t\t1800\n"
443 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
444 "RemoveFiles\t\t3500\n"
445 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
446 "InstallFiles\t\t4000\n"
447 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
448 "RegisterUser\t\t6000\n"
449 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
450 "RegisterProduct\t\t6100\n"
451 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
452 "PublishFeatures\t\t6300\n"
453 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
454 "PublishProduct\t\t6400\n"
455 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
456 "InstallExecute\t\t6500\n"
457 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
458 "InstallFinalize\t\t6600\n"
459 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
460
461static const char sd_custom_action_dat[] =
462 "Action\tType\tSource\tTarget\tISComments\n"
463 "s72\ti2\tS64\tS0\tS255\n"
464 "CustomAction\tAction\n"
465 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
466 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
467 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
468 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
469 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
470 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
471 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
472 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
473 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
474 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
475 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
476 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
477 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
478 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
479 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
480 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
481 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
482 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
483 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
484 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
485 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
486 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
487 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
488 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
489 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
490 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
491 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
492 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
493 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
494 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
495 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
496 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
497 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
498 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
499 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
500
501static const char ci_install_exec_seq_dat[] =
502 "Action\tCondition\tSequence\n"
503 "s72\tS255\tI2\n"
504 "InstallExecuteSequence\tAction\n"
505 "CostInitialize\t\t800\n"
506 "FileCost\t\t900\n"
507 "CostFinalize\t\t1000\n"
508 "InstallValidate\t\t1400\n"
509 "InstallInitialize\t\t1500\n"
510 "RunInstall\tnot Installed\t1550\n"
511 "ProcessComponents\t\t1600\n"
512 "UnpublishFeatures\t\t1800\n"
513 "RemoveFiles\t\t3500\n"
514 "InstallFiles\t\t4000\n"
515 "RegisterProduct\t\t6100\n"
516 "PublishFeatures\t\t6300\n"
517 "PublishProduct\t\t6400\n"
518 "InstallFinalize\t\t6600\n";
519
520static const char ci_custom_action_dat[] =
521 "Action\tType\tSource\tTarget\tISComments\n"
522 "s72\ti2\tS64\tS0\tS255\n"
523 "CustomAction\tAction\n"
524 "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
525
526static const char ci_component_dat[] =
527 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
528 "s72\tS38\ts72\ti2\tS255\tS72\n"
529 "Component\tComponent\n"
530 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
531
532static const char ci2_component_dat[] =
533 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
534 "s72\tS38\ts72\ti2\tS255\tS72\n"
535 "Component\tComponent\n"
536 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
537
538static const char ci2_feature_comp_dat[] =
539 "Feature_\tComponent_\n"
540 "s38\ts72\n"
541 "FeatureComponents\tFeature_\tComponent_\n"
542 "feature\taugustus";
543
544static const char ci2_file_dat[] =
545 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
546 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
547 "File\tFile\n"
548 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
549
550static const char cl_custom_action_dat[] =
551 "Action\tType\tSource\tTarget\tISComments\n"
552 "s72\ti2\tS64\tS0\tS255\n"
553 "CustomAction\tAction\n"
554 "TestCommandlineProp\t19\t\tTest1\t\n";
555
556static const char cl_install_exec_seq_dat[] =
557 "Action\tCondition\tSequence\n"
558 "s72\tS255\tI2\n"
559 "InstallExecuteSequence\tAction\n"
560 "LaunchConditions\t\t100\n"
561 "ValidateProductID\t\t700\n"
562 "CostInitialize\t\t800\n"
563 "FileCost\t\t900\n"
564 "CostFinalize\t\t1000\n"
565 "TestCommandlineProp\tP=\"one\"\t1100\n"
566 "InstallInitialize\t\t1500\n"
567 "ProcessComponents\t\t1600\n"
568 "InstallValidate\t\t1400\n"
569 "InstallFinalize\t\t5000\n";
570
571static const msi_table tables[] =
572{
574 ADD_TABLE(component),
576 ADD_TABLE(feature_comp),
578 ADD_TABLE(install_exec_seq),
581};
582
583static const msi_table mcp_tables[] =
584{
586 ADD_TABLE(mcp_component),
587 ADD_TABLE(mcp_feature),
588 ADD_TABLE(mcp_feature_comp),
589 ADD_TABLE(mcp_file),
590 ADD_TABLE(install_exec_seq),
593};
594
595static const msi_table lus0_tables[] =
596{
597 ADD_TABLE(lus_component),
599 ADD_TABLE(lus_feature),
600 ADD_TABLE(lus_feature_comp),
601 ADD_TABLE(lus_file),
602 ADD_TABLE(lus_install_exec_seq),
603 ADD_TABLE(lus0_media),
605};
606
607static const msi_table lus1_tables[] =
608{
609 ADD_TABLE(lus_component),
611 ADD_TABLE(lus_feature),
612 ADD_TABLE(lus_feature_comp),
613 ADD_TABLE(lus_file),
614 ADD_TABLE(lus_install_exec_seq),
615 ADD_TABLE(lus1_media),
617};
618
619static const msi_table lus2_tables[] =
620{
621 ADD_TABLE(lus_component),
623 ADD_TABLE(lus_feature),
624 ADD_TABLE(lus_feature_comp),
625 ADD_TABLE(lus_file),
626 ADD_TABLE(lus_install_exec_seq),
627 ADD_TABLE(lus2_media),
629};
630
631static const msi_table spf_tables[] =
632{
633 ADD_TABLE(lus_component),
635 ADD_TABLE(lus_feature),
636 ADD_TABLE(lus_feature_comp),
637 ADD_TABLE(lus_file),
638 ADD_TABLE(lus0_media),
640 ADD_TABLE(spf_custom_action),
641 ADD_TABLE(spf_install_exec_seq),
642 ADD_TABLE(spf_install_ui_seq)
643};
644
645static const msi_table spf2_tables[] =
646{
647 ADD_TABLE(spf_component),
648 ADD_TABLE(spf_directory),
649 ADD_TABLE(lus_feature),
650 ADD_TABLE(lus_feature_comp),
651 ADD_TABLE(lus_file),
652 ADD_TABLE(lus0_media),
654 ADD_TABLE(spf2_custom_action),
655 ADD_TABLE(spf2_install_exec_seq),
656 ADD_TABLE(spf_install_ui_seq),
657 ADD_TABLE(shortcut)
658};
659
660static const msi_table sd_tables[] =
661{
663 ADD_TABLE(sd_component),
664 ADD_TABLE(sd_feature),
665 ADD_TABLE(sd_feature_comp),
666 ADD_TABLE(sd_file),
667 ADD_TABLE(sd_install_exec_seq),
668 ADD_TABLE(sd_install_ui_seq),
669 ADD_TABLE(sd_custom_action),
672};
673
674static const msi_table ci_tables[] =
675{
676 ADD_TABLE(ci_component),
678 ADD_TABLE(lus_feature),
679 ADD_TABLE(lus_feature_comp),
680 ADD_TABLE(lus_file),
681 ADD_TABLE(ci_install_exec_seq),
682 ADD_TABLE(lus0_media),
684 ADD_TABLE(ci_custom_action),
685};
686
687static const msi_table ci2_tables[] =
688{
689 ADD_TABLE(ci2_component),
691 ADD_TABLE(lus_feature),
692 ADD_TABLE(ci2_feature_comp),
693 ADD_TABLE(ci2_file),
694 ADD_TABLE(install_exec_seq),
695 ADD_TABLE(lus0_media),
696 ADD_TABLE(ci2_property),
697};
698
699static const msi_table cl_tables[] =
700{
701 ADD_TABLE(component),
704 ADD_TABLE(feature_comp),
706 ADD_TABLE(cl_custom_action),
707 ADD_TABLE(cl_install_exec_seq),
710};
711
713{
714 UINT res;
716
717 /* build summary info */
719 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
720
722 "Installation Database");
723 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
724
726 "Installation Database");
727 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
728
730 "Wine Hackers");
731 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
732
734 ";1033");
735 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
736
738 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
739 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
740
742 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
743
745 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
746
748 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
749
751 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
752
753 return res;
754}
755
757{
758 MSIHANDLE hdb = 0;
759 CHAR query[MAX_PATH + 72];
760 UINT res;
761
763
764 /* create an empty database */
766 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
767 if (res != ERROR_SUCCESS)
768 return hdb;
769
770 res = MsiDatabaseCommit(hdb);
771 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
772
773 set_summary_info(hdb, prodcode);
774
775 res = run_query(hdb, 0,
776 "CREATE TABLE `Directory` ( "
777 "`Directory` CHAR(255) NOT NULL, "
778 "`Directory_Parent` CHAR(255), "
779 "`DefaultDir` CHAR(255) NOT NULL "
780 "PRIMARY KEY `Directory`)");
781 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
782
783 res = run_query(hdb, 0,
784 "CREATE TABLE `Property` ( "
785 "`Property` CHAR(72) NOT NULL, "
786 "`Value` CHAR(255) "
787 "PRIMARY KEY `Property`)");
788 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
789
790 sprintf(query, "INSERT INTO `Property` "
791 "(`Property`, `Value`) "
792 "VALUES( 'ProductCode', '%s' )", prodcode);
793 res = run_query(hdb, 0, query);
794 ok(res == ERROR_SUCCESS , "Failed\n");
795
796 res = MsiDatabaseCommit(hdb);
797 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
798
799 return hdb;
800}
801
802static void test_usefeature(void)
803{
805
807 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
808
809 r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
810 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
811
813 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
814
815 r = MsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
816 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
817
818 r = MsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
819 NULL, -2, 0 );
820 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
821
822 r = MsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
823 "WORDVIEWFiles", -2, 0 );
824 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
825
826 r = MsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
827 "WORDVIEWFiles", -2, 0 );
828 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
829
830 r = MsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
831 "WORDVIEWFiles", -2, 1 );
832 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
833}
834
835static void test_null(void)
836{
837 MSIHANDLE hpkg;
838 UINT r;
839 HKEY hkey;
840 DWORD dwType, cbData;
841 LPBYTE lpData = NULL;
844
845 if (is_wow64)
847
848 r = MsiOpenPackageExW(NULL, 0, &hpkg);
849 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
850
852 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
853
855 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
856
858 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
859
860 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
861 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
862
863 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
864 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
865
866 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
867 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
868
869 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
870 * necessary registry values */
871
872 /* empty product string */
873 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
874 if (r == ERROR_ACCESS_DENIED)
875 {
876 skip("Not enough rights to perform tests\n");
877 return;
878 }
879 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
880
881 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
882 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
883 if ( r == ERROR_SUCCESS )
884 {
885 if (!(lpData = malloc(cbData))) skip("Out of memory\n");
886 else
887 {
888 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
889 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
890 }
891 }
892
893 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
894 if (r == ERROR_ACCESS_DENIED)
895 {
896 skip("Not enough rights to perform tests\n");
897 free(lpData);
898 RegCloseKey(hkey);
899 return;
900 }
901 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
902
903 r = MsiGetProductInfoA("", "", NULL, NULL);
904 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
905
906 if (lpData)
907 {
908 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
909 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
910 free(lpData);
911 }
912 else
913 {
914 r = RegDeleteValueA(hkey, NULL);
915 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
916 }
917
918 r = RegCloseKey(hkey);
919 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
920
921 /* empty attribute */
922 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
923 0, NULL, 0, access, NULL, &hkey, NULL);
924 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
925
926 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
927 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
928
929 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
930 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
931
932 r = RegCloseKey(hkey);
933 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
934
935 r = RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
937 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
938}
939
940static void test_getcomponentpath(void)
941{
943 char buffer[0x100];
944 DWORD sz;
945
947 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
948
949 r = MsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
950 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
951
952 r = MsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
953 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
954
955 sz = sizeof buffer;
956 buffer[0]=0;
957 r = MsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
958 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
959
960 r = MsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
961 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
962 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
963
964 r = MsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
965 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
966 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
967
968 r = MsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
969 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
970 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
971
972 r = MsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
973 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
974 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
975}
976
977static void create_test_files(void)
978{
979 CreateDirectoryA("msitest", NULL);
980 create_file("msitest\\one.txt", 100);
981 CreateDirectoryA("msitest\\first", NULL);
982 create_file("msitest\\first\\two.txt", 100);
983 CreateDirectoryA("msitest\\second", NULL);
984 create_file("msitest\\second\\three.txt", 100);
985
986 create_file("four.txt", 100);
987 create_file("five.txt", 100);
988 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
989
990 create_file("msitest\\filename", 100);
991 create_file("msitest\\service.exe", 100);
992
993 DeleteFileA("four.txt");
994 DeleteFileA("five.txt");
995}
996
997static void delete_test_files(void)
998{
999 DeleteFileA("msitest.msi");
1000 DeleteFileA("msitest.cab");
1001 DeleteFileA("msitest\\second\\three.txt");
1002 DeleteFileA("msitest\\first\\two.txt");
1003 DeleteFileA("msitest\\one.txt");
1004 DeleteFileA("msitest\\service.exe");
1005 DeleteFileA("msitest\\filename");
1006 RemoveDirectoryA("msitest\\second");
1007 RemoveDirectoryA("msitest\\first");
1008 RemoveDirectoryA("msitest");
1009}
1010
1011#define HASHSIZE sizeof(MSIFILEHASHINFO)
1012
1013static const struct
1014{
1018} hash_data[] =
1019{
1020 { "", 0,
1021 { HASHSIZE,
1022 { 0, 0, 0, 0 },
1023 },
1024 },
1025
1026 { "abc", 0,
1027 { HASHSIZE,
1028 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1029 },
1030 },
1031
1032 { "C:\\Program Files\\msitest\\caesar\n", 0,
1033 { HASHSIZE,
1034 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1035 },
1036 },
1037
1038 { "C:\\Program Files\\msitest\\caesar\n", 500,
1039 { HASHSIZE,
1040 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1041 },
1042 },
1044
1045static void test_MsiGetFileHash(void)
1046{
1047 const char name[] = "msitest.bin";
1048 UINT r;
1050 DWORD i;
1051
1052 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1053
1054 /* szFilePath is NULL */
1055 r = MsiGetFileHashA(NULL, 0, &hash);
1056 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1057
1058 /* szFilePath is empty */
1059 r = MsiGetFileHashA("", 0, &hash);
1061 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1062
1063 /* szFilePath is nonexistent */
1064 r = MsiGetFileHashA(name, 0, &hash);
1065 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1066
1067 /* dwOptions is non-zero */
1068 r = MsiGetFileHashA(name, 1, &hash);
1069 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1070
1071 /* pHash.dwFileHashInfoSize is not correct */
1072 hash.dwFileHashInfoSize = 0;
1073 r = MsiGetFileHashA(name, 0, &hash);
1074 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1075
1076 /* pHash is NULL */
1077 r = MsiGetFileHashA(name, 0, NULL);
1078 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1079
1080 for (i = 0; i < ARRAY_SIZE(hash_data); i++)
1081 {
1082 int ret;
1083
1085
1086 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1087 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1088
1089 r = MsiGetFileHashA(name, 0, &hash);
1090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1091
1093 ok(!ret, "Hash incorrect\n");
1094
1096 }
1097}
1098
1099/* copied from dlls/msi/registry.c */
1101{
1102 DWORD i,n=1;
1103 GUID guid;
1104
1105 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1106 return FALSE;
1107
1108 for(i=0; i<8; i++)
1109 out[7-i] = in[n++];
1110 n++;
1111 for(i=0; i<4; i++)
1112 out[11-i] = in[n++];
1113 n++;
1114 for(i=0; i<4; i++)
1115 out[15-i] = in[n++];
1116 n++;
1117 for(i=0; i<2; i++)
1118 {
1119 out[17+i*2] = in[n++];
1120 out[16+i*2] = in[n++];
1121 }
1122 n++;
1123 for( ; i<8; i++)
1124 {
1125 out[17+i*2] = in[n++];
1126 out[16+i*2] = in[n++];
1127 }
1128 out[32]=0;
1129 return TRUE;
1130}
1131
1132static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1133{
1134 WCHAR guidW[GUID_SIZE];
1135 WCHAR squashedW[SQUASHED_GUID_SIZE];
1136 GUID guid;
1137 HRESULT hr;
1138 int size;
1139
1140 hr = CoCreateGuid(&guid);
1141 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
1142
1143 size = StringFromGUID2(&guid, guidW, ARRAY_SIZE(guidW));
1144 ok(size == GUID_SIZE, "Expected %d, got %d.\n", GUID_SIZE, size);
1145
1146 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, GUID_SIZE, NULL, NULL);
1147 if (squashed)
1148 {
1149 squash_guid(guidW, squashedW);
1150 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, SQUASHED_GUID_SIZE, NULL, NULL);
1151 }
1152}
1153
1154static char *get_user_sid(void)
1155{
1156 HANDLE token;
1157 DWORD size = 0;
1159 char *usersid = NULL;
1160
1163
1164 user = malloc(size);
1166 ConvertSidToStringSidA(user->User.Sid, &usersid);
1167 free(user);
1168
1170 return usersid;
1171}
1172
1174{
1175 CHAR prodcode[MAX_PATH];
1176 CHAR prod_squashed[MAX_PATH];
1177 CHAR keypath[MAX_PATH*2];
1178 LPSTR usersid;
1180 LONG res;
1181 HKEY userkey, localkey, props;
1182 HKEY prodkey;
1183 DWORD data, error;
1185
1186 create_test_guid(prodcode, prod_squashed);
1187 usersid = get_user_sid();
1188
1189 if (is_wow64)
1191
1192 /* NULL prodcode */
1193 SetLastError(0xdeadbeef);
1195 error = GetLastError();
1196 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1197 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1198
1199 /* empty prodcode */
1200 SetLastError(0xdeadbeef);
1202 error = GetLastError();
1203 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1204 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1205
1206 /* garbage prodcode */
1207 SetLastError(0xdeadbeef);
1208 state = MsiQueryProductStateA("garbage");
1209 error = GetLastError();
1210 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1211 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1212
1213 /* guid without brackets */
1214 SetLastError(0xdeadbeef);
1215 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1216 error = GetLastError();
1217 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1218 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1219
1220 /* guid with brackets */
1221 SetLastError(0xdeadbeef);
1222 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1223 error = GetLastError();
1224 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1225 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1226
1227 /* same length as guid, but random */
1228 SetLastError(0xdeadbeef);
1229 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1230 error = GetLastError();
1231 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1232 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1233
1234 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1235
1236 SetLastError(0xdeadbeef);
1237 state = MsiQueryProductStateA(prodcode);
1238 error = GetLastError();
1239 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1240 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1241
1242 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1243 lstrcatA(keypath, prod_squashed);
1244
1245 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1247
1248 /* user product key exists */
1249 SetLastError(0xdeadbeef);
1250 state = MsiQueryProductStateA(prodcode);
1251 error = GetLastError();
1252 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1253 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1254
1255 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1256 lstrcatA(keypath, prodcode);
1257
1258 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1259 if (res == ERROR_ACCESS_DENIED)
1260 {
1261 skip("Not enough rights to perform tests\n");
1262 RegDeleteKeyA(userkey, "");
1263 RegCloseKey(userkey);
1264 LocalFree(usersid);
1265 return;
1266 }
1267 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1268
1269 /* local uninstall key exists */
1270 SetLastError(0xdeadbeef);
1271 state = MsiQueryProductStateA(prodcode);
1272 error = GetLastError();
1273 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1274 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1275
1276 data = 1;
1277 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1279
1280 /* WindowsInstaller value exists */
1281 SetLastError(0xdeadbeef);
1282 state = MsiQueryProductStateA(prodcode);
1283 error = GetLastError();
1284 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1285 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1286
1287 RegDeleteValueA(localkey, "WindowsInstaller");
1288 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
1289
1290 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1291 lstrcatA(keypath, usersid);
1292 lstrcatA(keypath, "\\Products\\");
1293 lstrcatA(keypath, prod_squashed);
1294
1295 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1296 if (res == ERROR_ACCESS_DENIED)
1297 {
1298 skip("Not enough rights to perform tests\n");
1299 RegDeleteKeyA(userkey, "");
1300 RegCloseKey(userkey);
1301 LocalFree(usersid);
1302 return;
1303 }
1304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1305
1306 /* local product key exists */
1307 SetLastError(0xdeadbeef);
1308 state = MsiQueryProductStateA(prodcode);
1309 error = GetLastError();
1310 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1311 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1312
1313 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1315
1316 /* install properties key exists */
1317 SetLastError(0xdeadbeef);
1318 state = MsiQueryProductStateA(prodcode);
1319 error = GetLastError();
1320 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1321 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1322
1323 data = 1;
1324 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1326
1327 /* WindowsInstaller value exists */
1328 SetLastError(0xdeadbeef);
1329 state = MsiQueryProductStateA(prodcode);
1330 error = GetLastError();
1331 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1332 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1333
1334 data = 2;
1335 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1336 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1337
1338 /* WindowsInstaller value is not 1 */
1339 SetLastError(0xdeadbeef);
1340 state = MsiQueryProductStateA(prodcode);
1341 error = GetLastError();
1342 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1343 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1344
1345 RegDeleteKeyA(userkey, "");
1346
1347 /* user product key does not exist */
1348 SetLastError(0xdeadbeef);
1349 state = MsiQueryProductStateA(prodcode);
1350 error = GetLastError();
1351 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1352 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1353
1354 RegDeleteValueA(props, "WindowsInstaller");
1357 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
1358 RegCloseKey(localkey);
1359 RegDeleteKeyA(userkey, "");
1360 RegCloseKey(userkey);
1361
1362 /* MSIINSTALLCONTEXT_USERMANAGED */
1363
1364 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1365 lstrcatA(keypath, usersid);
1366 lstrcatA(keypath, "\\Installer\\Products\\");
1367 lstrcatA(keypath, prod_squashed);
1368
1369 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1370 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1371
1372 state = MsiQueryProductStateA(prodcode);
1374 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1375
1376 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1377 lstrcatA(keypath, usersid);
1378 lstrcatA(keypath, "\\Products\\");
1379 lstrcatA(keypath, prod_squashed);
1380
1381 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1382 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1383
1384 state = MsiQueryProductStateA(prodcode);
1386 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1387
1388 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1390
1391 state = MsiQueryProductStateA(prodcode);
1393 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1394
1395 data = 1;
1396 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1397 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1398
1399 /* WindowsInstaller value exists */
1400 state = MsiQueryProductStateA(prodcode);
1401 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1402
1403 RegDeleteValueA(props, "WindowsInstaller");
1406 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
1407 RegCloseKey(localkey);
1408 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
1409 RegCloseKey(prodkey);
1410
1411 /* MSIINSTALLCONTEXT_MACHINE */
1412
1413 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1414 lstrcatA(keypath, prod_squashed);
1415
1416 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1417 if (res == ERROR_ACCESS_DENIED)
1418 {
1419 skip( "insufficient rights\n" );
1420 LocalFree( usersid );
1421 return;
1422 }
1423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1424
1425 state = MsiQueryProductStateA(prodcode);
1426 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1427
1428 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1429 lstrcatA(keypath, "S-1-5-18\\Products\\");
1430 lstrcatA(keypath, prod_squashed);
1431
1432 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1434
1435 state = MsiQueryProductStateA(prodcode);
1437 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1438
1439 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1441
1442 state = MsiQueryProductStateA(prodcode);
1444 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1445
1446 data = 1;
1447 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1449
1450 /* WindowsInstaller value exists */
1451 state = MsiQueryProductStateA(prodcode);
1452 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1453
1454 RegDeleteValueA(props, "WindowsInstaller");
1457 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
1458 RegCloseKey(localkey);
1459 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
1460 RegCloseKey(prodkey);
1461
1462 LocalFree(usersid);
1463}
1464
1465static const char table_enc85[] =
1466"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1467"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1468"yz{}~";
1469
1470/*
1471 * Encodes a base85 guid given a GUID pointer
1472 * Caller should provide a 21 character buffer for the encoded string.
1473 */
1475{
1476 unsigned int x, *p, i;
1477
1478 p = (unsigned int*) guid;
1479 for( i=0; i<4; i++ )
1480 {
1481 x = p[i];
1482 *str++ = table_enc85[x%85];
1483 x = x/85;
1484 *str++ = table_enc85[x%85];
1485 x = x/85;
1486 *str++ = table_enc85[x%85];
1487 x = x/85;
1488 *str++ = table_enc85[x%85];
1489 x = x/85;
1490 *str++ = table_enc85[x%85];
1491 }
1492 *str = 0;
1493}
1494
1495static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1496{
1497 WCHAR guidW[MAX_PATH];
1498 WCHAR base85W[MAX_PATH];
1499 WCHAR squashedW[MAX_PATH];
1500 GUID guid;
1501 HRESULT hr;
1502 int size;
1503
1504 hr = CoCreateGuid(&guid);
1505 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
1506
1507 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1508 ok(size == 39, "Expected 39, got %d\n", size);
1509
1510 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1511 encode_base85_guid(&guid, base85W);
1512 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1513 squash_guid(guidW, squashedW);
1514 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1515}
1516
1518{
1519 HKEY userkey, localkey, compkey, compkey2;
1520 CHAR prodcode[MAX_PATH];
1521 CHAR prod_squashed[MAX_PATH];
1522 CHAR component[MAX_PATH];
1523 CHAR comp_base85[MAX_PATH];
1524 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
1525 CHAR keypath[MAX_PATH*2];
1527 LPSTR usersid;
1528 LONG res;
1530 DWORD error;
1531
1532 create_test_guid(prodcode, prod_squashed);
1533 compose_base85_guid(component, comp_base85, comp_squashed);
1534 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
1535 usersid = get_user_sid();
1536
1537 if (is_wow64)
1539
1540 /* NULL prodcode */
1541 SetLastError(0xdeadbeef);
1542 state = MsiQueryFeatureStateA(NULL, "feature");
1543 error = GetLastError();
1544 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1545 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1546
1547 /* empty prodcode */
1548 SetLastError(0xdeadbeef);
1549 state = MsiQueryFeatureStateA("", "feature");
1550 error = GetLastError();
1551 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1552 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1553
1554 /* garbage prodcode */
1555 SetLastError(0xdeadbeef);
1556 state = MsiQueryFeatureStateA("garbage", "feature");
1557 error = GetLastError();
1558 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1559 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1560
1561 /* guid without brackets */
1562 SetLastError(0xdeadbeef);
1563 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
1564 error = GetLastError();
1565 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1566 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1567
1568 /* guid with brackets */
1569 SetLastError(0xdeadbeef);
1570 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
1571 error = GetLastError();
1572 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1573 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1574
1575 /* same length as guid, but random */
1576 SetLastError(0xdeadbeef);
1577 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
1578 error = GetLastError();
1579 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1580 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1581
1582 /* NULL szFeature */
1583 SetLastError(0xdeadbeef);
1584 state = MsiQueryFeatureStateA(prodcode, NULL);
1585 error = GetLastError();
1586 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1587 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
1588
1589 /* empty szFeature */
1590 SetLastError(0xdeadbeef);
1591 state = MsiQueryFeatureStateA(prodcode, "");
1592 error = GetLastError();
1593 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1594 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1595
1596 /* feature key does not exist yet */
1597 SetLastError(0xdeadbeef);
1598 state = MsiQueryFeatureStateA(prodcode, "feature");
1599 error = GetLastError();
1600 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1601 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1602
1603 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1604
1605 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
1606 lstrcatA(keypath, prod_squashed);
1607
1608 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1609 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1610
1611 /* feature key exists */
1612 SetLastError(0xdeadbeef);
1613 state = MsiQueryFeatureStateA(prodcode, "feature");
1614 error = GetLastError();
1615 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1616 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1617
1618 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1619 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1620
1621 /* feature value exists */
1622 SetLastError(0xdeadbeef);
1623 state = MsiQueryFeatureStateA(prodcode, "feature");
1624 error = GetLastError();
1625 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1626 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1627
1628 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1629 lstrcatA(keypath, usersid);
1630 lstrcatA(keypath, "\\Products\\");
1631 lstrcatA(keypath, prod_squashed);
1632 lstrcatA(keypath, "\\Features");
1633
1634 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1635 if (res == ERROR_ACCESS_DENIED)
1636 {
1637 skip("Not enough rights to perform tests\n");
1638 RegDeleteKeyA(userkey, "");
1639 RegCloseKey(userkey);
1640 LocalFree(usersid);
1641 return;
1642 }
1643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1644
1645 /* userdata features key exists */
1646 SetLastError(0xdeadbeef);
1647 state = MsiQueryFeatureStateA(prodcode, "feature");
1648 error = GetLastError();
1649 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1650 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1651
1652 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1653 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1654
1655 SetLastError(0xdeadbeef);
1656 state = MsiQueryFeatureStateA(prodcode, "feature");
1657 error = GetLastError();
1658 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1659 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1660
1661 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1662 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1663
1664 SetLastError(0xdeadbeef);
1665 state = MsiQueryFeatureStateA(prodcode, "feature");
1666 error = GetLastError();
1667 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1668 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1669
1670 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1672
1673 SetLastError(0xdeadbeef);
1674 state = MsiQueryFeatureStateA(prodcode, "feature");
1675 error = GetLastError();
1676 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1677 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1678
1679 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1680 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1681
1682 SetLastError(0xdeadbeef);
1683 state = MsiQueryFeatureStateA(prodcode, "feature");
1684 error = GetLastError();
1685 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1686 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1687
1688 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1689 lstrcatA(keypath, usersid);
1690 lstrcatA(keypath, "\\Components\\");
1691 lstrcatA(keypath, comp_squashed);
1692
1693 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1695
1696 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1697 lstrcatA(keypath, usersid);
1698 lstrcatA(keypath, "\\Components\\");
1699 lstrcatA(keypath, comp_squashed2);
1700
1701 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1702 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1703
1704 SetLastError(0xdeadbeef);
1705 state = MsiQueryFeatureStateA(prodcode, "feature");
1706 error = GetLastError();
1707 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1708 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1709
1710 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1711 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1712
1713 SetLastError(0xdeadbeef);
1714 state = MsiQueryFeatureStateA(prodcode, "feature");
1715 error = GetLastError();
1716 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1717 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1718
1719 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1721
1722 SetLastError(0xdeadbeef);
1723 state = MsiQueryFeatureStateA(prodcode, "feature");
1724 error = GetLastError();
1725 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1726 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1727
1728 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1729 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1730
1731 /* INSTALLSTATE_LOCAL */
1732 SetLastError(0xdeadbeef);
1733 state = MsiQueryFeatureStateA(prodcode, "feature");
1734 error = GetLastError();
1735 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1736 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1737
1738 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1739 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1740
1741 /* INSTALLSTATE_SOURCE */
1742 SetLastError(0xdeadbeef);
1743 state = MsiQueryFeatureStateA(prodcode, "feature");
1744 error = GetLastError();
1745 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1746 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1747
1748 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1749 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1750
1751 /* bad INSTALLSTATE_SOURCE */
1752 SetLastError(0xdeadbeef);
1753 state = MsiQueryFeatureStateA(prodcode, "feature");
1754 error = GetLastError();
1755 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1756 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1757
1758 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1760
1761 /* INSTALLSTATE_SOURCE */
1762 SetLastError(0xdeadbeef);
1763 state = MsiQueryFeatureStateA(prodcode, "feature");
1764 error = GetLastError();
1765 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1766 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1767
1768 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1770
1771 /* bad INSTALLSTATE_SOURCE */
1772 SetLastError(0xdeadbeef);
1773 state = MsiQueryFeatureStateA(prodcode, "feature");
1774 error = GetLastError();
1775 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1776 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", error);
1777
1778 RegDeleteValueA(compkey, prod_squashed);
1779 RegDeleteValueA(compkey2, prod_squashed);
1780 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
1781 RegDeleteKeyExA(compkey2, "", access & KEY_WOW64_64KEY, 0);
1782 RegDeleteValueA(localkey, "feature");
1783 RegDeleteValueA(userkey, "feature");
1784 RegDeleteKeyA(userkey, "");
1785 RegCloseKey(compkey);
1786 RegCloseKey(compkey2);
1787 RegCloseKey(localkey);
1788 RegCloseKey(userkey);
1789
1790 /* MSIINSTALLCONTEXT_USERMANAGED */
1791
1792 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1793 lstrcatA(keypath, usersid);
1794 lstrcatA(keypath, "\\Installer\\Features\\");
1795 lstrcatA(keypath, prod_squashed);
1796
1797 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1799
1800 /* feature key exists */
1801 state = MsiQueryFeatureStateA(prodcode, "feature");
1802 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1803
1804 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1805 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1806
1807 /* feature value exists */
1808 state = MsiQueryFeatureStateA(prodcode, "feature");
1809 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1810
1811 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1812 lstrcatA(keypath, usersid);
1813 lstrcatA(keypath, "\\Products\\");
1814 lstrcatA(keypath, prod_squashed);
1815 lstrcatA(keypath, "\\Features");
1816
1817 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1819
1820 /* userdata features key exists */
1821 state = MsiQueryFeatureStateA(prodcode, "feature");
1822 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1823
1824 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1825 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1826
1827 state = MsiQueryFeatureStateA(prodcode, "feature");
1828 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1829
1830 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1832
1833 state = MsiQueryFeatureStateA(prodcode, "feature");
1834 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1835
1836 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1838
1839 state = MsiQueryFeatureStateA(prodcode, "feature");
1840 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1841
1842 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1843 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1844
1845 state = MsiQueryFeatureStateA(prodcode, "feature");
1846 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1847
1848 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1849 lstrcatA(keypath, usersid);
1850 lstrcatA(keypath, "\\Components\\");
1851 lstrcatA(keypath, comp_squashed);
1852
1853 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1854 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1855
1856 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1857 lstrcatA(keypath, usersid);
1858 lstrcatA(keypath, "\\Components\\");
1859 lstrcatA(keypath, comp_squashed2);
1860
1861 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1862 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1863
1864 state = MsiQueryFeatureStateA(prodcode, "feature");
1865 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1866
1867 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1869
1870 state = MsiQueryFeatureStateA(prodcode, "feature");
1871 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1872
1873 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1875
1876 state = MsiQueryFeatureStateA(prodcode, "feature");
1877 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1878
1879 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1880 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1881
1882 state = MsiQueryFeatureStateA(prodcode, "feature");
1883 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1884
1885 RegDeleteValueA(compkey, prod_squashed);
1886 RegDeleteValueA(compkey2, prod_squashed);
1887 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
1888 RegDeleteKeyExA(compkey2, "", access & KEY_WOW64_64KEY, 0);
1889 RegDeleteValueA(localkey, "feature");
1890 RegDeleteValueA(userkey, "feature");
1891 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
1892 RegCloseKey(compkey);
1893 RegCloseKey(compkey2);
1894 RegCloseKey(localkey);
1895 RegCloseKey(userkey);
1896
1897 /* MSIINSTALLCONTEXT_MACHINE */
1898
1899 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1900 lstrcatA(keypath, prod_squashed);
1901
1902 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1903 if (res == ERROR_ACCESS_DENIED)
1904 {
1905 skip( "insufficient rights\n" );
1906 LocalFree( usersid );
1907 return;
1908 }
1909 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1910
1911 /* feature key exists */
1912 state = MsiQueryFeatureStateA(prodcode, "feature");
1913 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1914
1915 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1916 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1917
1918 /* feature value exists */
1919 state = MsiQueryFeatureStateA(prodcode, "feature");
1920 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1921
1922 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1923 lstrcatA(keypath, "S-1-5-18\\Products\\");
1924 lstrcatA(keypath, prod_squashed);
1925 lstrcatA(keypath, "\\Features");
1926
1927 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1929
1930 /* userdata features key exists */
1931 state = MsiQueryFeatureStateA(prodcode, "feature");
1932 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1933
1934 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1935 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1936
1937 state = MsiQueryFeatureStateA(prodcode, "feature");
1938 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1939
1940 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1941 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1942
1943 state = MsiQueryFeatureStateA(prodcode, "feature");
1944 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1945
1946 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1948
1949 state = MsiQueryFeatureStateA(prodcode, "feature");
1950 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1951
1952 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1953 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1954
1955 state = MsiQueryFeatureStateA(prodcode, "feature");
1956 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1957
1958 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1959 lstrcatA(keypath, "S-1-5-18\\Components\\");
1960 lstrcatA(keypath, comp_squashed);
1961
1962 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1963 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1964
1965 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1966 lstrcatA(keypath, "S-1-5-18\\Components\\");
1967 lstrcatA(keypath, comp_squashed2);
1968
1969 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1971
1972 state = MsiQueryFeatureStateA(prodcode, "feature");
1973 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1974
1975 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1977
1978 state = MsiQueryFeatureStateA(prodcode, "feature");
1979 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1980
1981 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1982 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1983
1984 state = MsiQueryFeatureStateA(prodcode, "feature");
1985 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1986
1987 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1988 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1989
1990 state = MsiQueryFeatureStateA(prodcode, "feature");
1991 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1992
1993 RegDeleteValueA(compkey, prod_squashed);
1994 RegDeleteValueA(compkey2, prod_squashed);
1995 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
1996 RegDeleteKeyExA(compkey2, "", access & KEY_WOW64_64KEY, 0);
1997 RegDeleteValueA(localkey, "feature");
1998 RegDeleteValueA(userkey, "feature");
1999 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
2000 RegCloseKey(compkey);
2001 RegCloseKey(compkey2);
2002 RegCloseKey(localkey);
2003 RegCloseKey(userkey);
2004 LocalFree(usersid);
2005}
2006
2008{
2009 HKEY compkey, prodkey;
2010 CHAR prodcode[MAX_PATH];
2011 CHAR prod_squashed[MAX_PATH];
2012 CHAR component[MAX_PATH];
2013 CHAR comp_base85[MAX_PATH];
2014 CHAR comp_squashed[MAX_PATH];
2015 CHAR keypath[MAX_PATH];
2017 LPSTR usersid;
2018 LONG res;
2019 UINT r;
2021 DWORD error;
2022
2023 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2024
2025 create_test_guid(prodcode, prod_squashed);
2026 compose_base85_guid(component, comp_base85, comp_squashed);
2027 usersid = get_user_sid();
2028
2029 if (is_wow64)
2031
2032 /* NULL szProductCode */
2033 state = MAGIC_ERROR;
2034 SetLastError(0xdeadbeef);
2036 error = GetLastError();
2037 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2038 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2039 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2040
2041 /* empty szProductCode */
2042 state = MAGIC_ERROR;
2043 SetLastError(0xdeadbeef);
2045 error = GetLastError();
2046 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2047 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2048 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2049
2050 /* random szProductCode */
2051 state = MAGIC_ERROR;
2052 SetLastError(0xdeadbeef);
2054 error = GetLastError();
2055 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2056 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2057 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2058
2059 /* GUID-length szProductCode */
2060 state = MAGIC_ERROR;
2061 SetLastError(0xdeadbeef);
2062 r = MsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2063 error = GetLastError();
2064 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2065 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2066 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2067
2068 /* GUID-length with brackets */
2069 state = MAGIC_ERROR;
2070 SetLastError(0xdeadbeef);
2071 r = MsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2072 error = GetLastError();
2073 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2074 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2075 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2076
2077 /* actual GUID */
2078 state = MAGIC_ERROR;
2079 SetLastError(0xdeadbeef);
2081 error = GetLastError();
2082 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2083 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2084 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2085
2086 state = MAGIC_ERROR;
2087 SetLastError(0xdeadbeef);
2089 error = GetLastError();
2090 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2091 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2092 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2093
2094 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2095 lstrcatA(keypath, prod_squashed);
2096
2097 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2098 if (res == ERROR_ACCESS_DENIED)
2099 {
2100 skip("Not enough rights to perform tests\n");
2101 LocalFree(usersid);
2102 return;
2103 }
2104 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2105
2106 state = MAGIC_ERROR;
2107 SetLastError(0xdeadbeef);
2109 error = GetLastError();
2110 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2111 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2112 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2113
2114 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2115 RegCloseKey(prodkey);
2116
2117 /* create local system product key */
2118 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2119 lstrcatA(keypath, prod_squashed);
2120 lstrcatA(keypath, "\\InstallProperties");
2121
2122 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2123 if (res == ERROR_ACCESS_DENIED)
2124 {
2125 skip("Not enough rights to perform tests\n");
2126 LocalFree(usersid);
2127 return;
2128 }
2129 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2130
2131 /* local system product key exists */
2132 state = MAGIC_ERROR;
2134 error = GetLastError();
2135 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2136 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2137 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2138
2139 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2140 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2141
2142 /* LocalPackage value exists */
2143 state = MAGIC_ERROR;
2144 SetLastError(0xdeadbeef);
2146 error = GetLastError();
2147 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2148 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2149 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2150
2151 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2152 lstrcatA(keypath, comp_squashed);
2153
2154 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2155 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2156
2157 /* component key exists */
2158 state = MAGIC_ERROR;
2159 SetLastError(0xdeadbeef);
2161 error = GetLastError();
2162 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2163 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2164 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2165
2166 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2168
2169 /* component\product exists */
2170 state = MAGIC_ERROR;
2171 SetLastError(0xdeadbeef);
2173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2174 error = GetLastError();
2176 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2177 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2178
2179 /* NULL component, product exists */
2180 state = MAGIC_ERROR;
2181 SetLastError(0xdeadbeef);
2183 error = GetLastError();
2184 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2185 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2186 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2187
2188 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2190
2191 /* INSTALLSTATE_LOCAL */
2192 state = MAGIC_ERROR;
2193 SetLastError(0xdeadbeef);
2195 error = GetLastError();
2196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2197 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2198 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2199
2200 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2201 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2202
2203 /* INSTALLSTATE_SOURCE */
2204 state = MAGIC_ERROR;
2205 SetLastError(0xdeadbeef);
2207 error = GetLastError();
2208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2209 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2210 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2211
2212 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2213 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2214
2215 /* bad INSTALLSTATE_SOURCE */
2216 state = MAGIC_ERROR;
2217 SetLastError(0xdeadbeef);
2219 error = GetLastError();
2220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2221 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2222 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2223
2224 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2226
2227 /* INSTALLSTATE_SOURCE */
2228 state = MAGIC_ERROR;
2229 SetLastError(0xdeadbeef);
2231 error = GetLastError();
2232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2233 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2234 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2235
2236 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2238
2239 /* registry component */
2240 state = MAGIC_ERROR;
2241 SetLastError(0xdeadbeef);
2243 error = GetLastError();
2244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2245 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2246 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", error);
2247
2248 RegDeleteValueA(prodkey, "LocalPackage");
2249 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2250 RegDeleteValueA(compkey, prod_squashed);
2251 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2252 RegCloseKey(prodkey);
2253 RegCloseKey(compkey);
2254
2255 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2256
2257 state = MAGIC_ERROR;
2259 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2260 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2261
2262 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2263 lstrcatA(keypath, prod_squashed);
2264
2265 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2267
2268 state = MAGIC_ERROR;
2270 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2271 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2272
2273 RegDeleteKeyA(prodkey, "");
2274 RegCloseKey(prodkey);
2275
2276 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2277 lstrcatA(keypath, usersid);
2278 lstrcatA(keypath, "\\Products\\");
2279 lstrcatA(keypath, prod_squashed);
2280 lstrcatA(keypath, "\\InstallProperties");
2281
2282 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2283 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2284
2285 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2286 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2287
2288 RegCloseKey(prodkey);
2289
2290 state = MAGIC_ERROR;
2292 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2293 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2294
2295 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2296 lstrcatA(keypath, usersid);
2297 lstrcatA(keypath, "\\Components\\");
2298 lstrcatA(keypath, comp_squashed);
2299
2300 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2301 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2302
2303 /* component key exists */
2304 state = MAGIC_ERROR;
2306 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2307 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2308
2309 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2311
2312 /* component\product exists */
2313 state = MAGIC_ERROR;
2315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2317 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2318
2319 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2320 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2321
2322 state = MAGIC_ERROR;
2324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2325 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2326
2327 /* MSIINSTALLCONTEXT_USERMANAGED */
2328
2329 state = MAGIC_ERROR;
2331 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2332 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2333
2334 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2335 lstrcatA(keypath, prod_squashed);
2336
2337 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2338 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2339
2340 state = MAGIC_ERROR;
2342 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2343 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2344
2345 RegDeleteKeyA(prodkey, "");
2346 RegCloseKey(prodkey);
2347
2348 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2349 lstrcatA(keypath, usersid);
2350 lstrcatA(keypath, "\\Installer\\Products\\");
2351 lstrcatA(keypath, prod_squashed);
2352
2353 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2355
2356 state = MAGIC_ERROR;
2358 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2359 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2360
2361 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2362 RegCloseKey(prodkey);
2363
2364 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2365 lstrcatA(keypath, usersid);
2366 lstrcatA(keypath, "\\Products\\");
2367 lstrcatA(keypath, prod_squashed);
2368 lstrcatA(keypath, "\\InstallProperties");
2369
2370 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2372
2373 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2375
2376 state = MAGIC_ERROR;
2378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2379 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2380
2381 RegDeleteValueA(prodkey, "LocalPackage");
2382 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2383 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2384 RegDeleteValueA(compkey, prod_squashed);
2385 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2386 RegCloseKey(prodkey);
2387 RegCloseKey(compkey);
2388 LocalFree(usersid);
2389}
2390
2392{
2393 HKEY compkey, prodkey, installprop;
2394 CHAR prodcode[MAX_PATH];
2395 CHAR prod_squashed[MAX_PATH];
2396 CHAR component[MAX_PATH];
2397 CHAR comp_base85[MAX_PATH];
2398 CHAR comp_squashed[MAX_PATH];
2399 CHAR keypath[MAX_PATH];
2402 LPSTR usersid;
2403 DWORD size, val;
2405 LONG res;
2406
2407 create_test_guid(prodcode, prod_squashed);
2408 compose_base85_guid(component, comp_base85, comp_squashed);
2409 usersid = get_user_sid();
2410
2411 if (is_wow64)
2413
2414 /* NULL szProduct */
2415 size = MAX_PATH;
2416 state = MsiGetComponentPathA(NULL, component, path, &size);
2417 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2418 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2419
2420 /* NULL szComponent */
2421 size = MAX_PATH;
2422 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2423 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2424 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2425
2426 size = MAX_PATH;
2428 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2429 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2430
2431 /* NULL lpPathBuf */
2432 size = MAX_PATH;
2433 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2434 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2435 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2436
2437 size = MAX_PATH;
2438 state = MsiLocateComponentA(component, NULL, &size);
2439 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2440 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2441
2442 /* NULL pcchBuf */
2443 size = MAX_PATH;
2444 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2445 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2446 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2447
2448 size = MAX_PATH;
2449 state = MsiLocateComponentA(component, path, NULL);
2450 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2451 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2452
2453 /* all params valid */
2454 size = MAX_PATH;
2455 state = MsiGetComponentPathA(prodcode, component, path, &size);
2456 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2457 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2458
2459 size = MAX_PATH;
2460 state = MsiLocateComponentA(component, path, &size);
2461 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2462 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2463
2464 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2465 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2466 lstrcatA(keypath, comp_squashed);
2467
2468 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2469 if (res == ERROR_ACCESS_DENIED)
2470 {
2471 skip("Not enough rights to perform tests\n");
2472 LocalFree(usersid);
2473 return;
2474 }
2475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2476
2477 /* local system component key exists */
2478 size = MAX_PATH;
2479 state = MsiGetComponentPathA(prodcode, component, path, &size);
2480 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2481 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2482
2483 size = MAX_PATH;
2484 state = MsiLocateComponentA(component, path, &size);
2485 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2486 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2487
2488 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2489 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2490
2491 /* product value exists */
2492 path[0] = 0;
2493 size = MAX_PATH;
2494 state = MsiGetComponentPathA(prodcode, component, path, &size);
2495 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2496 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2497 ok(size == 10, "Expected 10, got %lu\n", size);
2498
2499 path[0] = 0;
2500 size = MAX_PATH;
2501 state = MsiLocateComponentA(component, path, &size);
2502 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2503 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2504 ok(size == 10, "Expected 10, got %lu\n", size);
2505
2506 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2507 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2508 lstrcatA(keypath, prod_squashed);
2509 lstrcatA(keypath, "\\InstallProperties");
2510
2511 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2512 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2513
2514 val = 1;
2515 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2517
2518 /* install properties key exists */
2519 path[0] = 0;
2520 size = MAX_PATH;
2521 state = MsiGetComponentPathA(prodcode, component, path, &size);
2522 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2523 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2524 ok(size == 10, "Expected 10, got %lu\n", size);
2525
2526 path[0] = 0;
2527 size = MAX_PATH;
2528 state = MsiLocateComponentA(component, path, &size);
2529 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2530 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2531 ok(size == 10, "Expected 10, got %lu\n", size);
2532
2533 create_file("C:\\imapath", 11);
2534
2535 /* file exists */
2536 path[0] = 'a';
2537 size = 0;
2538 state = MsiGetComponentPathA(prodcode, component, path, &size);
2539 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
2540 ok(path[0] == 'a', "got %s\n", path);
2541 ok(size == 10, "Expected 10, got %lu\n", size);
2542
2543 path[0] = 0;
2544 size = MAX_PATH;
2545 state = MsiGetComponentPathA(prodcode, component, path, &size);
2546 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2547 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2548 ok(size == 10, "Expected 10, got %lu\n", size);
2549
2550 size = 0;
2551 path[0] = 'a';
2552 state = MsiLocateComponentA(component, path, &size);
2553 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
2554 ok(path[0] == 'a', "got %s\n", path);
2555 ok(size == 10, "Expected 10, got %lu\n", size);
2556
2557 path[0] = 0;
2558 size = MAX_PATH;
2559 state = MsiLocateComponentA(component, path, &size);
2560 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2561 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2562 ok(size == 10, "Expected 10, got %lu\n", size);
2563
2564 RegDeleteValueA(compkey, prod_squashed);
2565 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2566 RegDeleteValueA(installprop, "WindowsInstaller");
2567 RegDeleteKeyExA(installprop, "", access & KEY_WOW64_64KEY, 0);
2568 RegCloseKey(compkey);
2569 RegCloseKey(installprop);
2570 DeleteFileA("C:\\imapath");
2571
2572 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2573 lstrcatA(keypath, "Installer\\UserData\\");
2574 lstrcatA(keypath, usersid);
2575 lstrcatA(keypath, "\\Components\\");
2576 lstrcatA(keypath, comp_squashed);
2577
2578 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2579 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2580
2581 /* user managed component key exists */
2582 size = MAX_PATH;
2583 state = MsiGetComponentPathA(prodcode, component, path, &size);
2584 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2585 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2586
2587 size = MAX_PATH;
2588 state = MsiLocateComponentA(component, path, &size);
2589 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2590 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2591
2592 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2593 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2594
2595 /* product value exists */
2596 path[0] = 0;
2597 size = MAX_PATH;
2598 state = MsiGetComponentPathA(prodcode, component, path, &size);
2599 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2600 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2601 ok(size == 10, "Expected 10, got %lu\n", size);
2602
2603 path[0] = 0;
2604 size = MAX_PATH;
2605 state = MsiLocateComponentA(component, path, &size);
2606 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2607 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2608 ok(size == 10, "Expected 10, got %lu\n", size);
2609
2610 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2611 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2612 lstrcatA(keypath, prod_squashed);
2613 lstrcatA(keypath, "\\InstallProperties");
2614
2615 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2617
2618 val = 1;
2619 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2620 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2621
2622 /* install properties key exists */
2623 path[0] = 0;
2624 size = MAX_PATH;
2625 state = MsiGetComponentPathA(prodcode, component, path, &size);
2626 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2627 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2628 ok(size == 10, "Expected 10, got %lu\n", size);
2629
2630 path[0] = 0;
2631 size = MAX_PATH;
2632 state = MsiLocateComponentA(component, path, &size);
2633 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2634 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2635 ok(size == 10, "Expected 10, got %lu\n", size);
2636
2637 create_file("C:\\imapath", 11);
2638
2639 /* file exists */
2640 path[0] = 0;
2641 size = MAX_PATH;
2642 state = MsiGetComponentPathA(prodcode, component, path, &size);
2643 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2644 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2645 ok(size == 10, "Expected 10, got %lu\n", size);
2646
2647 path[0] = 0;
2648 size = MAX_PATH;
2649 state = MsiLocateComponentA(component, path, &size);
2650 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2651 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2652 ok(size == 10, "Expected 10, got %lu\n", size);
2653
2654 RegDeleteValueA(compkey, prod_squashed);
2655 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2656 RegDeleteValueA(installprop, "WindowsInstaller");
2657 RegDeleteKeyExA(installprop, "", access & KEY_WOW64_64KEY, 0);
2658 RegCloseKey(compkey);
2659 RegCloseKey(installprop);
2660 DeleteFileA("C:\\imapath");
2661
2662 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2663 lstrcatA(keypath, "Installer\\Managed\\");
2664 lstrcatA(keypath, usersid);
2665 lstrcatA(keypath, "\\Installer\\Products\\");
2666 lstrcatA(keypath, prod_squashed);
2667
2668 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2670
2671 /* user managed product key exists */
2672 size = MAX_PATH;
2673 state = MsiGetComponentPathA(prodcode, component, path, &size);
2674 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2675 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2676
2677 size = MAX_PATH;
2678 state = MsiLocateComponentA(component, path, &size);
2679 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2680 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2681
2682 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2683 lstrcatA(keypath, "Installer\\UserData\\");
2684 lstrcatA(keypath, usersid);
2685 lstrcatA(keypath, "\\Components\\");
2686 lstrcatA(keypath, comp_squashed);
2687
2688 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2690
2691 /* user managed component key exists */
2692 size = MAX_PATH;
2693 state = MsiGetComponentPathA(prodcode, component, path, &size);
2694 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2695 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2696
2697 size = MAX_PATH;
2698 state = MsiLocateComponentA(component, path, &size);
2699 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2700 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2701
2702 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2703 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2704
2705 /* product value exists */
2706 path[0] = 0;
2707 size = MAX_PATH;
2708 state = MsiGetComponentPathA(prodcode, component, path, &size);
2709 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2710 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2711 ok(size == 10, "Expected 10, got %lu\n", size);
2712
2713 path[0] = 0;
2714 size = MAX_PATH;
2715 state = MsiLocateComponentA(component, path, &size);
2716 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2717 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2718 ok(size == 10, "Expected 10, got %lu\n", size);
2719
2720 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2721 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2722 lstrcatA(keypath, prod_squashed);
2723 lstrcatA(keypath, "\\InstallProperties");
2724
2725 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2726 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2727
2728 val = 1;
2729 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2731
2732 /* install properties key exists */
2733 path[0] = 0;
2734 size = MAX_PATH;
2735 state = MsiGetComponentPathA(prodcode, component, path, &size);
2736 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2737 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2738 ok(size == 10, "Expected 10, got %lu\n", size);
2739
2740 path[0] = 0;
2741 size = MAX_PATH;
2742 state = MsiLocateComponentA(component, path, &size);
2743 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2744 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2745 ok(size == 10, "Expected 10, got %lu\n", size);
2746
2747 create_file("C:\\imapath", 11);
2748
2749 /* file exists */
2750 path[0] = 0;
2751 size = MAX_PATH;
2752 state = MsiGetComponentPathA(prodcode, component, path, &size);
2753 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2754 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2755 ok(size == 10, "Expected 10, got %lu\n", size);
2756
2757 path[0] = 0;
2758 size = MAX_PATH;
2759 state = MsiLocateComponentA(component, path, &size);
2760 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2761 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2762 ok(size == 10, "Expected 10, got %lu\n", size);
2763
2764 RegDeleteValueA(compkey, prod_squashed);
2765 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2766 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2767 RegDeleteValueA(installprop, "WindowsInstaller");
2768 RegDeleteKeyExA(installprop, "", access & KEY_WOW64_64KEY, 0);
2769 RegCloseKey(prodkey);
2770 RegCloseKey(compkey);
2771 RegCloseKey(installprop);
2772 DeleteFileA("C:\\imapath");
2773
2774 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2775 lstrcatA(keypath, prod_squashed);
2776
2777 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2778 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2779
2780 /* user unmanaged product key exists */
2781 size = MAX_PATH;
2782 state = MsiGetComponentPathA(prodcode, component, path, &size);
2783 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2784 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2785
2786 size = MAX_PATH;
2787 state = MsiLocateComponentA(component, path, &size);
2788 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2789 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2790
2791 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2792 lstrcatA(keypath, "Installer\\UserData\\");
2793 lstrcatA(keypath, usersid);
2794 lstrcatA(keypath, "\\Components\\");
2795 lstrcatA(keypath, comp_squashed);
2796
2797 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2799
2800 /* user unmanaged component key exists */
2801 size = MAX_PATH;
2802 state = MsiGetComponentPathA(prodcode, component, path, &size);
2803 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2804 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2805
2806 size = MAX_PATH;
2807 state = MsiLocateComponentA(component, path, &size);
2808 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2809 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2810
2811 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2812 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2813
2814 /* product value exists */
2815 path[0] = 0;
2816 size = MAX_PATH;
2817 state = MsiGetComponentPathA(prodcode, component, path, &size);
2818 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2819 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2820 ok(size == 10, "Expected 10, got %lu\n", size);
2821
2822 path[0] = 0;
2823 size = MAX_PATH;
2824 state = MsiLocateComponentA(component, path, &size);
2825 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2826 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2827 ok(size == 10, "Expected 10, got %lu\n", size);
2828
2829 create_file("C:\\imapath", 11);
2830
2831 /* file exists */
2832 path[0] = 0;
2833 size = MAX_PATH;
2834 state = MsiGetComponentPathA(prodcode, component, path, &size);
2835 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2836 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2837 ok(size == 10, "Expected 10, got %lu\n", size);
2838
2839 path[0] = 0;
2840 size = MAX_PATH;
2841 state = MsiLocateComponentA(component, path, &size);
2842 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2843 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2844 ok(size == 10, "Expected 10, got %lu\n", size);
2845
2846 RegDeleteValueA(compkey, prod_squashed);
2847 RegDeleteKeyA(prodkey, "");
2848 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2849 RegCloseKey(prodkey);
2850 RegCloseKey(compkey);
2851 DeleteFileA("C:\\imapath");
2852
2853 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2854 lstrcatA(keypath, prod_squashed);
2855
2856 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2857 if (res == ERROR_ACCESS_DENIED)
2858 {
2859 skip( "insufficient rights\n" );
2860 LocalFree( usersid );
2861 return;
2862 }
2863 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2864
2865 /* local classes product key exists */
2866 size = MAX_PATH;
2867 state = MsiGetComponentPathA(prodcode, component, path, &size);
2868 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2869 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2870
2871 size = MAX_PATH;
2872 state = MsiLocateComponentA(component, path, &size);
2873 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2874 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
2875
2876 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2877 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2878 lstrcatA(keypath, comp_squashed);
2879
2880 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2881 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2882
2883 /* local user component key exists */
2884 size = MAX_PATH;
2885 state = MsiGetComponentPathA(prodcode, component, path, &size);
2886 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2887 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2888
2889 size = MAX_PATH;
2890 state = MsiLocateComponentA(component, path, &size);
2891 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2892 ok(size == MAX_PATH, "Expected size to be unchanged, got %ld\n", size);
2893
2894 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2895 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2896
2897 /* product value exists */
2898 path[0] = 0;
2899 size = MAX_PATH;
2900 state = MsiGetComponentPathA(prodcode, component, path, &size);
2901 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2902 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2903 ok(size == 10, "Expected 10, got %lu\n", size);
2904
2905 path[0] = 0;
2906 size = MAX_PATH;
2907 state = MsiLocateComponentA(component, path, &size);
2908 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2909 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2910 ok(size == 10, "Expected 10, got %lu\n", size);
2911
2912 create_file("C:\\imapath", 11);
2913
2914 /* file exists */
2915 path[0] = 0;
2916 size = MAX_PATH;
2917 state = MsiGetComponentPathA(prodcode, component, path, &size);
2918 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2919 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2920 ok(size == 10, "Expected 10, got %lu\n", size);
2921
2922 path[0] = 0;
2923 size = MAX_PATH;
2924 state = MsiLocateComponentA(component, path, &size);
2925 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2926 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2927 ok(size == 10, "Expected 10, got %lu\n", size);
2928
2929 RegDeleteValueA(compkey, prod_squashed);
2930 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
2931 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
2932 RegCloseKey(prodkey);
2933 RegCloseKey(compkey);
2934 DeleteFileA("C:\\imapath");
2935 LocalFree(usersid);
2936}
2937
2939{
2940 HKEY key_comp, key_installprop, key_prod;
2941 char prod[MAX_PATH], prod_squashed[MAX_PATH];
2942 char comp[MAX_PATH], comp_base85[MAX_PATH], comp_squashed[MAX_PATH];
2943 char path[MAX_PATH], path_key[MAX_PATH], *usersid;
2945 DWORD size, val;
2947 LONG res;
2948
2950
2951 create_test_guid( prod, prod_squashed );
2952 compose_base85_guid( comp, comp_base85, comp_squashed );
2953 usersid = get_user_sid();
2954
2955 /* NULL product */
2956 size = MAX_PATH;
2958 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
2959 todo_wine ok( !size, "got %lu\n", size );
2960
2961 /* NULL component */
2962 size = MAX_PATH;
2964 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
2965 todo_wine ok( !size, "got %lu\n", size );
2966
2967 /* non-NULL usersid, MSIINSTALLCONTEXT_MACHINE */
2968 size = MAX_PATH;
2970 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
2971 todo_wine ok( !size, "got %lu\n", size );
2972
2973 /* NULL buf */
2974 size = MAX_PATH;
2976 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
2977 todo_wine ok( size == MAX_PATH * 2, "got %lu\n", size );
2978
2979 /* NULL buflen */
2980 size = MAX_PATH;
2982 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
2983 ok( size == MAX_PATH, "got %lu\n", size );
2984
2985 /* all params valid */
2986 size = MAX_PATH;
2988 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
2989 todo_wine ok( !size, "got %lu\n", size );
2990
2991 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
2992 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
2993 lstrcatA( path_key, comp_squashed );
2994
2995 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
2996 if (res == ERROR_ACCESS_DENIED)
2997 {
2998 skip( "insufficient rights\n" );
2999 LocalFree( usersid );
3000 return;
3001 }
3002 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3003
3004 /* local system component key exists */
3005 size = MAX_PATH;
3007 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3008
3009 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3010 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3011
3012 /* product value exists */
3013 path[0] = 0;
3014 size = MAX_PATH;
3016 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3017 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3018 ok( size == 20, "got %lu\n", size );
3019
3020 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3021 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
3022 lstrcatA( path_key, prod_squashed );
3023 lstrcatA( path_key, "\\InstallProperties" );
3024
3025 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
3026 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3027
3028 val = 1;
3029 res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
3030 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3031
3032 /* install properties key exists */
3033 path[0] = 0;
3034 size = MAX_PATH;
3036 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3037 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3038 ok( size == 20, "got %lu\n", size );
3039
3040 create_file( "c:\\testcomponentpath", 21 );
3041
3042 /* file exists */
3043 path[0] = 0;
3044 size = 0;
3046 ok( state == INSTALLSTATE_MOREDATA, "got %d\n", state );
3047 ok( !path[0], "got %s\n", path );
3048 todo_wine ok( size == 40, "got %lu\n", size );
3049
3050 path[0] = 0;
3051 size = MAX_PATH;
3053 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3054 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3055 ok( size == 20, "got %lu\n", size );
3056
3057 RegDeleteValueA( key_comp, prod_squashed );
3058 RegDeleteKeyExA( key_comp, "", access & KEY_WOW64_64KEY, 0 );
3059 RegDeleteValueA( key_installprop, "WindowsInstaller" );
3060 RegDeleteKeyExA( key_installprop, "", access & KEY_WOW64_64KEY, 0 );
3061 RegCloseKey( key_comp );
3062 RegCloseKey( key_installprop );
3063 DeleteFileA( "c:\\testcomponentpath" );
3064
3065 lstrcpyA( path_key, "Software\\Microsoft\\Installer\\Products\\" );
3066 lstrcatA( path_key, prod_squashed );
3067
3068 res = RegCreateKeyA( HKEY_CURRENT_USER, path_key, &key_prod );
3069 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3070
3071 /* user unmanaged product key exists */
3072 size = MAX_PATH;
3074 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3075 todo_wine ok(!size, "got %lu\n", size);
3076
3077 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3078 lstrcatA( path_key, "Installer\\UserData\\" );
3079 lstrcatA( path_key, usersid );
3080 lstrcatA( path_key, "\\Components\\" );
3081 lstrcatA( path_key, comp_squashed );
3082
3083 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3084 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3085
3086 /* user unmanaged component key exists */
3087 size = MAX_PATH;
3089 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3090 todo_wine ok(!size, "got %lu\n", size);
3091
3092 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3093 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3094
3095 /* product value exists */
3096 path[0] = 0;
3097 size = MAX_PATH;
3099 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3100 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3101 ok( size == 20, "got %lu\n", size );
3102
3103 create_file( "c:\\testcomponentpath", 21 );
3104
3105 /* file exists */
3106 path[0] = 0;
3107 size = MAX_PATH;
3109 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3110 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3111 ok( size == 20, "got %lu\n", size );
3112
3113 RegDeleteValueA( key_comp, prod_squashed );
3114 RegDeleteKeyA( key_prod, "" );
3115 RegDeleteKeyExA( key_comp, "", access & KEY_WOW64_64KEY, 0 );
3116 RegCloseKey( key_prod );
3117 RegCloseKey( key_comp );
3118 DeleteFileA( "c:\\testcomponentpath" );
3119
3120 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3121 lstrcatA( path_key, "Installer\\Managed\\" );
3122 lstrcatA( path_key, usersid );
3123 lstrcatA( path_key, "\\Installer\\Products\\" );
3124 lstrcatA( path_key, prod_squashed );
3125
3126 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
3127 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3128
3129 /* user managed product key exists */
3130 size = MAX_PATH;
3132 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3133
3134 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3135 lstrcatA( path_key, "Installer\\UserData\\" );
3136 lstrcatA( path_key, usersid );
3137 lstrcatA( path_key, "\\Components\\" );
3138 lstrcatA( path_key, comp_squashed );
3139
3140 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3141 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3142
3143 /* user managed component key exists */
3144 size = MAX_PATH;
3146 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3147
3148 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3149 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3150
3151 /* product value exists */
3152 path[0] = 0;
3153 size = MAX_PATH;
3155 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3156 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3157 ok( size == 20, "got %lu\n", size );
3158
3159 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3160 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
3161 lstrcatA( path_key, prod_squashed );
3162 lstrcatA( path_key, "\\InstallProperties" );
3163
3164 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
3165 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3166
3167 val = 1;
3168 res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
3169 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3170
3171 /* install properties key exists */
3172 path[0] = 0;
3173 size = MAX_PATH;
3175 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3176 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3177 ok( size == 20, "got %lu\n", size );
3178
3179 create_file( "c:\\testcomponentpath", 21 );
3180
3181 /* file exists */
3182 path[0] = 0;
3183 size = MAX_PATH;
3185 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3186 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3187 ok( size == 20, "got %lu\n", size );
3188
3189 RegDeleteValueA( key_comp, prod_squashed );
3190 RegDeleteKeyExA( key_prod, "", access & KEY_WOW64_64KEY, 0 );
3191 RegDeleteKeyExA( key_comp, "", access & KEY_WOW64_64KEY, 0 );
3192 RegDeleteValueA( key_installprop, "WindowsInstaller" );
3193 RegDeleteKeyExA( key_installprop, "", access & KEY_WOW64_64KEY, 0 );
3194 RegCloseKey( key_prod );
3195 RegCloseKey( key_comp );
3196 RegCloseKey( key_installprop );
3197 DeleteFileA( "c:\\testcomponentpath" );
3198 lstrcpyA( path_key, "Software\\Classes\\Installer\\Products\\" );
3199 lstrcatA( path_key, prod_squashed );
3200
3201 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
3202 if (res == ERROR_ACCESS_DENIED)
3203 {
3204 skip( "insufficient rights\n" );
3205 LocalFree( usersid );
3206 return;
3207 }
3208 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3209
3210 /* local classes product key exists */
3211 size = MAX_PATH;
3213 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3214 todo_wine ok(!size, "got %lu\n", size);
3215
3216 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3217 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
3218 lstrcatA( path_key, comp_squashed );
3219
3220 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3221 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3222
3223 /* local user component key exists */
3224 size = MAX_PATH;
3226 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3227 todo_wine ok(!size, "got %lu\n", size);
3228
3229 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3230 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3231
3232 /* product value exists */
3233 path[0] = 0;
3234 size = MAX_PATH;
3236 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3237 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3238 ok( size == 20, "got %lu\n", size );
3239
3240 create_file( "c:\\testcomponentpath", 21 );
3241
3242 /* file exists */
3243 path[0] = 0;
3244 size = MAX_PATH;
3246 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3247 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3248 ok( size == 20, "got %lu\n", size );
3249
3250 RegDeleteValueA( key_comp, prod_squashed );
3251 RegDeleteKeyExA( key_prod, "", access & KEY_WOW64_64KEY, 0 );
3252 RegDeleteKeyExA( key_comp, "", access & KEY_WOW64_64KEY, 0 );
3253 RegCloseKey( key_prod );
3254 RegCloseKey( key_comp );
3255 DeleteFileA( "c:\\testcomponentpath" );
3256 LocalFree( usersid );
3257}
3258
3260{
3262 char buf[0x100];
3263 WCHAR bufW[0x100];
3264 DWORD len, len2;
3265 UINT r;
3266
3267 if (!is_process_elevated())
3268 {
3269 skip("process is limited\n");
3270 return;
3271 }
3272
3274 create_file("msitest\\sourcedir.txt", 1000);
3276
3278
3279 buf[0] = 0;
3280 len = sizeof(buf);
3281 r = MsiProvideComponentA("{90120000-0070-0000-0000-4000000FF1CE}",
3282 "{17961602-C4E2-482E-800A-DF6E627549CF}",
3283 "ProductFiles", INSTALLMODE_NODETECTION, buf, &len);
3284 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
3285
3287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3288
3289 state = MsiQueryFeatureStateA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir");
3290 ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
3291
3292 buf[0] = 0;
3293 len = sizeof(buf);
3294 r = MsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3295 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3297 ok(r == ERROR_SUCCESS, "got %u\n", r);
3298 ok(buf[0], "empty path\n");
3299 ok(len == lstrlenA(buf), "got %lu\n", len);
3300
3301 len2 = 0;
3302 r = MsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3303 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3305 ok(r == ERROR_SUCCESS, "got %u\n", r);
3306 ok(len2 == len, "got %lu\n", len2);
3307
3308 len2 = 0;
3309 r = MsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3310 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3312 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3313 ok(len2 == len, "got %lu\n", len2);
3314
3315 /* wide version */
3316
3317 bufW[0] = 0;
3318 len = sizeof(buf);
3319 r = MsiProvideComponentW(L"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", L"sourcedir",
3320 L"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}", INSTALLMODE_NODETECTION, bufW, &len);
3321 ok(r == ERROR_SUCCESS, "got %u\n", r);
3322 ok(bufW[0], "empty path\n");
3323 ok(len == lstrlenW(bufW), "got %lu\n", len);
3324
3325 len2 = 0;
3326 r = MsiProvideComponentW(L"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", L"sourcedir",
3327 L"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}", INSTALLMODE_NODETECTION, NULL, &len2);
3328 ok(r == ERROR_SUCCESS, "got %u\n", r);
3329 ok(len2 == len, "got %lu\n", len2);
3330
3331 len2 = 0;
3332 r = MsiProvideComponentW(L"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", L"sourcedir",
3333 L"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}", INSTALLMODE_NODETECTION, bufW, &len2);
3334 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3335 ok(len2 == len, "got %lu\n", len2);
3336
3337 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3338 ok(r == ERROR_SUCCESS, "got %u\n", r);
3339
3340 DeleteFileA("msitest\\sourcedir.txt");
3343}
3344
3346{
3347 UINT r;
3349 char comp[39], comp_squashed[33], comp2[39], comp2_base85[21], comp2_squashed[33];
3350 char prod[39], prod_base85[21], prod_squashed[33];
3351 char desc[MAX_PATH], buf[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
3352 DWORD len = sizeof(buf);
3354 HKEY hkey, hkey2, hkey3, hkey4, hkey5;
3355 LONG res;
3356
3357 if (!is_process_elevated())
3358 {
3359 skip( "process is limited\n" );
3360 return;
3361 }
3362
3363 create_test_guid( comp, comp_squashed );
3364 compose_base85_guid( comp2, comp2_base85, comp2_squashed );
3365 compose_base85_guid( prod, prod_base85, prod_squashed );
3366
3367 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3368 ok( r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r );
3369
3370 lstrcpyA( keypath, "Software\\Classes\\Installer\\Components\\" );
3371 lstrcatA( keypath, comp_squashed );
3372
3374 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey, NULL );
3375 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3376
3377 lstrcpyA( desc, prod_base85 );
3378 memcpy( desc + lstrlenA(desc), "feature<\0", sizeof("feature<\0") );
3379 res = RegSetValueExA( hkey, "qualifier", 0, REG_MULTI_SZ, (const BYTE *)desc,
3380 lstrlenA(prod_base85) + sizeof("feature<\0") );
3381 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3382
3383 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3384 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3385
3386 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3387 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3388
3389 state = MsiQueryProductStateA( prod );
3390 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3391
3392 lstrcpyA( keypath, "Software\\Classes\\Installer\\Products\\" );
3393 lstrcatA( keypath, prod_squashed );
3394
3395 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey2, NULL );
3396 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3397
3398 state = MsiQueryProductStateA( prod );
3399 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3400
3401 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3402 todo_wine ok( r == ERROR_UNKNOWN_FEATURE, "got %u\n", r );
3403
3404 lstrcpyA( keypath, "Software\\Classes\\Installer\\Features\\" );
3405 lstrcatA( keypath, prod_squashed );
3406
3407 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey3, NULL );
3408 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3409
3410 state = MsiQueryFeatureStateA( prod, "feature" );
3411 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3412
3413 res = RegSetValueExA( hkey3, "feature", 0, REG_SZ, (const BYTE *)"", 1 );
3414 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3415
3416 state = MsiQueryFeatureStateA( prod, "feature" );
3417 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3418
3419 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3420 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3421
3422 len = sizeof(buf);
3423 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3424 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3425
3426 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\" );
3427 lstrcatA( keypath, prod_squashed );
3428 lstrcatA( keypath, "\\Features" );
3429
3430 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey4, NULL );
3431 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3432
3433 res = RegSetValueExA( hkey4, "feature", 0, REG_SZ, (const BYTE *)comp2_base85, sizeof(comp2_base85) );
3434 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3435
3436 state = MsiQueryFeatureStateA( prod, "feature" );
3437 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3438
3439 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\" );
3440 lstrcatA( keypath, comp2_squashed );
3441
3442 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey5, NULL );
3443 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3444
3445 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\nosuchfile", sizeof("c:\\nosuchfile") );
3446 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3447
3448 state = MsiQueryFeatureStateA( prod, "feature" );
3449 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3450
3451 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3452 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3453
3455 lstrcatA( path, "\\msitest" );
3457 lstrcatA( path, "\\test.txt" );
3458 create_file_data( path, "test", 100 );
3459
3460 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1 );
3461 ok( res == ERROR_SUCCESS, "got %ld\n", res );
3462
3463 buf[0] = 0;
3464 len = sizeof(buf);
3465 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3466 ok( r == ERROR_SUCCESS, "got %u\n", r );
3467 ok( len == lstrlenA(path), "got %lu\n", len );
3468 ok( !lstrcmpA( path, buf ), "got '%s'\n", buf );
3469
3470 DeleteFileA( "msitest\\text.txt" );
3471 RemoveDirectoryA( "msitest" );
3472
3473 RegDeleteKeyExA( hkey5, "", access & KEY_WOW64_64KEY, 0 );
3474 RegCloseKey( hkey5 );
3475 RegDeleteKeyExA( hkey4, "", access & KEY_WOW64_64KEY, 0 );
3476 RegCloseKey( hkey4 );
3477 RegDeleteKeyExA( hkey3, "", access & KEY_WOW64_64KEY, 0 );
3478 RegCloseKey( hkey3 );
3479 RegDeleteKeyExA( hkey2, "", access & KEY_WOW64_64KEY, 0 );
3480 RegCloseKey( hkey2 );
3481 RegDeleteKeyExA( hkey, "", access & KEY_WOW64_64KEY, 0 );
3482 RegCloseKey( hkey );
3483}
3484
3485static void test_MsiGetProductCode(void)
3486{
3487 HKEY compkey, prodkey;
3488 CHAR prodcode[MAX_PATH];
3489 CHAR prod_squashed[MAX_PATH];
3490 CHAR prodcode2[MAX_PATH];
3491 CHAR prod2_squashed[MAX_PATH];
3492 CHAR component[MAX_PATH];
3493 CHAR comp_base85[MAX_PATH];
3494 CHAR comp_squashed[MAX_PATH];
3495 CHAR keypath[MAX_PATH];
3496 CHAR product[MAX_PATH];
3497 LPSTR usersid;
3498 LONG res;
3499 UINT r;
3501
3502 create_test_guid(prodcode, prod_squashed);
3503 create_test_guid(prodcode2, prod2_squashed);
3504 compose_base85_guid(component, comp_base85, comp_squashed);
3505 usersid = get_user_sid();
3506
3507 if (is_wow64)
3509
3510 /* szComponent is NULL */
3511 lstrcpyA(product, "prod");
3512 r = MsiGetProductCodeA(NULL, product);
3513 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3514 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3515
3516 /* szComponent is empty */
3517 lstrcpyA(product, "prod");
3518 r = MsiGetProductCodeA("", product);
3519 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3520 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3521
3522 /* garbage szComponent */
3523 lstrcpyA(product, "prod");
3524 r = MsiGetProductCodeA("garbage", product);
3525 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3526 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3527
3528 /* guid without brackets */
3529 lstrcpyA(product, "prod");
3530 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
3531 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3532 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3533
3534 /* guid with brackets */
3535 lstrcpyA(product, "prod");
3536 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
3537 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3538 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3539
3540 /* same length as guid, but random */
3541 lstrcpyA(product, "prod");
3542 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
3543 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3544 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3545
3546 /* all params correct, szComponent not published */
3547 lstrcpyA(product, "prod");
3548 r = MsiGetProductCodeA(component, product);
3549 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3550 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3551
3552 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3553 lstrcatA(keypath, "Installer\\UserData\\");
3554 lstrcatA(keypath, usersid);
3555 lstrcatA(keypath, "\\Components\\");
3556 lstrcatA(keypath, comp_squashed);
3557
3558 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3559 if (res == ERROR_ACCESS_DENIED)
3560 {
3561 skip("Not enough rights to perform tests\n");
3562 LocalFree(usersid);
3563 return;
3564 }
3565 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3566
3567 /* user unmanaged component key exists */
3568 lstrcpyA(product, "prod");
3569 r = MsiGetProductCodeA(component, product);
3570 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3571 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3572
3573 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3574 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3575
3576 /* product value exists */
3577 lstrcpyA(product, "prod");
3578 r = MsiGetProductCodeA(component, product);
3579 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3580 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3581
3582 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3583 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3584
3585 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3586 lstrcatA(keypath, "Installer\\Managed\\");
3587 lstrcatA(keypath, usersid);
3588 lstrcatA(keypath, "\\Installer\\Products\\");
3589 lstrcatA(keypath, prod_squashed);
3590
3591 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3593
3594 /* user managed product key of first product exists */
3595 lstrcpyA(product, "prod");
3596 r = MsiGetProductCodeA(component, product);
3597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3598 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3599
3600 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3601 RegCloseKey(prodkey);
3602
3603 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3604 lstrcatA(keypath, prod_squashed);
3605
3606 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3608
3609 /* user unmanaged product key exists */
3610 lstrcpyA(product, "prod");
3611 r = MsiGetProductCodeA(component, product);
3612 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3613 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3614
3615 RegDeleteKeyA(prodkey, "");
3616 RegCloseKey(prodkey);
3617
3618 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3619 lstrcatA(keypath, prod_squashed);
3620
3621 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3622 if (res == ERROR_ACCESS_DENIED)
3623 {
3624 skip( "insufficient rights\n" );
3625 LocalFree( usersid );
3626 return;
3627 }
3628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3629
3630 /* local classes product key exists */
3631 lstrcpyA(product, "prod");
3632 r = MsiGetProductCodeA(component, product);
3633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3634 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3635
3636 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3637 RegCloseKey(prodkey);
3638
3639 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3640 lstrcatA(keypath, "Installer\\Managed\\");
3641 lstrcatA(keypath, usersid);
3642 lstrcatA(keypath, "\\Installer\\Products\\");
3643 lstrcatA(keypath, prod2_squashed);
3644
3645 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3646 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3647
3648 /* user managed product key of second product exists */
3649 lstrcpyA(product, "prod");
3650 r = MsiGetProductCodeA(component, product);
3651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3652 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3653
3654 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3655 RegCloseKey(prodkey);
3656 RegDeleteValueA(compkey, prod_squashed);
3657 RegDeleteValueA(compkey, prod2_squashed);
3658 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
3659 RegCloseKey(compkey);
3660
3661 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3662 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3663 lstrcatA(keypath, comp_squashed);
3664
3665 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3667
3668 /* local user component key exists */
3669 lstrcpyA(product, "prod");
3670 r = MsiGetProductCodeA(component, product);
3671 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3672 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3673
3674 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3675 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3676
3677 /* product value exists */
3678 lstrcpyA(product, "prod");
3679 r = MsiGetProductCodeA(component, product);
3680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3681 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3682
3683 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3685
3686 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3687 lstrcatA(keypath, "Installer\\Managed\\");
3688 lstrcatA(keypath, usersid);
3689 lstrcatA(keypath, "\\Installer\\Products\\");
3690 lstrcatA(keypath, prod_squashed);
3691
3692 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3693 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3694
3695 /* user managed product key of first product exists */
3696 lstrcpyA(product, "prod");
3697 r = MsiGetProductCodeA(component, product);
3698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3699 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3700
3701 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3702 RegCloseKey(prodkey);
3703
3704 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3705 lstrcatA(keypath, prod_squashed);
3706
3707 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3708 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3709
3710 /* user unmanaged product key exists */
3711 lstrcpyA(product, "prod");
3712 r = MsiGetProductCodeA(component, product);
3713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3714 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3715
3716 RegDeleteKeyA(prodkey, "");
3717 RegCloseKey(prodkey);
3718
3719 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3720 lstrcatA(keypath, prod_squashed);
3721
3722 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3723 if (res == ERROR_ACCESS_DENIED)
3724 {
3725 skip( "insufficient rights\n" );
3726 LocalFree( usersid );
3727 return;
3728 }
3729 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3730
3731 /* local classes product key exists */
3732 lstrcpyA(product, "prod");
3733 r = MsiGetProductCodeA(component, product);
3734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3735 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3736
3737 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3738 RegCloseKey(prodkey);
3739
3740 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3741 lstrcatA(keypath, "Installer\\Managed\\");
3742 lstrcatA(keypath, usersid);
3743 lstrcatA(keypath, "\\Installer\\Products\\");
3744 lstrcatA(keypath, prod2_squashed);
3745
3746 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3747 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3748
3749 /* user managed product key of second product exists */
3750 lstrcpyA(product, "prod");
3751 r = MsiGetProductCodeA(component, product);
3752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3753 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3754
3755 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
3756 RegCloseKey(prodkey);
3757 RegDeleteValueA(compkey, prod_squashed);
3758 RegDeleteValueA(compkey, prod2_squashed);
3759 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
3760 RegCloseKey(compkey);
3761 LocalFree(usersid);
3762}
3763
3764static void test_MsiEnumClients(void)
3765{
3766 HKEY compkey;
3767 CHAR prodcode[MAX_PATH];
3768 CHAR prod_squashed[MAX_PATH];
3769 CHAR prodcode2[MAX_PATH];
3770 CHAR prod2_squashed[MAX_PATH];
3771 CHAR component[MAX_PATH];
3772 CHAR comp_base85[MAX_PATH];
3773 CHAR comp_squashed[MAX_PATH];
3774 CHAR product[MAX_PATH];
3775 CHAR keypath[MAX_PATH];
3776 LPSTR usersid;
3777 LONG res;
3778 UINT r;
3780
3781 create_test_guid(prodcode, prod_squashed);
3782 create_test_guid(prodcode2, prod2_squashed);
3783 compose_base85_guid(component, comp_base85, comp_squashed);
3784 usersid = get_user_sid();
3785
3786 if (is_wow64)
3788
3789 /* NULL szComponent */
3790 product[0] = '\0';
3791 r = MsiEnumClientsA(NULL, 0, product);
3792 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3793 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3794
3795 /* empty szComponent */
3796 product[0] = '\0';
3797 r = MsiEnumClientsA("", 0, product);
3798 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3799 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3800
3801 /* NULL lpProductBuf */
3802 r = MsiEnumClientsA(component, 0, NULL);
3803 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3804
3805 /* all params correct, component missing */
3806 product[0] = '\0';
3807 r = MsiEnumClientsA(component, 0, product);
3808 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3809 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3810
3811 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3812 lstrcatA(keypath, "Installer\\UserData\\");
3813 lstrcatA(keypath, usersid);
3814 lstrcatA(keypath, "\\Components\\");
3815 lstrcatA(keypath, comp_squashed);
3816
3817 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3818 if (res == ERROR_ACCESS_DENIED)
3819 {
3820 skip("Not enough rights to perform tests\n");
3821 LocalFree(usersid);
3822 return;
3823 }
3824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3825
3826 /* user unmanaged component key exists */
3827 product[0] = '\0';
3828 r = MsiEnumClientsA(component, 0, product);
3829 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3830 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3831
3832 /* index > 0, no products exist */
3833 product[0] = '\0';
3834 r = MsiEnumClientsA(component, 1, product);
3835 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3836 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3837
3838 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3839 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3840
3841 /* product value exists */
3842 r = MsiEnumClientsA(component, 0, product);
3843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3844 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3845
3846 /* try index 0 again */
3847 product[0] = '\0';
3848 r = MsiEnumClientsA(component, 0, product);
3849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3850 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3851
3852 /* try index 1, second product value does not exist */
3853 product[0] = '\0';
3854 r = MsiEnumClientsA(component, 1, product);
3855 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3856 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3857
3858 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3860
3861 /* try index 1, second product value does exist */
3862 product[0] = '\0';
3863 r = MsiEnumClientsA(component, 1, product);
3864 todo_wine
3865 {
3866 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3867 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3868 }
3869
3870 /* start the enumeration over */
3871 product[0] = '\0';
3872 r = MsiEnumClientsA(component, 0, product);
3873 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3874 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3875 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3876
3877 /* correctly query second product */
3878 product[0] = '\0';
3879 r = MsiEnumClientsA(component, 1, product);
3880 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3881 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3882 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3883
3884 RegDeleteValueA(compkey, prod_squashed);
3885 RegDeleteValueA(compkey, prod2_squashed);
3886 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
3887 RegCloseKey(compkey);
3888
3889 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3890 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3891 lstrcatA(keypath, comp_squashed);
3892
3893 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3894 if (res == ERROR_ACCESS_DENIED)
3895 {
3896 skip("Not enough rights to perform tests\n");
3897 LocalFree(usersid);
3898 return;
3899 }
3900 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3901
3902 /* user local component key exists */
3903 product[0] = '\0';
3904 r = MsiEnumClientsA(component, 0, product);
3905 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3906 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3907
3908 /* index > 0, no products exist */
3909 product[0] = '\0';
3910 r = MsiEnumClientsA(component, 1, product);
3911 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3912 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3913
3914 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3915 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3916
3917 /* product value exists */
3918 product[0] = '\0';
3919 r = MsiEnumClientsA(component, 0, product);
3920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3921 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3922
3923 /* try index 0 again */
3924 product[0] = '\0';
3925 r = MsiEnumClientsA(component, 0, product);
3926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3927
3928 /* try index 1, second product value does not exist */
3929 product[0] = '\0';
3930 r = MsiEnumClientsA(component, 1, product);
3931 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3932 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3933
3934 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3935 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3936
3937 /* try index 1, second product value does exist */
3938 product[0] = '\0';
3939 r = MsiEnumClientsA(component, 1, product);
3940 todo_wine
3941 {
3942 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3943 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3944 }
3945
3946 /* start the enumeration over */
3947 product[0] = '\0';
3948 r = MsiEnumClientsA(component, 0, product);
3949 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3950 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3951 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3952
3953 /* correctly query second product */
3954 product[0] = '\0';
3955 r = MsiEnumClientsA(component, 1, product);
3956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3957 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3958 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3959
3960 RegDeleteValueA(compkey, prod_squashed);
3961 RegDeleteValueA(compkey, prod2_squashed);
3962 RegDeleteKeyExA(compkey, "", access & KEY_WOW64_64KEY, 0);
3963 RegCloseKey(compkey);
3964 LocalFree(usersid);
3965}
3966
3967static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
3968 LPSTR *langcheck, LPDWORD langchecksz)
3969{
3970 LPSTR version;
3971 VS_FIXEDFILEINFO *ffi;
3973 UINT len;
3974 USHORT *lang;
3975
3976 version = malloc(size);
3978
3979 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &len);
3980 *vercheck = malloc(MAX_PATH);
3981 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
3983 LOWORD(ffi->dwFileVersionLS));
3984 *verchecksz = lstrlenA(*vercheck);
3985
3986 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &len);
3987 *langcheck = malloc(MAX_PATH);
3988 sprintf(*langcheck, "%d", *lang);
3989 *langchecksz = lstrlenA(*langcheck);
3990
3991 free(version);
3992}
3993
3994static void test_MsiGetFileVersion(void)
3995{
3996 UINT r;
3997 DWORD versz, langsz;
3998 char version[MAX_PATH];
3999 char lang[MAX_PATH];
4000 char path[MAX_PATH];
4001 LPSTR vercheck, langcheck;
4002 DWORD verchecksz, langchecksz;
4003
4004 /* NULL szFilePath */
4006 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4007
4008 versz = MAX_PATH;
4009 langsz = MAX_PATH;
4010 lstrcpyA(version, "version");
4011 lstrcpyA(lang, "lang");
4012 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
4014 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4015 ok(!lstrcmpA(version, "version"),
4016 "Expected version to be unchanged, got %s\n", version);
4017 ok(versz == MAX_PATH, "got %lu\n", versz);
4018 ok(!lstrcmpA(lang, "lang"),
4019 "Expected lang to be unchanged, got %s\n", lang);
4020 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4021
4022 /* empty szFilePath */
4024 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4025
4026 versz = MAX_PATH;
4027 langsz = MAX_PATH;
4028 lstrcpyA(version, "version");
4029 lstrcpyA(lang, "lang");
4030 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
4032 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4033 ok(!lstrcmpA(version, "version"),
4034 "Expected version to be unchanged, got %s\n", version);
4035 ok(versz == MAX_PATH, "got %lu\n", versz);
4036 ok(!lstrcmpA(lang, "lang"),
4037 "Expected lang to be unchanged, got %s\n", lang);
4038 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4039
4040 /* nonexistent szFilePath */
4041 versz = MAX_PATH;
4042 langsz = MAX_PATH;
4043 lstrcpyA(version, "version");
4044 lstrcpyA(lang, "lang");
4045 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4047 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4048 ok(!lstrcmpA(version, "version"),
4049 "Expected version to be unchanged, got %s\n", version);
4050 ok(versz == MAX_PATH, "got %lu\n", versz);
4051 ok(!lstrcmpA(lang, "lang"),
4052 "Expected lang to be unchanged, got %s\n", lang);
4053 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4054
4055 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
4056 versz = MAX_PATH;
4057 langsz = MAX_PATH;
4058 lstrcpyA(version, "version");
4059 lstrcpyA(lang, "lang");
4060 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
4062 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4063 ok(!lstrcmpA(version, "version"),
4064 "Expected version to be unchanged, got %s\n", version);
4065 ok(versz == MAX_PATH, "got %lu\n", versz);
4066 ok(!lstrcmpA(lang, "lang"),
4067 "Expected lang to be unchanged, got %s\n", lang);
4068 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4069
4070 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
4071 versz = MAX_PATH;
4072 langsz = MAX_PATH;
4073 lstrcpyA(version, "version");
4074 lstrcpyA(lang, "lang");
4075 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
4077 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4078 ok(!lstrcmpA(version, "version"),
4079 "Expected version to be unchanged, got %s\n", version);
4080 ok(versz == MAX_PATH, "got %lu\n", versz);
4081 ok(!lstrcmpA(lang, "lang"),
4082 "Expected lang to be unchanged, got %s\n", lang);
4083 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4084
4085 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
4086 versz = 0;
4087 langsz = MAX_PATH;
4088 lstrcpyA(version, "version");
4089 lstrcpyA(lang, "lang");
4090 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4092 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4093 ok(!lstrcmpA(version, "version"),
4094 "Expected version to be unchanged, got %s\n", version);
4095 ok(versz == 0, "Expected 0, got %lu\n", versz);
4096 ok(!lstrcmpA(lang, "lang"),
4097 "Expected lang to be unchanged, got %s\n", lang);
4098 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4099
4100 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
4101 versz = MAX_PATH;
4102 langsz = 0;
4103 lstrcpyA(version, "version");
4104 lstrcpyA(lang, "lang");
4105 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4107 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4108 ok(!lstrcmpA(version, "version"),
4109 "Expected version to be unchanged, got %s\n", version);
4110 ok(versz == MAX_PATH, "got %lu\n", versz);
4111 ok(!lstrcmpA(lang, "lang"),
4112 "Expected lang to be unchanged, got %s\n", lang);
4113 ok(langsz == 0, "Expected 0, got %lu\n", langsz);
4114
4115 /* nonexistent szFilePath, rest NULL */
4116 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
4118 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4119
4120 create_file("ver.txt", 20);
4121
4122 /* file exists, no version information */
4123 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
4124 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
4125
4126 versz = MAX_PATH;
4127 langsz = MAX_PATH;
4128 lstrcpyA(version, "version");
4129 lstrcpyA(lang, "lang");
4130 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
4131 ok(versz == MAX_PATH, "got %lu\n", versz);
4132 ok(!lstrcmpA(version, "version"),
4133 "Expected version to be unchanged, got %s\n", version);
4134 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4135 ok(!lstrcmpA(lang, "lang"),
4136 "Expected lang to be unchanged, got %s\n", lang);
4138 "Expected ERROR_FILE_INVALID, got %d\n", r);
4139
4140 DeleteFileA("ver.txt");
4141
4142 /* relative path, has version information */
4143 versz = MAX_PATH;
4144 langsz = MAX_PATH;
4145 lstrcpyA(version, "version");
4146 lstrcpyA(lang, "lang");
4147 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
4148 todo_wine
4149 {
4151 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4152 ok(!lstrcmpA(version, "version"),
4153 "Expected version to be unchanged, got %s\n", version);
4154 ok(versz == MAX_PATH, "got %lu\n", versz);
4155 ok(!lstrcmpA(lang, "lang"),
4156 "Expected lang to be unchanged, got %s\n", lang);
4157 ok(langsz == MAX_PATH, "got %lu\n", langsz);
4158 }
4159
4161 lstrcatA(path, "\\kernel32.dll");
4162
4163 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4164
4165 /* absolute path, has version information */
4166 versz = MAX_PATH;
4167 langsz = MAX_PATH;
4168 lstrcpyA(version, "version");
4169 lstrcpyA(lang, "lang");
4170 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4172 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4173 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4174 ok(!lstrcmpA(version, vercheck),
4175 "Expected %s, got %s\n", vercheck, version);
4176
4177 /* only check version */
4178 versz = MAX_PATH;
4179 lstrcpyA(version, "version");
4180 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4182 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4183 ok(!lstrcmpA(version, vercheck), "Expected %s, got %s\n", vercheck, version);
4184
4185 /* only check language */
4186 langsz = MAX_PATH;
4187 lstrcpyA(lang, "lang");
4188 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4190 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4191
4192 /* check neither version nor language */
4194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4195
4196 /* get pcchVersionBuf */
4197 versz = MAX_PATH;
4198 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4200 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4201
4202 /* get pcchLangBuf */
4203 langsz = MAX_PATH;
4204 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4205 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4206 ok(langsz >= langchecksz, "Expected %lu >= %lu\n", langsz, langchecksz);
4207
4208 /* pcchVersionBuf not big enough */
4209 versz = 5;
4210 lstrcpyA(version, "version");
4211 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4212 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4213 ok(!strncmp(version, vercheck, 4),
4214 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4215 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4216
4217 /* pcchLangBuf not big enough */
4218 langsz = 4;
4219 lstrcpyA(lang, "lang");
4220 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4221 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4222 ok(lstrcmpA(lang, "lang"), "lang not set\n");
4223 ok(langsz >= langchecksz, "Expected %lu >= %lu\n", langsz, langchecksz);
4224
4225 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4226 versz = MAX_PATH;
4227 langsz = 0;
4228 lstrcpyA(version, "version");
4229 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4231 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4232 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4233 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %lu >= %lu\n", langsz, langchecksz);
4234
4235 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4236 versz = 5;
4237 langsz = MAX_PATH;
4238 lstrcpyA(lang, "lang");
4239 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4241 ok(versz == verchecksz, "Expected %lu, got %lu\n", verchecksz, versz);
4242 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %lu >= %lu\n", langsz, langchecksz);
4243 ok(strstr(lang, langcheck) != NULL, "expected %s in %s\n", langcheck, lang);
4244
4245 /* NULL pcchVersionBuf and pcchLangBuf */
4246 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4247 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4248
4249 /* All NULL except szFilePath */
4250 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252
4253 free(vercheck);
4254 free(langcheck);
4255}
4256
4257static void test_MsiGetProductInfo(void)
4258{
4259 UINT r;
4260 LONG res;
4261 HKEY propkey, source;
4262 HKEY prodkey, localkey;
4263 CHAR prodcode[MAX_PATH];
4264 CHAR prod_squashed[MAX_PATH];
4265 CHAR packcode[MAX_PATH];
4266 CHAR pack_squashed[MAX_PATH];
4267 CHAR buf[MAX_PATH];
4268 CHAR keypath[MAX_PATH];
4269 LPSTR usersid;
4270 DWORD sz, val = 42;
4271 REGSAM access = KEY_ALL_ACCESS;
4272
4273 create_test_guid(prodcode, prod_squashed);
4274 create_test_guid(packcode, pack_squashed);
4275 usersid = get_user_sid();
4276
4277 if (is_wow64)
4278 access |= KEY_WOW64_64KEY;
4279
4280 /* NULL szProduct */
4281 sz = MAX_PATH;
4282 lstrcpyA(buf, "apple");
4283 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4284 ok(r == ERROR_INVALID_PARAMETER,
4285 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4286 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4287 ok(sz == MAX_PATH, "got %lu\n", sz);
4288
4289 /* empty szProduct */
4290 sz = MAX_PATH;
4291 lstrcpyA(buf, "apple");
4292 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4293 ok(r == ERROR_INVALID_PARAMETER,
4294 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4295 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4296 ok(sz == MAX_PATH, "got %lu\n", sz);
4297
4298 /* garbage szProduct */
4299 sz = MAX_PATH;
4300 lstrcpyA(buf, "apple");
4301 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4302 ok(r == ERROR_INVALID_PARAMETER,
4303 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4304 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4305 ok(sz == MAX_PATH, "got %lu\n", sz);
4306
4307 /* guid without brackets */
4308 sz = MAX_PATH;
4309 lstrcpyA(buf, "apple");
4310 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4311 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4312 ok(r == ERROR_INVALID_PARAMETER,
4313 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4314 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4315 ok(sz == MAX_PATH, "got %lu\n", sz);
4316
4317 /* guid with brackets */
4318 sz = MAX_PATH;
4319 lstrcpyA(buf, "apple");
4320 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4321 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4322 ok(r == ERROR_UNKNOWN_PRODUCT,
4323 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4324 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4325 ok(sz == MAX_PATH, "got %lu\n", sz);
4326
4327 /* same length as guid, but random */
4328 sz = MAX_PATH;
4329 lstrcpyA(buf, "apple");
4330 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4331 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4332 ok(r == ERROR_INVALID_PARAMETER,
4333 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4334 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4335 ok(sz == MAX_PATH, "got %lu\n", sz);
4336
4337 /* not installed, NULL szAttribute */
4338 sz = MAX_PATH;
4339 lstrcpyA(buf, "apple");
4340 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4341 ok(r == ERROR_INVALID_PARAMETER,
4342 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4343 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4344 ok(sz == MAX_PATH, "got %lu\n", sz);
4345
4346 /* not installed, NULL lpValueBuf */
4347 sz = MAX_PATH;
4348 lstrcpyA(buf, "apple");
4349 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4350 ok(r == ERROR_UNKNOWN_PRODUCT,
4351 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4352 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4353 ok(sz == MAX_PATH, "got %lu\n", sz);
4354
4355 /* not installed, NULL pcchValueBuf */
4356 sz = MAX_PATH;
4357 lstrcpyA(buf, "apple");
4358 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, NULL);
4359 ok(r == ERROR_INVALID_PARAMETER,
4360 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4361 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4362 ok(sz == MAX_PATH, "got %lu\n", sz);
4363
4364 /* created guid cannot possibly be an installed product code */
4365 sz = MAX_PATH;
4366 lstrcpyA(buf, "apple");
4367 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4368 ok(r == ERROR_UNKNOWN_PRODUCT,
4369 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4370 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4371 ok(sz == MAX_PATH, "got %lu\n", sz);
4372
4373 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4374 lstrcatA(keypath, usersid);
4375 lstrcatA(keypath, "\\Installer\\Products\\");
4376 lstrcatA(keypath, prod_squashed);
4377
4378 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4379 if (res == ERROR_ACCESS_DENIED)
4380 {
4381 skip("Not enough rights to perform tests\n");
4382 LocalFree(usersid);
4383 return;
4384 }
4385 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4386
4387 /* managed product code exists */
4388 sz = MAX_PATH;
4389 lstrcpyA(buf, "apple");
4390 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4391 ok(r == ERROR_UNKNOWN_PROPERTY,
4392 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4393 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4394 ok(sz == MAX_PATH, "got %lu\n", sz);
4395
4396 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
4397 RegCloseKey(prodkey);
4398
4399 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4400 lstrcatA(keypath, usersid);
4401 lstrcatA(keypath, "\\Products\\");
4402 lstrcatA(keypath, prod_squashed);
4403
4404 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4405 if (res == ERROR_ACCESS_DENIED)
4406 {
4407 skip("Not enough rights to perform tests\n");
4408 LocalFree(usersid);
4409 return;
4410 }
4411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4412
4413 /* local user product code exists */
4414 sz = MAX_PATH;
4415 lstrcpyA(buf, "apple");
4416 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4417 ok(r == ERROR_UNKNOWN_PRODUCT,
4418 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4419 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4420 ok(sz == MAX_PATH, "got %lu\n", sz);
4421
4422 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4423 lstrcatA(keypath, usersid);
4424 lstrcatA(keypath, "\\Installer\\Products\\");
4425 lstrcatA(keypath, prod_squashed);
4426
4427 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4429
4430 /* both local and managed product code exist */
4431 sz = MAX_PATH;
4432 lstrcpyA(buf, "apple");
4433 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4434 ok(r == ERROR_UNKNOWN_PROPERTY,
4435 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4436 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4437 ok(sz == MAX_PATH, "%lu\n", sz);
4438
4439 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4441
4442 /* InstallProperties key exists */
4443 sz = MAX_PATH;
4444 lstrcpyA(buf, "apple");
4445 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4447 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4448 ok(sz == 0, "Expected 0, got %lu\n", sz);
4449
4450 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4452
4453 /* HelpLink value exists */
4454 sz = MAX_PATH;
4455 lstrcpyA(buf, "apple");
4457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4458 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4459 ok(sz == 4, "Expected 4, got %lu\n", sz);
4460
4461 /* pcchBuf is NULL */
4463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4464
4465 /* lpValueBuf is NULL */
4466 sz = MAX_PATH;
4468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4469 ok(sz == 4, "Expected 4, got %lu\n", sz);
4470
4471 /* lpValueBuf is NULL, pcchValueBuf is too small */
4472 sz = 2;
4474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4475 ok(sz == 4, "Expected 4, got %lu\n", sz);
4476
4477 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4478 sz = 2;
4479 lstrcpyA(buf, "apple");
4481 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4482 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4483 ok(sz == 4, "Expected 4, got %lu\n", sz);
4484
4485 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4486 sz = 4;
4487 lstrcpyA(buf, "apple");
4489 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4490 ok(!lstrcmpA(buf, "apple"),
4491 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4492 ok(sz == 4, "Expected 4, got %lu\n", sz);
4493
4494 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4496
4497 /* random property not supported by MSI, value exists */
4498 sz = MAX_PATH;
4499 lstrcpyA(buf, "apple");
4500 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4502 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4503 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4504 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4505
4506 RegDeleteValueA(propkey, "IMadeThis");
4507 RegDeleteValueA(propkey, "HelpLink");
4508 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
4509 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
4510 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
4511 RegCloseKey(propkey);
4512 RegCloseKey(localkey);
4513 RegCloseKey(prodkey);
4514
4515 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4516 lstrcatA(keypath, prod_squashed);
4517
4518 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4520
4521 /* user product key exists */
4522 sz = MAX_PATH;
4523 lstrcpyA(buf, "apple");
4526 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4527 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4528 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4529
4530 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4531 lstrcatA(keypath, usersid);
4532 lstrcatA(keypath, "\\Products\\");
4533 lstrcatA(keypath, prod_squashed);
4534
4535 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4537
4538 /* local user product key exists */
4539 sz = MAX_PATH;
4540 lstrcpyA(buf, "apple");
4543 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4544 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4545 ok(sz == MAX_PATH, "got %lu\n", sz);
4546
4547 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4549
4550 /* InstallProperties key exists */
4551 sz = MAX_PATH;
4552 lstrcpyA(buf, "apple");
4554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4555 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4556 ok(sz == 0, "Expected 0, got %lu\n", sz);
4557
4558 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4560
4561 /* HelpLink value exists */
4562 sz = MAX_PATH;
4563 lstrcpyA(buf, "apple");
4565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4566 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4567 ok(sz == 4, "Expected 4, got %lu\n", sz);
4568
4569 RegDeleteValueA(propkey, "HelpLink");
4570 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
4571 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
4572 RegDeleteKeyA(prodkey, "");
4573 RegCloseKey(propkey);
4574 RegCloseKey(localkey);
4575 RegCloseKey(prodkey);
4576
4577 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4578 lstrcatA(keypath, prod_squashed);
4579
4580 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4581 if (res == ERROR_ACCESS_DENIED)
4582 {
4583 skip( "insufficient rights\n" );
4584 LocalFree( usersid );
4585 return;
4586 }
4587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4588
4589 /* classes product key exists */
4590 sz = MAX_PATH;
4591 lstrcpyA(buf, "apple");
4594 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4595 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4596 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4597
4598 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4599 lstrcatA(keypath, usersid);
4600 lstrcatA(keypath, "\\Products\\");
4601 lstrcatA(keypath, prod_squashed);
4602
4603 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4604 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4605
4606 /* local user product key exists */
4607 sz = MAX_PATH;
4608 lstrcpyA(buf, "apple");
4611 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4612 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4613 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4614
4615 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4617
4618 /* InstallProperties key exists */
4619 sz = MAX_PATH;
4620 lstrcpyA(buf, "apple");
4623 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4624 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4625 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4626
4627 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
4628 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
4629 RegCloseKey(propkey);
4630 RegCloseKey(localkey);
4631
4632 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4633 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
4634 lstrcatA(keypath, prod_squashed);
4635
4636 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4638
4639 /* Local System product key exists */
4640 sz = MAX_PATH;
4641 lstrcpyA(buf, "apple");
4644 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4645 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4646 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
4647
4648 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4649 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4650
4651 /* InstallProperties key exists */
4652 sz = MAX_PATH;
4653 lstrcpyA(buf, "apple");
4655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4656 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4657 ok(sz == 0, "Expected 0, got %lu\n", sz);
4658
4659 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4661
4662 /* HelpLink value exists */
4663 sz = MAX_PATH;
4664 lstrcpyA(buf, "apple");
4666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4667 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4668 ok(sz == 4, "Expected 4, got %lu\n", sz);
4669
4670 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
4671 (const BYTE *)&val, sizeof(DWORD));
4672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4673
4674 /* HelpLink type is REG_DWORD */
4675 sz = MAX_PATH;
4676 lstrcpyA(buf, "apple");
4678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4679 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4680 ok(sz == 2, "Expected 2, got %lu\n", sz);
4681
4682 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4684
4685 /* DisplayName value exists */
4686 sz = MAX_PATH;
4687 lstrcpyA(buf, "apple");
4689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4690 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4691 ok(sz == 4, "Expected 4, got %lu\n", sz);
4692
4693 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4695
4696 /* DisplayName type is REG_DWORD */
4697 sz = MAX_PATH;
4698 lstrcpyA(buf, "apple");
4700 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4701 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4702 ok(sz == 2, "Expected 2, got %lu\n", sz);
4703
4704 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
4705 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4706
4707 /* DisplayVersion value exists */
4708 sz = MAX_PATH;
4709 lstrcpyA(buf, "apple");
4711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4712 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
4713 ok(sz == 5, "Expected 5, got %lu\n", sz);
4714
4715 res = RegSetValueExA(propkey, "DisplayVersion", 0,
4716 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4717 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4718
4719 /* DisplayVersion type is REG_DWORD */
4720 sz = MAX_PATH;
4721 lstrcpyA(buf, "apple");
4723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4724 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4725 ok(sz == 2, "Expected 2, got %lu\n", sz);
4726
4727 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
4728 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4729
4730 /* HelpTelephone value exists */
4731 sz = MAX_PATH;
4732 lstrcpyA(buf, "apple");
4734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4735 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
4736 ok(sz == 4, "Expected 4, got %lu\n", sz);
4737
4738 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
4739 (const BYTE *)&val, sizeof(DWORD));
4740 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4741
4742 /* HelpTelephone type is REG_DWORD */
4743 sz = MAX_PATH;
4744 lstrcpyA(buf, "apple");
4746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4747 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4748 ok(sz == 2, "Expected 2, got %lu\n", sz);
4749
4750 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4751 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4752
4753 /* InstallLocation value exists */
4754 sz = MAX_PATH;
4755 lstrcpyA(buf, "apple");
4757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4758 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4759 ok(sz == 3, "Expected 3, got %lu\n", sz);
4760
4761 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
4762 (const BYTE *)&val, sizeof(DWORD));
4763 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4764
4765 /* InstallLocation type is REG_DWORD */
4766 sz = MAX_PATH;
4767 lstrcpyA(buf, "apple");
4769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4770 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4771 ok(sz == 2, "Expected 2, got %lu\n", sz);
4772
4773 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4774 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4775
4776 /* InstallSource value exists */
4777 sz = MAX_PATH;
4778 lstrcpyA(buf, "apple");
4780 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4781 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4782 ok(sz == 6, "Expected 6, got %lu\n", sz);
4783
4784 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
4785 (const BYTE *)&val, sizeof(DWORD));
4786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4787
4788 /* InstallSource type is REG_DWORD */
4789 sz = MAX_PATH;
4790 lstrcpyA(buf, "apple");
4792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4793 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4794 ok(sz == 2, "Expected 2, got %lu\n", sz);
4795
4796 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4797 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4798
4799 /* InstallDate value exists */
4800 sz = MAX_PATH;
4801 lstrcpyA(buf, "apple");
4803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4804 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4805 ok(sz == 4, "Expected 4, got %lu\n", sz);
4806
4807 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
4808 (const BYTE *)&val, sizeof(DWORD));
4809 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4810
4811 /* InstallDate type is REG_DWORD */
4812 sz = MAX_PATH;
4813 lstrcpyA(buf, "apple");
4815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4816 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4817 ok(sz == 2, "Expected 2, got %lu\n", sz);
4818
4819 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4821
4822 /* Publisher value exists */
4823 sz = MAX_PATH;
4824 lstrcpyA(buf, "apple");
4826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4827 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4828 ok(sz == 3, "Expected 3, got %lu\n", sz);
4829
4830 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
4831 (const BYTE *)&val, sizeof(DWORD));
4832 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4833
4834 /* Publisher type is REG_DWORD */
4835 sz = MAX_PATH;
4836 lstrcpyA(buf, "apple");
4838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4839 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4840 ok(sz == 2, "Expected 2, got %lu\n", sz);
4841
4842 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
4843 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4844
4845 /* LocalPackage value exists */
4846 sz = MAX_PATH;
4847 lstrcpyA(buf, "apple");
4849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4850 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
4851 ok(sz == 4, "Expected 4, got %lu\n", sz);
4852
4853 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
4854 (const BYTE *)&val, sizeof(DWORD));
4855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4856
4857 /* LocalPackage type is REG_DWORD */
4858 sz = MAX_PATH;
4859 lstrcpyA(buf, "apple");
4861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4862 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4863 ok(sz == 2, "Expected 2, got %lu\n", sz);
4864
4865 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4867
4868 /* UrlInfoAbout value exists */
4869 sz = MAX_PATH;
4870 lstrcpyA(buf, "apple");
4872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4873 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4874 ok(sz == 5, "Expected 5, got %lu\n", sz);
4875
4876 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
4877 (const BYTE *)&val, sizeof(DWORD));
4878 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4879
4880 /* UrlInfoAbout type is REG_DWORD */
4881 sz = MAX_PATH;
4882 lstrcpyA(buf, "apple");
4884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4885 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4886 ok(sz == 2, "Expected 2, got %lu\n", sz);
4887
4888 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
4889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4890
4891 /* UrlUpdateInfo value exists */
4892 sz = MAX_PATH;
4893 lstrcpyA(buf, "apple");
4895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4896 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
4897 ok(sz == 4, "Expected 4, got %lu\n", sz);
4898
4899 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
4900 (const BYTE *)&val, sizeof(DWORD));
4901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4902
4903 /* UrlUpdateInfo type is REG_DWORD */
4904 sz = MAX_PATH;
4905 lstrcpyA(buf, "apple");
4907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4908 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4909 ok(sz == 2, "Expected 2, got %lu\n", sz);
4910
4911 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
4912 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4913
4914 /* VersionMinor value exists */
4915 sz = MAX_PATH;
4916 lstrcpyA(buf, "apple");
4918 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4919 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4920 ok(sz == 1, "Expected 1, got %lu\n", sz);
4921
4922 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
4923 (const BYTE *)&val, sizeof(DWORD));
4924 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4925
4926 /* VersionMinor type is REG_DWORD */
4927 sz = MAX_PATH;
4928 lstrcpyA(buf, "apple");
4930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4931 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4932 ok(sz == 2, "Expected 2, got %lu\n", sz);
4933
4934 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
4935 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4936
4937 /* VersionMajor value exists */
4938 sz = MAX_PATH;
4939 lstrcpyA(buf, "apple");
4941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4943 ok(sz == 1, "Expected 1, got %lu\n", sz);
4944
4945 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
4946 (const BYTE *)&val, sizeof(DWORD));
4947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4948
4949 /* VersionMajor type is REG_DWORD */
4950 sz = MAX_PATH;
4951 lstrcpyA(buf, "apple");
4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4955 ok(sz == 2, "Expected 2, got %lu\n", sz);
4956
4957 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4958 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4959
4960 /* ProductID value exists */
4961 sz = MAX_PATH;
4962 lstrcpyA(buf, "apple");
4964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4965 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4966 ok(sz == 2, "Expected 2, got %lu\n", sz);
4967
4968 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
4969 (const BYTE *)&val, sizeof(DWORD));
4970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4971
4972 /* ProductID type is REG_DWORD */
4973 sz = MAX_PATH;
4974 lstrcpyA(buf, "apple");
4976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4977 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4978 ok(sz == 2, "Expected 2, got %lu\n", sz);
4979
4980 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4981 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4982
4983 /* RegCompany value exists */
4984 sz = MAX_PATH;
4985 lstrcpyA(buf, "apple");
4987 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4988 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4989 ok(sz == 4, "Expected 4, got %lu\n", sz);
4990
4991 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
4992 (const BYTE *)&val, sizeof(DWORD));
4993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4994
4995 /* RegCompany type is REG_DWORD */
4996 sz = MAX_PATH;
4997 lstrcpyA(buf, "apple");
4999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5000 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5001 ok(sz == 2, "Expected 2, got %lu\n", sz);
5002
5003 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
5004 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5005
5006 /* RegOwner value exists */
5007 sz = MAX_PATH;
5008 lstrcpyA(buf, "apple");
5010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5011 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
5012 ok(sz == 3, "Expected 3, got %lu\n", sz);
5013
5014 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
5015 (const BYTE *)&val, sizeof(DWORD));
5016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5017
5018 /* RegOwner type is REG_DWORD */
5019 sz = MAX_PATH;
5020 lstrcpyA(buf, "apple");
5022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5023 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5024 ok(sz == 2, "Expected 2, got %lu\n", sz);
5025
5026 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5028
5029 /* InstanceType value exists */
5030 sz = MAX_PATH;
5031 lstrcpyA(buf, "apple");
5033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5034 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5035 ok(sz == 0, "Expected 0, got %lu\n", sz);
5036
5037 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
5038 (const BYTE *)&val, sizeof(DWORD));
5039 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5040
5041 /* InstanceType type is REG_DWORD */
5042 sz = MAX_PATH;
5043 lstrcpyA(buf, "apple");
5045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5046 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5047 ok(sz == 0, "Expected 0, got %lu\n", sz);
5048
5049 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5050 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5051
5052 /* InstanceType value exists */
5053 sz = MAX_PATH;
5054 lstrcpyA(buf, "apple");
5056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5057 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
5058 ok(sz == 4, "Expected 4, got %lu\n", sz);
5059
5060 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
5061 (const BYTE *)&val, sizeof(DWORD));
5062 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5063
5064 /* InstanceType type is REG_DWORD */
5065 sz = MAX_PATH;
5066 lstrcpyA(buf, "apple");
5068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5069 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5070 ok(sz == 2, "Expected 2, got %lu\n", sz);
5071
5072 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5074
5075 /* Transforms value exists */
5076 sz = MAX_PATH;
5077 lstrcpyA(buf, "apple");
5079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5080 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5081 ok(sz == 0, "Expected 0, got %lu\n", sz);
5082
5083 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
5084 (const BYTE *)&val, sizeof(DWORD));
5085 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5086
5087 /* Transforms type is REG_DWORD */
5088 sz = MAX_PATH;
5089 lstrcpyA(buf, "apple");
5091 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5092 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5093 ok(sz == 0, "Expected 0, got %lu\n", sz);
5094
5095 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5096 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5097
5098 /* Transforms value exists */
5099 sz = MAX_PATH;
5100 lstrcpyA(buf, "apple");
5102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5103 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
5104 ok(sz == 6, "Expected 6, got %lu\n", sz);
5105
5106 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
5107 (const BYTE *)&val, sizeof(DWORD));
5108 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5109
5110 /* Transforms type is REG_DWORD */
5111 sz = MAX_PATH;
5112 lstrcpyA(buf, "apple");
5114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5115 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5116 ok(sz == 2, "Expected 2, got %lu\n", sz);
5117
5118 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5120
5121 /* Language value exists */
5122 sz = MAX_PATH;
5123 lstrcpyA(buf, "apple");
5125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5126 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5127 ok(sz == 0, "Expected 0, got %lu\n", sz);
5128
5129 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
5130 (const BYTE *)&val, sizeof(DWORD));
5131 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5132
5133 /* Language type is REG_DWORD */
5134 sz = MAX_PATH;
5135 lstrcpyA(buf, "apple");
5137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5138 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5139 ok(sz == 0, "Expected 0, got %lu\n", sz);
5140
5141 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5143
5144 /* Language value exists */
5145 sz = MAX_PATH;
5146 lstrcpyA(buf, "apple");
5148 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5149 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5150 ok(sz == 4, "Expected 4, got %lu\n", sz);
5151
5152 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
5153 (const BYTE *)&val, sizeof(DWORD));
5154 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5155
5156 /* Language type is REG_DWORD */
5157 sz = MAX_PATH;
5158 lstrcpyA(buf, "apple");
5160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5161 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5162 ok(sz == 2, "Expected 2, got %lu\n", sz);
5163
5164 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5166
5167 /* ProductName value exists */
5168 sz = MAX_PATH;
5169 lstrcpyA(buf, "apple");
5171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5172 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5173 ok(sz == 0, "Expected 0, got %lu\n", sz);
5174
5175 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5176 (const BYTE *)&val, sizeof(DWORD));
5177 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5178
5179 /* ProductName type is REG_DWORD */
5180 sz = MAX_PATH;
5181 lstrcpyA(buf, "apple");
5183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5184 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5185 ok(sz == 0, "Expected 0, got %lu\n", sz);
5186
5187 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5188 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5189
5190 /* ProductName value exists */
5191 sz = MAX_PATH;
5192 lstrcpyA(buf, "apple");
5194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5195 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5196 ok(sz == 4, "Expected 4, got %lu\n", sz);
5197
5198 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5199 (const BYTE *)&val, sizeof(DWORD));
5200 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5201
5202 /* ProductName type is REG_DWORD */
5203 sz = MAX_PATH;
5204 lstrcpyA(buf, "apple");
5206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5207 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5208 ok(sz == 2, "Expected 2, got %lu\n", sz);
5209
5210 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5211 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5212
5213 /* Assignment value exists */
5214 sz = MAX_PATH;
5215 lstrcpyA(buf, "apple");
5217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5218 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5219 ok(sz == 0, "Expected 0, got %lu\n", sz);
5220
5221 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5222 (const BYTE *)&val, sizeof(DWORD));
5223 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5224
5225 /* Assignment type is REG_DWORD */
5226 sz = MAX_PATH;
5227 lstrcpyA(buf, "apple");
5229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5230 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5231 ok(sz == 0, "Expected 0, got %lu\n", sz);
5232
5233 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5235
5236 /* Assignment value exists */
5237 sz = MAX_PATH;
5238 lstrcpyA(buf, "apple");
5240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5242 ok(sz == 2, "Expected 2, got %lu\n", sz);
5243
5244 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5245 (const BYTE *)&val, sizeof(DWORD));
5246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5247
5248 /* Assignment type is REG_DWORD */
5249 sz = MAX_PATH;
5250 lstrcpyA(buf, "apple");
5252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5253 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5254 ok(sz == 2, "Expected 2, got %lu\n", sz);
5255
5256 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5258
5259 /* PackageCode value exists */
5260 sz = MAX_PATH;
5261 lstrcpyA(buf, "apple");
5263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5264 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5265 ok(sz == 0, "Expected 0, got %lu\n", sz);
5266
5267 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5268 (const BYTE *)&val, sizeof(DWORD));
5269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5270
5271 /* PackageCode type is REG_DWORD */
5272 sz = MAX_PATH;
5273 lstrcpyA(buf, "apple");
5275 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5276 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5277 ok(sz == 0, "Expected 0, got %lu\n", sz);
5278
5279 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5281
5282 /* PackageCode value exists */
5283 sz = MAX_PATH;
5284 lstrcpyA(buf, "apple");
5287 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5288 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5289 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5290
5291 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5292 (const BYTE *)&val, sizeof(DWORD));
5293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5294
5295 /* PackageCode type is REG_DWORD */
5296 sz = MAX_PATH;
5297 lstrcpyA(buf, "apple");
5299 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5300 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5301 ok(sz == 2, "Expected 2, got %lu\n", sz);
5302
5303 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5305
5306 /* PackageCode value exists */
5307 sz = MAX_PATH;
5308 lstrcpyA(buf, "apple");
5310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5311 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5312 ok(sz == 38, "Expected 38, got %lu\n", sz);
5313
5314 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5315 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5316
5317 /* Version value exists */
5318 sz = MAX_PATH;
5319 lstrcpyA(buf, "apple");
5321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5322 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5323 ok(sz == 0, "Expected 0, got %lu\n", sz);
5324
5325 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5326 (const BYTE *)&val, sizeof(DWORD));
5327 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5328
5329 /* Version type is REG_DWORD */
5330 sz = MAX_PATH;
5331 lstrcpyA(buf, "apple");
5333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5334 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5335 ok(sz == 0, "Expected 0, got %lu\n", sz);
5336
5337 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5338 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5339
5340 /* Version value exists */
5341 sz = MAX_PATH;
5342 lstrcpyA(buf, "apple");
5344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5345 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5346 ok(sz == 3, "Expected 3, got %lu\n", sz);
5347
5348 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5349 (const BYTE *)&val, sizeof(DWORD));
5350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5351
5352 /* Version type is REG_DWORD */
5353 sz = MAX_PATH;
5354 lstrcpyA(buf, "apple");
5356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5357 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5358 ok(sz == 2, "Expected 2, got %lu\n", sz);
5359
5360 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5361 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5362
5363 /* ProductIcon value exists */
5364 sz = MAX_PATH;
5365 lstrcpyA(buf, "apple");
5367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5368 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5369 ok(sz == 0, "Expected 0, got %lu\n", sz);
5370
5371 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5372 (const BYTE *)&val, sizeof(DWORD));
5373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5374
5375 /* ProductIcon type is REG_DWORD */
5376 sz = MAX_PATH;
5377 lstrcpyA(buf, "apple");
5379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5380 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5381 ok(sz == 0, "Expected 0, got %lu\n", sz);
5382
5383 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5385
5386 /* ProductIcon value exists */
5387 sz = MAX_PATH;
5388 lstrcpyA(buf, "apple");
5390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5391 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5392 ok(sz == 3, "Expected 3, got %lu\n", sz);
5393
5394 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5395 (const BYTE *)&val, sizeof(DWORD));
5396 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5397
5398 /* ProductIcon type is REG_DWORD */
5399 sz = MAX_PATH;
5400 lstrcpyA(buf, "apple");
5402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5403 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5404 ok(sz == 2, "Expected 2, got %lu\n", sz);
5405
5406 /* SourceList key does not exist */
5407 sz = MAX_PATH;
5408 lstrcpyA(buf, "apple");
5411 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5412 ok(!lstrcmpA(buf, "apple"),
5413 "Expected buf to be unchanged, got \"%s\"\n", buf);
5414 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %lu\n", sz);
5415
5416 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5417 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5418
5419 /* SourceList key exists, but PackageName val does not exist */
5420 sz = MAX_PATH;
5421 lstrcpyA(buf, "apple");
5423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5424 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5425 ok(sz == 0, "Expected 0, got %lu\n", sz);
5426
5427 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5429
5430 /* PackageName val exists */
5431 sz = MAX_PATH;
5432 lstrcpyA(buf, "apple");
5434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5435 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5436 ok(sz == 8, "Expected 8, got %lu\n", sz);
5437
5438 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5439 (const BYTE *)&val, sizeof(DWORD));
5440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5441
5442 /* PackageName type is REG_DWORD */
5443 sz = MAX_PATH;
5444 lstrcpyA(buf, "apple");
5446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5447 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5448 ok(sz == 2, "Expected 2, got %lu\n", sz);
5449
5450 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5452
5453 /* Authorized value exists */
5454 sz = MAX_PATH;
5455 lstrcpyA(buf, "apple");
5458 {
5459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5460 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5461 ok(sz == 0, "Expected 0, got %lu\n", sz);
5462 }
5463
5464 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5465 (const BYTE *)&val, sizeof(DWORD));
5466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5467
5468 /* AuthorizedLUAApp type is REG_DWORD */
5469 sz = MAX_PATH;
5470 lstrcpyA(buf, "apple");
5473 {
5474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5475 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5476 ok(sz == 0, "Expected 0, got %lu\n", sz);
5477 }
5478
5479 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5481
5482 /* Authorized value exists */
5483 sz = MAX_PATH;
5484 lstrcpyA(buf, "apple");
5487 {
5488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5489 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5490 ok(sz == 4, "Expected 4, got %lu\n", sz);
5491 }
5492
5493 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5494 (const BYTE *)&val, sizeof(DWORD));
5495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5496
5497 /* AuthorizedLUAApp type is REG_DWORD */
5498 sz = MAX_PATH;
5499 lstrcpyA(buf, "apple");
5502 {
5503 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5504 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5505 ok(sz == 2, "Expected 2, got %lu\n", sz);
5506 }
5507
5508 RegDeleteValueA(propkey, "HelpLink");
5509 RegDeleteValueA(propkey, "DisplayName");
5510 RegDeleteValueA(propkey, "DisplayVersion");
5511 RegDeleteValueA(propkey, "HelpTelephone");
5512 RegDeleteValueA(propkey, "InstallLocation");
5513 RegDeleteValueA(propkey, "InstallSource");
5514 RegDeleteValueA(propkey, "InstallDate");
5515 RegDeleteValueA(propkey, "Publisher");
5516 RegDeleteValueA(propkey, "LocalPackage");
5517 RegDeleteValueA(propkey, "UrlInfoAbout");
5518 RegDeleteValueA(propkey, "UrlUpdateInfo");
5519 RegDeleteValueA(propkey, "VersionMinor");
5520 RegDeleteValueA(propkey, "VersionMajor");
5521 RegDeleteValueA(propkey, "ProductID");
5522 RegDeleteValueA(propkey, "RegCompany");
5523 RegDeleteValueA(propkey, "RegOwner");
5524 RegDeleteValueA(propkey, "InstanceType");
5525 RegDeleteValueA(propkey, "Transforms");
5526 RegDeleteValueA(propkey, "Language");
5527 RegDeleteValueA(propkey, "ProductName");
5528 RegDeleteValueA(propkey, "Assignment");
5529 RegDeleteValueA(propkey, "PackageCode");
5530 RegDeleteValueA(propkey, "Version");
5531 RegDeleteValueA(propkey, "ProductIcon");
5532 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5533 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
5534 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
5535 RegDeleteValueA(prodkey, "InstanceType");
5536 RegDeleteValueA(prodkey, "Transforms");
5537 RegDeleteValueA(prodkey, "Language");
5538 RegDeleteValueA(prodkey, "ProductName");
5539 RegDeleteValueA(prodkey, "Assignment");
5540 RegDeleteValueA(prodkey, "PackageCode");
5541 RegDeleteValueA(prodkey, "Version");
5542 RegDeleteValueA(prodkey, "ProductIcon");
5543 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5544 RegDeleteValueA(source, "PackageName");
5546 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
5547 RegCloseKey(propkey);
5548 RegCloseKey(localkey);
5550 RegCloseKey(prodkey);
5551 LocalFree(usersid);
5552}
5553
5555{
5556 UINT r;
5557 LONG res;
5558 HKEY propkey, userkey;
5559 HKEY prodkey, localkey;
5560 CHAR prodcode[MAX_PATH];
5561 CHAR prod_squashed[MAX_PATH];
5562 CHAR packcode[MAX_PATH];
5563 CHAR pack_squashed[MAX_PATH];
5564 CHAR buf[MAX_PATH];
5565 CHAR keypath[MAX_PATH];
5566 LPSTR usersid;
5567 DWORD sz;
5569
5570 create_test_guid(prodcode, prod_squashed);
5571 create_test_guid(packcode, pack_squashed);
5572 usersid = get_user_sid();
5573
5574 if (is_wow64)
5576
5577 /* NULL szProductCode */
5578 sz = MAX_PATH;
5579 lstrcpyA(buf, "apple");
5582 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5583 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5584 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5585
5586 /* empty szProductCode */
5587 sz = MAX_PATH;
5588 lstrcpyA(buf, "apple");
5591 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5592 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5593 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5594
5595 /* garbage szProductCode */
5596 sz = MAX_PATH;
5597 lstrcpyA(buf, "apple");
5600 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5601 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5602 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5603
5604 /* guid without brackets */
5605 sz = MAX_PATH;
5606 lstrcpyA(buf, "apple");
5607 r = MsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
5610 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5611 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5612 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5613
5614 /* guid with brackets */
5615 sz = MAX_PATH;
5616 lstrcpyA(buf, "apple");
5617 r = MsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
5620 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5621 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5622 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5623
5624 /* szValue is non-NULL while pcchValue is NULL */
5625 lstrcpyA(buf, "apple");
5628 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5629 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5630
5631 /* dwContext is out of range */
5632 sz = MAX_PATH;
5633 lstrcpyA(buf, "apple");
5634 r = MsiGetProductInfoExA(prodcode, usersid, 42, INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5635 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5636 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5637 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5638
5639 /* szProperty is NULL */
5640 sz = MAX_PATH;
5641 lstrcpyA(buf, "apple");
5642 r = MsiGetProductInfoExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, NULL, buf, &sz);
5643 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5644 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5645 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5646
5647 /* szProperty is empty */
5648 sz = MAX_PATH;
5649 lstrcpyA(buf, "apple");
5650 r = MsiGetProductInfoExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, "", buf, &sz);
5651 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5652 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5653 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5654
5655 /* szProperty is not a valid property */
5656 sz = MAX_PATH;
5657 lstrcpyA(buf, "apple");
5658 r = MsiGetProductInfoExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, "notvalid", buf, &sz);
5659 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5660 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5661 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5662
5663 /* same length as guid, but random */
5664 sz = MAX_PATH;
5665 lstrcpyA(buf, "apple");
5666 r = MsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5668 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5669 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5670 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5671
5672 /* MSIINSTALLCONTEXT_USERUNMANAGED */
5673
5674 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5675 lstrcatA(keypath, usersid);
5676 lstrcatA(keypath, "\\Products\\");
5677 lstrcatA(keypath, prod_squashed);
5678
5679 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5680 if (res == ERROR_ACCESS_DENIED)
5681 {
5682 skip("Not enough rights to perform tests\n");
5683 LocalFree(usersid);
5684 return;
5685 }
5686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5687
5688 /* local user product key exists */
5689 sz = MAX_PATH;
5690 lstrcpyA(buf, "apple");
5692 buf, &sz);
5693 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5694 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5695 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5696
5697 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5698 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5699
5700 /* InstallProperties key exists */
5701 sz = MAX_PATH;
5702 lstrcpyA(buf, "apple");
5704 buf, &sz);
5705 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5706 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5707 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5708
5709 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5711
5712 /* LocalPackage value exists */
5713 sz = MAX_PATH;
5714 lstrcpyA(buf, "apple");
5716 buf, &sz);
5717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5718 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5719 ok(sz == 1, "Expected 1, got %lu\n", sz);
5720
5721 RegDeleteValueA(propkey, "LocalPackage");
5722
5723 /* LocalPackage value must exist */
5724 sz = MAX_PATH;
5725 lstrcpyA(buf, "apple");
5727 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5728 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5729 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5730
5731 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5732 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5733
5734 /* LocalPackage exists, but HelpLink does not exist */
5735 sz = MAX_PATH;
5736 lstrcpyA(buf, "apple");
5738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5739 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5740 ok(sz == 0, "Expected 0, got %lu\n", sz);
5741
5742 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5743 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5744
5745 /* HelpLink value exists */
5746 sz = MAX_PATH;
5747 lstrcpyA(buf, "apple");
5749 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5750 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5751 ok(sz == 4, "Expected 4, got %lu\n", sz);
5752
5753 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5754 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5755
5756 /* HelpTelephone value exists */
5757 sz = MAX_PATH;
5758 lstrcpyA(buf, "apple");
5760 buf, &sz);
5761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5763 ok(sz == 5, "Expected 5, got %lu\n", sz);
5764
5765 /* szValue and pcchValue are NULL */
5767 NULL, NULL);
5768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5769
5770 /* pcchValue is exactly 5 */
5771 sz = 5;
5772 lstrcpyA(buf, "apple");
5774 buf, &sz);
5775 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
5776 ok(sz == 10, "Expected 10, got %lu\n", sz);
5777
5778 /* szValue is NULL, pcchValue is exactly 5 */
5779 sz = 5;
5781 NULL, &sz);
5782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5783 ok(sz == 10, "Expected 10, got %lu\n", sz);
5784
5785 /* szValue is NULL, pcchValue is MAX_PATH */
5786 sz = MAX_PATH;
5788 NULL, &sz);
5789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5790 ok(sz == 10, "Expected 10, got %lu\n", sz);
5791
5792 /* pcchValue is exactly 0 */
5793 sz = 0;
5794 lstrcpyA(buf, "apple");
5796 buf, &sz);
5797 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
5798 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5799 ok(sz == 10, "Expected 10, got %lu\n", sz);
5800
5801 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
5802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5803
5804 /* szProperty is not a valid property */
5805 sz = MAX_PATH;
5806 lstrcpyA(buf, "apple");
5807 r = MsiGetProductInfoExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, "notvalid", buf, &sz);
5808 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5809 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5810 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5811
5812 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5813 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5814
5815 /* InstallDate value exists */
5816 sz = MAX_PATH;
5817 lstrcpyA(buf, "apple");
5819 buf, &sz);
5820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5821 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5822 ok(sz == 4, "Expected 4, got %lu\n", sz);
5823
5824 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5825 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5826
5827 /* DisplayName value exists */
5828 sz = MAX_PATH;
5829 lstrcpyA(buf, "apple");
5831 buf, &sz);
5832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5833 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5834 ok(sz == 4, "Expected 4, got %lu\n", sz);
5835
5836 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5838
5839 /* InstallLocation value exists */
5840 sz = MAX_PATH;
5841 lstrcpyA(buf, "apple");
5843 buf, &sz);
5844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5845 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5846 ok(sz == 3, "Expected 3, got %lu\n", sz);
5847
5848 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5850
5851 /* InstallSource value exists */
5852 sz = MAX_PATH;
5853 lstrcpyA(buf, "apple");
5855 buf, &sz);
5856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5857 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5858 ok(sz == 6, "Expected 6, got %lu\n", sz);
5859
5860 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5861 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5862
5863 /* LocalPackage value exists */
5864 sz = MAX_PATH;
5865 lstrcpyA(buf, "apple");
5867 buf, &sz);
5868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5869 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5870 ok(sz == 5, "Expected 5, got %lu\n", sz);
5871
5872 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5873 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5874
5875 /* Publisher value exists */
5876 sz = MAX_PATH;
5877 lstrcpyA(buf, "apple");
5879 buf, &sz);
5880 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5881 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5882 ok(sz == 3, "Expected 3, got %lu\n", sz);
5883
5884 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5886
5887 /* URLInfoAbout value exists */
5888 sz = MAX_PATH;
5889 lstrcpyA(buf, "apple");
5891 buf, &sz);
5892 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5893 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5894 ok(sz == 5, "Expected 5, got %lu\n", sz);
5895
5896 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5897 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5898
5899 /* URLUpdateInfo value exists */
5900 sz = MAX_PATH;
5901 lstrcpyA(buf, "apple");
5903 buf, &sz);
5904 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5905 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5906 ok(sz == 6, "Expected 6, got %lu\n", sz);
5907
5908 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5909 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5910
5911 /* VersionMinor value exists */
5912 sz = MAX_PATH;
5913 lstrcpyA(buf, "apple");
5915 buf, &sz);
5916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5917 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5918 ok(sz == 1, "Expected 1, got %lu\n", sz);
5919
5920 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5922
5923 /* VersionMajor value exists */
5924 sz = MAX_PATH;
5925 lstrcpyA(buf, "apple");
5927 buf, &sz);
5928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5929 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5930 ok(sz == 1, "Expected 1, got %lu\n", sz);
5931
5932 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5933 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5934
5935 /* DisplayVersion value exists */
5936 sz = MAX_PATH;
5937 lstrcpyA(buf, "apple");
5939 buf, &sz);
5940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5941 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5942 ok(sz == 5, "Expected 5, got %lu\n", sz);
5943
5944 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5945 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5946
5947 /* ProductID value exists */
5948 sz = MAX_PATH;
5949 lstrcpyA(buf, "apple");
5951 buf, &sz);
5952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5953 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5954 ok(sz == 2, "Expected 2, got %lu\n", sz);
5955
5956 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5958
5959 /* RegCompany value exists */
5960 sz = MAX_PATH;
5961 lstrcpyA(buf, "apple");
5963 buf, &sz);
5964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5965 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5966 ok(sz == 4, "Expected 4, got %lu\n", sz);
5967
5968 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5969 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5970
5971 /* RegOwner value exists */
5972 sz = MAX_PATH;
5973 lstrcpyA(buf, "apple");
5975 buf, &sz);
5976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5977 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5978 ok(sz == 5, "Expected 5, got %lu\n", sz);
5979
5980 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5981 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5982
5983 /* Transforms value exists */
5984 sz = MAX_PATH;
5985 lstrcpyA(buf, "apple");
5987 buf, &sz);
5988 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5989 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5990 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
5991
5992 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
5994
5995 /* Language value exists */
5996 sz = MAX_PATH;
5997 lstrcpyA(buf, "apple");
5999 buf, &sz);
6000 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6001 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6002 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6003
6004 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6005 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6006
6007 /* ProductName value exists */
6008 sz = MAX_PATH;
6009 lstrcpyA(buf, "apple");
6011 buf, &sz);
6012 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6013 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6014 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6015
6016 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6017 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6018
6019 /* FIXME */
6020
6021 /* AssignmentType value exists */
6022 sz = MAX_PATH;
6023 lstrcpyA(buf, "apple");
6025 buf, &sz);
6026 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6027 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6028 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6029
6030 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6031 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6032
6033 /* PackageCode value exists */
6034 sz = MAX_PATH;
6035 lstrcpyA(buf, "apple");
6037 buf, &sz);
6038 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6039 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6040 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6041
6042 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6044
6045 /* Version value exists */
6046 sz = MAX_PATH;
6047 lstrcpyA(buf, "apple");
6049 buf, &sz);
6050 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6051 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6052 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6053
6054 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6055 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6056
6057 /* ProductIcon value exists */
6058 sz = MAX_PATH;
6059 lstrcpyA(buf, "apple");
6061 buf, &sz);
6062 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6063 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6064 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6065
6066 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6067 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6068
6069 /* PackageName value exists */
6070 sz = MAX_PATH;
6071 lstrcpyA(buf, "apple");
6073 buf, &sz);
6074 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6075 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6076 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6077
6078 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6079 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6080
6081 /* AuthorizedLUAApp value exists */
6082 sz = MAX_PATH;
6083 lstrcpyA(buf, "apple");
6085 buf, &sz);
6086 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6087 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6088 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6089
6090 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6091 RegDeleteValueA(propkey, "PackageName");
6092 RegDeleteValueA(propkey, "ProductIcon");
6093 RegDeleteValueA(propkey, "Version");
6094 RegDeleteValueA(propkey, "PackageCode");
6095 RegDeleteValueA(propkey, "AssignmentType");
6096 RegDeleteValueA(propkey, "ProductName");
6097 RegDeleteValueA(propkey, "Language");
6098 RegDeleteValueA(propkey, "Transforms");
6099 RegDeleteValueA(propkey, "RegOwner");
6100 RegDeleteValueA(propkey, "RegCompany");
6101 RegDeleteValueA(propkey, "ProductID");
6102 RegDeleteValueA(propkey, "DisplayVersion");
6103 RegDeleteValueA(propkey, "VersionMajor");
6104 RegDeleteValueA(propkey, "VersionMinor");
6105 RegDeleteValueA(propkey, "URLUpdateInfo");
6106 RegDeleteValueA(propkey, "URLInfoAbout");
6107 RegDeleteValueA(propkey, "Publisher");
6108 RegDeleteValueA(propkey, "LocalPackage");
6109 RegDeleteValueA(propkey, "InstallSource");
6110 RegDeleteValueA(propkey, "InstallLocation");
6111 RegDeleteValueA(propkey, "DisplayName");
6112 RegDeleteValueA(propkey, "InstallDate");
6113 RegDeleteValueA(propkey, "HelpTelephone");
6114 RegDeleteValueA(propkey, "HelpLink");
6115 RegDeleteValueA(propkey, "LocalPackage");
6116 RegDeleteKeyA(propkey, "");
6117 RegCloseKey(propkey);
6118 RegDeleteKeyA(localkey, "");
6119 RegCloseKey(localkey);
6120
6121 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6122 lstrcatA(keypath, usersid);
6123 lstrcatA(keypath, "\\Installer\\Products\\");
6124 lstrcatA(keypath, prod_squashed);
6125
6126 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6127 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6128
6129 /* user product key exists */
6130 sz = MAX_PATH;
6131 lstrcpyA(buf, "apple");
6133 buf, &sz);
6134 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6135 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6136 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6137
6138 RegDeleteKeyA(userkey, "");
6139 RegCloseKey(userkey);
6140
6141 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6142 lstrcatA(keypath, prod_squashed);
6143
6144 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6146
6147 sz = MAX_PATH;
6148 lstrcpyA(buf, "apple");
6150 buf, &sz);
6151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6152 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6153 ok(sz == 1, "Expected 1, got %lu\n", sz);
6154
6155 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6156 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6157
6158 /* HelpLink value exists */
6159 sz = MAX_PATH;
6160 lstrcpyA(buf, "apple");
6162 buf, &sz);
6163 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6164 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6165 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6166
6167 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6169
6170 /* HelpTelephone value exists */
6171 sz = MAX_PATH;
6172 lstrcpyA(buf, "apple");
6174 buf, &sz);
6175 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6176 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6177 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6178
6179 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6180 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6181
6182 /* InstallDate value exists */
6183 sz = MAX_PATH;
6184 lstrcpyA(buf, "apple");
6186 buf, &sz);
6187 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6188 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6189 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6190
6191 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6192 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6193
6194 /* DisplayName value exists */
6195 sz = MAX_PATH;
6196 lstrcpyA(buf, "apple");
6198 buf, &sz);
6199 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6200 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6201 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6202
6203 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6205
6206 /* InstallLocation value exists */
6207 sz = MAX_PATH;
6208 lstrcpyA(buf, "apple");
6210 buf, &sz);
6211 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6212 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6213 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6214
6215 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6216 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6217
6218 /* InstallSource value exists */
6219 sz = MAX_PATH;
6220 lstrcpyA(buf, "apple");
6222 buf, &sz);
6223 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6224 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6225 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6226
6227 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6229
6230 /* LocalPackage value exists */
6231 sz = MAX_PATH;
6232 lstrcpyA(buf, "apple");
6234 buf, &sz);
6235 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6236 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6237 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6238
6239 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6241
6242 /* Publisher value exists */
6243 sz = MAX_PATH;
6244 lstrcpyA(buf, "apple");
6246 buf, &sz);
6247 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6248 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6249 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6250
6251 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6252 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6253
6254 /* URLInfoAbout value exists */
6255 sz = MAX_PATH;
6256 lstrcpyA(buf, "apple");
6258 buf, &sz);
6259 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6260 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6261 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6262
6263 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6265
6266 /* URLUpdateInfo value exists */
6267 sz = MAX_PATH;
6268 lstrcpyA(buf, "apple");
6270 buf, &sz);
6271 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6272 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6273 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6274
6275 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6277
6278 /* VersionMinor value exists */
6279 sz = MAX_PATH;
6280 lstrcpyA(buf, "apple");
6282 buf, &sz);
6283 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6284 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6285 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6286
6287 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6289
6290 /* VersionMajor value exists */
6291 sz = MAX_PATH;
6292 lstrcpyA(buf, "apple");
6294 buf, &sz);
6295 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6296 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6297 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6298
6299 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6301
6302 /* DisplayVersion value exists */
6303 sz = MAX_PATH;
6304 lstrcpyA(buf, "apple");
6306 buf, &sz);
6307 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6308 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6309 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6310
6311 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6312 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6313
6314 /* ProductID value exists */
6315 sz = MAX_PATH;
6316 lstrcpyA(buf, "apple");
6318 buf, &sz);
6319 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6320 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6321 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6322
6323 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6324 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6325
6326 /* RegCompany value exists */
6327 sz = MAX_PATH;
6328 lstrcpyA(buf, "apple");
6330 buf, &sz);
6331 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6332 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6333 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6334
6335 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6336 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6337
6338 /* RegOwner value exists */
6339 sz = MAX_PATH;
6340 lstrcpyA(buf, "apple");
6342 buf, &sz);
6343 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6344 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6345 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6346
6347 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6349
6350 /* Transforms value exists */
6351 sz = MAX_PATH;
6352 lstrcpyA(buf, "apple");
6354 buf, &sz);
6355 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6356 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6357 ok(sz == 5, "Expected 5, got %lu\n", sz);
6358
6359 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6361
6362 /* Language value exists */
6363 sz = MAX_PATH;
6364 lstrcpyA(buf, "apple");
6366 buf, &sz);
6367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6368 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6369 ok(sz == 4, "Expected 4, got %lu\n", sz);
6370
6371 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6372 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6373
6374 /* ProductName value exists */
6375 sz = MAX_PATH;
6376 lstrcpyA(buf, "apple");
6378 buf, &sz);
6379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6380 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6381 ok(sz == 4, "Expected 4, got %lu\n", sz);
6382
6383 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6385
6386 /* FIXME */
6387
6388 /* AssignmentType value exists */
6389 sz = MAX_PATH;
6390 lstrcpyA(buf, "apple");
6392 buf, &sz);
6393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6394 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6395 ok(sz == 0, "Expected 0, got %lu\n", sz);
6396
6397 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6399
6400 /* FIXME */
6401
6402 /* PackageCode value exists */
6403 sz = MAX_PATH;
6404 lstrcpyA(buf, "apple");
6406 buf, &sz);
6407 todo_wine
6408 {
6409 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6410 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6411 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6412 }
6413
6414 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6415 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6416
6417 /* Version value exists */
6418 sz = MAX_PATH;
6419 lstrcpyA(buf, "apple");
6421 buf, &sz);
6422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6423 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6424 ok(sz == 3, "Expected 3, got %lu\n", sz);
6425
6426 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6428
6429 /* ProductIcon value exists */
6430 sz = MAX_PATH;
6431 lstrcpyA(buf, "apple");
6433 buf, &sz);
6434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6435 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6436 ok(sz == 4, "Expected 4, got %lu\n", sz);
6437
6438 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6440
6441 /* PackageName value exists */
6442 sz = MAX_PATH;
6443 lstrcpyA(buf, "apple");
6445 buf, &sz);
6446 todo_wine
6447 {
6448 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6449 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6450 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6451 }
6452
6453 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6455
6456 /* AuthorizedLUAApp value exists */
6457 sz = MAX_PATH;
6458 lstrcpyA(buf, "apple");
6460 buf, &sz);
6461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6462 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6463 ok(sz == 4, "Expected 4, got %lu\n", sz);
6464
6465 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6466 RegDeleteValueA(prodkey, "PackageName");
6467 RegDeleteValueA(prodkey, "ProductIcon");
6468 RegDeleteValueA(prodkey, "Version");
6469 RegDeleteValueA(prodkey, "PackageCode");
6470 RegDeleteValueA(prodkey, "AssignmentType");
6471 RegDeleteValueA(prodkey, "ProductName");
6472 RegDeleteValueA(prodkey, "Language");
6473 RegDeleteValueA(prodkey, "Transforms");
6474 RegDeleteValueA(prodkey, "RegOwner");
6475 RegDeleteValueA(prodkey, "RegCompany");
6476 RegDeleteValueA(prodkey, "ProductID");
6477 RegDeleteValueA(prodkey, "DisplayVersion");
6478 RegDeleteValueA(prodkey, "VersionMajor");
6479 RegDeleteValueA(prodkey, "VersionMinor");
6480 RegDeleteValueA(prodkey, "URLUpdateInfo");
6481 RegDeleteValueA(prodkey, "URLInfoAbout");
6482 RegDeleteValueA(prodkey, "Publisher");
6483 RegDeleteValueA(prodkey, "LocalPackage");
6484 RegDeleteValueA(prodkey, "InstallSource");
6485 RegDeleteValueA(prodkey, "InstallLocation");
6486 RegDeleteValueA(prodkey, "DisplayName");
6487 RegDeleteValueA(prodkey, "InstallDate");
6488 RegDeleteValueA(prodkey, "HelpTelephone");
6489 RegDeleteValueA(prodkey, "HelpLink");
6490 RegDeleteValueA(prodkey, "LocalPackage");
6491 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
6492 RegCloseKey(prodkey);
6493
6494 /* MSIINSTALLCONTEXT_USERMANAGED */
6495
6496 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6497 lstrcatA(keypath, usersid);
6498 lstrcatA(keypath, "\\Products\\");
6499 lstrcatA(keypath, prod_squashed);
6500
6501 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6502 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6503
6504 /* local user product key exists */
6505 sz = MAX_PATH;
6506 lstrcpyA(buf, "apple");
6508 buf, &sz);
6509 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6510 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6511 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6512
6513 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6515
6516 /* InstallProperties key exists */
6517 sz = MAX_PATH;
6518 lstrcpyA(buf, "apple");
6520 buf, &sz);
6521 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6522 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6523 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6524
6525 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6526 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6527
6528 /* ManagedLocalPackage value exists */
6529 sz = MAX_PATH;
6530 lstrcpyA(buf, "apple");
6532 buf, &sz);
6533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6534 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6535 ok(sz == 1, "Expected 1, got %lu\n", sz);
6536
6537 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6539
6540 /* HelpLink value exists */
6541 sz = MAX_PATH;
6542 lstrcpyA(buf, "apple");
6544 buf, &sz);
6545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6546 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6547 ok(sz == 4, "Expected 4, got %lu\n", sz);
6548
6549 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6550 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6551
6552 /* HelpTelephone value exists */
6553 sz = MAX_PATH;
6554 lstrcpyA(buf, "apple");
6556 buf, &sz);
6557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6558 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6559 ok(sz == 5, "Expected 5, got %lu\n", sz);
6560
6561 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6563
6564 /* InstallDate value exists */
6565 sz = MAX_PATH;
6566 lstrcpyA(buf, "apple");
6568 buf, &sz);
6569 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6570 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6571 ok(sz == 4, "Expected 4, got %lu\n", sz);
6572
6573 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6574 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6575
6576 /* DisplayName value exists */
6577 sz = MAX_PATH;
6578 lstrcpyA(buf, "apple");
6580 buf, &sz);
6581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6582 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6583 ok(sz == 4, "Expected 4, got %lu\n", sz);
6584
6585 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6586 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6587
6588 /* InstallLocation value exists */
6589 sz = MAX_PATH;
6590 lstrcpyA(buf, "apple");
6592 buf, &sz);
6593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6594 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6595 ok(sz == 3, "Expected 3, got %lu\n", sz);
6596
6597 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6598 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6599
6600 /* InstallSource value exists */
6601 sz = MAX_PATH;
6602 lstrcpyA(buf, "apple");
6604 buf, &sz);
6605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6606 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6607 ok(sz == 6, "Expected 6, got %lu\n", sz);
6608
6609 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6610 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6611
6612 /* LocalPackage value exists */
6613 sz = MAX_PATH;
6614 lstrcpyA(buf, "apple");
6616 buf, &sz);
6617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6618 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6619 ok(sz == 5, "Expected 5, got %lu\n", sz);
6620
6621 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6622 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6623
6624 /* Publisher value exists */
6625 sz = MAX_PATH;
6626 lstrcpyA(buf, "apple");
6628 buf, &sz);
6629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6630 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6631 ok(sz == 3, "Expected 3, got %lu\n", sz);
6632
6633 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6634 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6635
6636 /* URLInfoAbout value exists */
6637 sz = MAX_PATH;
6638 lstrcpyA(buf, "apple");
6640 buf, &sz);
6641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6642 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6643 ok(sz == 5, "Expected 5, got %lu\n", sz);
6644
6645 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6646 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6647
6648 /* URLUpdateInfo value exists */
6649 sz = MAX_PATH;
6650 lstrcpyA(buf, "apple");
6652 buf, &sz);
6653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6654 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6655 ok(sz == 6, "Expected 6, got %lu\n", sz);
6656
6657 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6658 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6659
6660 /* VersionMinor value exists */
6661 sz = MAX_PATH;
6662 lstrcpyA(buf, "apple");
6664 buf, &sz);
6665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6666 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6667 ok(sz == 1, "Expected 1, got %lu\n", sz);
6668
6669 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6670 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6671
6672 /* VersionMajor value exists */
6673 sz = MAX_PATH;
6674 lstrcpyA(buf, "apple");
6676 buf, &sz);
6677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6678 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6679 ok(sz == 1, "Expected 1, got %lu\n", sz);
6680
6681 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6682 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6683
6684 /* DisplayVersion value exists */
6685 sz = MAX_PATH;
6686 lstrcpyA(buf, "apple");
6688 buf, &sz);
6689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6690 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6691 ok(sz == 5, "Expected 5, got %lu\n", sz);
6692
6693 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6695
6696 /* ProductID value exists */
6697 sz = MAX_PATH;
6698 lstrcpyA(buf, "apple");
6700 buf, &sz);
6701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6702 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6703 ok(sz == 2, "Expected 2, got %lu\n", sz);
6704
6705 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6706 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6707
6708 /* RegCompany value exists */
6709 sz = MAX_PATH;
6710 lstrcpyA(buf, "apple");
6712 buf, &sz);
6713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6714 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6715 ok(sz == 4, "Expected 4, got %lu\n", sz);
6716
6717 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6718 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6719
6720 /* RegOwner value exists */
6721 sz = MAX_PATH;
6722 lstrcpyA(buf, "apple");
6724 buf, &sz);
6725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6726 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6727 ok(sz == 5, "Expected 5, got %lu\n", sz);
6728
6729 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6731
6732 /* Transforms value exists */
6733 sz = MAX_PATH;
6734 lstrcpyA(buf, "apple");
6736 buf, &sz);
6737 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6738 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6739 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6740
6741 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6742 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6743
6744 /* Language value exists */
6745 sz = MAX_PATH;
6746 lstrcpyA(buf, "apple");
6748 buf, &sz);
6749 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6750 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6751 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6752
6753 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6754 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6755
6756 /* ProductName value exists */
6757 sz = MAX_PATH;
6758 lstrcpyA(buf, "apple");
6760 buf, &sz);
6761 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6762 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6763 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6764
6765 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6767
6768 /* FIXME */
6769
6770 /* AssignmentType value exists */
6771 sz = MAX_PATH;
6772 lstrcpyA(buf, "apple");
6774 buf, &sz);
6775 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6776 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6777 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6778
6779 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6780 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6781
6782 /* PackageCode value exists */
6783 sz = MAX_PATH;
6784 lstrcpyA(buf, "apple");
6786 buf, &sz);
6787 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6788 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6789 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6790
6791 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6793
6794 /* Version value exists */
6795 sz = MAX_PATH;
6796 lstrcpyA(buf, "apple");
6798 buf, &sz);
6799 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6800 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6801 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6802
6803 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6805
6806 /* ProductIcon value exists */
6807 sz = MAX_PATH;
6808 lstrcpyA(buf, "apple");
6810 buf, &sz);
6811 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6812 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6813 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6814
6815 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6817
6818 /* PackageName value exists */
6819 sz = MAX_PATH;
6820 lstrcpyA(buf, "apple");
6822 buf, &sz);
6823 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6824 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6825 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6826
6827 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6828 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6829
6830 /* AuthorizedLUAApp value exists */
6831 sz = MAX_PATH;
6832 lstrcpyA(buf, "apple");
6834 buf, &sz);
6835 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6836 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6837 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6838
6839 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6840 RegDeleteValueA(propkey, "PackageName");
6841 RegDeleteValueA(propkey, "ProductIcon");
6842 RegDeleteValueA(propkey, "Version");
6843 RegDeleteValueA(propkey, "PackageCode");
6844 RegDeleteValueA(propkey, "AssignmentType");
6845 RegDeleteValueA(propkey, "ProductName");
6846 RegDeleteValueA(propkey, "Language");
6847 RegDeleteValueA(propkey, "Transforms");
6848 RegDeleteValueA(propkey, "RegOwner");
6849 RegDeleteValueA(propkey, "RegCompany");
6850 RegDeleteValueA(propkey, "ProductID");
6851 RegDeleteValueA(propkey, "DisplayVersion");
6852 RegDeleteValueA(propkey, "VersionMajor");
6853 RegDeleteValueA(propkey, "VersionMinor");
6854 RegDeleteValueA(propkey, "URLUpdateInfo");
6855 RegDeleteValueA(propkey, "URLInfoAbout");
6856 RegDeleteValueA(propkey, "Publisher");
6857 RegDeleteValueA(propkey, "LocalPackage");
6858 RegDeleteValueA(propkey, "InstallSource");
6859 RegDeleteValueA(propkey, "InstallLocation");
6860 RegDeleteValueA(propkey, "DisplayName");
6861 RegDeleteValueA(propkey, "InstallDate");
6862 RegDeleteValueA(propkey, "HelpTelephone");
6863 RegDeleteValueA(propkey, "HelpLink");
6864 RegDeleteValueA(propkey, "ManagedLocalPackage");
6865 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
6866 RegCloseKey(propkey);
6867 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
6868 RegCloseKey(localkey);
6869
6870 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6871 lstrcatA(keypath, usersid);
6872 lstrcatA(keypath, "\\Installer\\Products\\");
6873 lstrcatA(keypath, prod_squashed);
6874
6875 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6877
6878 /* user product key exists */
6879 sz = MAX_PATH;
6880 lstrcpyA(buf, "apple");
6882 buf, &sz);
6883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6884 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6885 ok(sz == 1, "Expected 1, got %lu\n", sz);
6886
6887 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
6888 RegCloseKey(userkey);
6889
6890 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6891 lstrcatA(keypath, prod_squashed);
6892
6893 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6894 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6895
6896 /* current user product key exists */
6897 sz = MAX_PATH;
6898 lstrcpyA(buf, "apple");
6900 buf, &sz);
6901 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6902 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6903 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6904
6905 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6906 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6907
6908 /* HelpLink value exists, user product key does not exist */
6909 sz = MAX_PATH;
6910 lstrcpyA(buf, "apple");
6912 buf, &sz);
6913 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6914 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6915 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6916
6917 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6918 lstrcatA(keypath, usersid);
6919 lstrcatA(keypath, "\\Installer\\Products\\");
6920 lstrcatA(keypath, prod_squashed);
6921
6922 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6923 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6924
6925 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6926 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6927
6928 /* HelpLink value exists, user product key does exist */
6929 sz = MAX_PATH;
6930 lstrcpyA(buf, "apple");
6932 buf, &sz);
6933 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6934 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6935 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6936
6937 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6938 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6939
6940 /* HelpTelephone value exists */
6941 sz = MAX_PATH;
6942 lstrcpyA(buf, "apple");
6944 buf, &sz);
6945 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6946 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6947 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6948
6949 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6950 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6951
6952 /* InstallDate value exists */
6953 sz = MAX_PATH;
6954 lstrcpyA(buf, "apple");
6956 buf, &sz);
6957 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6958 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6959 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6960
6961 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6963
6964 /* DisplayName value exists */
6965 sz = MAX_PATH;
6966 lstrcpyA(buf, "apple");
6968 buf, &sz);
6969 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6970 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6971 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6972
6973 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6974 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6975
6976 /* InstallLocation value exists */
6977 sz = MAX_PATH;
6978 lstrcpyA(buf, "apple");
6980 buf, &sz);
6981 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6982 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6983 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6984
6985 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6986 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6987
6988 /* InstallSource value exists */
6989 sz = MAX_PATH;
6990 lstrcpyA(buf, "apple");
6992 buf, &sz);
6993 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6994 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6995 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
6996
6997 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6998 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
6999
7000 /* LocalPackage value exists */
7001 sz = MAX_PATH;
7002 lstrcpyA(buf, "apple");
7004 buf, &sz);
7005 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7006 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7007 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7008
7009 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7010 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7011
7012 /* Publisher value exists */
7013 sz = MAX_PATH;
7014 lstrcpyA(buf, "apple");
7016 buf, &sz);
7017 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7018 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7019 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7020
7021 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7022 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7023
7024 /* URLInfoAbout value exists */
7025 sz = MAX_PATH;
7026 lstrcpyA(buf, "apple");
7028 buf, &sz);
7029 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7030 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7031 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7032
7033 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7034 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7035
7036 /* URLUpdateInfo value exists */
7037 sz = MAX_PATH;
7038 lstrcpyA(buf, "apple");
7040 buf, &sz);
7041 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7042 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7043 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7044
7045 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7046 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7047
7048 /* VersionMinor value exists */
7049 sz = MAX_PATH;
7050 lstrcpyA(buf, "apple");
7052 buf, &sz);
7053 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7054 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7055 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7056
7057 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7059
7060 /* VersionMajor value exists */
7061 sz = MAX_PATH;
7062 lstrcpyA(buf, "apple");
7064 buf, &sz);
7065 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7066 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7067 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7068
7069 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7070 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7071
7072 /* DisplayVersion value exists */
7073 sz = MAX_PATH;
7074 lstrcpyA(buf, "apple");
7076 buf, &sz);
7077 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7078 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7079 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7080
7081 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7082 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7083
7084 /* ProductID value exists */
7085 sz = MAX_PATH;
7086 lstrcpyA(buf, "apple");
7088 buf, &sz);
7089 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7090 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7091 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7092
7093 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7095
7096 /* RegCompany value exists */
7097 sz = MAX_PATH;
7098 lstrcpyA(buf, "apple");
7100 buf, &sz);
7101 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7102 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7103 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7104
7105 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7106 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7107
7108 /* RegOwner value exists */
7109 sz = MAX_PATH;
7110 lstrcpyA(buf, "apple");
7112 buf, &sz);
7113 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7114 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7115 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7116
7117 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7118 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7119
7120 /* Transforms value exists */
7121 sz = MAX_PATH;
7122 lstrcpyA(buf, "apple");
7124 buf, &sz);
7125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7126 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7127 ok(sz == 5, "Expected 5, got %lu\n", sz);
7128
7129 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7130 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7131
7132 /* Language value exists */
7133 sz = MAX_PATH;
7134 lstrcpyA(buf, "apple");
7136 buf, &sz);
7137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7138 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7139 ok(sz == 4, "Expected 4, got %lu\n", sz);
7140
7141 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7143
7144 /* ProductName value exists */
7145 sz = MAX_PATH;
7146 lstrcpyA(buf, "apple");
7148 buf, &sz);
7149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7150 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7151 ok(sz == 4, "Expected 4, got %lu\n", sz);
7152
7153 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7154 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7155
7156 /* FIXME */
7157
7158 /* AssignmentType value exists */
7159 sz = MAX_PATH;
7160 lstrcpyA(buf, "apple");
7162 buf, &sz);
7163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7164 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7165 ok(sz == 0, "Expected 0, got %lu\n", sz);
7166
7167 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7169
7170 /* FIXME */
7171
7172 /* PackageCode value exists */
7173 sz = MAX_PATH;
7174 lstrcpyA(buf, "apple");
7176 buf, &sz);
7177 todo_wine
7178 {
7179 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7180 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7181 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7182 }
7183
7184 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7186
7187 /* Version value exists */
7188 sz = MAX_PATH;
7189 lstrcpyA(buf, "apple");
7191 buf, &sz);
7192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7193 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7194 ok(sz == 3, "Expected 3, got %lu\n", sz);
7195
7196 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7198
7199 /* ProductIcon value exists */
7200 sz = MAX_PATH;
7201 lstrcpyA(buf, "apple");
7203 buf, &sz);
7204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7205 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7206 ok(sz == 4, "Expected 4, got %lu\n", sz);
7207
7208 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7209 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7210
7211 /* PackageName value exists */
7212 sz = MAX_PATH;
7213 lstrcpyA(buf, "apple");
7215 buf, &sz);
7216 todo_wine
7217 {
7218 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7219 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7220 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7221 }
7222
7223 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7225
7226 /* AuthorizedLUAApp value exists */
7227 sz = MAX_PATH;
7228 lstrcpyA(buf, "apple");
7230 buf, &sz);
7231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7232 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7233 ok(sz == 4, "Expected 4, got %lu\n", sz);
7234
7235 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7236 RegDeleteValueA(userkey, "PackageName");
7237 RegDeleteValueA(userkey, "ProductIcon");
7238 RegDeleteValueA(userkey, "Version");
7239 RegDeleteValueA(userkey, "PackageCode");
7240 RegDeleteValueA(userkey, "AssignmentType");
7241 RegDeleteValueA(userkey, "ProductName");
7242 RegDeleteValueA(userkey, "Language");
7243 RegDeleteValueA(userkey, "Transforms");
7244 RegDeleteValueA(userkey, "RegOwner");
7245 RegDeleteValueA(userkey, "RegCompany");
7246 RegDeleteValueA(userkey, "ProductID");
7247 RegDeleteValueA(userkey, "DisplayVersion");
7248 RegDeleteValueA(userkey, "VersionMajor");
7249 RegDeleteValueA(userkey, "VersionMinor");
7250 RegDeleteValueA(userkey, "URLUpdateInfo");
7251 RegDeleteValueA(userkey, "URLInfoAbout");
7252 RegDeleteValueA(userkey, "Publisher");
7253 RegDeleteValueA(userkey, "LocalPackage");
7254 RegDeleteValueA(userkey, "InstallSource");
7255 RegDeleteValueA(userkey, "InstallLocation");
7256 RegDeleteValueA(userkey, "DisplayName");
7257 RegDeleteValueA(userkey, "InstallDate");
7258 RegDeleteValueA(userkey, "HelpTelephone");
7259 RegDeleteValueA(userkey, "HelpLink");
7260 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
7261 RegCloseKey(userkey);
7262 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
7263 RegCloseKey(prodkey);
7264
7265 /* MSIINSTALLCONTEXT_MACHINE */
7266
7267 /* szUserSid is non-NULL */
7268 sz = MAX_PATH;
7269 lstrcpyA(buf, "apple");
7271 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7272 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7273 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7274
7275 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7276 lstrcatA(keypath, prod_squashed);
7277
7278 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7279 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7280
7281 /* local system product key exists */
7282 sz = MAX_PATH;
7283 lstrcpyA(buf, "apple");
7285 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7286 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7287 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7288
7289 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7290 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7291
7292 /* InstallProperties key exists */
7293 sz = MAX_PATH;
7294 lstrcpyA(buf, "apple");
7296 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7297 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7298 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7299
7300 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7301 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7302
7303 /* LocalPackage value exists */
7304 sz = MAX_PATH;
7305 lstrcpyA(buf, "apple");
7307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7308 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7309 ok(sz == 1, "Expected 1, got %lu\n", sz);
7310
7311 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7312 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7313
7314 /* HelpLink value exists */
7315 sz = MAX_PATH;
7316 lstrcpyA(buf, "apple");
7318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7319 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7320 ok(sz == 4, "Expected 4, got %lu\n", sz);
7321
7322 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7324
7325 /* HelpTelephone value exists */
7326 sz = MAX_PATH;
7327 lstrcpyA(buf, "apple");
7329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7330 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7331 ok(sz == 5, "Expected 5, got %lu\n", sz);
7332
7333 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7334 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7335
7336 /* InstallDate value exists */
7337 sz = MAX_PATH;
7338 lstrcpyA(buf, "apple");
7340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7341 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7342 ok(sz == 4, "Expected 4, got %lu\n", sz);
7343
7344 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7346
7347 /* DisplayName value exists */
7348 sz = MAX_PATH;
7349 lstrcpyA(buf, "apple");
7351 buf, &sz);
7352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7353 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7354 ok(sz == 4, "Expected 4, got %lu\n", sz);
7355
7356 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7357 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7358
7359 /* InstallLocation value exists */
7360 sz = MAX_PATH;
7361 lstrcpyA(buf, "apple");
7363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7364 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7365 ok(sz == 3, "Expected 3, got %lu\n", sz);
7366
7367 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7369
7370 /* InstallSource value exists */
7371 sz = MAX_PATH;
7372 lstrcpyA(buf, "apple");
7374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7375 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7376 ok(sz == 6, "Expected 6, got %lu\n", sz);
7377
7378 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7379 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7380
7381 /* LocalPackage value exists */
7382 sz = MAX_PATH;
7383 lstrcpyA(buf, "apple");
7385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7386 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7387 ok(sz == 5, "Expected 5, got %lu\n", sz);
7388
7389 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7390 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7391
7392 /* Publisher value exists */
7393 sz = MAX_PATH;
7394 lstrcpyA(buf, "apple");
7396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7397 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7398 ok(sz == 3, "Expected 3, got %lu\n", sz);
7399
7400 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7401 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7402
7403 /* URLInfoAbout value exists */
7404 sz = MAX_PATH;
7405 lstrcpyA(buf, "apple");
7407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7408 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7409 ok(sz == 5, "Expected 5, got %lu\n", sz);
7410
7411 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7413
7414 /* URLUpdateInfo value exists */
7415 sz = MAX_PATH;
7416 lstrcpyA(buf, "apple");
7418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7419 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7420 ok(sz == 6, "Expected 6, got %lu\n", sz);
7421
7422 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7424
7425 /* VersionMinor value exists */
7426 sz = MAX_PATH;
7427 lstrcpyA(buf, "apple");
7429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7430 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7431 ok(sz == 1, "Expected 1, got %lu\n", sz);
7432
7433 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7435
7436 /* VersionMajor value exists */
7437 sz = MAX_PATH;
7438 lstrcpyA(buf, "apple");
7440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7441 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7442 ok(sz == 1, "Expected 1, got %lu\n", sz);
7443
7444 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7445 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7446
7447 /* DisplayVersion value exists */
7448 sz = MAX_PATH;
7449 lstrcpyA(buf, "apple");
7451 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7452 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7453 ok(sz == 5, "Expected 5, got %lu\n", sz);
7454
7455 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7457
7458 /* ProductID value exists */
7459 sz = MAX_PATH;
7460 lstrcpyA(buf, "apple");
7462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7463 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7464 ok(sz == 2, "Expected 2, got %lu\n", sz);
7465
7466 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7468
7469 /* RegCompany value exists */
7470 sz = MAX_PATH;
7471 lstrcpyA(buf, "apple");
7473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7474 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7475 ok(sz == 4, "Expected 4, got %lu\n", sz);
7476
7477 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7479
7480 /* RegOwner value exists */
7481 sz = MAX_PATH;
7482 lstrcpyA(buf, "apple");
7484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7485 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7486 ok(sz == 5, "Expected 5, got %lu\n", sz);
7487
7488 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7489 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7490
7491 /* Transforms value exists */
7492 sz = MAX_PATH;
7493 lstrcpyA(buf, "apple");
7495 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7496 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7497 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7498
7499 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7500 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7501
7502 /* Language value exists */
7503 sz = MAX_PATH;
7504 lstrcpyA(buf, "apple");
7506 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7507 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7508 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7509
7510 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7512
7513 /* ProductName value exists */
7514 sz = MAX_PATH;
7515 lstrcpyA(buf, "apple");
7517 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7518 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7519 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7520
7521 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7523
7524 /* FIXME */
7525
7526 /* AssignmentType value exists */
7527 sz = MAX_PATH;
7528 lstrcpyA(buf, "apple");
7530 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7531 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7532 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7533
7534 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7535 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7536
7537 /* PackageCode value exists */
7538 sz = MAX_PATH;
7539 lstrcpyA(buf, "apple");
7541 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7542 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7543 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7544
7545 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7546 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7547
7548 /* Version value exists */
7549 sz = MAX_PATH;
7550 lstrcpyA(buf, "apple");
7552 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7553 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7554 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7555
7556 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7557 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7558
7559 /* ProductIcon value exists */
7560 sz = MAX_PATH;
7561 lstrcpyA(buf, "apple");
7563 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7564 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7565 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7566
7567 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7568 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7569
7570 /* PackageName value exists */
7571 sz = MAX_PATH;
7572 lstrcpyA(buf, "apple");
7574 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7575 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7576 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7577
7578 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7579 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7580
7581 /* AuthorizedLUAApp value exists */
7582 sz = MAX_PATH;
7583 lstrcpyA(buf, "apple");
7585 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7586 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7587 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7588
7589 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7590 RegDeleteValueA(propkey, "PackageName");
7591 RegDeleteValueA(propkey, "ProductIcon");
7592 RegDeleteValueA(propkey, "Version");
7593 RegDeleteValueA(propkey, "PackageCode");
7594 RegDeleteValueA(propkey, "AssignmentType");
7595 RegDeleteValueA(propkey, "ProductName");
7596 RegDeleteValueA(propkey, "Language");
7597 RegDeleteValueA(propkey, "Transforms");
7598 RegDeleteValueA(propkey, "RegOwner");
7599 RegDeleteValueA(propkey, "RegCompany");
7600 RegDeleteValueA(propkey, "ProductID");
7601 RegDeleteValueA(propkey, "DisplayVersion");
7602 RegDeleteValueA(propkey, "VersionMajor");
7603 RegDeleteValueA(propkey, "VersionMinor");
7604 RegDeleteValueA(propkey, "URLUpdateInfo");
7605 RegDeleteValueA(propkey, "URLInfoAbout");
7606 RegDeleteValueA(propkey, "Publisher");
7607 RegDeleteValueA(propkey, "LocalPackage");
7608 RegDeleteValueA(propkey, "InstallSource");
7609 RegDeleteValueA(propkey, "InstallLocation");
7610 RegDeleteValueA(propkey, "DisplayName");
7611 RegDeleteValueA(propkey, "InstallDate");
7612 RegDeleteValueA(propkey, "HelpTelephone");
7613 RegDeleteValueA(propkey, "HelpLink");
7614 RegDeleteValueA(propkey, "LocalPackage");
7615 RegDeleteKeyExA(propkey, "", access & KEY_WOW64_64KEY, 0);
7616 RegCloseKey(propkey);
7617 RegDeleteKeyExA(localkey, "", access & KEY_WOW64_64KEY, 0);
7618 RegCloseKey(localkey);
7619
7620 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7621 lstrcatA(keypath, prod_squashed);
7622
7623 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7624 if (res == ERROR_ACCESS_DENIED)
7625 {
7626 skip( "insufficient rights\n" );
7627 LocalFree( usersid );
7628 return;
7629 }
7630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7631
7632 /* local classes product key exists */
7633 sz = MAX_PATH;
7634 lstrcpyA(buf, "apple");
7636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7637 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7638 ok(sz == 1, "Expected 1, got %lu\n", sz);
7639
7640 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7641 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7642
7643 /* HelpLink value exists */
7644 sz = MAX_PATH;
7645 lstrcpyA(buf, "apple");
7647 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7648 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7649 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7650
7651 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7653
7654 /* HelpTelephone value exists */
7655 sz = MAX_PATH;
7656 lstrcpyA(buf, "apple");
7658 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7659 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7660 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7661
7662 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7664
7665 /* InstallDate value exists */
7666 sz = MAX_PATH;
7667 lstrcpyA(buf, "apple");
7669 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7670 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7671 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7672
7673 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7674 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7675
7676 /* DisplayName value exists */
7677 sz = MAX_PATH;
7678 lstrcpyA(buf, "apple");
7680 buf, &sz);
7681 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7682 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7683 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7684
7685 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7687
7688 /* InstallLocation value exists */
7689 sz = MAX_PATH;
7690 lstrcpyA(buf, "apple");
7692 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7693 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7694 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7695
7696 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7698
7699 /* InstallSource value exists */
7700 sz = MAX_PATH;
7701 lstrcpyA(buf, "apple");
7703 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7704 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7705 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7706
7707 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7708 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7709
7710 /* LocalPackage value exists */
7711 sz = MAX_PATH;
7712 lstrcpyA(buf, "apple");
7714 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7715 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7716 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7717
7718 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7720
7721 /* Publisher value exists */
7722 sz = MAX_PATH;
7723 lstrcpyA(buf, "apple");
7725 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7726 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7727 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7728
7729 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7731
7732 /* URLInfoAbout value exists */
7733 sz = MAX_PATH;
7734 lstrcpyA(buf, "apple");
7736 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7737 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7738 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7739
7740 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7741 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7742
7743 /* URLUpdateInfo value exists */
7744 sz = MAX_PATH;
7745 lstrcpyA(buf, "apple");
7747 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7748 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7749 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7750
7751 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7752 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7753
7754 /* VersionMinor value exists */
7755 sz = MAX_PATH;
7756 lstrcpyA(buf, "apple");
7758 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7759 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7760 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7761
7762 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7763 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7764
7765 /* VersionMajor value exists */
7766 sz = MAX_PATH;
7767 lstrcpyA(buf, "apple");
7769 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7770 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7771 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7772
7773 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7774 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7775
7776 /* DisplayVersion value exists */
7777 sz = MAX_PATH;
7778 lstrcpyA(buf, "apple");
7780 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7781 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7782 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7783
7784 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7785 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7786
7787 /* ProductID value exists */
7788 sz = MAX_PATH;
7789 lstrcpyA(buf, "apple");
7791 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7792 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7793 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7794
7795 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7796 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7797
7798 /* RegCompany value exists */
7799 sz = MAX_PATH;
7800 lstrcpyA(buf, "apple");
7802 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7803 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7804 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7805
7806 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7807 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7808
7809 /* RegOwner value exists */
7810 sz = MAX_PATH;
7811 lstrcpyA(buf, "apple");
7813 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7814 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7815 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7816
7817 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7819
7820 /* Transforms value exists */
7821 sz = MAX_PATH;
7822 lstrcpyA(buf, "apple");
7824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7825 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7826 ok(sz == 5, "Expected 5, got %lu\n", sz);
7827
7828 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7830
7831 /* Language value exists */
7832 sz = MAX_PATH;
7833 lstrcpyA(buf, "apple");
7835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7836 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7837 ok(sz == 4, "Expected 4, got %lu\n", sz);
7838
7839 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7841
7842 /* ProductName value exists */
7843 sz = MAX_PATH;
7844 lstrcpyA(buf, "apple");
7846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7847 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7848 ok(sz == 4, "Expected 4, got %lu\n", sz);
7849
7850 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7851 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7852
7853 /* FIXME */
7854
7855 /* AssignmentType value exists */
7856 sz = MAX_PATH;
7857 lstrcpyA(buf, "apple");
7859 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7860 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7861 ok(sz == 0, "Expected 0, got %lu\n", sz);
7862
7863 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7864 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7865
7866 /* FIXME */
7867
7868 /* PackageCode value exists */
7869 sz = MAX_PATH;
7870 lstrcpyA(buf, "apple");
7872 todo_wine
7873 {
7874 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7875 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7876 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7877 }
7878
7879 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7880 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7881
7882 /* Version value exists */
7883 sz = MAX_PATH;
7884 lstrcpyA(buf, "apple");
7886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7887 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7888 ok(sz == 3, "Expected 3, got %lu\n", sz);
7889
7890 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7891 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7892
7893 /* ProductIcon value exists */
7894 sz = MAX_PATH;
7895 lstrcpyA(buf, "apple");
7897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7898 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7899 ok(sz == 4, "Expected 4, got %lu\n", sz);
7900
7901 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7902 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7903
7904 /* PackageName value exists */
7905 sz = MAX_PATH;
7906 lstrcpyA(buf, "apple");
7908 todo_wine
7909 {
7910 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7911 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7912 ok(sz == MAX_PATH, "Expected MAX_PATH, got %lu\n", sz);
7913 }
7914
7915 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7916 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
7917
7918 /* AuthorizedLUAApp value exists */
7919 sz = MAX_PATH;
7920 lstrcpyA(buf, "apple");
7922 buf, &sz);
7923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7924 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7925 ok(sz == 4, "Expected 4, got %lu\n", sz);
7926
7927 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7928 RegDeleteValueA(prodkey, "PackageName");
7929 RegDeleteValueA(prodkey, "ProductIcon");
7930 RegDeleteValueA(prodkey, "Version");
7931 RegDeleteValueA(prodkey, "PackageCode");
7932 RegDeleteValueA(prodkey, "AssignmentType");
7933 RegDeleteValueA(prodkey, "ProductName");
7934 RegDeleteValueA(prodkey, "Language");
7935 RegDeleteValueA(prodkey, "Transforms");
7936 RegDeleteValueA(prodkey, "RegOwner");
7937 RegDeleteValueA(prodkey, "RegCompany");
7938 RegDeleteValueA(prodkey, "ProductID");
7939 RegDeleteValueA(prodkey, "DisplayVersion");
7940 RegDeleteValueA(prodkey, "VersionMajor");
7941 RegDeleteValueA(prodkey, "VersionMinor");
7942 RegDeleteValueA(prodkey, "URLUpdateInfo");
7943 RegDeleteValueA(prodkey, "URLInfoAbout");
7944 RegDeleteValueA(prodkey, "Publisher");
7945 RegDeleteValueA(prodkey, "LocalPackage");
7946 RegDeleteValueA(prodkey, "InstallSource");
7947 RegDeleteValueA(prodkey, "InstallLocation");
7948 RegDeleteValueA(prodkey, "DisplayName");
7949 RegDeleteValueA(prodkey, "InstallDate");
7950 RegDeleteValueA(prodkey, "HelpTelephone");
7951 RegDeleteValueA(prodkey, "HelpLink");
7952 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
7953 RegCloseKey(prodkey);
7954 LocalFree(usersid);
7955}
7956
7957#define INIT_USERINFO() \
7958 lstrcpyA(user, "apple"); \
7959 lstrcpyA(org, "orange"); \
7960 lstrcpyA(serial, "banana"); \
7961 usersz = orgsz = serialsz = MAX_PATH;
7962
7963static void test_MsiGetUserInfo(void)
7964{
7967 CHAR org[MAX_PATH];
7969 DWORD usersz, orgsz, serialsz;
7970 CHAR keypath[MAX_PATH * 2];
7971 CHAR prodcode[MAX_PATH];
7972 CHAR prod_squashed[MAX_PATH];
7973 HKEY prodkey, userprod, props;
7974 LPSTR usersid;
7975 LONG res;
7977
7978 create_test_guid(prodcode, prod_squashed);
7979 usersid = get_user_sid();
7980
7981 if (is_wow64)
7983
7984 /* NULL szProduct */
7985 INIT_USERINFO();
7986 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7988 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7989 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7990 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7991 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7992 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
7993 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
7994 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
7995
7996 /* empty szProductCode */
7997 INIT_USERINFO();
7998 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8000 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8001 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8002 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8003 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8004 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8005 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8006 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8007
8008 /* garbage szProductCode */
8009 INIT_USERINFO();
8010 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8012 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8013 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8014 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8015 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8016 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8017 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8018 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8019
8020 /* guid without brackets */
8021 INIT_USERINFO();
8022 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8023 user, &usersz, org, &orgsz, serial, &serialsz);
8025 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8026 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8027 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8028 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8029 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8030 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8031 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8032
8033 /* guid with brackets */
8034 INIT_USERINFO();
8035 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8036 user, &usersz, org, &orgsz, serial, &serialsz);
8038 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8039 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8040 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8041 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8042 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8043 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8044 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8045
8046 /* NULL lpUserNameBuf */
8047 INIT_USERINFO();
8048 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8050 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8051 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8052 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8053 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8054 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8055 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8056
8057 /* NULL pcchUserNameBuf */
8058 INIT_USERINFO();
8059 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8061 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8062 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8063 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8064 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8065 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8066 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8067
8068 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8069 INIT_USERINFO();
8070 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8072 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8073 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8074 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8075 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8076 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8077
8078 /* NULL lpOrgNameBuf */
8079 INIT_USERINFO();
8080 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8082 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8083 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8084 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8085 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8086 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8087 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8088
8089 /* NULL pcchOrgNameBuf */
8090 INIT_USERINFO();
8091 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8093 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8094 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8095 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8096 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8097 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8098 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8099
8100 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8101 INIT_USERINFO();
8102 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8104 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8105 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8106 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8107 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8108 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8109
8110 /* NULL lpSerialBuf */
8111 INIT_USERINFO();
8112 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8114 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8115 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8116 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8117 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8118 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8119 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8120
8121 /* NULL pcchSerialBuf */
8122 INIT_USERINFO();
8123 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8125 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8126 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8127 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8128 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8129 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8130 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8131
8132 /* both lpSerialBuf and pcchSerialBuf NULL */
8133 INIT_USERINFO();
8134 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8136 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8137 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8138 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8139 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8140 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8141
8142 /* MSIINSTALLCONTEXT_USERMANAGED */
8143
8144 /* create local system product key */
8145 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8146 lstrcatA(keypath, usersid);
8147 lstrcatA(keypath, "\\Installer\\Products\\");
8148 lstrcatA(keypath, prod_squashed);
8149
8150 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8151 if (res == ERROR_ACCESS_DENIED)
8152 {
8153 skip("Not enough rights to perform tests\n");
8154 LocalFree(usersid);
8155 return;
8156 }
8157 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8158
8159 /* managed product key exists */
8160 INIT_USERINFO();
8161 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8163 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8164 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8165 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8166 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8167 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8168 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8169 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8170
8171 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8172 lstrcatA(keypath, "Installer\\UserData\\");
8173 lstrcatA(keypath, usersid);
8174 lstrcatA(keypath, "\\Products\\");
8175 lstrcatA(keypath, prod_squashed);
8176
8177 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8178 if (res == ERROR_ACCESS_DENIED)
8179 {
8180 skip("Not enough rights to perform tests\n");
8181 LocalFree(usersid);
8182 return;
8183 }
8184 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8185
8186 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8187 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8188
8189 /* InstallProperties key exists */
8190 INIT_USERINFO();
8191 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8193 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8194 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8195 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8196 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8197 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", usersz);
8198 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8199 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8200
8201 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8202 INIT_USERINFO();
8203 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8205 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8206 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8207 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8208 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8209 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8210
8211 /* RegOwner, RegCompany don't exist, out params are NULL */
8212 INIT_USERINFO();
8213 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8215 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8216 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8217 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8218
8219 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8221
8222 /* RegOwner value exists */
8223 INIT_USERINFO();
8224 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8226 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8227 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8228 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8229 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8230 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8231 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8232 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8233
8234 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8236
8237 /* RegCompany value exists */
8238 INIT_USERINFO();
8239 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8241 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8242 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8243 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8244 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8245 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8246 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8247 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8248
8249 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8251
8252 /* ProductID value exists */
8253 INIT_USERINFO();
8254 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8256 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8257 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8258 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8259 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8260 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8261 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8262 ok(serialsz == 2, "Expected 2, got %lu\n", serialsz);
8263
8264 /* pcchUserNameBuf is too small */
8265 INIT_USERINFO();
8266 usersz = 0;
8267 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8269 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8270 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8271 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8272 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8273 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8274 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8275 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8276
8277 /* pcchUserNameBuf has no room for NULL terminator */
8278 INIT_USERINFO();
8279 usersz = 5;
8280 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8282 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8283 todo_wine
8284 {
8285 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8286 }
8287 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8288 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8289 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8290 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8291 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8292
8293 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
8294 INIT_USERINFO();
8295 usersz = 0;
8296 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8298 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8299 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8300 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8301 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8302 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8303 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8304 ok(serialsz == 2, "Expected 2, got %lu\n", serialsz);
8305
8306 RegDeleteValueA(props, "ProductID");
8307 RegDeleteValueA(props, "RegCompany");
8308 RegDeleteValueA(props, "RegOwner");
8311 RegDeleteKeyExA(userprod, "", access & KEY_WOW64_64KEY, 0);
8312 RegCloseKey(userprod);
8313 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
8314 RegCloseKey(prodkey);
8315
8316 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8317
8318 /* create local system product key */
8319 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8320 lstrcatA(keypath, prod_squashed);
8321
8322 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8324
8325 /* product key exists */
8326 INIT_USERINFO();
8327 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8329 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8330 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8331 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8332 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8333 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8334 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8335 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8336
8337 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8338 lstrcatA(keypath, "Installer\\UserData\\");
8339 lstrcatA(keypath, usersid);
8340 lstrcatA(keypath, "\\Products\\");
8341 lstrcatA(keypath, prod_squashed);
8342
8343 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8344 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8345
8346 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8347 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8348
8349 /* InstallProperties key exists */
8350 INIT_USERINFO();
8351 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8353 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8354 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8355 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8356 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8357 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", usersz);
8358 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8359 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8360
8361 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8362 INIT_USERINFO();
8363 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8365 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8366 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8367 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8368 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8369 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8370
8371 /* RegOwner, RegCompany don't exist, out params are NULL */
8372 INIT_USERINFO();
8373 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8375 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8376 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8377 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8378
8379 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8381
8382 /* RegOwner value exists */
8383 INIT_USERINFO();
8384 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8386 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8387 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8388 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8389 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8390 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8391 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8392 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8393
8394 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8395 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8396
8397 /* RegCompany value exists */
8398 INIT_USERINFO();
8399 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8401 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8402 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8403 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8404 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8405 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8406 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8407 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8408
8409 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8410 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8411
8412 /* ProductID value exists */
8413 INIT_USERINFO();
8414 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8416 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8417 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8418 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8419 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8420 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8421 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8422 ok(serialsz == 2, "Expected 2, got %lu\n", serialsz);
8423
8424 RegDeleteValueA(props, "ProductID");
8425 RegDeleteValueA(props, "RegCompany");
8426 RegDeleteValueA(props, "RegOwner");
8429 RegDeleteKeyExA(userprod, "", access & KEY_WOW64_64KEY, 0);
8430 RegCloseKey(userprod);
8431 RegDeleteKeyA(prodkey, "");
8432 RegCloseKey(prodkey);
8433
8434 /* MSIINSTALLCONTEXT_MACHINE */
8435
8436 /* create local system product key */
8437 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8438 lstrcatA(keypath, prod_squashed);
8439
8440 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8441 if (res == ERROR_ACCESS_DENIED)
8442 {
8443 skip( "insufficient rights\n" );
8444 LocalFree( usersid );
8445 return;
8446 }
8447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8448
8449 /* product key exists */
8450 INIT_USERINFO();
8451 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8453 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8454 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8455 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8456 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8457 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %lu\n", usersz);
8458 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8459 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8460
8461 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8462 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
8463 lstrcatA(keypath, "\\Products\\");
8464 lstrcatA(keypath, prod_squashed);
8465
8466 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8468
8469 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8470 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8471
8472 /* InstallProperties key exists */
8473 INIT_USERINFO();
8474 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8476 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8477 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8478 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8479 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8480 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", usersz);
8481 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", orgsz);
8482 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", serialsz);
8483
8484 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8485 INIT_USERINFO();
8486 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8488 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8489 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8490 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8491 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8492 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8493
8494 /* RegOwner, RegCompany don't exist, out params are NULL */
8495 INIT_USERINFO();
8496 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8498 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8499 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8500 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8501
8502 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8503 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8504
8505 /* RegOwner value exists */
8506 INIT_USERINFO();
8507 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8509 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8510 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8511 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8512 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8513 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8514 ok(orgsz == 0, "Expected 0, got %lu\n", orgsz);
8515 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8516
8517 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8518 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8519
8520 /* RegCompany value exists */
8521 INIT_USERINFO();
8522 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8524 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8525 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8526 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8527 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8528 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8529 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8530 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %lu\n", serialsz);
8531
8532 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8533 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8534
8535 /* ProductID value exists */
8536 INIT_USERINFO();
8537 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8539 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8540 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8541 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8542 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8543 ok(usersz == 5, "Expected 5, got %lu\n", usersz);
8544 ok(orgsz == 7, "Expected 7, got %lu\n", orgsz);
8545 ok(serialsz == 2, "Expected 2, got %lu\n", serialsz);
8546
8547 RegDeleteValueA(props, "ProductID");
8548 RegDeleteValueA(props, "RegCompany");
8549 RegDeleteValueA(props, "RegOwner");
8552 RegDeleteKeyExA(userprod, "", access & KEY_WOW64_64KEY, 0);
8553 RegCloseKey(userprod);
8554 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
8555 RegCloseKey(prodkey);
8556 LocalFree(usersid);
8557}
8558
8559static void test_MsiOpenProduct(void)
8560{
8561 MSIHANDLE hprod, hdb;
8562 CHAR val[MAX_PATH];
8564 CHAR keypath[MAX_PATH*2];
8565 CHAR prodcode[MAX_PATH];
8566 CHAR prod_squashed[MAX_PATH];
8567 HKEY prodkey, userkey, props;
8568 LPSTR usersid;
8569 DWORD size;
8570 LONG res;
8571 UINT r;
8573
8575
8577 lstrcatA(path, "\\");
8578
8579 create_test_guid(prodcode, prod_squashed);
8580 usersid = get_user_sid();
8581
8582 if (is_wow64)
8584
8585 hdb = create_package_db(prodcode);
8586 MsiCloseHandle(hdb);
8587
8588 /* NULL szProduct */
8589 hprod = 0xdeadbeef;
8590 r = MsiOpenProductA(NULL, &hprod);
8592 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8593 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8594
8595 /* empty szProduct */
8596 hprod = 0xdeadbeef;
8597 r = MsiOpenProductA("", &hprod);
8599 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8600 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8601
8602 /* garbage szProduct */
8603 hprod = 0xdeadbeef;
8604 r = MsiOpenProductA("garbage", &hprod);
8606 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8607 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8608
8609 /* guid without brackets */
8610 hprod = 0xdeadbeef;
8611 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
8613 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8614 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8615
8616 /* guid with brackets */
8617 hprod = 0xdeadbeef;
8618 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
8620 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8621 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8622
8623 /* same length as guid, but random */
8624 hprod = 0xdeadbeef;
8625 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
8627 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8628 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8629
8630 /* hProduct is NULL */
8631 hprod = 0xdeadbeef;
8632 r = MsiOpenProductA(prodcode, NULL);
8634 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8635 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8636
8637 /* MSIINSTALLCONTEXT_USERMANAGED */
8638
8639 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8640 lstrcatA(keypath, "Installer\\Managed\\");
8641 lstrcatA(keypath, usersid);
8642 lstrcatA(keypath, "\\Installer\\Products\\");
8643 lstrcatA(keypath, prod_squashed);
8644
8645 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8646 if (res == ERROR_ACCESS_DENIED)
8647 {
8648 skip("Not enough rights to perform tests\n");
8649 LocalFree(usersid);
8650 return;
8651 }
8652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8653
8654 /* managed product key exists */
8655 hprod = 0xdeadbeef;
8656 r = MsiOpenProductA(prodcode, &hprod);
8658 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8659 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8660
8661 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8662 lstrcatA(keypath, "Installer\\UserData\\");
8663 lstrcatA(keypath, usersid);
8664 lstrcatA(keypath, "\\Products\\");
8665 lstrcatA(keypath, prod_squashed);
8666
8667 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8668 if (res == ERROR_ACCESS_DENIED)
8669 {
8670 skip("Not enough rights to perform tests\n");
8671 LocalFree(usersid);
8672 return;
8673 }
8674 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8675
8676 /* user product key exists */
8677 hprod = 0xdeadbeef;
8678 r = MsiOpenProductA(prodcode, &hprod);
8680 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8681 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8682
8683 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8685
8686 /* InstallProperties key exists */
8687 hprod = 0xdeadbeef;
8688 r = MsiOpenProductA(prodcode, &hprod);
8690 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8691 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8692
8693 lstrcpyA(val, path);
8694 lstrcatA(val, "\\winetest.msi");
8695 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
8696 (const BYTE *)val, lstrlenA(val) + 1);
8697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8698
8699 /* ManagedLocalPackage value exists */
8700 hprod = 0xdeadbeef;
8701 r = MsiOpenProductA(prodcode, &hprod);
8702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8703 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8704
8705 size = MAX_PATH;
8706 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8707 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8708 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8709 ok(size == lstrlenA(prodcode), "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8710
8711 MsiCloseHandle(hprod);
8712
8713 RegDeleteValueA(props, "ManagedLocalPackage");
8716 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
8717 RegCloseKey(userkey);
8718 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
8719 RegCloseKey(prodkey);
8720
8721 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8722
8723 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8724 lstrcatA(keypath, prod_squashed);
8725
8726 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8727 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8728
8729 /* unmanaged product key exists */
8730 hprod = 0xdeadbeef;
8731 r = MsiOpenProductA(prodcode, &hprod);
8733 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8734 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8735
8736 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8737 lstrcatA(keypath, "Installer\\UserData\\");
8738 lstrcatA(keypath, usersid);
8739 lstrcatA(keypath, "\\Products\\");
8740 lstrcatA(keypath, prod_squashed);
8741
8742 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8743 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8744
8745 /* user product key exists */
8746 hprod = 0xdeadbeef;
8747 r = MsiOpenProductA(prodcode, &hprod);
8749 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8750 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8751
8752 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8754
8755 /* InstallProperties key exists */
8756 hprod = 0xdeadbeef;
8757 r = MsiOpenProductA(prodcode, &hprod);
8759 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8760 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8761
8762 lstrcpyA(val, path);
8763 lstrcatA(val, "\\winetest.msi");
8764 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8765 (const BYTE *)val, lstrlenA(val) + 1);
8766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8767
8768 /* LocalPackage value exists */
8769 hprod = 0xdeadbeef;
8770 r = MsiOpenProductA(prodcode, &hprod);
8771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8772 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8773
8774 size = MAX_PATH;
8775 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8777 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8778 ok(size == lstrlenA(prodcode), "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8779
8780 MsiCloseHandle(hprod);
8781
8782 RegDeleteValueA(props, "LocalPackage");
8785 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
8786 RegCloseKey(userkey);
8787 RegDeleteKeyA(prodkey, "");
8788 RegCloseKey(prodkey);
8789
8790 /* MSIINSTALLCONTEXT_MACHINE */
8791
8792 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8793 lstrcatA(keypath, prod_squashed);
8794
8795 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8796 if (res == ERROR_ACCESS_DENIED)
8797 {
8798 skip( "insufficient rights\n" );
8799 LocalFree( usersid );
8800 return;
8801 }
8802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8803
8804 /* managed product key exists */
8805 hprod = 0xdeadbeef;
8806 r = MsiOpenProductA(prodcode, &hprod);
8808 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8809 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8810
8811 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8812 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8813 lstrcatA(keypath, prod_squashed);
8814
8815 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8817
8818 /* user product key exists */
8819 hprod = 0xdeadbeef;
8820 r = MsiOpenProductA(prodcode, &hprod);
8822 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8823 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8824
8825 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8826 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8827
8828 /* InstallProperties key exists */
8829 hprod = 0xdeadbeef;
8830 r = MsiOpenProductA(prodcode, &hprod);
8832 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8833 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8834
8835 lstrcpyA(val, path);
8836 lstrcatA(val, "\\winetest.msi");
8837 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8838 (const BYTE *)val, lstrlenA(val) + 1);
8839 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8840
8841 /* LocalPackage value exists */
8842 hprod = 0xdeadbeef;
8843 r = MsiOpenProductA(prodcode, &hprod);
8844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8845 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8846
8847 size = MAX_PATH;
8848 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8850 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8851 ok(size == lstrlenA(prodcode), "Expected %d, got %lu\n", lstrlenA(prodcode), size);
8852
8853 MsiCloseHandle(hprod);
8854
8855 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8856 (const BYTE *)"winetest.msi", 13);
8857 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8858
8859 lstrcpyA(val, path);
8860 lstrcatA(val, "\\winetest.msi");
8861 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8862 (const BYTE *)val, lstrlenA(val) + 1);
8863 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8864
8866
8867 /* local package does not exist */
8868 hprod = 0xdeadbeef;
8869 r = MsiOpenProductA(prodcode, &hprod);
8871 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8872 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8873
8874 RegDeleteValueA(props, "LocalPackage");
8877 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
8878 RegCloseKey(userkey);
8879 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
8880 RegCloseKey(prodkey);
8881
8883 LocalFree(usersid);
8884}
8885
8886static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
8887{
8889 CHAR keypath[MAX_PATH], patch[MAX_PATH];
8890 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8891 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8892 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8893 HKEY prodkey, patches, udprod, udpatch, hpatch;
8894 DWORD size, data;
8895 LONG res;
8896 UINT r;
8898
8899 create_test_guid(prodcode, prod_squashed);
8900 create_test_guid(patch, patch_squashed);
8901
8902 if (is_wow64)
8904
8905 /* MSIPATCHSTATE_APPLIED */
8906
8907 lstrcpyA(patchcode, "apple");
8908 lstrcpyA(targetprod, "banana");
8909 context = 0xdeadbeef;
8910 lstrcpyA(targetsid, "kiwi");
8911 size = MAX_PATH;
8913 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8914 &context, targetsid, &size);
8915 if (r == ERROR_ACCESS_DENIED)
8916 {
8917 skip("Not enough rights to perform tests\n");
8918 return;
8919 }
8920 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8921 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
8922 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
8923 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
8924 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
8925 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8926
8927 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8928 lstrcatA(keypath, expectedsid);
8929 lstrcatA(keypath, "\\Installer\\Products\\");
8930 lstrcatA(keypath, prod_squashed);
8931
8932 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8933 if (res == ERROR_ACCESS_DENIED)
8934 {
8935 skip("Not enough rights to perform tests\n");
8936 return;
8937 }
8938 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8939
8940 /* managed product key exists */
8941 lstrcpyA(patchcode, "apple");
8942 lstrcpyA(targetprod, "banana");
8943 context = 0xdeadbeef;
8944 lstrcpyA(targetsid, "kiwi");
8945 size = MAX_PATH;
8947 0, patchcode, targetprod, &context, targetsid, &size);
8948 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8949 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
8950 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
8951 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
8952 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
8953 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8954
8955 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8956 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8957
8958 /* patches key exists */
8959 lstrcpyA(patchcode, "apple");
8960 lstrcpyA(targetprod, "banana");
8961 context = 0xdeadbeef;
8962 lstrcpyA(targetsid, "kiwi");
8963 size = MAX_PATH;
8965 0, patchcode, targetprod, &context, targetsid, &size);
8966 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8967 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
8968 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
8969 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
8970 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
8971 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8972
8973 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8974 (const BYTE *)patch_squashed,
8975 lstrlenA(patch_squashed) + 1);
8976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8977
8978 /* Patches value exists, is not REG_MULTI_SZ */
8979 lstrcpyA(patchcode, "apple");
8980 lstrcpyA(targetprod, "banana");
8981 context = 0xdeadbeef;
8982 lstrcpyA(targetsid, "kiwi");
8983 size = MAX_PATH;
8985 0, patchcode, targetprod, &context, targetsid, &size);
8986 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8987 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
8988 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
8989 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
8990 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
8991 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
8992
8993 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8994 (const BYTE *)"a\0b\0c\0\0", 7);
8995 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
8996
8997 /* Patches value exists, is not a squashed guid */
8998 lstrcpyA(patchcode, "apple");
8999 lstrcpyA(targetprod, "banana");
9000 context = 0xdeadbeef;
9001 lstrcpyA(targetsid, "kiwi");
9002 size = MAX_PATH;
9004 0, patchcode, targetprod, &context, targetsid, &size);
9005 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9006 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9007 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9008 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9009 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9010 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9011
9012 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9013 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9014 (const BYTE *)patch_squashed,
9015 lstrlenA(patch_squashed) + 2);
9016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9017
9018 /* Patches value exists */
9019 lstrcpyA(patchcode, "apple");
9020 lstrcpyA(targetprod, "banana");
9021 context = 0xdeadbeef;
9022 lstrcpyA(targetsid, "kiwi");
9023 size = MAX_PATH;
9025 0, patchcode, targetprod, &context, targetsid, &size);
9026 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9027 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9028 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9029 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9030 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9031 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9032
9033 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9034 (const BYTE *)"whatever", 9);
9035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9036
9037 /* patch squashed value exists */
9038 lstrcpyA(patchcode, "apple");
9039 lstrcpyA(targetprod, "banana");
9040 context = 0xdeadbeef;
9041 lstrcpyA(targetsid, "kiwi");
9042 size = MAX_PATH;
9044 0, patchcode, targetprod, &context, targetsid, &size);
9045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9046 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9047 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9048 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9049 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9050 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9051
9052 /* increase the index */
9053 lstrcpyA(patchcode, "apple");
9054 lstrcpyA(targetprod, "banana");
9055 context = 0xdeadbeef;
9056 lstrcpyA(targetsid, "kiwi");
9057 size = MAX_PATH;
9059 1, patchcode, targetprod, &context, targetsid, &size);
9060 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9061 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9062 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9063 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9064 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9065 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9066
9067 /* increase again */
9068 lstrcpyA(patchcode, "apple");
9069 lstrcpyA(targetprod, "banana");
9070 context = 0xdeadbeef;
9071 lstrcpyA(targetsid, "kiwi");
9072 size = MAX_PATH;
9074 2, patchcode, targetprod, &context, targetsid, &size);
9075 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9076 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9077 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9078 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9079 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9080 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9081
9082 /* szPatchCode is NULL */
9083 lstrcpyA(targetprod, "banana");
9084 context = 0xdeadbeef;
9085 lstrcpyA(targetsid, "kiwi");
9086 size = MAX_PATH;
9088 0, NULL, targetprod, &context, targetsid, &size);
9089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9090 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9091 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9092 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9093 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9094
9095 /* szTargetProductCode is NULL */
9096 lstrcpyA(patchcode, "apple");
9097 context = 0xdeadbeef;
9098 lstrcpyA(targetsid, "kiwi");
9099 size = MAX_PATH;
9101 0, patchcode, NULL, &context, targetsid, &size);
9102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9103 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9104 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9105 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9106 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9107
9108 /* pdwTargetProductContext is NULL */
9109 lstrcpyA(patchcode, "apple");
9110 lstrcpyA(targetprod, "banana");
9111 lstrcpyA(targetsid, "kiwi");
9112 size = MAX_PATH;
9114 0, patchcode, targetprod, NULL, targetsid, &size);
9115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9116 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9117 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9118 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9119 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9120
9121 /* szTargetUserSid is NULL */
9122 lstrcpyA(patchcode, "apple");
9123 lstrcpyA(targetprod, "banana");
9124 context = 0xdeadbeef;
9125 size = MAX_PATH;
9127 0, patchcode, targetprod, &context, NULL, &size);
9128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9129 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9130 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9131 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9132 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR), "Expected %d*sizeof(WCHAR), got %lu\n", lstrlenA(expectedsid), size);
9133
9134 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
9135 lstrcpyA(patchcode, "apple");
9136 lstrcpyA(targetprod, "banana");
9137 context = 0xdeadbeef;
9138 lstrcpyA(targetsid, "kiwi");
9139 size = lstrlenA(expectedsid);
9141 0, patchcode, targetprod, &context, targetsid, &size);
9142 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9143 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9144 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9145 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9146 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9147 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR), "Expected %d*sizeof(WCHAR), got %lu\n", lstrlenA(expectedsid), size);
9148
9149 /* pcchTargetUserSid has enough room for NULL terminator */
9150 lstrcpyA(patchcode, "apple");
9151 lstrcpyA(targetprod, "banana");
9152 context = 0xdeadbeef;
9153 lstrcpyA(targetsid, "kiwi");
9154 size = lstrlenA(expectedsid) + 1;
9156 0, patchcode, targetprod, &context, targetsid, &size);
9157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9158 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9159 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9160 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9161 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9162 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9163
9164 /* both szTargetuserSid and pcchTargetUserSid are NULL */
9165 lstrcpyA(patchcode, "apple");
9166 lstrcpyA(targetprod, "banana");
9167 context = 0xdeadbeef;
9169 0, patchcode, targetprod, &context, NULL, NULL);
9170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9171 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9172 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9173 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9174
9175 /* MSIPATCHSTATE_SUPERSEDED */
9176
9177 lstrcpyA(patchcode, "apple");
9178 lstrcpyA(targetprod, "banana");
9179 context = 0xdeadbeef;
9180 lstrcpyA(targetsid, "kiwi");
9181 size = MAX_PATH;
9183 0, patchcode, targetprod, &context, targetsid, &size);
9184 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9185 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9186 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9187 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9188 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9189 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9190
9191 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9192 lstrcatA(keypath, expectedsid);
9193 lstrcatA(keypath, "\\Products\\");
9194 lstrcatA(keypath, prod_squashed);
9195
9196 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9197 if (res == ERROR_ACCESS_DENIED)
9198 {
9199 skip("Not enough rights to perform tests\n");
9200 return;
9201 }
9202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9203
9204 /* UserData product key exists */
9205 lstrcpyA(patchcode, "apple");
9206 lstrcpyA(targetprod, "banana");
9207 context = 0xdeadbeef;
9208 lstrcpyA(targetsid, "kiwi");
9209 size = MAX_PATH;
9211 0, patchcode, targetprod, &context, targetsid, &size);
9212 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9213 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9214 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9215 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9216 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9217 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9218
9219 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9221
9222 /* UserData patches key exists */
9223 lstrcpyA(patchcode, "apple");
9224 lstrcpyA(targetprod, "banana");
9225 context = 0xdeadbeef;
9226 lstrcpyA(targetsid, "kiwi");
9227 size = MAX_PATH;
9229 0, patchcode, targetprod, &context, targetsid, &size);
9230 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9231 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9232 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9233 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9234 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9235 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9236
9237 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9238 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9239
9240 /* specific UserData patch key exists */
9241 lstrcpyA(patchcode, "apple");
9242 lstrcpyA(targetprod, "banana");
9243 context = 0xdeadbeef;
9244 lstrcpyA(targetsid, "kiwi");
9245 size = MAX_PATH;
9247 0, patchcode, targetprod, &context, targetsid, &size);
9248 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9249 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9250 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9251 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9252 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9253 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9254
9256 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9257 (const BYTE *)&data, sizeof(DWORD));
9258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9259
9260 /* State value exists */
9261 lstrcpyA(patchcode, "apple");
9262 lstrcpyA(targetprod, "banana");
9263 context = 0xdeadbeef;
9264 lstrcpyA(targetsid, "kiwi");
9265 size = MAX_PATH;
9267 0, patchcode, targetprod, &context, targetsid, &size);
9268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9269 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9270 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9271 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9272 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9273 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9274
9275 /* MSIPATCHSTATE_OBSOLETED */
9276
9277 lstrcpyA(patchcode, "apple");
9278 lstrcpyA(targetprod, "banana");
9279 context = 0xdeadbeef;
9280 lstrcpyA(targetsid, "kiwi");
9281 size = MAX_PATH;
9283 0, patchcode, targetprod, &context, targetsid, &size);
9284 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9285 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9286 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9287 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9288 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9289 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9290
9292 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9293 (const BYTE *)&data, sizeof(DWORD));
9294 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9295
9296 /* State value is obsoleted */
9297 lstrcpyA(patchcode, "apple");
9298 lstrcpyA(targetprod, "banana");
9299 context = 0xdeadbeef;
9300 lstrcpyA(targetsid, "kiwi");
9301 size = MAX_PATH;
9303 0, patchcode, targetprod, &context, targetsid, &size);
9304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9305 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9306 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9307 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9308 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9309 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9310
9311 /* MSIPATCHSTATE_REGISTERED */
9312 /* FIXME */
9313
9314 /* MSIPATCHSTATE_ALL */
9315
9316 /* 1st */
9317 lstrcpyA(patchcode, "apple");
9318 lstrcpyA(targetprod, "banana");
9319 context = 0xdeadbeef;
9320 lstrcpyA(targetsid, "kiwi");
9321 size = MAX_PATH;
9323 0, patchcode, targetprod, &context, targetsid, &size);
9324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9325 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9326 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9327 ok(context == MSIINSTALLCONTEXT_USERMANAGED, "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9328 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9329 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9330
9331 /* same patch in multiple places, only one is enumerated */
9332 lstrcpyA(patchcode, "apple");
9333 lstrcpyA(targetprod, "banana");
9334 context = 0xdeadbeef;
9335 lstrcpyA(targetsid, "kiwi");
9336 size = MAX_PATH;
9338 1, patchcode, targetprod, &context, targetsid, &size);
9339 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9340 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9341 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9342 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9343 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9344 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9345
9346 RegDeleteValueA(hpatch, "State");
9347 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
9348 RegCloseKey(hpatch);
9349 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
9350 RegCloseKey(udpatch);
9351 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
9352 RegCloseKey(udprod);
9353 RegDeleteValueA(patches, "Patches");
9354 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
9355 RegCloseKey(patches);
9356 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
9357 RegCloseKey(prodkey);
9358}
9359
9360static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
9361{
9363 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9364 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9365 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9366 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9367 HKEY prodkey, patches, udprod, udpatch;
9368 HKEY userkey, hpatch;
9369 DWORD size, data;
9370 LONG res;
9371 UINT r;
9373
9374 create_test_guid(prodcode, prod_squashed);
9375 create_test_guid(patch, patch_squashed);
9376
9377 if (is_wow64)
9379
9380 /* MSIPATCHSTATE_APPLIED */
9381
9382 lstrcpyA(patchcode, "apple");
9383 lstrcpyA(targetprod, "banana");
9384 context = 0xdeadbeef;
9385 lstrcpyA(targetsid, "kiwi");
9386 size = MAX_PATH;
9388 0, patchcode, targetprod, &context, targetsid, &size);
9389 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9390 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9391 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9392 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9393 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9394 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9395
9396 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9397 lstrcatA(keypath, prod_squashed);
9398
9399 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9401
9402 /* current user product key exists */
9403 lstrcpyA(patchcode, "apple");
9404 lstrcpyA(targetprod, "banana");
9405 context = 0xdeadbeef;
9406 lstrcpyA(targetsid, "kiwi");
9407 size = MAX_PATH;
9409 0, patchcode, targetprod, &context, targetsid, &size);
9410 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9411 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9412 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9413 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9414 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9415 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9416
9417 res = RegCreateKeyA(prodkey, "Patches", &patches);
9418 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9419
9420 /* Patches key exists */
9421 lstrcpyA(patchcode, "apple");
9422 lstrcpyA(targetprod, "banana");
9423 context = 0xdeadbeef;
9424 lstrcpyA(targetsid, "kiwi");
9425 size = MAX_PATH;
9427 0, patchcode, targetprod, &context, targetsid, &size);
9428 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9429 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9430 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9431 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9432 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9433 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9434
9435 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9436 (const BYTE *)patch_squashed,
9437 lstrlenA(patch_squashed) + 1);
9438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9439
9440 /* Patches value exists, is not REG_MULTI_SZ */
9441 lstrcpyA(patchcode, "apple");
9442 lstrcpyA(targetprod, "banana");
9443 context = 0xdeadbeef;
9444 lstrcpyA(targetsid, "kiwi");
9445 size = MAX_PATH;
9447 0, patchcode, targetprod, &context, targetsid, &size);
9448 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9449 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9450 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9451 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9452 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9453 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9454
9455 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9456 (const BYTE *)"a\0b\0c\0\0", 7);
9457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9458
9459 /* Patches value exists, is not a squashed guid */
9460 lstrcpyA(patchcode, "apple");
9461 lstrcpyA(targetprod, "banana");
9462 context = 0xdeadbeef;
9463 lstrcpyA(targetsid, "kiwi");
9464 size = MAX_PATH;
9466 0, patchcode, targetprod, &context, targetsid, &size);
9467 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9468 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9469 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9470 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9471 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9472 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9473
9474 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
9475 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9476 (const BYTE *)patch_squashed,
9477 lstrlenA(patch_squashed) + 2);
9478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9479
9480 /* Patches value exists */
9481 lstrcpyA(patchcode, "apple");
9482 lstrcpyA(targetprod, "banana");
9483 context = 0xdeadbeef;
9484 lstrcpyA(targetsid, "kiwi");
9485 size = MAX_PATH;
9487 0, patchcode, targetprod, &context, targetsid, &size);
9488 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9489 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9490 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9491 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9492 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9493 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9494
9495 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9496 (const BYTE *)"whatever", 9);
9497 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9498
9499 /* patch code value exists */
9500 lstrcpyA(patchcode, "apple");
9501 lstrcpyA(targetprod, "banana");
9502 context = 0xdeadbeef;
9503 lstrcpyA(targetsid, "kiwi");
9504 size = MAX_PATH;
9506 0, patchcode, targetprod, &context, targetsid, &size);
9507 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9508 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9509 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9510 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9511 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9512 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9513
9514 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9515 lstrcatA(keypath, expectedsid);
9516 lstrcatA(keypath, "\\Patches\\");
9517 lstrcatA(keypath, patch_squashed);
9518
9519 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9520 if (res == ERROR_ACCESS_DENIED)
9521 {
9522 skip("Not enough rights to perform tests\n");
9523 goto error;
9524 }
9525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9526
9527 /* userdata patch key exists */
9528 lstrcpyA(patchcode, "apple");
9529 lstrcpyA(targetprod, "banana");
9530 context = 0xdeadbeef;
9531 lstrcpyA(targetsid, "kiwi");
9532 size = MAX_PATH;
9534 0, patchcode, targetprod, &context, targetsid, &size);
9535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9536 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9537 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9538 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED, "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9539 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9540 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9541
9542 /* MSIPATCHSTATE_SUPERSEDED */
9543
9544 lstrcpyA(patchcode, "apple");
9545 lstrcpyA(targetprod, "banana");
9546 context = 0xdeadbeef;
9547 lstrcpyA(targetsid, "kiwi");
9548 size = MAX_PATH;
9550 0, patchcode, targetprod, &context, targetsid, &size);
9551 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9552 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9553 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9554 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9555 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9556 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9557
9558 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9559 lstrcatA(keypath, expectedsid);
9560 lstrcatA(keypath, "\\Products\\");
9561 lstrcatA(keypath, prod_squashed);
9562
9563 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9564 if (res == ERROR_ACCESS_DENIED)
9565 {
9566 skip("Not enough rights to perform tests\n");
9567 goto error;
9568 }
9569 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9570
9571 /* UserData product key exists */
9572 lstrcpyA(patchcode, "apple");
9573 lstrcpyA(targetprod, "banana");
9574 context = 0xdeadbeef;
9575 lstrcpyA(targetsid, "kiwi");
9576 size = MAX_PATH;
9578 0, patchcode, targetprod, &context, targetsid, &size);
9579 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9580 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9581 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9582 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9583 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9584 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9585
9586 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9588
9589 /* UserData patches key exists */
9590 lstrcpyA(patchcode, "apple");
9591 lstrcpyA(targetprod, "banana");
9592 context = 0xdeadbeef;
9593 lstrcpyA(targetsid, "kiwi");
9594 size = MAX_PATH;
9596 0, patchcode, targetprod, &context, targetsid, &size);
9597 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9598 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9599 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9600 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9601 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9602 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9603
9604 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9605 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9606
9607 /* specific UserData patch key exists */
9608 lstrcpyA(patchcode, "apple");
9609 lstrcpyA(targetprod, "banana");
9610 context = 0xdeadbeef;
9611 lstrcpyA(targetsid, "kiwi");
9612 size = MAX_PATH;
9614 0, patchcode, targetprod, &context, targetsid, &size);
9615 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9616 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9617 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9618 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9619 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9620 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9621
9623 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9624 (const BYTE *)&data, sizeof(DWORD));
9625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9626
9627 /* State value exists */
9628 lstrcpyA(patchcode, "apple");
9629 lstrcpyA(targetprod, "banana");
9630 context = 0xdeadbeef;
9631 lstrcpyA(targetsid, "kiwi");
9632 size = MAX_PATH;
9634 0, patchcode, targetprod, &context, targetsid, &size);
9635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9636 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9637 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9638 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED, "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9639 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9640 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9641
9642 /* MSIPATCHSTATE_OBSOLETED */
9643
9644 lstrcpyA(patchcode, "apple");
9645 lstrcpyA(targetprod, "banana");
9646 context = 0xdeadbeef;
9647 lstrcpyA(targetsid, "kiwi");
9648 size = MAX_PATH;
9650 0, patchcode, targetprod, &context, targetsid, &size);
9651 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9652 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9653 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9654 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9655 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9656 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9657
9659 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9660 (const BYTE *)&data, sizeof(DWORD));
9661 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9662
9663 /* State value is obsoleted */
9664 lstrcpyA(patchcode, "apple");
9665 lstrcpyA(targetprod, "banana");
9666 context = 0xdeadbeef;
9667 lstrcpyA(targetsid, "kiwi");
9668 size = MAX_PATH;
9670 0, patchcode, targetprod, &context, targetsid, &size);
9671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9672 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9673 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9674 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED, "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9675 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9676 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9677
9678 /* MSIPATCHSTATE_REGISTERED */
9679 /* FIXME */
9680
9681 /* MSIPATCHSTATE_ALL */
9682
9683 /* 1st */
9684 lstrcpyA(patchcode, "apple");
9685 lstrcpyA(targetprod, "banana");
9686 context = 0xdeadbeef;
9687 lstrcpyA(targetsid, "kiwi");
9688 size = MAX_PATH;
9690 0, patchcode, targetprod, &context, targetsid, &size);
9691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9692 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9693 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9694 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED, "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9695 ok(!lstrcmpA(targetsid, expectedsid), "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9696 ok(size == lstrlenA(expectedsid), "Expected %d, got %lu\n", lstrlenA(expectedsid), size);
9697
9698 /* same patch in multiple places, only one is enumerated */
9699 lstrcpyA(patchcode, "apple");
9700 lstrcpyA(targetprod, "banana");
9701 context = 0xdeadbeef;
9702 lstrcpyA(targetsid, "kiwi");
9703 size = MAX_PATH;
9705 1, patchcode, targetprod, &context, targetsid, &size);
9706 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9707 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9708 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9709 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9710 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9711 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9712
9713 RegDeleteValueA(hpatch, "State");
9714 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
9715 RegCloseKey(hpatch);
9716 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
9717 RegCloseKey(udpatch);
9718 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
9719 RegCloseKey(udprod);
9720 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
9721 RegCloseKey(userkey);
9722 RegDeleteValueA(patches, patch_squashed);
9723 RegDeleteValueA(patches, "Patches");
9724
9725error:
9726 RegDeleteKeyA(patches, "");
9727 RegCloseKey(patches);
9728 RegDeleteKeyA(prodkey, "");
9729 RegCloseKey(prodkey);
9730}
9731
9733{
9734 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9735 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9736 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9737 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9738 HKEY prodkey, patches, udprod, udpatch;
9739 HKEY hpatch;
9741 DWORD size, data;
9742 LONG res;
9743 UINT r;
9745
9746 create_test_guid(prodcode, prod_squashed);
9747 create_test_guid(patch, patch_squashed);
9748
9749 if (is_wow64)
9751
9752 /* MSIPATCHSTATE_APPLIED */
9753
9754 lstrcpyA(patchcode, "apple");
9755 lstrcpyA(targetprod, "banana");
9756 context = 0xdeadbeef;
9757 lstrcpyA(targetsid, "kiwi");
9758 size = MAX_PATH;
9760 0, patchcode, targetprod, &context, targetsid, &size);
9761 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9762 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9763 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9764 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9765 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9766 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9767
9768 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9769 lstrcatA(keypath, prod_squashed);
9770
9771 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9772 if (res == ERROR_ACCESS_DENIED)
9773 {
9774 skip("Not enough rights to perform tests\n");
9775 return;
9776 }
9777 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9778
9779 /* local product key exists */
9780 lstrcpyA(patchcode, "apple");
9781 lstrcpyA(targetprod, "banana");
9782 context = 0xdeadbeef;
9783 lstrcpyA(targetsid, "kiwi");
9784 size = MAX_PATH;
9786 0, patchcode, targetprod, &context, targetsid, &size);
9787 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9788 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9789 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9790 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9791 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9792 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9793
9794 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9795 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9796
9797 /* Patches key exists */
9798 lstrcpyA(patchcode, "apple");
9799 lstrcpyA(targetprod, "banana");
9800 context = 0xdeadbeef;
9801 lstrcpyA(targetsid, "kiwi");
9802 size = MAX_PATH;
9804 0, patchcode, targetprod, &context, targetsid, &size);
9805 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9806 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9807 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9808 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9809 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9810 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9811
9812 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9813 (const BYTE *)patch_squashed,
9814 lstrlenA(patch_squashed) + 1);
9815 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9816
9817 /* Patches value exists, is not REG_MULTI_SZ */
9818 lstrcpyA(patchcode, "apple");
9819 lstrcpyA(targetprod, "banana");
9820 context = 0xdeadbeef;
9821 lstrcpyA(targetsid, "kiwi");
9822 size = MAX_PATH;
9824 0, patchcode, targetprod, &context, targetsid, &size);
9825 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9826 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9827 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9828 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9829 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9830 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9831
9832 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9833 (const BYTE *)"a\0b\0c\0\0", 7);
9834 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9835
9836 /* Patches value exists, is not a squashed guid */
9837 lstrcpyA(patchcode, "apple");
9838 lstrcpyA(targetprod, "banana");
9839 context = 0xdeadbeef;
9840 lstrcpyA(targetsid, "kiwi");
9841 size = MAX_PATH;
9843 0, patchcode, targetprod, &context, targetsid, &size);
9844 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9845 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9846 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9847 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9848 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9849 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9850
9851 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9852 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9853 (const BYTE *)patch_squashed,
9854 lstrlenA(patch_squashed) + 2);
9855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9856
9857 /* Patches value exists */
9858 lstrcpyA(patchcode, "apple");
9859 lstrcpyA(targetprod, "banana");
9860 context = 0xdeadbeef;
9861 lstrcpyA(targetsid, "kiwi");
9862 size = MAX_PATH;
9864 0, patchcode, targetprod, &context, targetsid, &size);
9865 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9866 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9867 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9868 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9869 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9870 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9871
9872 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9873 (const BYTE *)"whatever", 9);
9874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9875
9876 /* patch code value exists */
9877 lstrcpyA(patchcode, "apple");
9878 lstrcpyA(targetprod, "banana");
9879 context = 0xdeadbeef;
9880 lstrcpyA(targetsid, "kiwi");
9881 size = MAX_PATH;
9883 0, patchcode, targetprod, &context, targetsid, &size);
9884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9885 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9886 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9887 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9888 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9889 ok(size == 0, "Expected 0, got %lu\n", size);
9890
9891 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9892 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9893 lstrcatA(keypath, prod_squashed);
9894
9895 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9896 if (res == ERROR_ACCESS_DENIED)
9897 {
9898 skip("Not enough rights to perform tests\n");
9899 goto done;
9900 }
9901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9902
9903 /* local UserData product key exists */
9904 lstrcpyA(patchcode, "apple");
9905 lstrcpyA(targetprod, "banana");
9906 context = 0xdeadbeef;
9907 lstrcpyA(targetsid, "kiwi");
9908 size = MAX_PATH;
9910 0, patchcode, targetprod, &context, targetsid, &size);
9911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9912 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9913 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9914 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9915 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9916 ok(size == 0, "Expected 0, got %lu\n", size);
9917
9918 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9919 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9920
9921 /* local UserData Patches key exists */
9922 lstrcpyA(patchcode, "apple");
9923 lstrcpyA(targetprod, "banana");
9924 context = 0xdeadbeef;
9925 lstrcpyA(targetsid, "kiwi");
9926 size = MAX_PATH;
9928 0, patchcode, targetprod, &context, targetsid, &size);
9929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9930 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9931 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9932 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9933 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9934 ok(size == 0, "Expected 0, got %lu\n", size);
9935
9936 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9937 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9938
9939 /* local UserData Product patch key exists */
9940 lstrcpyA(patchcode, "apple");
9941 lstrcpyA(targetprod, "banana");
9942 context = 0xdeadbeef;
9943 lstrcpyA(targetsid, "kiwi");
9944 size = MAX_PATH;
9946 0, patchcode, targetprod, &context, targetsid, &size);
9947 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9948 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9949 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9950 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9951 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9952 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9953
9955 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9956 (const BYTE *)&data, sizeof(DWORD));
9957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9958
9959 /* State value exists */
9960 lstrcpyA(patchcode, "apple");
9961 lstrcpyA(targetprod, "banana");
9962 context = 0xdeadbeef;
9963 lstrcpyA(targetsid, "kiwi");
9964 size = MAX_PATH;
9966 0, patchcode, targetprod, &context, targetsid, &size);
9967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9968 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9969 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9970 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9971 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9972 ok(size == 0, "Expected 0, got %lu\n", size);
9973
9974 /* MSIPATCHSTATE_SUPERSEDED */
9975
9976 lstrcpyA(patchcode, "apple");
9977 lstrcpyA(targetprod, "banana");
9978 context = 0xdeadbeef;
9979 lstrcpyA(targetsid, "kiwi");
9980 size = MAX_PATH;
9982 0, patchcode, targetprod, &context, targetsid, &size);
9983 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9984 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
9985 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
9986 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
9987 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
9988 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
9989
9991 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9992 (const BYTE *)&data, sizeof(DWORD));
9993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
9994
9995 /* State value is MSIPATCHSTATE_SUPERSEDED */
9996 lstrcpyA(patchcode, "apple");
9997 lstrcpyA(targetprod, "banana");
9998 context = 0xdeadbeef;
9999 lstrcpyA(targetsid, "kiwi");
10000 size = MAX_PATH;
10002 0, patchcode, targetprod, &context, targetsid, &size);
10003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10004 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10005 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10006 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10007 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10008 ok(size == 0, "Expected 0, got %lu\n", size);
10009
10010 /* MSIPATCHSTATE_OBSOLETED */
10011
10012 lstrcpyA(patchcode, "apple");
10013 lstrcpyA(targetprod, "banana");
10014 context = 0xdeadbeef;
10015 lstrcpyA(targetsid, "kiwi");
10016 size = MAX_PATH;
10018 0, patchcode, targetprod, &context, targetsid, &size);
10019 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10020 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10021 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10022 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10023 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10024 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10025
10027 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10028 (const BYTE *)&data, sizeof(DWORD));
10029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10030
10031 /* State value is obsoleted */
10032 lstrcpyA(patchcode, "apple");
10033 lstrcpyA(targetprod, "banana");
10034 context = 0xdeadbeef;
10035 lstrcpyA(targetsid, "kiwi");
10036 size = MAX_PATH;
10038 0, patchcode, targetprod, &context, targetsid, &size);
10039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10040 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10041 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10042 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10043 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10044 ok(size == 0, "Expected 0, got %lu\n", size);
10045
10046 /* MSIPATCHSTATE_REGISTERED */
10047 /* FIXME */
10048
10049 /* MSIPATCHSTATE_ALL */
10050
10051 /* 1st */
10052 lstrcpyA(patchcode, "apple");
10053 lstrcpyA(targetprod, "banana");
10054 context = 0xdeadbeef;
10055 lstrcpyA(targetsid, "kiwi");
10056 size = MAX_PATH;
10058 0, patchcode, targetprod, &context, targetsid, &size);
10059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10060 ok(!lstrcmpA(patchcode, patch), "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10061 ok(!lstrcmpA(targetprod, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10062 ok(context == MSIINSTALLCONTEXT_MACHINE, "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10063 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10064 ok(size == 0, "Expected 0, got %lu\n", size);
10065
10066 /* same patch in multiple places, only one is enumerated */
10067 lstrcpyA(patchcode, "apple");
10068 lstrcpyA(targetprod, "banana");
10069 context = 0xdeadbeef;
10070 lstrcpyA(targetsid, "kiwi");
10071 size = MAX_PATH;
10073 1, patchcode, targetprod, &context, targetsid, &size);
10074 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10075 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10076 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10077 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10078 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10079 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10080
10081 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
10082 RegDeleteValueA(hpatch, "State");
10083 RegCloseKey(hpatch);
10084 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
10085 RegCloseKey(udpatch);
10086 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
10087 RegCloseKey(udprod);
10088
10089done:
10090 RegDeleteValueA(patches, patch_squashed);
10091 RegDeleteValueA(patches, "Patches");
10092 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
10093 RegCloseKey(patches);
10094 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
10095 RegCloseKey(prodkey);
10096}
10097
10098static void test_MsiEnumPatchesEx(void)
10099{
10100 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10101 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10102 CHAR patchcode[MAX_PATH];
10104 LPSTR usersid;
10105 DWORD size;
10106 UINT r;
10107
10108 create_test_guid(prodcode, prod_squashed);
10109 usersid = get_user_sid();
10110
10111 /* empty szProductCode */
10112 lstrcpyA(patchcode, "apple");
10113 lstrcpyA(targetprod, "banana");
10114 context = 0xdeadbeef;
10115 lstrcpyA(targetsid, "kiwi");
10116 size = MAX_PATH;
10118 0, patchcode, targetprod, &context, targetsid, &size);
10119 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10120 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10121 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10122 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10123 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10124 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10125
10126 /* garbage szProductCode */
10127 lstrcpyA(patchcode, "apple");
10128 lstrcpyA(targetprod, "banana");
10129 context = 0xdeadbeef;
10130 lstrcpyA(targetsid, "kiwi");
10131 size = MAX_PATH;
10133 0, patchcode, targetprod, &context, targetsid, &size);
10134 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10135 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10136 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10137 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10138 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10139 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10140
10141 /* guid without brackets */
10142 lstrcpyA(patchcode, "apple");
10143 lstrcpyA(targetprod, "banana");
10144 context = 0xdeadbeef;
10145 lstrcpyA(targetsid, "kiwi");
10146 size = MAX_PATH;
10147 r = MsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10148 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context, targetsid, &size);
10149 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10150 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10151 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10152 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10153 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10154 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10155
10156 /* guid with brackets */
10157 lstrcpyA(patchcode, "apple");
10158 lstrcpyA(targetprod, "banana");
10159 context = 0xdeadbeef;
10160 lstrcpyA(targetsid, "kiwi");
10161 size = MAX_PATH;
10162 r = MsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10163 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context, targetsid, &size);
10164 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10165 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10166 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10167 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10168 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10169 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10170
10171 /* szUserSid is S-1-5-18 */
10172 lstrcpyA(patchcode, "apple");
10173 lstrcpyA(targetprod, "banana");
10174 context = 0xdeadbeef;
10175 lstrcpyA(targetsid, "kiwi");
10176 size = MAX_PATH;
10178 0, patchcode, targetprod, &context, targetsid, &size);
10179 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10180 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10181 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10182 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10183 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10184 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10185
10186 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
10187 lstrcpyA(patchcode, "apple");
10188 lstrcpyA(targetprod, "banana");
10189 context = 0xdeadbeef;
10190 lstrcpyA(targetsid, "kiwi");
10191 size = MAX_PATH;
10193 0, patchcode, targetprod, &context, targetsid, &size);
10194 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10195 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10196 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10197 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10198 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10199 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10200
10201 /* dwContext is out of bounds */
10202 lstrcpyA(patchcode, "apple");
10203 lstrcpyA(targetprod, "banana");
10204 context = 0xdeadbeef;
10205 lstrcpyA(targetsid, "kiwi");
10206 size = MAX_PATH;
10207 r = MsiEnumPatchesExA(prodcode, usersid, 0, MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10208 &context, targetsid, &size);
10209 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10210 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10211 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10212 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10213 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10214 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10215
10216 /* dwContext is out of bounds */
10217 lstrcpyA(patchcode, "apple");
10218 lstrcpyA(targetprod, "banana");
10219 context = 0xdeadbeef;
10220 lstrcpyA(targetsid, "kiwi");
10221 size = MAX_PATH;
10222 r = MsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1, MSIPATCHSTATE_ALL, 0, patchcode,
10223 targetprod, &context, targetsid, &size);
10224 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10225 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10226 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10227 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10228 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10229 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10230
10231 /* dwFilter is out of bounds */
10232 lstrcpyA(patchcode, "apple");
10233 lstrcpyA(targetprod, "banana");
10234 context = 0xdeadbeef;
10235 lstrcpyA(targetsid, "kiwi");
10236 size = MAX_PATH;
10238 0, patchcode, targetprod, &context, targetsid, &size);
10239 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10240 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10241 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10242 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10243 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10244 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10245
10246 /* dwFilter is out of bounds */
10247 lstrcpyA(patchcode, "apple");
10248 lstrcpyA(targetprod, "banana");
10249 context = 0xdeadbeef;
10250 lstrcpyA(targetsid, "kiwi");
10251 size = MAX_PATH;
10253 0, patchcode, targetprod, &context, targetsid, &size);
10254 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10255 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10256 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10257 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10258 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10259 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10260
10261 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
10262 lstrcpyA(patchcode, "apple");
10263 lstrcpyA(targetprod, "banana");
10264 context = 0xdeadbeef;
10265 lstrcpyA(targetsid, "kiwi");
10267 0, patchcode, targetprod, &context, targetsid, NULL);
10268 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10269 ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode);
10270 ok(!lstrcmpA(targetprod, "banana"), "Expected targetprod to be unchanged, got %s\n", targetprod);
10271 ok(context == 0xdeadbeef, "Expected context to be unchanged, got %d\n", context);
10272 ok(!lstrcmpA(targetsid, "kiwi"), "Expected targetsid to be unchanged, got %s\n", targetsid);
10273
10274 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
10276 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
10277 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
10279 /* FIXME: Successfully test userunmanaged with a different user */
10281 LocalFree(usersid);
10282}
10283
10284static void test_MsiEnumPatches(void)
10285{
10286 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10287 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10288 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10289 CHAR transforms[MAX_PATH];
10290 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
10291 HKEY prodkey, patches, udprod;
10292 HKEY userkey, hpatch, udpatch;
10293 DWORD size, data;
10294 LPSTR usersid;
10295 LONG res;
10296 UINT r;
10298
10299 create_test_guid(prodcode, prod_squashed);
10300 create_test_guid(patchcode, patch_squashed);
10301 usersid = get_user_sid();
10302
10303 if (is_wow64)
10305
10306 /* NULL szProduct */
10307 size = MAX_PATH;
10308 lstrcpyA(patch, "apple");
10309 lstrcpyA(transforms, "banana");
10310 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
10312 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10313 ok(!lstrcmpA(patch, "apple"),
10314 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10315 ok(!lstrcmpA(transforms, "banana"),
10316 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10317 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10318
10319 /* empty szProduct */
10320 size = MAX_PATH;
10321 lstrcpyA(patch, "apple");
10322 lstrcpyA(transforms, "banana");
10323 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
10325 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10326 ok(!lstrcmpA(patch, "apple"),
10327 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10328 ok(!lstrcmpA(transforms, "banana"),
10329 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10330 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10331
10332 /* garbage szProduct */
10333 size = MAX_PATH;
10334 lstrcpyA(patch, "apple");
10335 lstrcpyA(transforms, "banana");
10336 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
10338 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10339 ok(!lstrcmpA(patch, "apple"),
10340 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10341 ok(!lstrcmpA(transforms, "banana"),
10342 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10343 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10344
10345 /* guid without brackets */
10346 size = MAX_PATH;
10347 lstrcpyA(patch, "apple");
10348 lstrcpyA(transforms, "banana");
10349 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
10350 transforms, &size);
10352 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10353 ok(!lstrcmpA(patch, "apple"),
10354 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10355 ok(!lstrcmpA(transforms, "banana"),
10356 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10357 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10358
10359 /* guid with brackets */
10360 size = MAX_PATH;
10361 lstrcpyA(patch, "apple");
10362 lstrcpyA(transforms, "banana");
10363 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
10364 transforms, &size);
10366 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10367 ok(!lstrcmpA(patch, "apple"),
10368 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10369 ok(!lstrcmpA(transforms, "banana"),
10370 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10371 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10372
10373 /* same length as guid, but random */
10374 size = MAX_PATH;
10375 lstrcpyA(patch, "apple");
10376 lstrcpyA(transforms, "banana");
10377 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
10378 transforms, &size);
10380 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10381 ok(!lstrcmpA(patch, "apple"),
10382 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10383 ok(!lstrcmpA(transforms, "banana"),
10384 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10385 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10386
10387 /* MSIINSTALLCONTEXT_USERMANAGED */
10388
10389 size = MAX_PATH;
10390 lstrcpyA(patch, "apple");
10391 lstrcpyA(transforms, "banana");
10392 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10394 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10395 ok(!lstrcmpA(patch, "apple"),
10396 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10397 ok(!lstrcmpA(transforms, "banana"),
10398 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10399 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10400
10401 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10402 lstrcatA(keypath, usersid);
10403 lstrcatA(keypath, "\\Installer\\Products\\");
10404 lstrcatA(keypath, prod_squashed);
10405
10406 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10407 if (res == ERROR_ACCESS_DENIED)
10408 {
10409 skip("Not enough rights to perform tests\n");
10410 LocalFree(usersid);
10411 return;
10412 }
10413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10414
10415 /* managed product key exists */
10416 size = MAX_PATH;
10417 lstrcpyA(patch, "apple");
10418 lstrcpyA(transforms, "banana");
10419 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10420 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10421 ok(!lstrcmpA(patch, "apple"),
10422 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10423 ok(!lstrcmpA(transforms, "banana"),
10424 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10425 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10426
10427 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10429
10430 /* patches key exists */
10431 size = MAX_PATH;
10432 lstrcpyA(patch, "apple");
10433 lstrcpyA(transforms, "banana");
10434 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10435 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10436 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10437 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10438 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10439
10440 res = RegSetValueExA(patches, "Patches", 0, REG_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 1);
10441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10442
10443 /* Patches value exists, is not REG_MULTI_SZ */
10444 size = MAX_PATH;
10445 lstrcpyA(patch, "apple");
10446 lstrcpyA(transforms, "banana");
10447 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10448 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10449 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10450 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10451 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10452
10453 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)"a\0b\0c\0\0", 7);
10454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10455
10456 /* Patches value exists, is not a squashed guid */
10457 size = MAX_PATH;
10458 lstrcpyA(patch, "apple");
10459 lstrcpyA(transforms, "banana");
10460 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10461 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10462 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10463 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10464 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10465
10466 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10467 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 2);
10468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10469
10470 /* Patches value exists */
10471 size = MAX_PATH;
10472 lstrcpyA(patch, "apple");
10473 lstrcpyA(transforms, "banana");
10474 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10475 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10476 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10477 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10478 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10479
10480 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ, (const BYTE *)"whatever", 9);
10481 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10482
10483 /* patch squashed value exists */
10484 size = MAX_PATH;
10485 lstrcpyA(patch, "apple");
10486 lstrcpyA(transforms, "banana");
10487 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10489 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10490 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10491 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10492
10493 /* lpPatchBuf is NULL */
10494 size = MAX_PATH;
10495 lstrcpyA(transforms, "banana");
10496 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
10497 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10498 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10499 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10500
10501 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10502 size = MAX_PATH;
10503 lstrcpyA(patch, "apple");
10504 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10505 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10506 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10507 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10508
10509 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10510 lstrcpyA(patch, "apple");
10511 lstrcpyA(transforms, "banana");
10512 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10513 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10514 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10515 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10516
10517 /* pcchTransformsBuf is too small */
10518 size = 6;
10519 lstrcpyA(patch, "apple");
10520 lstrcpyA(transforms, "banana");
10521 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10522 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10523 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10524 ok(!lstrcmpA(transforms, "whate"), "Expected \"whate\", got \"%s\"\n", transforms);
10525 ok(size == 8 || size == 16, "Expected 8 or 16, got %lu\n", size);
10526
10527 /* increase the index */
10528 size = MAX_PATH;
10529 lstrcpyA(patch, "apple");
10530 lstrcpyA(transforms, "banana");
10531 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10532 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10533 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10534 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10535 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10536
10537 /* increase again */
10538 size = MAX_PATH;
10539 lstrcpyA(patch, "apple");
10540 lstrcpyA(transforms, "banana");
10541 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10542 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10543 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10544 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10545 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10546
10547 RegDeleteValueA(patches, "Patches");
10548 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
10549 RegCloseKey(patches);
10550 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
10551 RegCloseKey(prodkey);
10552
10553 /* MSIINSTALLCONTEXT_USERUNMANAGED */
10554
10555 size = MAX_PATH;
10556 lstrcpyA(patch, "apple");
10557 lstrcpyA(transforms, "banana");
10558 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10559 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10560 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10561 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10562 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10563
10564 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10565 lstrcatA(keypath, prod_squashed);
10566
10567 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10568 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10569
10570 /* current user product key exists */
10571 size = MAX_PATH;
10572 lstrcpyA(patch, "apple");
10573 lstrcpyA(transforms, "banana");
10574 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10575 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10576 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10577 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10578 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10579
10580 res = RegCreateKeyA(prodkey, "Patches", &patches);
10581 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10582
10583 /* Patches key exists */
10584 size = MAX_PATH;
10585 lstrcpyA(patch, "apple");
10586 lstrcpyA(transforms, "banana");
10587 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10588 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10589 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10590 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10591 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10592
10593 res = RegSetValueExA(patches, "Patches", 0, REG_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 1);
10594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10595
10596 /* Patches value exists, is not REG_MULTI_SZ */
10597 size = MAX_PATH;
10598 lstrcpyA(patch, "apple");
10599 lstrcpyA(transforms, "banana");
10600 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10601 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10602 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10603 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10604 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10605
10606 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)"a\0b\0c\0\0", 7);
10607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10608
10609 /* Patches value exists, is not a squashed guid */
10610 size = MAX_PATH;
10611 lstrcpyA(patch, "apple");
10612 lstrcpyA(transforms, "banana");
10613 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10614 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10615 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10616 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10617 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10618
10619 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10620 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 2);
10621 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10622
10623 /* Patches value exists */
10624 size = MAX_PATH;
10625 lstrcpyA(patch, "apple");
10626 lstrcpyA(transforms, "banana");
10627 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10628 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10629 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10630 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10631 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10632
10633 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ, (const BYTE *)"whatever", 9);
10634 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10635
10636 /* patch code value exists */
10637 size = MAX_PATH;
10638 lstrcpyA(patch, "apple");
10639 lstrcpyA(transforms, "banana");
10640 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10641 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10642 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10643 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10644 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10645
10646 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10647 lstrcatA(keypath, usersid);
10648 lstrcatA(keypath, "\\Patches\\");
10649 lstrcatA(keypath, patch_squashed);
10650
10651 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10652 if (res == ERROR_ACCESS_DENIED)
10653 {
10654 skip("Not enough rights to perform tests\n");
10655 LocalFree(usersid);
10656 return;
10657 }
10658 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10659
10660 /* userdata patch key exists */
10661 size = MAX_PATH;
10662 lstrcpyA(patch, "apple");
10663 lstrcpyA(transforms, "banana");
10664 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10666 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10667 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10668 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10669
10670 RegDeleteKeyExA(userkey, "", access & KEY_WOW64_64KEY, 0);
10671 RegCloseKey(userkey);
10672 RegDeleteValueA(patches, patch_squashed);
10673 RegDeleteValueA(patches, "Patches");
10674 RegDeleteKeyA(patches, "");
10675 RegCloseKey(patches);
10676 RegDeleteKeyA(prodkey, "");
10677 RegCloseKey(prodkey);
10678
10679 /* MSIINSTALLCONTEXT_MACHINE */
10680
10681 size = MAX_PATH;
10682 lstrcpyA(patch, "apple");
10683 lstrcpyA(transforms, "banana");
10684 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10685 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10686 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10687 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10688 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10689
10690 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10691 lstrcatA(keypath, prod_squashed);
10692
10693 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10694 if (res == ERROR_ACCESS_DENIED)
10695 {
10696 skip("Not enough rights to perform tests\n");
10697 LocalFree(usersid);
10698 return;
10699 }
10700 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10701
10702 /* local product key exists */
10703 size = MAX_PATH;
10704 lstrcpyA(patch, "apple");
10705 lstrcpyA(transforms, "banana");
10706 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10707 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10708 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10709 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10710 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10711
10712 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10714
10715 /* Patches key exists */
10716 size = MAX_PATH;
10717 lstrcpyA(patch, "apple");
10718 lstrcpyA(transforms, "banana");
10719 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10720 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10721 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10722 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10723 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10724
10725 res = RegSetValueExA(patches, "Patches", 0, REG_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 1);
10726 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10727
10728 /* Patches value exists, is not REG_MULTI_SZ */
10729 size = MAX_PATH;
10730 lstrcpyA(patch, "apple");
10731 lstrcpyA(transforms, "banana");
10732 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10733 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10734 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10735 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10736 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10737
10738 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)"a\0b\0c\0\0", 7);
10739 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10740
10741 /* Patches value exists, is not a squashed guid */
10742 size = MAX_PATH;
10743 lstrcpyA(patch, "apple");
10744 lstrcpyA(transforms, "banana");
10745 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10746 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10747 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10748 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10749 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10750
10751 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10752 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)patch_squashed, lstrlenA(patch_squashed) + 2);
10753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10754
10755 /* Patches value exists */
10756 size = MAX_PATH;
10757 lstrcpyA(patch, "apple");
10758 lstrcpyA(transforms, "banana");
10759 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10760 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10761 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10762 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10763 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10764
10765 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ, (const BYTE *)"whatever", 9);
10766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10767
10768 /* patch code value exists */
10769 size = MAX_PATH;
10770 lstrcpyA(patch, "apple");
10771 lstrcpyA(transforms, "banana");
10772 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10774 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10775 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10776 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10777
10778 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10779 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10780 lstrcatA(keypath, prod_squashed);
10781
10782 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10783 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10784
10785 /* local UserData product key exists */
10786 size = MAX_PATH;
10787 lstrcpyA(patch, "apple");
10788 lstrcpyA(transforms, "banana");
10789 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10791 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10792 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10793 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10794
10795 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10796 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10797
10798 /* local UserData Patches key exists */
10799 size = MAX_PATH;
10800 lstrcpyA(patch, "apple");
10801 lstrcpyA(transforms, "banana");
10802 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10804 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10805 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10806 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10807
10808 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10809 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10810
10811 /* local UserData Product patch key exists */
10812 size = MAX_PATH;
10813 lstrcpyA(patch, "apple");
10814 lstrcpyA(transforms, "banana");
10815 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10816 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10817 ok(!lstrcmpA(patch, "apple"), "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10818 ok(!lstrcmpA(transforms, "banana"), "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10819 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10820
10822 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
10823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10824
10825 /* State value exists */
10826 size = MAX_PATH;
10827 lstrcpyA(patch, "apple");
10828 lstrcpyA(transforms, "banana");
10829 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10831 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10832 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10833 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10834
10835 /* now duplicate some of the tests for the W version */
10836
10837 /* pcchTransformsBuf is too small */
10838 size = 6;
10839 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10840 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10841 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10842 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10843 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10844 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10845 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10846 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10847 ok(!lstrcmpA(transforms, "whate"), "Expected \"whate\", got \"%s\"\n", transforms);
10848 ok(size == 8, "Expected 8, got %lu\n", size);
10849
10850 /* patch code value exists */
10851 size = MAX_PATH;
10852 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10853 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10854 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10856 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10857 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10858 ok(!lstrcmpA(patch, patchcode), "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10859 ok(!lstrcmpA(transforms, "whatever"), "Expected \"whatever\", got \"%s\"\n", transforms);
10860 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
10861
10862 RegDeleteValueA(patches, patch_squashed);
10863 RegDeleteValueA(patches, "Patches");
10864 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
10865 RegCloseKey(patches);
10866 RegDeleteValueA(hpatch, "State");
10867 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
10868 RegCloseKey(hpatch);
10869 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
10870 RegCloseKey(udpatch);
10871 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
10872 RegCloseKey(udprod);
10873 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
10874 RegCloseKey(prodkey);
10875 LocalFree(usersid);
10876}
10877
10878static void test_MsiGetPatchInfoEx(void)
10879{
10880 CHAR keypath[MAX_PATH], val[MAX_PATH];
10881 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10882 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10883 HKEY prodkey, patches, udprod, props;
10884 HKEY hpatch, udpatch, prodpatches;
10885 LPSTR usersid;
10886 DWORD size;
10887 LONG res;
10888 UINT r;
10890
10891 create_test_guid(prodcode, prod_squashed);
10892 create_test_guid(patchcode, patch_squashed);
10893 usersid = get_user_sid();
10894
10895 if (is_wow64)
10897
10898 /* NULL szPatchCode */
10899 lstrcpyA(val, "apple");
10900 size = MAX_PATH;
10902 val, &size);
10903 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10904 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10905 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10906
10907 /* empty szPatchCode */
10908 size = MAX_PATH;
10909 lstrcpyA(val, "apple");
10911 val, &size);
10912 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10913 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10914 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10915
10916 /* garbage szPatchCode */
10917 size = MAX_PATH;
10918 lstrcpyA(val, "apple");
10920 val, &size);
10921 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10922 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10923 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10924
10925 /* guid without brackets */
10926 size = MAX_PATH;
10927 lstrcpyA(val, "apple");
10928 r = MsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10930 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10931 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10932 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10933
10934 /* guid with brackets */
10935 size = MAX_PATH;
10936 lstrcpyA(val, "apple");
10937 r = MsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10939 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10940 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10941 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10942
10943 /* same length as guid, but random */
10944 size = MAX_PATH;
10945 lstrcpyA(val, "apple");
10946 r = MsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10948 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10949 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10950 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10951
10952 /* NULL szProductCode */
10953 lstrcpyA(val, "apple");
10954 size = MAX_PATH;
10956 val, &size);
10957 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10958 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10959 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10960
10961 /* empty szProductCode */
10962 size = MAX_PATH;
10963 lstrcpyA(val, "apple");
10965 val, &size);
10966 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10967 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10968 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10969
10970 /* garbage szProductCode */
10971 size = MAX_PATH;
10972 lstrcpyA(val, "apple");
10974 val, &size);
10975 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10976 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10977 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10978
10979 /* guid without brackets */
10980 size = MAX_PATH;
10981 lstrcpyA(val, "apple");
10982 r = MsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10984 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10985 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10986 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10987
10988 /* guid with brackets */
10989 size = MAX_PATH;
10990 lstrcpyA(val, "apple");
10991 r = MsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10993 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10994 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
10995 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10996
10997 /* same length as guid, but random */
10998 size = MAX_PATH;
10999 lstrcpyA(val, "apple");
11000 r = MsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", NULL, MSIINSTALLCONTEXT_USERMANAGED,
11002 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11003 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11004 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11005
11006 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
11007 size = MAX_PATH;
11008 lstrcpyA(val, "apple");
11010 val, &size);
11011 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11012 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11013 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11014
11015 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
11016 size = MAX_PATH;
11017 lstrcpyA(val, "apple");
11019 val, &size);
11020 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11021 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11022 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11023
11024 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
11025 size = MAX_PATH;
11026 lstrcpyA(val, "apple");
11028 val, &size);
11029 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11030 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11031 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11032
11033 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
11034 size = MAX_PATH;
11035 lstrcpyA(val, "apple");
11037 val, &size);
11038 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11039 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11040 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11041
11042 /* dwContext is out of range */
11043 size = MAX_PATH;
11044 lstrcpyA(val, "apple");
11046 val, &size);
11047 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11048 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11049 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11050
11051 /* dwContext is out of range */
11052 size = MAX_PATH;
11053 lstrcpyA(val, "apple");
11055 val, &size);
11056 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11057 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11058 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11059
11060 /* dwContext is invalid */
11061 size = MAX_PATH;
11062 lstrcpyA(val, "apple");
11063 r = MsiGetPatchInfoExA(patchcode, prodcode, usersid, 3, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11064 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11065 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11066 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11067
11068 /* MSIINSTALLCONTEXT_USERMANAGED */
11069
11070 size = MAX_PATH;
11071 lstrcpyA(val, "apple");
11073 val, &size);
11074 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11075 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11076 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11077
11078 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11079 lstrcatA(keypath, usersid);
11080 lstrcatA(keypath, "\\Products\\");
11081 lstrcatA(keypath, prod_squashed);
11082
11083 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11084 if (res == ERROR_ACCESS_DENIED)
11085 {
11086 skip("Not enough rights to perform tests\n");
11087 LocalFree(usersid);
11088 return;
11089 }
11090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11091
11092 /* local UserData product key exists */
11093 size = MAX_PATH;
11094 lstrcpyA(val, "apple");
11096 val, &size);
11097 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11098 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11099 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11100
11101 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11103
11104 /* InstallProperties key exists */
11105 size = MAX_PATH;
11106 lstrcpyA(val, "apple");
11108 val, &size);
11109 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11110 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11111 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11112
11113 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11114 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11115
11116 /* Patches key exists */
11117 size = MAX_PATH;
11118 lstrcpyA(val, "apple");
11120 val, &size);
11121 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCHA, got %d\n", r);
11122 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11123 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11124
11125 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11126 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11127
11128 /* Patches key exists */
11129 size = MAX_PATH;
11130 lstrcpyA(val, "apple");
11132 val, &size);
11133 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11134 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11135 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11136
11137 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11138 lstrcatA(keypath, usersid);
11139 lstrcatA(keypath, "\\Installer\\Products\\");
11140 lstrcatA(keypath, prod_squashed);
11141
11142 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11144
11145 /* managed product key exists */
11146 size = MAX_PATH;
11147 lstrcpyA(val, "apple");
11149 val, &size);
11150 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11151 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11152 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11153
11154 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11155 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11156
11157 /* Patches key exists */
11158 size = MAX_PATH;
11159 lstrcpyA(val, "apple");
11161 val, &size);
11162 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11163 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11164 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11165
11166 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ, (const BYTE *)"transforms", 11);
11167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11168
11169 /* specific patch value exists */
11170 size = MAX_PATH;
11171 lstrcpyA(val, "apple");
11173 val, &size);
11174 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11175 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11176 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11177
11178 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11179 lstrcatA(keypath, usersid);
11180 lstrcatA(keypath, "\\Patches\\");
11181 lstrcatA(keypath, patch_squashed);
11182
11183 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11184 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11185
11186 /* UserData Patches key exists */
11187 size = MAX_PATH;
11188 lstrcpyA(val, "apple");
11190 val, &size);
11191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11192 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11193 ok(size == 0, "Expected 0, got %lu\n", size);
11194
11195 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"pack", 5);
11196 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11197
11198 /* ManagedLocalPatch value exists */
11199 size = MAX_PATH;
11200 lstrcpyA(val, "apple");
11202 val, &size);
11203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11204 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11205 ok(size == 4, "Expected 4, got %lu\n", size);
11206
11207 size = MAX_PATH;
11208 lstrcpyA(val, "apple");
11210 val, &size);
11211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11212 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11213 ok(size == 10, "Expected 10, got %lu\n", size);
11214
11215 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ, (const BYTE *)"mydate", 7);
11216 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11217
11218 /* Installed value exists */
11219 size = MAX_PATH;
11220 lstrcpyA(val, "apple");
11222 val, &size);
11223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11224 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
11225 ok(size == 6, "Expected 6, got %lu\n", size);
11226
11227 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ, (const BYTE *)"yes", 4);
11228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11229
11230 /* Uninstallable value exists */
11231 size = MAX_PATH;
11232 lstrcpyA(val, "apple");
11234 val, &size);
11235 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11236 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
11237 ok(size == 3, "Expected 3, got %lu\n", size);
11238
11239 res = RegSetValueExA(hpatch, "State", 0, REG_SZ, (const BYTE *)"good", 5);
11240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11241
11242 /* State value exists */
11243 size = MAX_PATH;
11244 lstrcpyA(val, "apple");
11246 val, &size);
11247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11248 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
11249 ok(size == 4, "Expected 4, got %lu\n", size);
11250
11251 size = 1;
11252 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD, (const BYTE *)&size, sizeof(DWORD));
11253 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11254
11255 /* State value exists */
11256 size = MAX_PATH;
11257 lstrcpyA(val, "apple");
11259 val, &size);
11260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11261 ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
11262 ok(size == 1, "Expected 1, got %lu\n", size);
11263
11264 size = 1;
11265 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_DWORD, (const BYTE *)&size, sizeof(DWORD));
11266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11267
11268 /* Uninstallable value exists */
11269 size = MAX_PATH;
11270 lstrcpyA(val, "apple");
11272 val, &size);
11273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11274 ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
11275 ok(size == 1, "Expected 1, got %lu\n", size);
11276
11277 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ, (const BYTE *)"display", 8);
11278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11279
11280 /* DisplayName value exists */
11281 size = MAX_PATH;
11282 lstrcpyA(val, "apple");
11284 val, &size);
11285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11286 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
11287 ok(size == 7, "Expected 7, got %lu\n", size);
11288
11289 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ, (const BYTE *)"moreinfo", 9);
11290 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11291
11292 /* MoreInfoURL value exists */
11293 size = MAX_PATH;
11294 lstrcpyA(val, "apple");
11296 val, &size);
11297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11298 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
11299 ok(size == 8, "Expected 8, got %lu\n", size);
11300
11301 /* szProperty is invalid */
11302 size = MAX_PATH;
11303 lstrcpyA(val, "apple");
11304 r = MsiGetPatchInfoExA(patchcode, prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED, "IDontExist", val, &size);
11305 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
11306 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11307 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
11308
11309 /* lpValue is NULL, while pcchValue is non-NULL */
11310 size = MAX_PATH;
11312 NULL, &size);
11313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11314 ok(size == 16, "Expected 16, got %lu\n", size);
11315
11316 /* pcchValue is NULL, while lpValue is non-NULL */
11317 lstrcpyA(val, "apple");
11319 val, NULL);
11320 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11321 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11322
11323 /* both lpValue and pcchValue are NULL */
11325 NULL, NULL);
11326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11327
11328 /* pcchValue doesn't have enough room for NULL terminator */
11329 size = 8;
11330 lstrcpyA(val, "apple");
11332 val, &size);
11333 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11334 ok(!lstrcmpA(val, "moreinf"), "Expected \"moreinf\", got \"%s\"\n", val);
11335 ok(size == 16, "Expected 16, got %lu\n", size);
11336
11337 /* pcchValue has exactly enough room for NULL terminator */
11338 size = 9;
11339 lstrcpyA(val, "apple");
11341 val, &size);
11342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11343 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
11344 ok(size == 8, "Expected 8, got %lu\n", size);
11345
11346 /* pcchValue is too small, lpValue is NULL */
11347 size = 0;
11349 NULL, &size);
11350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11351 ok(size == 16, "Expected 16, got %lu\n", size);
11352
11353 RegDeleteValueA(prodpatches, patch_squashed);
11354 RegDeleteKeyExA(prodpatches, "", access & KEY_WOW64_64KEY, 0);
11355 RegCloseKey(prodpatches);
11356 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
11357 RegCloseKey(prodkey);
11358
11359 /* UserData is sufficient for all properties
11360 * except INSTALLPROPERTY_TRANSFORMS
11361 */
11362 size = MAX_PATH;
11363 lstrcpyA(val, "apple");
11365 val, &size);
11366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11367 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11368 ok(size == 4, "Expected 4, got %lu\n", size);
11369
11370 /* UserData is sufficient for all properties
11371 * except INSTALLPROPERTY_TRANSFORMS
11372 */
11373 size = MAX_PATH;
11374 lstrcpyA(val, "apple");
11376 val, &size);
11377 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11378 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11379 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
11380
11381 RegDeleteValueA(hpatch, "MoreInfoURL");
11382 RegDeleteValueA(hpatch, "Display");
11383 RegDeleteValueA(hpatch, "State");
11384 RegDeleteValueA(hpatch, "Uninstallable");
11385 RegDeleteValueA(hpatch, "Installed");
11386 RegDeleteValueA(udpatch, "ManagedLocalPackage");
11387 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
11388 RegCloseKey(udpatch);
11389 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
11390 RegCloseKey(hpatch);
11391 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
11392 RegCloseKey(patches);
11395 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
11396 RegCloseKey(udprod);
11397
11398 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11399
11400 size = MAX_PATH;
11401 lstrcpyA(val, "apple");
11403 val, &size);
11404 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11405 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11406 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11407
11408 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11409 lstrcatA(keypath, usersid);
11410 lstrcatA(keypath, "\\Products\\");
11411 lstrcatA(keypath, prod_squashed);
11412
11413 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11414 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11415
11416 /* local UserData product key exists */
11417 size = MAX_PATH;
11418 lstrcpyA(val, "apple");
11420 val, &size);
11421 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11422 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11423 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11424
11425 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11426 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11427
11428 /* InstallProperties key exists */
11429 size = MAX_PATH;
11430 lstrcpyA(val, "apple");
11432 val, &size);
11433 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11434 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11435 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11436
11437 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11439
11440 /* Patches key exists */
11441 size = MAX_PATH;
11442 lstrcpyA(val, "apple");
11444 val, &size);
11445 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11446 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11447 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11448
11449 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11451
11452 /* Patches key exists */
11453 size = MAX_PATH;
11454 lstrcpyA(val, "apple");
11456 val, &size);
11457 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11458 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11459 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11460
11461 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11462 lstrcatA(keypath, prod_squashed);
11463
11464 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11465 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11466
11467 /* current user product key exists */
11468 size = MAX_PATH;
11469 lstrcpyA(val, "apple");
11471 val, &size);
11472 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11473 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11474 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11475
11476 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11477 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11478
11479 /* Patches key exists */
11480 size = MAX_PATH;
11481 lstrcpyA(val, "apple");
11483 val, &size);
11484 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11485 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11486 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11487
11488 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11489 (const BYTE *)"transforms", 11);
11490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11491
11492 /* specific patch value exists */
11493 size = MAX_PATH;
11494 lstrcpyA(val, "apple");
11496 val, &size);
11497 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11498 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11499 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11500
11501 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11502 lstrcatA(keypath, usersid);
11503 lstrcatA(keypath, "\\Patches\\");
11504 lstrcatA(keypath, patch_squashed);
11505
11506 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11508
11509 /* UserData Patches key exists */
11510 size = MAX_PATH;
11511 lstrcpyA(val, "apple");
11513 val, &size);
11514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11515 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11516 ok(size == 0, "Expected 0, got %lu\n", size);
11517
11518 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11519 (const BYTE *)"pack", 5);
11520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11521
11522 /* LocalPatch value exists */
11523 size = MAX_PATH;
11524 lstrcpyA(val, "apple");
11526 val, &size);
11527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11528 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11529 ok(size == 4, "Expected 4, got %lu\n", size);
11530
11531 size = MAX_PATH;
11532 lstrcpyA(val, "apple");
11534 val, &size);
11535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11536 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11537 ok(size == 10, "Expected 10, got %lu\n", size);
11538
11539 RegDeleteValueA(prodpatches, patch_squashed);
11540 RegDeleteKeyExA(prodpatches, "", access & KEY_WOW64_64KEY, 0);
11541 RegCloseKey(prodpatches);
11542 RegDeleteKeyA(prodkey, "");
11543 RegCloseKey(prodkey);
11544
11545 /* UserData is sufficient for all properties
11546 * except INSTALLPROPERTY_TRANSFORMS
11547 */
11548 size = MAX_PATH;
11549 lstrcpyA(val, "apple");
11551 val, &size);
11552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11553 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11554 ok(size == 4, "Expected 4, got %lu\n", size);
11555
11556 /* UserData is sufficient for all properties
11557 * except INSTALLPROPERTY_TRANSFORMS
11558 */
11559 size = MAX_PATH;
11560 lstrcpyA(val, "apple");
11562 val, &size);
11563 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11564 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11565 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
11566
11567 RegDeleteValueA(udpatch, "LocalPackage");
11568 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
11569 RegCloseKey(udpatch);
11570 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
11571 RegCloseKey(hpatch);
11572 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
11573 RegCloseKey(patches);
11576 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
11577 RegCloseKey(udprod);
11578
11579 /* MSIINSTALLCONTEXT_MACHINE */
11580
11581 size = MAX_PATH;
11582 lstrcpyA(val, "apple");
11584 val, &size);
11585 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11586 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11587 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11588
11589 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11590 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11591 lstrcatA(keypath, prod_squashed);
11592
11593 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11595
11596 /* local UserData product key exists */
11597 size = MAX_PATH;
11598 lstrcpyA(val, "apple");
11600 val, &size);
11601 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11602 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11603 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11604
11605 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11607
11608 /* InstallProperties key exists */
11609 size = MAX_PATH;
11610 lstrcpyA(val, "apple");
11612 val, &size);
11613 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11614 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11615 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11616
11617 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11618 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11619
11620 /* Patches key exists */
11621 size = MAX_PATH;
11622 lstrcpyA(val, "apple");
11624 val, &size);
11625 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11626 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11627 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11628
11629 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11631
11632 /* Patches key exists */
11633 size = MAX_PATH;
11634 lstrcpyA(val, "apple");
11636 val, &size);
11637 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11638 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11639 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11640
11641 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11642 lstrcatA(keypath, prod_squashed);
11643
11644 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11645 if (res == ERROR_ACCESS_DENIED)
11646 {
11647 skip( "insufficient rights\n" );
11648 LocalFree( usersid );
11649 return;
11650 }
11651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11652
11653 /* local product key exists */
11654 size = MAX_PATH;
11655 lstrcpyA(val, "apple");
11657 val, &size);
11658 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11659 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11660 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11661
11662 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11664
11665 /* Patches key exists */
11666 size = MAX_PATH;
11667 lstrcpyA(val, "apple");
11669 val, &size);
11670 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11671 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11672 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11673
11674 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11675 (const BYTE *)"transforms", 11);
11676 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11677
11678 /* specific patch value exists */
11679 size = MAX_PATH;
11680 lstrcpyA(val, "apple");
11682 val, &size);
11683 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11684 ok(!lstrcmpA(val, "apple"), "Expected val to be unchanged, got \"%s\"\n", val);
11685 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11686
11687 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11688 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11689 lstrcatA(keypath, patch_squashed);
11690
11691 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11693
11694 /* UserData Patches key exists */
11695 size = MAX_PATH;
11696 lstrcpyA(val, "apple");
11698 val, &size);
11699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11700 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11701 ok(size == 0, "Expected 0, got %lu\n", size);
11702
11703 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"pack", 5);
11704 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11705
11706 /* LocalPatch value exists */
11707 size = MAX_PATH;
11708 lstrcpyA(val, "apple");
11710 val, &size);
11711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11712 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11713 ok(size == 4, "Expected 4, got %lu\n", size);
11714
11715 size = MAX_PATH;
11716 lstrcpyA(val, "apple");
11718 val, &size);
11719 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11720 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11721 ok(size == 10, "Expected 10, got %lu\n", size);
11722
11723 RegDeleteValueA(prodpatches, patch_squashed);
11724 RegDeleteKeyExA(prodpatches, "", access & KEY_WOW64_64KEY, 0);
11725 RegCloseKey(prodpatches);
11726 RegDeleteKeyExA(prodkey, "", access & KEY_WOW64_64KEY, 0);
11727 RegCloseKey(prodkey);
11728
11729 /* UserData is sufficient for all properties
11730 * except INSTALLPROPERTY_TRANSFORMS
11731 */
11732 size = MAX_PATH;
11733 lstrcpyA(val, "apple");
11735 val, &size);
11736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11737 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11738 ok(size == 4, "Expected 4, got %lu\n", size);
11739
11740 /* UserData is sufficient for all properties
11741 * except INSTALLPROPERTY_TRANSFORMS
11742 */
11743 size = MAX_PATH;
11744 lstrcpyA(val, "apple");
11746 val, &size);
11747 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11748 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11749 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
11750
11751 RegDeleteValueA(udpatch, "LocalPackage");
11752 RegDeleteKeyExA(udpatch, "", access & KEY_WOW64_64KEY, 0);
11753 RegCloseKey(udpatch);
11754 RegDeleteKeyExA(hpatch, "", access & KEY_WOW64_64KEY, 0);
11755 RegCloseKey(hpatch);
11756 RegDeleteKeyExA(patches, "", access & KEY_WOW64_64KEY, 0);
11757 RegCloseKey(patches);
11760 RegDeleteKeyExA(udprod, "", access & KEY_WOW64_64KEY, 0);
11761 RegCloseKey(udprod);
11762 LocalFree(usersid);
11763}
11764
11765static void test_MsiGetPatchInfo(void)
11766{
11767 UINT r;
11768 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11769 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11770 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11771 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11772 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11773 DWORD size;
11774 LONG res;
11776
11777 create_test_guid(patch_code, patch_squashed);
11778 create_test_guid(prod_code, prod_squashed);
11779 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11780
11781 if (is_wow64)
11783
11785 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11786
11787 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11788 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11789
11791 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11792
11793 size = 0;
11794 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11795 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11796
11797 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11798 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11799
11800 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11801 lstrcatA(keypath, prod_squashed);
11802
11803 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11804 if (res == ERROR_ACCESS_DENIED)
11805 {
11806 skip("Not enough rights to perform tests\n");
11807 return;
11808 }
11809 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11810
11811 /* product key exists */
11812 size = MAX_PATH;
11813 lstrcpyA(val, "apple");
11815 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11816 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11817 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11818
11819 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11820 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11821
11822 /* patches key exists */
11823 size = MAX_PATH;
11824 lstrcpyA(val, "apple");
11826 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11827 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11828 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11829
11830 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11831 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11832
11833 /* patch key exists */
11834 size = MAX_PATH;
11835 lstrcpyA(val, "apple");
11837 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11838 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11839 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11840
11841 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11842 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11843 lstrcatA(keypath, prod_squashed);
11844
11845 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11846 if (res == ERROR_ACCESS_DENIED)
11847 {
11848 skip("Not enough rights to perform tests\n");
11849 goto done;
11850 }
11851 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %ld\n", res);
11852
11853 /* UserData product key exists */
11854 size = MAX_PATH;
11855 lstrcpyA(val, "apple");
11857 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11858 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11859 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11860
11861 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11862 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11863
11864 /* InstallProperties key exists */
11865 size = MAX_PATH;
11866 lstrcpyA(val, "apple");
11868 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11869 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11870 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11871
11872 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11873 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11874
11875 /* UserData Patches key exists */
11876 size = MAX_PATH;
11877 lstrcpyA(val, "apple");
11879 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11880 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11881 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11882
11883 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11884 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11885
11886 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11887 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11888
11889 /* UserData product patch key exists */
11890 size = MAX_PATH;
11891 lstrcpyA(val, "apple");
11893 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11894 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11895 ok(size == MAX_PATH, "expected size to be unchanged got %lu\n", size);
11896
11897 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11898 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11899 lstrcatA(keypath, patch_squashed);
11900
11901 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11902 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11903
11904 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11905 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %ld\n", res);
11906
11907 /* UserData Patch key exists */
11908 size = 0;
11909 lstrcpyA(val, "apple");
11911 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11912 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11913 ok(size == 11, "expected 11 got %lu\n", size);
11914
11915 size = MAX_PATH;
11916 lstrcpyA(val, "apple");
11918 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11919 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11920 ok(size == 11, "expected 11 got %lu\n", size);
11921
11922 size = 0;
11923 valW[0] = 0;
11924 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11925 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11926 ok(!valW[0], "expected 0 got %u\n", valW[0]);
11927 ok(size == 11, "expected 11 got %lu\n", size);
11928
11929 size = MAX_PATH;
11930 valW[0] = 0;
11931 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11932 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11933 ok(valW[0], "expected > 0 got %u\n", valW[0]);
11934 ok(size == 11, "expected 11 got %lu\n", size);
11935
11936 RegDeleteKeyExA(hkey_udproductpatch, "", access & KEY_WOW64_64KEY, 0);
11937 RegCloseKey(hkey_udproductpatch);
11938 RegDeleteKeyExA(hkey_udproductpatches, "", access & KEY_WOW64_64KEY, 0);
11939 RegCloseKey(hkey_udproductpatches);
11940 RegDeleteKeyExA(hkey_udpatch, "", access & KEY_WOW64_64KEY, 0);
11941 RegCloseKey(hkey_udpatch);
11942 RegDeleteKeyExA(hkey_udpatches, "", access & KEY_WOW64_64KEY, 0);
11943 RegCloseKey(hkey_udpatches);
11944 RegDeleteKeyExA(hkey_udprops, "", access & KEY_WOW64_64KEY, 0);
11945 RegCloseKey(hkey_udprops);
11946 RegDeleteKeyExA(hkey_udproduct, "", access & KEY_WOW64_64KEY, 0);
11947 RegCloseKey(hkey_udproduct);
11948
11949done:
11950 RegDeleteKeyExA(hkey_patches, "", access & KEY_WOW64_64KEY, 0);
11951 RegCloseKey(hkey_patches);
11952 RegDeleteKeyExA(hkey_product, "", access & KEY_WOW64_64KEY, 0);
11953 RegCloseKey(hkey_product);
11954 RegDeleteKeyExA(hkey_patch, "", access & KEY_WOW64_64KEY, 0);
11955 RegCloseKey(hkey_patch);
11956}
11957
11958static void test_MsiEnumProducts(void)
11959{
11960 UINT r;
11961 BOOL found1, found2, found3;
11962 DWORD index;
11963 char product1[39], product2[39], product3[39], guid[39];
11964 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11965 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11966 char *usersid;
11967 HKEY key1, key2, key3;
11969
11970 if (!is_process_elevated())
11971 {
11972 skip( "process is limited\n" );
11973 return;
11974 }
11975
11976 create_test_guid(product1, product_squashed1);
11977 create_test_guid(product2, product_squashed2);
11978 create_test_guid(product3, product_squashed3);
11979 usersid = get_user_sid();
11980
11981 if (is_wow64)
11983
11984 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11985 strcat(keypath2, usersid);
11986 strcat(keypath2, "\\Installer\\Products\\");
11987 strcat(keypath2, product_squashed2);
11988
11989 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11990 if (r == ERROR_ACCESS_DENIED)
11991 {
11992 skip("Not enough rights to perform tests\n");
11993 LocalFree(usersid);
11994 return;
11995 }
11996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11997
11998 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11999 strcat(keypath1, product_squashed1);
12000
12001 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
12002 if (r == ERROR_ACCESS_DENIED)
12003 {
12004 skip( "insufficient rights\n" );
12005 LocalFree( usersid );
12006 return;
12007 }
12008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12009
12010 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
12011 strcat(keypath3, product_squashed3);
12012
12013 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
12014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12015
12016 index = 0;
12018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12019
12021 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12022
12023 index = 2;
12025 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12026
12027 index = 0;
12029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12030
12031 found1 = found2 = found3 = FALSE;
12032 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
12033 {
12034 if (!strcmp(product1, guid)) found1 = TRUE;
12035 if (!strcmp(product2, guid)) found2 = TRUE;
12036 if (!strcmp(product3, guid)) found3 = TRUE;
12037 if (found1 && found2 && found3) break;
12038 index++;
12039 }
12040 ok(found1, "product1 not found\n");
12041 ok(found2, "product2 not found\n");
12043 ok(found3, "product3 not found\n");
12044
12046 RegDeleteKeyExA(key2, "", access & KEY_WOW64_64KEY, 0);
12047 RegDeleteKeyA(key3, "");
12049 RegCloseKey(key2);
12050 RegCloseKey(key3);
12051 LocalFree(usersid);
12052}
12053
12055{
12056 HRESULT hr;
12057 const CERT_CONTEXT *cert;
12058 DWORD len;
12059
12061 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12062
12064 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12065
12067 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12068
12070 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12071
12072 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12073 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12074
12075 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12076 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12077
12078 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12079 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got %#lx\n", hr);
12080
12081 create_file_data( "signature.bin", "signature", sizeof("signature") );
12082
12083 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12084 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12085
12086 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12087 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %#lx\n", hr);
12088
12089 cert = (const CERT_CONTEXT *)0xdeadbeef;
12090 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12092 ok(cert == NULL, "got %p\n", cert);
12093
12094 DeleteFileA( "signature.bin" );
12095}
12096
12097static void test_MsiEnumProductsEx(void)
12098{
12099 UINT r;
12100 DWORD len, index;
12102 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
12103 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12104 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12105 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
12107 char *usersid = get_user_sid();
12108 BOOL found1, found2, found3;
12109
12110 create_test_guid( product0, NULL );
12111 create_test_guid( product1, product_squashed1 );
12112 create_test_guid( product2, product_squashed2 );
12113 create_test_guid( product3, product_squashed3 );
12114
12116
12117 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
12118 strcat( keypath2, usersid );
12119 strcat( keypath2, "\\Installer\\Products\\" );
12120 strcat( keypath2, product_squashed2 );
12121
12122 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12123 if (r == ERROR_ACCESS_DENIED)
12124 {
12125 skip( "insufficient rights\n" );
12126 goto done;
12127 }
12128 ok( r == ERROR_SUCCESS, "got %u\n", r );
12129
12130 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
12131 strcat( keypath1, product_squashed1 );
12132
12133 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12134 if (r == ERROR_ACCESS_DENIED)
12135 {
12136 skip( "insufficient rights\n" );
12137 goto done;
12138 }
12139 ok( r == ERROR_SUCCESS, "got %u\n", r );
12140
12141 strcpy( keypath3, usersid );
12142 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
12143 strcat( keypath3, product_squashed3 );
12144
12145 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
12146 ok( r == ERROR_SUCCESS, "got %u\n", r );
12147
12148 r = MsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
12149 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12150
12151 len = sizeof(sid);
12152 r = MsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
12153 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12154 ok( len == sizeof(sid), "got %lu\n", len );
12155
12157 ok( r == ERROR_SUCCESS, "got %u\n", r );
12158
12159 sid[0] = 0;
12160 len = sizeof(sid);
12162 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12163 ok( len == sizeof(sid), "got %lu\n", len );
12164 ok( !sid[0], "got %s\n", sid );
12165
12166 sid[0] = 0;
12167 len = sizeof(sid);
12168 r = MsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
12169 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12170 ok( len == sizeof(sid), "got %lu\n", len );
12171 ok( !sid[0], "got %s\n", sid );
12172
12173 sid[0] = 0;
12174 len = 0;
12176 ok( r == ERROR_MORE_DATA, "got %u\n", r );
12177 ok( len, "length unchanged\n" );
12178 ok( !sid[0], "got %s\n", sid );
12179
12180 guid[0] = 0;
12181 context = 0xdeadbeef;
12182 sid[0] = 0;
12183 len = sizeof(sid);
12185 ok( r == ERROR_SUCCESS, "got %u\n", r );
12186 ok( guid[0], "empty guid\n" );
12187 ok( context != 0xdeadbeef, "context unchanged\n" );
12188 ok( !len, "got %lu\n", len );
12189 ok( !sid[0], "got %s\n", sid );
12190
12191 guid[0] = 0;
12192 context = 0xdeadbeef;
12193 sid[0] = 0;
12194 len = sizeof(sid);
12196 ok( r == ERROR_SUCCESS, "got %u\n", r );
12197 ok( guid[0], "empty guid\n" );
12198 ok( context != 0xdeadbeef, "context unchanged\n" );
12199 ok( !len, "got %lu\n", len );
12200 ok( !sid[0], "got %s\n", sid );
12201
12202 guid[0] = 0;
12203 context = 0xdeadbeef;
12204 sid[0] = 0;
12205 len = sizeof(sid);
12207 if (r == ERROR_ACCESS_DENIED)
12208 {
12209 skip( "insufficient rights\n" );
12210 goto done;
12211 }
12212 ok( r == ERROR_SUCCESS, "got %u\n", r );
12213 ok( guid[0], "empty guid\n" );
12214 ok( context != 0xdeadbeef, "context unchanged\n" );
12215 ok( !len, "got %lu\n", len );
12216 ok( !sid[0], "got %s\n", sid );
12217
12218 index = 0;
12219 guid[0] = 0;
12220 context = 0xdeadbeef;
12221 sid[0] = 0;
12222 len = sizeof(sid);
12223 found1 = found2 = found3 = FALSE;
12224 while (!MsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
12225 {
12226 if (!strcmp( product1, guid ))
12227 {
12228 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
12229 ok( !sid[0], "got \"%s\"\n", sid );
12230 ok( !len, "unexpected length %lu\n", len );
12231 found1 = TRUE;
12232 }
12233 if (!strcmp( product2, guid ))
12234 {
12236 ok( sid[0], "empty sid\n" );
12237 ok( len == strlen(sid), "unexpected length %lu\n", len );
12238 found2 = TRUE;
12239 }
12240 if (!strcmp( product3, guid ))
12241 {
12243 ok( sid[0], "empty sid\n" );
12244 ok( len == strlen(sid), "unexpected length %lu\n", len );
12245 found3 = TRUE;
12246 }
12247 if (found1 && found2 && found3) break;
12248 index++;
12249 guid[0] = 0;
12250 context = 0xdeadbeef;
12251 sid[0] = 0;
12252 len = sizeof(sid);
12253 }
12254 ok(found1, "product1 not found\n");
12255 ok(found2, "product2 not found\n");
12256 ok(found3, "product3 not found\n");
12257
12258done:
12259 RegDeleteKeyExA( key1, "", access, 0 );
12260 RegDeleteKeyExA( key2, "", access, 0 );
12261 RegDeleteKeyExA( key3, "", access, 0 );
12262 RegCloseKey( key1 );
12263 RegCloseKey( key2 );
12264 RegCloseKey( key3 );
12265 LocalFree( usersid );
12266}
12267
12268static void test_MsiEnumComponents(void)
12269{
12270 UINT r;
12271 BOOL found1, found2;
12272 DWORD index;
12273 char comp1[39], comp2[39], guid[39];
12274 char comp_squashed1[33], comp_squashed2[33];
12275 char keypath1[MAX_PATH], keypath2[MAX_PATH];
12277 char *usersid = get_user_sid();
12278 HKEY key1 = NULL, key2 = NULL;
12279
12280 if (!is_process_elevated())
12281 {
12282 skip("process is limited\n");
12283 return;
12284 }
12285
12286 create_test_guid( comp1, comp_squashed1 );
12287 create_test_guid( comp2, comp_squashed2 );
12288
12290
12291 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12292 strcat( keypath1, "S-1-5-18\\Components\\" );
12293 strcat( keypath1, comp_squashed1 );
12294
12295 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12296 if (r == ERROR_ACCESS_DENIED)
12297 {
12298 skip( "insufficient rights\n" );
12299 goto done;
12300 }
12301 ok( r == ERROR_SUCCESS, "got %u\n", r );
12302
12303 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12304 strcat( keypath2, usersid );
12305 strcat( keypath2, "\\Components\\" );
12306 strcat( keypath2, comp_squashed2 );
12307
12308 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12309 if (r == ERROR_ACCESS_DENIED)
12310 {
12311 skip( "insufficient rights\n" );
12312 goto done;
12313 }
12314
12315 r = MsiEnumComponentsA( 0, NULL );
12316 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12317
12318 index = 0;
12319 guid[0] = 0;
12320 found1 = found2 = FALSE;
12321 while (!MsiEnumComponentsA( index, guid ))
12322 {
12323 if (!strcmp( guid, comp1 )) found1 = TRUE;
12324 if (!strcmp( guid, comp2 )) found2 = TRUE;
12325 ok( guid[0], "empty guid\n" );
12326 if (found1 && found2) break;
12327 guid[0] = 0;
12328 index++;
12329 }
12330 ok( found1, "comp1 not found\n" );
12331 ok( found2, "comp2 not found\n" );
12332
12333done:
12334 RegDeleteKeyExA( key1, "", access, 0 );
12335 RegDeleteKeyExA( key2, "", access, 0 );
12336 RegCloseKey( key1 );
12337 RegCloseKey( key2 );
12338 LocalFree( usersid );
12339}
12340
12342{
12343 UINT r;
12344 BOOL found1, found2;
12345 DWORD len, index;
12347 char comp1[39], comp2[39], guid[39], sid[128];
12348 char comp_squashed1[33], comp_squashed2[33];
12349 char keypath1[MAX_PATH], keypath2[MAX_PATH];
12350 HKEY key1 = NULL, key2 = NULL;
12352 char *usersid = get_user_sid();
12353
12354 if (!is_process_elevated())
12355 {
12356 skip("process is limited\n");
12357 return;
12358 }
12359
12360 create_test_guid( comp1, comp_squashed1 );
12361 create_test_guid( comp2, comp_squashed2 );
12362
12364
12365 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12366 strcat( keypath1, "S-1-5-18\\Components\\" );
12367 strcat( keypath1, comp_squashed1 );
12368
12369 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12370 if (r == ERROR_ACCESS_DENIED)
12371 {
12372 skip( "insufficient rights\n" );
12373 goto done;
12374 }
12375 ok( r == ERROR_SUCCESS, "got %u\n", r );
12376
12377 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12378 strcat( keypath2, usersid );
12379 strcat( keypath2, "\\Components\\" );
12380 strcat( keypath2, comp_squashed2 );
12381
12382 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12383 if (r == ERROR_ACCESS_DENIED)
12384 {
12385 skip( "insufficient rights\n" );
12386 goto done;
12387 }
12388 ok( r == ERROR_SUCCESS, "got %u\n", r );
12389 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
12390 sizeof("c:\\doesnotexist"));
12391 ok( r == ERROR_SUCCESS, "got %u\n", r );
12392
12393 index = 0;
12394 guid[0] = 0;
12395 context = 0xdeadbeef;
12396 sid[0] = 0;
12397 len = sizeof(sid);
12398 found1 = found2 = FALSE;
12399 while (!MsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
12400 {
12401 if (!strcmp( comp1, guid ))
12402 {
12403 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
12404 ok( !sid[0], "got \"%s\"\n", sid );
12405 ok( !len, "unexpected length %lu\n", len );
12406 found1 = TRUE;
12407 if (found2) break;
12408 }
12409 if (!strcmp( comp2, guid ))
12410 {
12412 ok( sid[0], "empty sid\n" );
12413 ok( len == strlen(sid), "unexpected length %lu\n", len );
12414 found2 = TRUE;
12415 if (found1) break;
12416 }
12417 index++;
12418 guid[0] = 0;
12419 context = 0xdeadbeef;
12420 sid[0] = 0;
12421 len = sizeof(sid);
12422 }
12423 ok( found1, "comp1 not found\n" );
12424 ok( found2, "comp2 not found\n" );
12425
12426 r = MsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
12427 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12428
12430 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12431
12432done:
12433 RegDeleteValueA( key2, comp_squashed2 );
12434 RegDeleteKeyExA( key1, "", access, 0 );
12435 RegDeleteKeyExA( key2, "", access, 0 );
12436 RegCloseKey( key1 );
12437 RegCloseKey( key2 );
12438 LocalFree( usersid );
12439}
12440
12442{
12443 UINT r;
12444 LONG res;
12445 DWORD type, size;
12446 HKEY props, source;
12447 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
12449
12450 if (!is_process_elevated())
12451 {
12452 skip("process is limited\n");
12453 return;
12454 }
12455
12456 CreateDirectoryA("msitest", NULL);
12457 create_file_data("msitest\\hydrogen", "hydrogen", 500);
12458 create_file_data("msitest\\helium", "helium", 500);
12459 create_file_data("msitest\\lithium", "lithium", 500);
12460
12462
12463 if (is_wow64)
12465
12467
12468 /* NULL szProduct */
12470 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12472 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12473
12474 /* empty szProduct */
12476 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12478 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12479
12480 /* garbage szProduct */
12482 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12484 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12485
12486 /* guid without brackets */
12487 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
12489 "PROPVAR=42");
12491 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12492
12493 /* guid with brackets */
12494 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
12496 "PROPVAR=42");
12498 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12499
12500 /* same length as guid, but random */
12501 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
12503 "PROPVAR=42");
12505 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12506
12507 /* product not installed yet */
12508 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
12510 "PROPVAR=42");
12512 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12513
12514 /* install the product, per-user unmanaged */
12515 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
12517 {
12518 skip("Not enough rights to perform tests\n");
12519 goto error;
12520 }
12521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12522 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12523 ok(pf_exists("msitest\\helium"), "File not installed\n");
12524 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12525 ok(pf_exists("msitest"), "File not installed\n");
12526
12527 /* product is installed per-user managed, remove it */
12528 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12530 "PROPVAR=42");
12531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12532 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12533 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12534 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12535 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12536
12537 /* product has been removed */
12538 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12540 "PROPVAR=42");
12542 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12543
12544 /* install the product, machine */
12545 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12547 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12548 ok(pf_exists("msitest\\helium"), "File not installed\n");
12549 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12550 ok(pf_exists("msitest"), "File not installed\n");
12551
12552 /* product is installed machine, remove it */
12553 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12555 "PROPVAR=42");
12556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12557 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12558 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12559 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12560 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12561
12562 /* product has been removed */
12563 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12565 "PROPVAR=42");
12567 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12568
12569 /* install the product, machine */
12570 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12572 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12573 ok(pf_exists("msitest\\helium"), "File not installed\n");
12574 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12575 ok(pf_exists("msitest"), "File not installed\n");
12576
12578
12579 /* msifile is removed */
12580 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12582 "PROPVAR=42");
12583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12584 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12585 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12586 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12587 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12588
12590
12591 /* install the product, machine */
12592 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12594 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12595 ok(pf_exists("msitest\\helium"), "File not installed\n");
12596 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12597 ok(pf_exists("msitest"), "File not installed\n");
12598
12600
12601 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
12602 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
12603 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
12604
12606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12607
12608 type = REG_SZ;
12609 size = MAX_PATH;
12610 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
12611 (LPBYTE)localpackage, &size);
12612 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12613
12614 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12615 (const BYTE *)"C:\\idontexist.msi", 18);
12616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12617
12618 /* LocalPackage is used to find the cached msi package */
12619 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12621 "PROPVAR=42");
12623 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
12624 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12625 ok(pf_exists("msitest\\helium"), "File not installed\n");
12626 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12627 ok(pf_exists("msitest"), "File not installed\n");
12628
12631
12632 /* LastUsedSource can be used as a last resort */
12633 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12635 "PROPVAR=42");
12636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12637 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12638 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12639 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12640 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12641 DeleteFileA( localpackage );
12642
12643 /* install the product, machine */
12644 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12646 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12647 ok(pf_exists("msitest\\helium"), "File not installed\n");
12648 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12649 ok(pf_exists("msitest"), "File not installed\n");
12650
12651 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
12652 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
12653 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
12654
12656 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12657
12658 type = REG_SZ;
12659 size = MAX_PATH;
12660 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
12661 (LPBYTE)localpackage, &size);
12662 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12663
12664 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12665 (const BYTE *)"C:\\idontexist.msi", 18);
12666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12667
12668 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
12669 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
12670
12672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12673
12674 type = REG_SZ;
12675 size = MAX_PATH;
12676 res = RegQueryValueExA(source, "PackageName", NULL, &type,
12677 (LPBYTE)packagename, &size);
12678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12679
12680 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
12681 (const BYTE *)"idontexist.msi", 15);
12682 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12683
12684 /* SourceList is altered */
12685 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12687 "PROPVAR=42");
12689 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
12690 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12691 ok(pf_exists("msitest\\helium"), "File not installed\n");
12692 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12693 ok(pf_exists("msitest"), "File not installed\n");
12694
12695 /* restore PackageName */
12696 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
12697 (const BYTE *)packagename, lstrlenA(packagename) + 1);
12698 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12699
12700 /* restore LocalPackage */
12701 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12702 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
12703 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
12704
12705 /* finally remove the product */
12706 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12708 "PROPVAR=42");
12709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12710 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12711 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12712 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12713 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12714
12717
12718error:
12719 DeleteFileA("msitest\\hydrogen");
12720 DeleteFileA("msitest\\helium");
12721 DeleteFileA("msitest\\lithium");
12722 RemoveDirectoryA("msitest");
12724}
12725
12727{
12728 UINT r;
12729 DWORD attrs;
12730 char path[MAX_PATH];
12731 MSIHANDLE package;
12732
12733 if (!is_process_elevated())
12734 {
12735 skip("process is limited\n");
12736 return;
12737 }
12739
12740 strcpy( path, CURR_DIR );
12741 strcat( path, "\\" );
12742 strcat( path, msifile );
12743
12744 r = MsiOpenPackageA( path, &package );
12746 {
12747 skip("Not enough rights to perform tests\n");
12749 return;
12750 }
12751 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12752
12754 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
12755
12756 r = MsiDoActionA( package, "CostInitialize" );
12757 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12758
12760 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
12761
12763 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12764
12766 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12767
12768 r = MsiSetFeatureAttributesA( package, "One", 0 );
12769 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12770
12771 attrs = 0xdeadbeef;
12772 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12773 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12775 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %#lx\n", attrs);
12776
12778 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12779
12780 attrs = 0;
12781 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12782 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12784 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %#lx\n", attrs);
12785
12786 r = MsiDoActionA( package, "FileCost" );
12787 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12788
12790 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12791
12792 attrs = 0;
12793 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12794 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12796 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got %#lx\n", attrs);
12797
12798 r = MsiDoActionA( package, "CostFinalize" );
12799 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12800
12802 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
12803
12804 MsiCloseHandle( package );
12806}
12807
12808static void test_MsiGetFeatureInfo(void)
12809{
12810 UINT r;
12811 MSIHANDLE package;
12812 char title[32], help[32], path[MAX_PATH];
12813 DWORD attrs, title_len, help_len;
12814
12815 if (!is_process_elevated())
12816 {
12817 skip("process is limited\n");
12818 return;
12819 }
12821
12822 strcpy( path, CURR_DIR );
12823 strcat( path, "\\" );
12824 strcat( path, msifile );
12825
12826 r = MsiOpenPackageA( path, &package );
12828 {
12829 skip("Not enough rights to perform tests\n");
12831 return;
12832 }
12833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12834
12836 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12837
12838 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
12839 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12840
12841 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
12842 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12843
12844 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
12845 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12846
12847 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
12848 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
12849
12850 title_len = help_len = 0;
12851 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
12852 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12853 ok(title_len == 3, "expected 3, got %lu\n", title_len);
12854 ok(help_len == 3, "expected 3, got %lu\n", help_len);
12855
12856 title[0] = help[0] = 0;
12857 title_len = help_len = 0;
12858 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
12859 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
12860 ok(title_len == 3, "expected 3, got %lu\n", title_len);
12861 ok(help_len == 3, "expected 3, got %lu\n", help_len);
12862
12863 attrs = 0;
12864 title[0] = help[0] = 0;
12865 title_len = sizeof(title);
12866 help_len = sizeof(help);
12867 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
12868 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12869 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %lu\n", attrs);
12870 ok(title_len == 3, "expected 3, got %lu\n", title_len);
12871 ok(help_len == 3, "expected 3, got %lu\n", help_len);
12872 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
12873 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
12874
12875 attrs = 0;
12876 title[0] = help[0] = 0;
12877 title_len = sizeof(title);
12878 help_len = sizeof(help);
12879 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
12880 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12881 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %lu\n", attrs);
12882 ok(!title_len, "expected 0, got %lu\n", title_len);
12883 ok(!help_len, "expected 0, got %lu\n", help_len);
12884 ok(!title[0], "expected \"\", got \"%s\"\n", title);
12885 ok(!help[0], "expected \"\", got \"%s\"\n", help);
12886
12887 MsiCloseHandle( package );
12889}
12890
12892{
12893 return IDOK;
12894}
12895
12897{
12898 return IDOK;
12899}
12900
12902{
12903 return IDOK;
12904}
12905
12906static void test_MsiSetInternalUI(void)
12907{
12909
12911 ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
12912
12914 ok(level == INSTALLUILEVEL_FULL, "expected INSTALLUILEVEL_FULL, got %d\n", level);
12915
12917 ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
12918
12919 level = MsiSetInternalUI(0xdeadbeef, NULL);
12920 ok(level == INSTALLUILEVEL_NOCHANGE, "expected INSTALLUILEVEL_NOCHANGE, got %d\n", level);
12921}
12922
12923static void test_MsiSetExternalUI(void)
12924{
12925 INSTALLUI_HANDLERA ret_a;
12926 INSTALLUI_HANDLERW ret_w;
12928 UINT error;
12929
12931 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
12932
12933 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
12934 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
12935
12937 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12938 ok(prev == NULL, "expected NULL, got %p\n", prev);
12939
12940 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
12942 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12943 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
12944
12946 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
12947
12948 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
12949 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
12950
12952 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
12953
12955 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
12956
12957 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
12959 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12960 ok(prev == NULL, "expected NULL, got %p\n", prev);
12961
12962 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
12963 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
12964
12965 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
12966 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
12967
12968 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
12969 error = MsiSetExternalUIRecord(NULL, 0, NULL, &prev);
12970 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12971 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
12972
12974 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12975
12977 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
12978}
12979
12980static void test_lastusedsource(void)
12981{
12982 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
12983 char value[MAX_PATH], path[MAX_PATH];
12984 DWORD size;
12985 UINT r;
12986
12987 CreateDirectoryA("msitest", NULL);
12988 create_file("maximus", 500);
12989 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
12990 DeleteFileA("maximus");
12991
12995
12997
12998 /* no cabinet file */
12999
13000 size = MAX_PATH;
13001 lstrcpyA(value, "aaa");
13004 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13005 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13006
13007 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
13009 {
13010 skip("Not enough rights to perform tests\n");
13011 goto error;
13012 }
13013 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13014
13016 lstrcatA(path, "\\");
13017
13018 size = MAX_PATH;
13019 lstrcpyA(value, "aaa");
13022 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13023 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13024 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
13025
13026 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL FULL=1");
13027 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13028
13029 /* separate cabinet file */
13030
13031 size = MAX_PATH;
13032 lstrcpyA(value, "aaa");
13035 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13036 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13037
13038 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
13039 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13040
13042 lstrcatA(path, "\\");
13043
13044 size = MAX_PATH;
13045 lstrcpyA(value, "aaa");
13048 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13049 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13050 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
13051
13052 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL FULL=1");
13053 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13054
13055 size = MAX_PATH;
13056 lstrcpyA(value, "aaa");
13059 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13060 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13061
13062 /* embedded cabinet stream */
13063
13064 add_cabinet_storage("msifile2.msi", "test1.cab");
13065
13066 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
13067 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13068
13069 size = MAX_PATH;
13070 lstrcpyA(value, "aaa");
13073 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13074 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13075 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
13076
13077 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL FULL=1");
13078 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13079
13080 size = MAX_PATH;
13081 lstrcpyA(value, "aaa");
13084 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13085 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13086
13087error:
13089 DeleteFileA("msitest\\maximus");
13090 RemoveDirectoryA("msitest");
13091 DeleteFileA("msifile0.msi");
13092 DeleteFileA("msifile1.msi");
13093 DeleteFileA("msifile2.msi");
13094}
13095
13096static void test_setpropertyfolder(void)
13097{
13098 UINT r;
13099
13100 if (!is_process_elevated())
13101 {
13102 skip("process is limited\n");
13103 return;
13104 }
13105
13106 CreateDirectoryA("msitest", NULL);
13107 create_file("msitest\\maximus", 500);
13108
13110
13112
13115 {
13116 skip("Not enough rights to perform tests\n");
13117 goto error;
13118 }
13119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13120 ok(delete_pf("msitest\\added\\added2\\maximus", TRUE), "File not installed\n");
13121 ok(delete_pf("msitest\\added\\added2", FALSE), "Directory not created\n");
13122 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
13123 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13124
13125 CreateDirectoryA("parent", NULL);
13126 CreateDirectoryA("parent\\child", NULL);
13127 create_file("parent\\child\\maximus", 500);
13128
13130
13131 r = MsiInstallProductA(msifile, "TARGETDIR=c:\\");
13132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13133
13134 ok(delete_pf("msitest\\maximus", TRUE), "file not installed\n");
13135 ok(delete_pf("msitest", FALSE), "directory not created\n");
13136
13137 ok(DeleteFileA("c:\\parent\\child\\Shortcut.lnk"), "file not installed\n");
13138 ok(RemoveDirectoryA("c:\\parent\\child"), "directory not created\n");
13139 ok(RemoveDirectoryA("c:\\parent"), "directory not created\n");
13140
13141 DeleteFileA("parent\\child\\maximus");
13142 RemoveDirectoryA("parent\\child");
13143 RemoveDirectoryA("parent");
13144
13145error:
13147 DeleteFileA("msitest\\maximus");
13148 RemoveDirectoryA("msitest");
13149}
13150
13151static void test_sourcedir_props(void)
13152{
13153 UINT r;
13154
13155 if (!is_process_elevated())
13156 {
13157 skip("process is limited\n");
13158 return;
13159 }
13160
13162 create_file("msitest\\sourcedir.txt", 1000);
13164
13166
13167 /* full UI, no ResolveSource action */
13169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13170
13171 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13173
13174 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13175 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13176
13177 /* full UI, ResolveSource action */
13178 r = MsiInstallProductA(msifile, "ResolveSource=1");
13179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13180
13181 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13183
13184 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13185 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13186
13188
13189 /* no UI, no ResolveSource action */
13191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13192
13193 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13195
13196 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13197 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13198
13199 /* no UI, ResolveSource action */
13200 r = MsiInstallProductA(msifile, "ResolveSource=1");
13201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13202
13203 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13205
13206 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13207 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13208
13209 DeleteFileA("msitest\\sourcedir.txt");
13212}
13213
13214static void test_concurrentinstall(void)
13215{
13216 UINT r;
13218
13219 if (!is_process_elevated())
13220 {
13221 skip("process is limited\n");
13222 return;
13223 }
13224
13225 CreateDirectoryA("msitest", NULL);
13226 CreateDirectoryA("msitest\\msitest", NULL);
13227 create_file("msitest\\maximus", 500);
13228 create_file("msitest\\msitest\\augustus", 500);
13229
13231
13233 lstrcatA(path, "\\msitest\\concurrent.msi");
13235
13237
13240 {
13241 skip("Not enough rights to perform tests\n");
13242 goto error;
13243 }
13244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13245 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
13246 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
13247 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13248
13249 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
13251 ok(r == ERROR_SUCCESS, "got %u\n", r);
13252
13253 r = MsiConfigureProductA("{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}", INSTALLLEVEL_DEFAULT,
13255 ok(r == ERROR_SUCCESS, "got %u\n", r);
13256
13257error:
13260 DeleteFileA("msitest\\msitest\\augustus");
13261 DeleteFileA("msitest\\maximus");
13262 RemoveDirectoryA("msitest\\msitest");
13263 RemoveDirectoryA("msitest");
13264}
13265
13267{
13268 UINT r;
13269 const char *cmd;
13270
13271 if (!is_process_elevated())
13272 {
13273 skip("process is limited\n");
13274 return;
13275 }
13276
13279
13281
13282 cmd = " ";
13284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13285
13286 cmd = "=";
13288 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13289
13290 cmd = "==";
13292 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13293
13294 cmd = "one";
13296 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13297
13298 cmd = "=one";
13300 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13301
13302 cmd = "P=";
13304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13305
13306 cmd = " P=";
13308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13309
13310 cmd = "P= ";
13312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13313
13314 cmd = "P=\"";
13316 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13317
13318 cmd = "P=\"\"";
13320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13321
13322 cmd = "P=\"\"\"";
13324 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13325
13326 cmd = "P=\"\"\"\"";
13328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13329
13330 cmd = "P=\" ";
13332 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13333
13334 cmd = "P= \"";
13336 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13337
13338 cmd = "P= \"\" ";
13340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13341
13342 cmd = "P=\" \"";
13344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13345
13346 cmd = "P=one";
13348 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13349
13350 cmd = "P= one";
13352 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13353
13354 cmd = "P=\"one";
13356 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13357
13358 cmd = "P=one\"";
13360 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13361
13362 cmd = "P=\"one\"";
13364 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13365
13366 cmd = "P= \"one\" ";
13368 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13369
13370 cmd = "P=\"one\"\"";
13372 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13373
13374 cmd = "P=\"\"one\"";
13376 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13377
13378 cmd = "P=\"\"one\"\"";
13380 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
13381
13382 cmd = "P=\"one two\"";
13384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13385
13386 cmd = "P=\"\"\"one\"\" two\"";
13388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13389
13390 cmd = "P=\"\"\"one\"\" two\" Q=three";
13392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13393
13394 cmd = "P=\"\" Q=\"two\"";
13396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13397
13398 cmd = "P=\"one\" Q=\"two\"";
13400 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13401
13402 cmd = "P=\"one=two\"";
13404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13405
13406 cmd = "Q=\"\" P=\"one\"";
13408 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
13409
13410 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
13412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13413
13414 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
13416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13417
13418 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
13420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13421
13424}
13425
13427{
13428 DWORD len;
13429 char temp_path[MAX_PATH], prev_path[MAX_PATH];
13430
13431#ifdef __REACTOS__
13432 if (!winetest_interactive &&
13433 !strcmp(winetest_platform, "windows"))
13434 {
13435 skip("ROSTESTS-180: Skipping msi_winetest:msi because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
13436 return;
13437 }
13438#endif
13439
13441
13443
13444 GetCurrentDirectoryA(MAX_PATH, prev_path);
13447
13450
13451 if(len && (CURR_DIR[len - 1] == '\\'))
13452 CURR_DIR[len - 1] = 0;
13453
13454 ok(get_system_dirs(), "failed to retrieve system dirs\n");
13455
13457 test_null();
13493
13494 SetCurrentDirectoryA(prev_path);
13495}
BOOLEAN Expected
static char CURR_DIR[MAX_PATH]
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static int state
Definition: maze.c:121
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
static int run_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse)
Definition: query.c:311
int help
Definition: sort.c:20
#define index(s, c)
Definition: various.h:29
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:20
#define RegCloseKey(hKey)
Definition: registry.h:49
FT_UInt sid
Definition: cffcmap.c:139
static const CHAR suminfo[]
Definition: db.c:2166
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1254
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegSetValueA(HKEY hKeyOriginal, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData)
Definition: reg.c:4954
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3637
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define GENERIC_READ
Definition: compat.h:135
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
@ VT_LPSTR
Definition: compat.h:2324
@ VT_I4
Definition: compat.h:2298
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4195
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
UINT WINAPI MsiSetFeatureAttributesA(MSIHANDLE handle, LPCSTR feature, DWORD attrs)
Definition: install.c:988
UINT WINAPI MsiDoActionA(MSIHANDLE hInstall, LPCSTR szAction)
Definition: install.c:45
UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE handle, const char *feature, DWORD *attrs, char *title, DWORD *title_len, char *help, DWORD *help_len)
Definition: install.c:1259
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
Definition: msi.c:80
UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf, LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
Definition: msi.c:3088
UINT WINAPI MsiProvideQualifiedComponentExA(const char *szComponent, const char *szQualifier, DWORD dwInstallMode, const char *szProduct, DWORD Unused1, DWORD Unused2, char *lpPathBuf, DWORD *pcchPathBuf)
Definition: msi.c:3445
UINT WINAPI MsiGetPatchInfoA(LPCSTR patch, LPCSTR attr, LPSTR buffer, LPDWORD buflen)
Definition: msi.c:1795
UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
Definition: msi.c:3746
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCSTR szCommandLine)
Definition: msi.c:916
UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD handler, DWORD filter, void *context, INSTALLUI_HANDLER_RECORD *prev)
Definition: msi.c:4149
INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
Definition: msi.c:2207
BOOL is_wow64
Definition: msi.c:52
UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
Definition: msi.c:1590
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:198
UINT WINAPI MsiGetFileHashA(const char *szFilePath, DWORD dwOptions, MSIFILEHASHINFO *pHash)
Definition: msi.c:4090
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, DWORD dwMessageFilter, void *pvContext)
Definition: msi.c:2306
INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler, DWORD dwMessageFilter, void *pvContext)
Definition: msi.c:2320
INSTALLSTATE WINAPI MsiGetComponentPathExA(LPCSTR product, LPCSTR comp, LPCSTR usersid, MSIINSTALLCONTEXT ctx, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2860
UINT WINAPI MsiGetPatchInfoW(LPCWSTR patch, LPCWSTR attr, LPWSTR buffer, LPDWORD buflen)
Definition: msi.c:1843
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, LPDWORD pcchValueBuf)
Definition: msi.c:1254
UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
Definition: msi.c:3719
UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
Definition: msi.c:973
UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szComponent, INSTALLSTATE *pdwState)
Definition: msi.c:2055
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2281
UINT WINAPI MsiProvideComponentA(const char *product, const char *feature, const char *component, DWORD mode, char *buf, DWORD *buflen)
Definition: msi.c:4198
INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR product, LPCSTR comp, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2898
HRESULT WINAPI MsiGetFileSignatureInformationA(const char *path, DWORD flags, PCCERT_CONTEXT *cert, BYTE *hash, DWORD *hashlen)
Definition: msi.c:2511
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
Definition: msi.c:3023
INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf, LPDWORD pcchBuf)
Definition: msi.c:2419
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
Definition: msi.c:946
UINT WINAPI MsiProvideComponentW(const WCHAR *product, const WCHAR *feature, const WCHAR *component, DWORD mode, WCHAR *buf, DWORD *buflen)
Definition: msi.c:4246
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
Definition: msi.c:2223
INSTALLSTATE WINAPI MsiUseFeatureExA(const char *szProduct, const char *szFeature, DWORD dwInstallMode, DWORD dwReserved)
Definition: msi.c:3303
UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: msi.c:1300
USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf, LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf, LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
Definition: msi.c:3632
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
Definition: package.c:1664
UINT WINAPI MsiOpenPackageExW(const WCHAR *szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1607
UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz)
Definition: package.c:2313
UINT WINAPI MsiEnumComponentsA(DWORD index, char *lpguid)
Definition: registry.c:1099
UINT WINAPI MsiEnumFeaturesW(const WCHAR *szProduct, DWORD index, WCHAR *szFeature, WCHAR *szParent)
Definition: registry.c:1078
UINT WINAPI MsiEnumPatchesW(const WCHAR *szProduct, DWORD iPatchIndex, WCHAR *lpPatchBuf, WCHAR *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2054
UINT WINAPI MsiEnumProductsA(DWORD index, char *lpguid)
Definition: registry.c:1024
UINT WINAPI MsiEnumClientsA(const char *szComponent, DWORD index, char *szProduct)
Definition: registry.c:1328
UINT WINAPI MsiEnumProductsExA(const char *product, const char *usersid, DWORD ctx, DWORD index, char installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, char *sid, DWORD *sid_len)
Definition: registry.c:2100
UINT WINAPI MsiEnumPatchesExA(const char *szProductCode, const char *szUserSid, DWORD dwContext, DWORD dwFilter, DWORD dwIndex, char *szPatchCode, char *szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext, char *szTargetUserSid, DWORD *pcchTargetUserSid)
Definition: registry.c:1618
UINT WINAPI MsiEnumComponentsExA(const char *user_sid, DWORD ctx, DWORD index, CHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, char *sid, DWORD *sid_len)
Definition: registry.c:1124
UINT WINAPI MsiEnumPatchesA(const char *szProduct, DWORD iPatchIndex, char *lpPatchBuf, char *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2000
UINT WINAPI MsiSourceListGetInfoA(LPCSTR szProduct, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: source.c:470
UINT WINAPI MsiSummaryInfoSetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const char *szValue)
Definition: suminfo.c:942
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:589
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1227
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:619
BOOL WINAPI VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1001
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:853
static BOOL is_process_elevated(void)
Definition: dplayx.c:6742
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t serial
Definition: fsck.fat.h:29
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define d
Definition: ke_i.h:81
#define REG_SZ
Definition: layer.c:22
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const GUID * guid
__u8 media
Definition: mkdosfs.c:9
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static void create_cab_file(void)
Definition: files.c:356
static char org[]
Definition: encode.c:7456
static BYTE cert[]
Definition: msg.c:1437
static const WCHAR desc[]
Definition: protectdata.c:36
BOOL expected
Definition: store.c:2063
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmcache.c:795
#define create_file(name, size)
Definition: asmcache.c:813
void restart_as_admin_elevated(void)
Definition: action.c:6478
#define ADD_TABLE(x)
Definition: automation.c:156
static BOOL pf_exists(const char *file)
Definition: custom.c:1414
#define todo_wine
Definition: custom.c:89
BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
Definition: install.c:2433
BOOL get_system_dirs(void)
Definition: install.c:2357
void delete_cab_files(void)
Definition: install.c:3003
static const char file_dat[]
Definition: msi.c:116
#define MEDIA_SIZE
Definition: msi.c:47
static const char lus_install_exec_seq_dat[]
Definition: msi.c:229
static void test_MsiGetComponentPathEx(void)
Definition: msi.c:2938
static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
Definition: msi.c:1495
static void test_MsiGetComponentPath(void)
Definition: msi.c:2391
static void test_MsiGetFileSignatureInformation(void)
Definition: msi.c:12054
static void test_MsiEnumComponents(void)
Definition: msi.c:12268
static const char spf2_custom_action_dat[]
Definition: msi.c:338
static const WCHAR msifileW[]
Definition: msi.c:42
static void test_MsiGetFeatureInfo(void)
Definition: msi.c:12808
static const char lus_file_dat[]
Definition: msi.c:216
static void test_MsiGetProductInfo(void)
Definition: msi.c:4257
static void delete_test_files(void)
Definition: msi.c:997
static const char mcp_component_dat[]
Definition: msi.c:171
static const char cl_install_exec_seq_dat[]
Definition: msi.c:556
static char * get_user_sid(void)
Definition: msi.c:1154
static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
Definition: msi.c:50
static const char spf_install_exec_seq_dat[]
Definition: msi.c:274
static const char spf2_install_exec_seq_dat[]
Definition: msi.c:314
static const char mcp_feature_dat[]
Definition: msi.c:179
static const char table_enc85[]
Definition: msi.c:1465
#define HASHSIZE
Definition: msi.c:1011
static const char media_dat[]
Definition: msi.c:141
static const char ci2_file_dat[]
Definition: msi.c:544
static void test_MsiEnumPatches(void)
Definition: msi.c:10284
MSIFILEHASHINFO hash
Definition: msi.c:1017
static const msi_table spf_tables[]
Definition: msi.c:631
static void test_MsiEnumClients(void)
Definition: msi.c:3764
static const char msifile[]
Definition: msi.c:41
static const char ci2_property_dat[]
Definition: msi.c:159
static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
Definition: msi.c:8886
static void test_usefeature(void)
Definition: msi.c:802
static void test_MsiGetPatchInfo(void)
Definition: msi.c:11765
static void test_MsiEnumPatchesEx_machine(void)
Definition: msi.c:9732
static const char ci2_feature_comp_dat[]
Definition: msi.c:538
static const char property_dat[]
Definition: msi.c:147
static const char sd_install_ui_seq_dat[]
Definition: msi.c:384
static const msi_table mcp_tables[]
Definition: msi.c:583
static void test_MsiEnumProductsEx(void)
Definition: msi.c:12097
static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
Definition: msi.c:712
static const char lus_feature_comp_dat[]
Definition: msi.c:222
static void test_MsiSetFeatureAttributes(void)
Definition: msi.c:12726
static const msi_table spf2_tables[]
Definition: msi.c:645
static void test_MsiQueryFeatureState(void)
Definition: msi.c:1517
static void test_MsiSetExternalUI(void)
Definition: msi.c:12923
static void test_MsiGetFileVersion(void)
Definition: msi.c:3994
static const char shortcut_dat[]
Definition: msi.c:354
static void test_MsiGetFileHash(void)
Definition: msi.c:1045
static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
Definition: msi.c:12896
static void create_test_files(void)
Definition: msi.c:977
static const char sd_install_exec_seq_dat[]
Definition: msi.c:414
static void test_MsiGetUserInfo(void)
Definition: msi.c:7963
static const char sd_component_dat[]
Definition: msi.c:378
static const char spf_directory_dat[]
Definition: msi.c:298
static const char ci2_component_dat[]
Definition: msi.c:532
#define INIT_USERINFO()
Definition: msi.c:7957
static const char spf_install_ui_seq_dat[]
Definition: msi.c:289
static const char sd_file_dat[]
Definition: msi.c:360
static void test_MsiEnumPatchesEx(void)
Definition: msi.c:10098
static const char spf_component_dat[]
Definition: msi.c:308
static const char sd_feature_dat[]
Definition: msi.c:366
static void test_MsiOpenProduct(void)
Definition: msi.c:8559
static const msi_table lus0_tables[]
Definition: msi.c:595
static void test_MsiQueryComponentState(void)
Definition: msi.c:2007
static const char sd_custom_action_dat[]
Definition: msi.c:461
static const msi_table tables[]
Definition: msi.c:571
static void test_null(void)
Definition: msi.c:835
static void test_MsiGetProductCode(void)
Definition: msi.c:3485
static const char lus0_media_dat[]
Definition: msi.c:249
static const char feature_dat[]
Definition: msi.c:103
static void test_MsiProvideComponent(void)
Definition: msi.c:3259
static const char sd_feature_comp_dat[]
Definition: msi.c:372
static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
Definition: msi.c:12901
static void test_MsiQueryProductState(void)
Definition: msi.c:1173
static void test_MsiConfigureProductEx(void)
Definition: msi.c:12441
static const char ci_component_dat[]
Definition: msi.c:526
static const char lus_component_dat[]
Definition: msi.c:203
static void test_MsiGetPatchInfoEx(void)
Definition: msi.c:10878
static const msi_table ci2_tables[]
Definition: msi.c:687
static void test_MsiGetProductInfoEx(void)
Definition: msi.c:5554
static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
Definition: msi.c:9360
static void test_setpropertyfolder(void)
Definition: msi.c:13096
static const char install_exec_seq_dat[]
Definition: msi.c:122
static const msi_table sd_tables[]
Definition: msi.c:660
static void test_MsiSetInternalUI(void)
Definition: msi.c:12906
static const char mcp_feature_comp_dat[]
Definition: msi.c:187
static void test_MsiEnumProducts(void)
Definition: msi.c:11958
static const char directory_dat[]
Definition: msi.c:89
LPCSTR data
Definition: msi.c:1015
static const char lus_feature_dat[]
Definition: msi.c:209
static const msi_table lus2_tables[]
Definition: msi.c:619
static const char ci_install_exec_seq_dat[]
Definition: msi.c:501
static const msi_table ci_tables[]
Definition: msi.c:674
static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz, LPSTR *langcheck, LPDWORD langchecksz)
Definition: msi.c:3967
static void test_getcomponentpath(void)
Definition: msi.c:940
static const msi_table lus1_tables[]
Definition: msi.c:607
static const struct @1681 hash_data[]
static void test_command_line_parsing(void)
Definition: msi.c:13266
static void test_MsiEnumComponentsEx(void)
Definition: msi.c:12341
static const char component_dat[]
Definition: msi.c:97
static void test_concurrentinstall(void)
Definition: msi.c:13214
static const char mcp_file_dat[]
Definition: msi.c:195
static const char lus1_media_dat[]
Definition: msi.c:255
static void test_sourcedir_props(void)
Definition: msi.c:13151
static const char feature_comp_dat[]
Definition: msi.c:110
static void test_MsiProvideQualifiedComponentEx(void)
Definition: msi.c:3345
static const msi_table cl_tables[]
Definition: msi.c:699
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1132
static const char ci_custom_action_dat[]
Definition: msi.c:520
static const char lus2_media_dat[]
Definition: msi.c:261
static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
Definition: msi.c:12891
static void test_lastusedsource(void)
Definition: msi.c:12980
static void encode_base85_guid(GUID *guid, LPWSTR str)
Definition: msi.c:1474
static const char spf_custom_action_dat[]
Definition: msi.c:267
static const char cl_custom_action_dat[]
Definition: msi.c:550
static MSIHANDLE create_package_db(void)
Definition: package.c:815
#define PID_REVNUMBER
Definition: suminfo.c:51
#define create_database(name, tables, num_tables)
Definition: utils.h:42
INTERNETFEATURELIST feature
Definition: misc.c:1719
#define INSTALLPROPERTY_HELPLINKA
Definition: msi.h:318
@ MSIPATCHSTATE_ALL
Definition: msi.h:58
@ MSIPATCHSTATE_APPLIED
Definition: msi.h:54
@ MSIPATCHSTATE_SUPERSEDED
Definition: msi.h:55
@ MSIPATCHSTATE_OBSOLETED
Definition: msi.h:56
@ MSIPATCHSTATE_INVALID
Definition: msi.h:53
#define INSTALLPROPERTY_PATCHSTATEA
Definition: msi.h:383
#define INSTALLPROPERTY_LOCALPACKAGEA
Definition: msi.h:342
#define INSTALLPROPERTY_ASSIGNMENTTYPEA
Definition: msi.h:280
#define INSTALLPROPERTY_INSTALLSOURCEA
Definition: msi.h:330
#define INSTALLPROPERTY_HELPTELEPHONEA
Definition: msi.h:322
#define INSTALLPROPERTY_PRODUCTICONA
Definition: msi.h:294
#define INSTALLPROPERTY_REGCOMPANYA
Definition: msi.h:366
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
#define INSTALLPROPERTY_VERSIONSTRINGA
Definition: msi.h:314
#define INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA
Definition: msi.h:310
#define INSTALLPROPERTY_VERSIONMAJORA
Definition: msi.h:358
#define INSTALLPROPERTY_REGOWNERA
Definition: msi.h:370
#define INSTALLPROPERTY_URLUPDATEINFOA
Definition: msi.h:350
struct _MSIFILEHASHINFO MSIFILEHASHINFO
enum tagUSERINFOSTATE USERINFOSTATE
INT(CALLBACK * INSTALLUI_HANDLERW)(LPVOID, UINT, LPCWSTR)
Definition: msi.h:421
#define INSTALLPROPERTY_TRANSFORMSA
Definition: msi.h:268
#define INSTALLPROPERTY_VERSIONA
Definition: msi.h:288
#define INSTALLPROPERTY_INSTALLLOCATIONA
Definition: msi.h:326
#define INSTALLPROPERTY_LASTUSEDSOURCEA
Definition: msi.h:404
@ INSTALLLOGMODE_ERROR
Definition: msi.h:132
#define INSTALLPROPERTY_INSTANCETYPEA
Definition: msi.h:299
#define INSTALLPROPERTY_PRODUCTNAMEA
Definition: msi.h:276
#define INSTALLPROPERTY_AUTHORIZED_LUA_APPA
Definition: msi.h:304
#define INSTALLPROPERTY_MOREINFOURLA
Definition: msi.h:399
@ INSTALLFEATUREATTRIBUTE_FAVORSOURCE
Definition: msi.h:222
@ INSTALLFEATUREATTRIBUTE_FAVORLOCAL
Definition: msi.h:221
#define INSTALLPROPERTY_URLINFOABOUTA
Definition: msi.h:346
@ MSICODE_PRODUCT
Definition: msi.h:215
#define INSTALLPROPERTY_PRODUCTSTATEA
Definition: msi.h:379
INT(CALLBACK * INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR)
Definition: msi.h:420
#define INSTALLPROPERTY_PRODUCTIDA
Definition: msi.h:362
@ INSTALLMODE_EXISTING
Definition: msi.h:165
@ INSTALLMODE_NODETECTION
Definition: msi.h:164
static const WCHAR INSTALLPROPERTY_LOCALPACKAGEW[]
Definition: msi.h:343
#define INSTALLPROPERTY_UNINSTALLABLEA
Definition: msi.h:375
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
@ INSTALLSTATE_LOCAL
Definition: msi.h:46
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
@ INSTALLSTATE_NOTUSED
Definition: msi.h:36
@ INSTALLSTATE_INVALIDARG
Definition: msi.h:41
@ INSTALLSTATE_SOURCE
Definition: msi.h:47
@ INSTALLSTATE_BADCONFIG
Definition: msi.h:37
@ INSTALLSTATE_DEFAULT
Definition: msi.h:48
@ INSTALLSTATE_ADVERTISED
Definition: msi.h:44
@ INSTALLSTATE_MOREDATA
Definition: msi.h:40
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_ALL
Definition: msi.h:201
@ MSIINSTALLCONTEXT_NONE
Definition: msi.h:197
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
@ MSIINSTALLCONTEXT_USERMANAGED
Definition: msi.h:198
@ USERINFOSTATE_MOREDATA
Definition: msi.h:78
@ USERINFOSTATE_UNKNOWN
Definition: msi.h:80
@ USERINFOSTATE_INVALIDARG
Definition: msi.h:79
@ USERINFOSTATE_ABSENT
Definition: msi.h:81
@ USERINFOSTATE_PRESENT
Definition: msi.h:82
#define INSTALLPROPERTY_INSTALLDATEA
Definition: msi.h:334
#define INSTALLPROPERTY_PUBLISHERA
Definition: msi.h:338
INT(CALLBACK * INSTALLUI_HANDLER_RECORD)(LPVOID, UINT, MSIHANDLE)
Definition: msi.h:422
@ INSTALLLEVEL_DEFAULT
Definition: msi.h:87
enum tagINSTALLUILEVEL INSTALLUILEVEL
#define INSTALLPROPERTY_VERSIONMINORA
Definition: msi.h:354
#define INSTALLPROPERTY_PACKAGECODEA
Definition: msi.h:284
#define INSTALLPROPERTY_PACKAGENAMEA
Definition: msi.h:264
@ INSTALLUILEVEL_FULL
Definition: msi.h:69
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
@ INSTALLUILEVEL_DEFAULT
Definition: msi.h:65
@ INSTALLUILEVEL_NOCHANGE
Definition: msi.h:64
#define INSTALLPROPERTY_LANGUAGEA
Definition: msi.h:272
#define INSTALLPROPERTY_DISPLAYNAMEA
Definition: msi.h:395
BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:74
#define GUID_SIZE
Definition: msipriv.h:733
#define SQUASHED_GUID_SIZE
Definition: msipriv.h:734
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:962
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
unsigned int UINT
Definition: ndis.h:50
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define L(x)
Definition: ntvdm.h:50
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_WRITE
Definition: objbase.h:918
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static char title[]
Definition: ps.c:92
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
const char * winetest_platform
#define ros_skip_flaky
Definition: test.h:180
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
Definition: ftp_var.h:139
Definition: http.c:7252
Definition: fci.c:127
Definition: _hash_fun.h:40
Definition: name.c:39
DWORD dwFileVersionLS
Definition: compat.h:903
DWORD dwFileVersionMS
Definition: compat.h:902
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:94
static const WCHAR lang[]
Definition: wbemdisp.c:287
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
unsigned long MSIHANDLE
Definition: winemsi.idl:27
int INSTALLSTATE
Definition: winemsi.idl:31
#define ERROR_INVALID_COMMAND_LINE
Definition: winerror.h:997
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961
#define CRYPT_E_FILE_ERROR
Definition: winerror.h:3006
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_UNKNOWN_PATCH
Definition: winerror.h:1005
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965
#define ERROR_UNKNOWN_FEATURE
Definition: winerror.h:964
#define ERROR_INSTALL_SOURCE_ABSENT
Definition: winerror.h:970
#define ERROR_FILE_INVALID
Definition: winerror.h:585
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_UNKNOWN_PROPERTY
Definition: winerror.h:966
#define ERROR_BAD_CONFIGURATION
Definition: winerror.h:968
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_USERS
Definition: winreg.h:13
#define IDOK
Definition: winuser.h:833
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193