diff --git a/rostests/winetests/msi/CMakeLists.txt b/rostests/winetests/msi/CMakeLists.txt index c395e4d55ae..adacf626d07 100644 --- a/rostests/winetests/msi/CMakeLists.txt +++ b/rostests/winetests/msi/CMakeLists.txt @@ -4,6 +4,7 @@ add_definitions( -D_DLL -D__USE_CRTIMP) list(APPEND SOURCE + action.c automation.c db.c format.c diff --git a/rostests/winetests/msi/action.c b/rostests/winetests/msi/action.c new file mode 100644 index 00000000000..3743e502a17 --- /dev/null +++ b/rostests/winetests/msi/action.c @@ -0,0 +1,6100 @@ +/* + * Copyright (C) 2006 James Hawkins + * Copyright 2010 Hans Leidekker for CodeWeavers + * + * Tests concentrating on standard actions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _WIN32_MSI 300 +#include + +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" + +static UINT (WINAPI *pMsiQueryComponentStateA) + (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *); +static UINT (WINAPI *pMsiSourceListEnumSourcesA) + (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD); +static UINT (WINAPI *pMsiSourceListGetInfoA) + (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD); +static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA) + (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD); + +static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *); +static BOOL (WINAPI *pGetTokenInformation)(HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD); +static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE); +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + +static HMODULE hsrclient; +static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD); +static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA *, STATEMGRSTATUS *); + +static BOOL is_wow64; +static const BOOL is_64bit = sizeof(void *) > sizeof(int); + +static const char *msifile = "msitest.msi"; +static CHAR CURR_DIR[MAX_PATH]; +static CHAR PROG_FILES_DIR[MAX_PATH]; +static CHAR COMMON_FILES_DIR[MAX_PATH]; +static CHAR APP_DATA_DIR[MAX_PATH]; +static CHAR WINDOWS_DIR[MAX_PATH]; + +/* msi database data */ + +static const char component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n" + "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n" + "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n" + "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n" + "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n" + "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n" + "component\t\tMSITESTDIR\t0\t1\tfile\n" + "service_comp\t\tMSITESTDIR\t0\t1\tservice_file"; + +static const char directory_dat[] = + "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "CABOUTDIR\tMSITESTDIR\tcabout\n" + "CHANGEDDIR\tMSITESTDIR\tchanged:second\n" + "FIRSTDIR\tMSITESTDIR\tfirst\n" + "MSITESTDIR\tProgramFilesFolder\tmsitest\n" + "NEWDIR\tCABOUTDIR\tnew\n" + "ProgramFilesFolder\tTARGETDIR\t.\n" + "TARGETDIR\t\tSourceDir"; + +static const char feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n" + "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n" + "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n" + "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n" + "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n" + "feature\t\t\t\t2\t1\tTARGETDIR\t0\n" + "service_feature\t\t\t\t2\t1\tTARGETDIR\t0"; + +static const char feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "Five\tFive\n" + "Four\tFour\n" + "One\tOne\n" + "Three\tThree\n" + "Two\tTwo\n" + "feature\tcomponent\n" + "service_feature\tservice_comp\n"; + +static const char file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n" + "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n" + "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n" + "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n" + "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n" + "file\tcomponent\tfilename\t100\t\t\t8192\t1\n" + "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1"; + +static const char install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "AllocateRegistrySpace\tNOT Installed\t1550\n" + "CostFinalize\t\t1000\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "ResolveSource\t\t950\n" + "MoveFiles\t\t1700\n" + "InstallFiles\t\t4000\n" + "DuplicateFiles\t\t4500\n" + "WriteEnvironmentStrings\t\t4550\n" + "CreateShortcuts\t\t4600\n" + "InstallServices\t\t5000\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n" + "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000"; + +static const char media_dat[] = + "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t3\t\t\tDISK1\t\n" + "2\t5\t\tmsitest.cab\tDISK2\t\n"; + +static const char property_dat[] = + "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "DefaultUIFont\tDlgFont8\n" + "HASUIRUN\t0\n" + "INSTALLLEVEL\t3\n" + "InstallMode\tTypical\n" + "Manufacturer\tWine\n" + "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" + "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" + "ProductID\tnone\n" + "ProductLanguage\t1033\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "PROMPTROLLBACKCOST\tP\n" + "Setup\tSetup\n" + "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n" + "AdminProperties\tPOSTADMIN\n" + "ROOTDRIVE\tC:\\\n" + "SERVNAME\tTestService\n" + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; + +static const char environment_dat[] = + "Environment\tName\tValue\tComponent_\n" + "s72\tl255\tL255\ts72\n" + "Environment\tEnvironment\n" + "Var1\t=-MSITESTVAR1\t1\tOne\n" + "Var2\tMSITESTVAR2\t1\tOne\n" + "Var3\t=-MSITESTVAR3\t1\tOne\n" + "Var4\tMSITESTVAR4\t1\tOne\n" + "Var5\t-MSITESTVAR5\t\tOne\n" + "Var6\tMSITESTVAR6\t\tOne\n" + "Var7\t!-MSITESTVAR7\t\tOne\n" + "Var8\t!-*MSITESTVAR8\t\tOne\n" + "Var9\t=-MSITESTVAR9\t\tOne\n" + "Var10\t=MSITESTVAR10\t\tOne\n" + "Var11\t+-MSITESTVAR11\t[~];1\tOne\n" + "Var12\t+-MSITESTVAR11\t[~];2\tOne\n" + "Var13\t+-MSITESTVAR12\t[~];1\tOne\n" + "Var14\t=MSITESTVAR13\t[~];1\tOne\n" + "Var15\t=MSITESTVAR13\t[~];2\tOne\n" + "Var16\t=MSITESTVAR14\t;1;\tOne\n" + "Var17\t=MSITESTVAR15\t;;1;;\tOne\n" + "Var18\t=MSITESTVAR16\t 1 \tOne\n" + "Var19\t+-MSITESTVAR17\t1\tOne\n" + "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n" + "Var21\t+-MSITESTVAR18\t1\tOne\n" + "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n" + "Var23\t+-MSITESTVAR19\t1\tOne\n" + "Var24\t+-MSITESTVAR19\t[~]2\tOne\n" + "Var25\t+-MSITESTVAR20\t1\tOne\n" + "Var26\t+-MSITESTVAR20\t2[~]\tOne\n"; + +static const char service_install_dat[] = + "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t" + "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n" + "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n" + "ServiceInstall\tServiceInstall\n" + "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription"; + +static const char service_control_dat[] = + "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n" + "s72\tl255\ti2\tL255\tI2\ts72\n" + "ServiceControl\tServiceControl\n" + "ServiceControl\tTestService\t8\t\t0\tservice_comp"; + +static const char sss_service_control_dat[] = + "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n" + "s72\tl255\ti2\tL255\tI2\ts72\n" + "ServiceControl\tServiceControl\n" + "ServiceControl\tSpooler\t1\t\t0\tservice_comp"; + +static const char sss_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "ResolveSource\t\t950\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "DeleteServices\t\t5000\n" + "MoveFiles\t\t5100\n" + "InstallFiles\t\t5200\n" + "DuplicateFiles\t\t5300\n" + "StartServices\t\t5400\n" + "InstallFinalize\t\t6000\n"; + +static const char sds_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "ResolveSource\t\t950\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "DeleteServices\tInstalled\t5000\n" + "MoveFiles\t\t5100\n" + "InstallFiles\t\t5200\n" + "DuplicateFiles\t\t5300\n" + "InstallServices\tNOT Installed\t5400\n" + "RegisterProduct\t\t5500\n" + "PublishFeatures\t\t5600\n" + "PublishProduct\t\t5700\n" + "InstallFinalize\t\t6000\n"; + +static const char rof_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"; + +static const char rof_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n" + "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0"; + +static const char rof_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\tmaximus\n" + "montecristo\tmaximus"; + +static const char rof_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1"; + +static const char rof_media_dat[] = + "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t1\t\t\tDISK1\t\n"; + +static const char ci2_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\taugustus"; + +static const char ci2_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "augustus\taugustus\taugustus\t500\t\t\t8192\t1"; + +static const char pp_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n" + "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n" + "RemoveFiles\t\t3500\n" + "InstallFiles\t\t4000\n" + "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n" + "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n" + "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n" + "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n" + "InstallFinalize\t\t6600"; + +static const char pp_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n"; + +static const char ppc_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n" + "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n"; + +static const char ppc_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n" + "augustus\taugustus\taugustus\t500\t\t\t8192\t2"; + +static const char ppc_media_dat[] = + "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t2\t\t\tDISK1\t\n"; + +static const char ppc_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\tmaximus\n" + "feature\taugustus\n" + "montecristo\tmaximus"; + +static const char cwd_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; + +static const char rem_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n" + "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n" + "lithium\t\tMSITESTDIR\t2\t\tlithium\n"; + +static const char rem_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\thydrogen\n" + "feature\thelium\n" + "feature\tlithium"; + +static const char rem_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n" + "helium\thelium\thelium\t0\t\t\t8192\t1\n" + "lithium\tlithium\tlithium\t0\t\t\t8192\t1"; + +static const char rem_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "UnpublishFeatures\t\t1800\n" + "RemoveFiles\t\t3500\n" + "InstallFiles\t\t4000\n" + "RegisterProduct\t\t6100\n" + "PublishFeatures\t\t6300\n" + "PublishProduct\t\t6400\n" + "InstallFinalize\t\t6600"; + +static const char rem_remove_files_dat[] = + "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n" + "s72\ts72\tS255\ts72\tI2\n" + "RemoveFile\tFileKey\n" + "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n" + "firkin\thelium\tfirkin\tMSITESTDIR\t1\n" + "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n" + "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n" + "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n" + "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n" + "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n" + "block\thelium\tblock\tMSITESTDIR\t3\n" + "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n" + "nanoacre\thydrogen\t\tCABOUTDIR\t3\n"; + +static const char mov_move_file_dat[] = + "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n" + "s72\ts72\tS255\tS255\tS72\ts72\ti2\n" + "MoveFile\tFileKey\n" + "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n" + "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n" + "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n" + "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n" + "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n" + "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n" + "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n" + "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n" + "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n" + "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n" + "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n" + "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n" + "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n" + "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n" + "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n" + "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n" + "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n" + "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n"; + +static const char df_directory_dat[] = + "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "THIS\tMSITESTDIR\tthis\n" + "DOESNOT\tTHIS\tdoesnot\n" + "NONEXISTENT\tDOESNOT\texist\n" + "MSITESTDIR\tProgramFilesFolder\tmsitest\n" + "ProgramFilesFolder\tTARGETDIR\t.\n" + "TARGETDIR\t\tSourceDir"; + +static const char df_duplicate_file_dat[] = + "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n" + "s72\ts72\ts72\tS255\tS72\n" + "DuplicateFile\tFileKey\n" + "maximus\tmaximus\tmaximus\taugustus\t\n" + "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n" + "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n"; + +static const char wrv_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; + +static const char wrv_registry_dat[] = + "Registry\tRoot\tKey\tName\tValue\tComponent_\n" + "s72\ti2\tl255\tL255\tL0\ts72\n" + "Registry\tRegistry\n" + "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus"; + +static const char cf_directory_dat[] = + "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "FIRSTDIR\tMSITESTDIR\tfirst\n" + "SECONDDIR\tMSITESTDIR\tsecond\n" + "THIRDDIR\tMSITESTDIR\tthird\n" + "MSITESTDIR\tProgramFilesFolder\tmsitest\n" + "ProgramFilesFolder\tTARGETDIR\t.\n" + "TARGETDIR\t\tSourceDir"; + +static const char cf_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "One\t{F8CD42AC-9C38-48FE-8664-B35FD121012A}\tFIRSTDIR\t0\t\tone.txt\n" + "Two\t{DE2DB02E-2DDF-4E34-8CF6-DCA13E29DF52}\tSECONDDIR\t0\t\ttwo.txt\n"; + +static const char cf_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "One\t\tOne\tThe One Feature\t1\t3\tFIRSTDIR\t0\n" + "Two\t\tTwo\tThe Two Feature\t1\t3\tSECONDDIR\t0\n"; + +static const char cf_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "One\tOne\n" + "Two\tTwo\n"; + +static const char cf_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "one.txt\tOne\tone.txt\t0\t\t\t0\t1\n" + "two.txt\tTwo\ttwo.txt\t0\t\t\t0\t2\n"; + +static const char cf_create_folders_dat[] = + "Directory_\tComponent_\n" + "s72\ts72\n" + "CreateFolder\tDirectory_\tComponent_\n" + "FIRSTDIR\tOne\n" + "SECONDDIR\tTwo\n" + "THIRDDIR\tTwo\n"; + +static const char cf_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "CostFinalize\t\t1000\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "RemoveFiles\t\t3500\n" + "CreateFolders\t\t3700\n" + "RemoveFolders\t\t3800\n" + "InstallFiles\t\t4000\n" + "RegisterUser\t\t6000\n" + "RegisterProduct\t\t6100\n" + "PublishFeatures\t\t6300\n" + "PublishProduct\t\t6400\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "UnpublishFeatures\t\t1800\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n"; + +static const char sr_selfreg_dat[] = + "File_\tCost\n" + "s72\tI2\n" + "SelfReg\tFile_\n" + "one.txt\t1\n"; + +static const char sr_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "CostFinalize\t\t1000\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "ResolveSource\t\t950\n" + "MoveFiles\t\t1700\n" + "SelfUnregModules\t\t3900\n" + "InstallFiles\t\t4000\n" + "DuplicateFiles\t\t4500\n" + "WriteEnvironmentStrings\t\t4550\n" + "CreateShortcuts\t\t4600\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n"; + +static const char font_media_dat[] = + "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t3\t\t\tDISK1\t\n"; + +static const char font_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n"; + +static const char font_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char font_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n"; + +static const char font_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "fonts\tfonts\n"; + +static const char font_dat[] = + "File_\tFontTitle\n" + "s72\tS128\n" + "Font\tFile_\n" + "font.ttf\tmsi test font\n"; + +static const char font_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "UnpublishFeatures\t\t1800\n" + "RemoveFiles\t\t3500\n" + "InstallFiles\t\t4000\n" + "RegisterFonts\t\t4100\n" + "UnregisterFonts\t\t4200\n" + "RegisterUser\t\t6000\n" + "RegisterProduct\t\t6100\n" + "PublishFeatures\t\t6300\n" + "PublishProduct\t\t6400\n" + "InstallFinalize\t\t6600"; + +static const char vp_property_dat[] = + "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "HASUIRUN\t0\n" + "INSTALLLEVEL\t3\n" + "InstallMode\tTypical\n" + "Manufacturer\tWine\n" + "PIDTemplate\t###-#######\n" + "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" + "ProductLanguage\t1033\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n" + "MSIFASTINSTALL\t1\n"; + +static const char vp_custom_action_dat[] = + "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "SetProductID1\t51\tProductID\t1\t\n" + "SetProductID2\t51\tProductID\t2\t\n" + "TestProductID1\t19\t\t\tHalts installation\n" + "TestProductID2\t19\t\t\tHalts installation\n"; + +static const char vp_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "SetProductID1\tSET_PRODUCT_ID=1\t3000\n" + "SetProductID2\tSET_PRODUCT_ID=2\t3100\n" + "ValidateProductID\t\t3200\n" + "InstallExecute\t\t3300\n" + "TestProductID1\tProductID=1\t3400\n" + "TestProductID2\tProductID=\"123-1234567\"\t3500\n" + "InstallFiles\t\t4000\n" + "InstallFinalize\t\t6000\n"; + +static const char odbc_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n" + "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n" + "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n" + "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n" + "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n"; + +static const char odbc_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char odbc_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "odbc\todbc\n"; + +static const char odbc_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n"; + +static const char odbc_driver_dat[] = + "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n" + "s72\ts72\ts255\ts72\tS72\n" + "ODBCDriver\tDriver\n" + "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n" + "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n"; + +static const char odbc_translator_dat[] = + "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n" + "s72\ts72\ts255\ts72\tS72\n" + "ODBCTranslator\tTranslator\n" + "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n" + "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n"; + +static const char odbc_datasource_dat[] = + "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n" + "s72\ts72\ts255\ts255\ti2\n" + "ODBCDataSource\tDataSource\n" + "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n"; + +static const char odbc_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "InstallODBC\t\t3000\n" + "RemoveODBC\t\t3100\n" + "RemoveFiles\t\t3900\n" + "InstallFiles\t\t4000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char odbc_media_dat[] = + "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t5\t\t\tDISK1\t\n"; + +static const char tl_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n"; + +static const char tl_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char tl_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "typelib\ttypelib\n"; + +static const char tl_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n"; + +static const char tl_typelib_dat[] = + "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n" + "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n" + "TypeLib\tLibID\tLanguage\tComponent_\n" + "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n"; + +static const char tl_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n" + "UnregisterTypeLibraries\t\t3100\n" + "RegisterProduct\t\t5100\n" + "PublishFeatures\t\t5200\n" + "PublishProduct\t\t5300\n" + "InstallFinalize\t\t6000\n"; + +static const char crs_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n"; + +static const char crs_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char crs_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "shortcut\tshortcut\n"; + +static const char crs_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n"; + +static const char crs_shortcut_dat[] = + "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n" + "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n" + "Shortcut\tShortcut\n" + "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n"; + +static const char crs_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RemoveShortcuts\t\t3000\n" + "CreateShortcuts\t\t3100\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char pub_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n"; + +static const char pub_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char pub_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "publish\tpublish\n"; + +static const char pub_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n"; + +static const char pub_publish_component_dat[] = + "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n" + "s38\ts255\ts72\tL255\ts38\n" + "PublishComponent\tComponentId\tQualifier\tComponent_\n" + "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n"; + +static const char pub_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "PublishComponents\t\t3000\n" + "UnpublishComponents\t\t3100\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char rd_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n" + "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n" + "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n"; + +static const char rd_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char rd_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "duplicate\tduplicate\n"; + +static const char rd_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n" + "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n"; + +static const char rd_duplicate_file_dat[] = + "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n" + "s72\ts72\ts72\tS255\tS72\n" + "DuplicateFile\tFileKey\n" + "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n" + "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n" + "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n"; + +static const char rd_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveDuplicateFiles\t\t1900\n" + "InstallFiles\t\t2000\n" + "DuplicateFiles\t\t2100\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char rrv_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n"; + +static const char rrv_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char rrv_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "registry\tregistry\n"; + +static const char rrv_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n"; + +static const char rrv_registry_dat[] = + "Registry\tRoot\tKey\tName\tValue\tComponent_\n" + "s72\ti2\tl255\tL255\tL0\ts72\n" + "Registry\tRegistry\n" + "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n" + "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n" + "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n"; + +static const char rrv_remove_registry_dat[] = + "RemoveRegistry\tRoot\tKey\tName\tComponent_\n" + "s72\ti2\tl255\tL255\ts72\n" + "RemoveRegistry\tRemoveRegistry\n" + "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n" + "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n" + "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n"; + +static const char rrv_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RemoveRegistryValues\t\t3000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char frp_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n"; + +static const char frp_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char frp_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "product\tproduct\n"; + +static const char frp_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n"; + +static const char frp_custom_action_dat[] = + "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "TestProp\t19\t\t\tPROP set\n"; + +static const char frp_upgrade_dat[] = + "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n" + "s38\tS20\tS20\tS255\ti4\tS255\ts72\n" + "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n" + "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n"; + +static const char frp_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "FindRelatedProducts\t\t50\n" + "TestProp\tPROP AND NOT REMOVE\t51\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char riv_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n"; + +static const char riv_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char riv_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "inifile\tinifile\n"; + +static const char riv_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n"; + +static const char riv_ini_file_dat[] = + "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n" + "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n" + "IniFile\tIniFile\n" + "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n"; + +static const char riv_remove_ini_file_dat[] = + "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n" + "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n" + "RemoveIniFile\tRemoveIniFile\n" + "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n"; + +static const char riv_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RemoveIniValues\t\t3000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char res_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n"; + +static const char res_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char res_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "envvar\tenvvar\n"; + +static const char res_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n"; + +static const char res_environment_dat[] = + "Environment\tName\tValue\tComponent_\n" + "s72\tl255\tL255\ts72\n" + "Environment\tEnvironment\n" + "var1\t=-MSITESTVAR1\t1\tenvvar\n" + "var2\t=+-MSITESTVAR2\t1\tenvvar\n" + "var3\t=MSITESTVAR3\t1\tenvvar\n" + "var4\t=-MSITESTVAR4\t\tenvvar\n" + "var5\t=MSITESTVAR5\t\tenvvar\n"; + +static const char res_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "RemoveEnvironmentStrings\t\t3000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char rci_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n"; + +static const char rci_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char rci_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "class\tclass\n"; + +static const char rci_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n"; + +static const char rci_appid_dat[] = + "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n" + "s38\tS255\tS255\tS255\tS255\tI2\tI2\n" + "AppId\tAppId\n" + "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n"; + +static const char rci_class_dat[] = + "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n" + "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n" + "Class\tCLSID\tContext\tComponent_\n" + "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n"; + +static const char rci_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "UnregisterClassInfo\t\t3000\n" + "RegisterClassInfo\t\t4000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char rei_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n"; + +static const char rei_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char rei_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "extension\textension\n"; + +static const char rei_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n"; + +static const char rei_extension_dat[] = + "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n" + "s255\ts72\tS255\tS64\ts38\n" + "Extension\tExtension\tComponent_\n" + "extension\textension\tProg.Id.1\t\textension\n"; + +static const char rei_verb_dat[] = + "Extension_\tVerb\tSequence\tCommand\tArgument\n" + "s255\ts32\tI2\tL255\tL255\n" + "Verb\tExtension_\tVerb\n" + "extension\tOpen\t1\t&Open\t/argument\n"; + +static const char rei_progid_dat[] = + "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n" + "s255\tS255\tS38\tL255\tS72\tI2\n" + "ProgId\tProgId\n" + "Prog.Id.1\t\t\tdescription\t\t\n"; + +static const char rei_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "UnregisterExtensionInfo\t\t3000\n" + "RegisterExtensionInfo\t\t4000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char rmi_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n"; + +static const char rmi_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char rmi_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "mime\tmime\n"; + +static const char rmi_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n"; + +static const char rmi_extension_dat[] = + "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n" + "s255\ts72\tS255\tS64\ts38\n" + "Extension\tExtension\tComponent_\n" + "mime\tmime\t\tmime/type\tmime\n"; + +static const char rmi_verb_dat[] = + "Extension_\tVerb\tSequence\tCommand\tArgument\n" + "s255\ts32\tI2\tL255\tL255\n" + "Verb\tExtension_\tVerb\n" + "mime\tOpen\t1\t&Open\t/argument\n"; + +static const char rmi_mime_dat[] = + "ContentType\tExtension_\tCLSID\n" + "s64\ts255\tS38\n" + "MIME\tContentType\n" + "mime/type\tmime\t\n"; + +static const char rmi_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "RemoveFiles\t\t1700\n" + "InstallFiles\t\t2000\n" + "UnregisterExtensionInfo\t\t3000\n" + "UnregisterMIMEInfo\t\t3500\n" + "RegisterExtensionInfo\t\t4000\n" + "RegisterMIMEInfo\t\t4500\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +static const char pa_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "win32.txt\twin32\twin32.txt\t1000\t\t\t8192\t1\n" + "manifest.txt\twin32\tmanifest.txt\t1000\t\t\t8192\t1\n" + "win32_local.txt\twin32_local\twin32_local.txt\t1000\t\t\t8192\t1\n" + "manifest_local.txt\twin32_local\tmanifest_local.txt\t1000\t\t\t8192\t1\n" + "dotnet.txt\tdotnet\tdotnet.txt\t1000\t\t\t8192\t1\n" + "dotnet_local.txt\tdotnet_local\tdotnet_local.txt\t1000\t\t\t8192\t1\n" + "application_win32.txt\twin32_local\tapplication_win32.txt\t1000\t\t\t8192\t1\n" + "application_dotnet.txt\tdotnet_local\tapplication_dotnet.txt\t1000\t\t\t8192\t1\n"; + +static const char pa_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "assembly\t\t\tassembly feature\t1\t2\tMSITESTDIR\t0\n"; + +static const char pa_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "assembly\twin32\n" + "assembly\twin32_local\n" + "assembly\tdotnet\n" + "assembly\tdotnet_local\n"; + +static const char pa_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "win32\t{F515549E-7E61-425D-AAC1-9BEF2E066D06}\tMSITESTDIR\t0\t\twin32.txt\n" + "win32_local\t{D34D3FBA-6789-4E57-AD1A-1281297DC201}\tMSITESTDIR\t0\t\twin32_local.txt\n" + "dotnet\t{8943164F-2B31-4C09-A894-493A8CBDE0A4}\tMSITESTDIR\t0\t\tdotnet.txt\n" + "dotnet_local\t{4E8567E8-8EAE-4E36-90F1-B99D33C663F8}\tMSITESTDIR\t0\t\tdotnet_local.txt\n"; + +static const char pa_msi_assembly_dat[] = + "Component_\tFeature_\tFile_Manifest\tFile_Application\tAttributes\n" + "s72\ts38\tS72\tS72\tI2\n" + "MsiAssembly\tComponent_\n" + "win32\tassembly\tmanifest.txt\t\t1\n" + "win32_local\tassembly\tmanifest_local.txt\tapplication_win32.txt\t1\n" + "dotnet\tassembly\t\t\t0\n" + "dotnet_local\tassembly\t\tapplication_dotnet.txt\t0\n"; + +static const char pa_msi_assembly_name_dat[] = + "Component_\tName\tValue\n" + "s72\ts255\ts255\n" + "MsiAssemblyName\tComponent_\tName\n" + "win32\tName\tWine.Win32.Assembly\n" + "win32\tprocessorArchitecture\tx86\n" + "win32\tpublicKeyToken\tabcdef0123456789\n" + "win32\ttype\twin32\n" + "win32\tversion\t1.0.0.0\n" + "win32_local\tName\tWine.Win32.Local.Assembly\n" + "win32_local\tprocessorArchitecture\tx86\n" + "win32_local\tpublicKeyToken\tabcdef0123456789\n" + "win32_local\ttype\twin32\n" + "win32_local\tversion\t1.0.0.0\n" + "dotnet\tName\tWine.Dotnet.Assembly\n" + "dotnet\tprocessorArchitecture\tMSIL\n" + "dotnet\tpublicKeyToken\tabcdef0123456789\n" + "dotnet\tculture\tneutral\n" + "dotnet\tversion\t1.0.0.0\n" + "dotnet_local\tName\tWine.Dotnet.Local.Assembly\n" + "dotnet_local\tprocessorArchitecture\tMSIL\n" + "dotnet_local\tpublicKeyToken\tabcdef0123456789\n" + "dotnet_local\tculture\tneutral\n" + "dotnet_local\tversion\t1.0.0.0\n"; + +static const char pa_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "MsiPublishAssemblies\t\t3000\n" + "MsiUnpublishAssemblies\t\t4000\n" + "RegisterProduct\t\t5000\n" + "PublishFeatures\t\t5100\n" + "PublishProduct\t\t5200\n" + "InstallFinalize\t\t6000\n"; + +typedef struct _msi_table +{ + const char *filename; + const char *data; + unsigned int size; +} msi_table; + +#define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)} + +static const msi_table env_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property), + ADD_TABLE(environment) +}; + +static const msi_table pp_tables[] = +{ + ADD_TABLE(pp_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(rof_feature_comp), + ADD_TABLE(rof_file), + ADD_TABLE(pp_install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), +}; + +static const msi_table ppc_tables[] = +{ + ADD_TABLE(ppc_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(ppc_feature_comp), + ADD_TABLE(ppc_file), + ADD_TABLE(pp_install_exec_seq), + ADD_TABLE(ppc_media), + ADD_TABLE(property), +}; + +static const msi_table rem_tables[] = +{ + ADD_TABLE(rem_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(rem_feature_comp), + ADD_TABLE(rem_file), + ADD_TABLE(rem_install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), + ADD_TABLE(rem_remove_files), +}; + +static const msi_table mov_tables[] = +{ + ADD_TABLE(cwd_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(ci2_feature_comp), + ADD_TABLE(ci2_file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), + ADD_TABLE(mov_move_file), +}; + +static const msi_table df_tables[] = +{ + ADD_TABLE(rof_component), + ADD_TABLE(df_directory), + ADD_TABLE(rof_feature), + ADD_TABLE(rof_feature_comp), + ADD_TABLE(rof_file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), + ADD_TABLE(df_duplicate_file), +}; + +static const msi_table wrv_tables[] = +{ + ADD_TABLE(wrv_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(ci2_feature_comp), + ADD_TABLE(ci2_file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), + ADD_TABLE(wrv_registry), +}; + +static const msi_table cf_tables[] = +{ + ADD_TABLE(cf_component), + ADD_TABLE(cf_directory), + ADD_TABLE(cf_feature), + ADD_TABLE(cf_feature_comp), + ADD_TABLE(cf_file), + ADD_TABLE(cf_create_folders), + ADD_TABLE(cf_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table sss_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(sss_install_exec_seq), + ADD_TABLE(sss_service_control), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table sds_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(sds_install_exec_seq), + ADD_TABLE(service_control), + ADD_TABLE(service_install), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table sr_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(sr_selfreg), + ADD_TABLE(sr_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table font_tables[] = +{ + ADD_TABLE(font_component), + ADD_TABLE(directory), + ADD_TABLE(font_feature), + ADD_TABLE(font_feature_comp), + ADD_TABLE(font_file), + ADD_TABLE(font), + ADD_TABLE(font_install_exec_seq), + ADD_TABLE(font_media), + ADD_TABLE(property) +}; + +static const msi_table vp_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(vp_custom_action), + ADD_TABLE(vp_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(vp_property) +}; + +static const msi_table odbc_tables[] = +{ + ADD_TABLE(odbc_component), + ADD_TABLE(directory), + ADD_TABLE(odbc_feature), + ADD_TABLE(odbc_feature_comp), + ADD_TABLE(odbc_file), + ADD_TABLE(odbc_driver), + ADD_TABLE(odbc_translator), + ADD_TABLE(odbc_datasource), + ADD_TABLE(odbc_install_exec_seq), + ADD_TABLE(odbc_media), + ADD_TABLE(property) +}; + +static const msi_table tl_tables[] = +{ + ADD_TABLE(tl_component), + ADD_TABLE(directory), + ADD_TABLE(tl_feature), + ADD_TABLE(tl_feature_comp), + ADD_TABLE(tl_file), + ADD_TABLE(tl_typelib), + ADD_TABLE(tl_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table crs_tables[] = +{ + ADD_TABLE(crs_component), + ADD_TABLE(directory), + ADD_TABLE(crs_feature), + ADD_TABLE(crs_feature_comp), + ADD_TABLE(crs_file), + ADD_TABLE(crs_shortcut), + ADD_TABLE(crs_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table pub_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(pub_component), + ADD_TABLE(pub_feature), + ADD_TABLE(pub_feature_comp), + ADD_TABLE(pub_file), + ADD_TABLE(pub_publish_component), + ADD_TABLE(pub_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table rd_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(rd_component), + ADD_TABLE(rd_feature), + ADD_TABLE(rd_feature_comp), + ADD_TABLE(rd_file), + ADD_TABLE(rd_duplicate_file), + ADD_TABLE(rd_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table rrv_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(rrv_component), + ADD_TABLE(rrv_feature), + ADD_TABLE(rrv_feature_comp), + ADD_TABLE(rrv_file), + ADD_TABLE(rrv_registry), + ADD_TABLE(rrv_remove_registry), + ADD_TABLE(rrv_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table frp_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(frp_component), + ADD_TABLE(frp_feature), + ADD_TABLE(frp_feature_comp), + ADD_TABLE(frp_file), + ADD_TABLE(frp_upgrade), + ADD_TABLE(frp_custom_action), + ADD_TABLE(frp_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table riv_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(riv_component), + ADD_TABLE(riv_feature), + ADD_TABLE(riv_feature_comp), + ADD_TABLE(riv_file), + ADD_TABLE(riv_ini_file), + ADD_TABLE(riv_remove_ini_file), + ADD_TABLE(riv_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table res_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(res_component), + ADD_TABLE(res_feature), + ADD_TABLE(res_feature_comp), + ADD_TABLE(res_file), + ADD_TABLE(res_environment), + ADD_TABLE(res_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table rci_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(rci_component), + ADD_TABLE(rci_feature), + ADD_TABLE(rci_feature_comp), + ADD_TABLE(rci_file), + ADD_TABLE(rci_appid), + ADD_TABLE(rci_class), + ADD_TABLE(rci_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table rei_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(rei_component), + ADD_TABLE(rei_feature), + ADD_TABLE(rei_feature_comp), + ADD_TABLE(rei_file), + ADD_TABLE(rei_extension), + ADD_TABLE(rei_verb), + ADD_TABLE(rei_progid), + ADD_TABLE(rei_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table rmi_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(rmi_component), + ADD_TABLE(rmi_feature), + ADD_TABLE(rmi_feature_comp), + ADD_TABLE(rmi_file), + ADD_TABLE(rmi_extension), + ADD_TABLE(rmi_verb), + ADD_TABLE(rmi_mime), + ADD_TABLE(rmi_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table pa_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(pa_component), + ADD_TABLE(pa_feature), + ADD_TABLE(pa_feature_comp), + ADD_TABLE(pa_file), + ADD_TABLE(pa_msi_assembly), + ADD_TABLE(pa_msi_assembly_name), + ADD_TABLE(pa_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +/* cabinet definitions */ + +/* make the max size large so there is only one cab file */ +#define MEDIA_SIZE 0x7FFFFFFF +#define FOLDER_THRESHOLD 900000 + +/* the FCI callbacks */ + +static void * CDECL mem_alloc(ULONG cb) +{ + return HeapAlloc(GetProcessHeap(), 0, cb); +} + +static void CDECL mem_free(void *memory) +{ + HeapFree(GetProcessHeap(), 0, memory); +} + +static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv) +{ + sprintf(pccab->szCab, pv, pccab->iCab); + return TRUE; +} + +static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv) +{ + return 0; +} + +static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile, + BOOL fContinuation, void *pv) +{ + return 0; +} + +static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv) +{ + HANDLE handle; + DWORD dwAccess = 0; + DWORD dwShareMode = 0; + DWORD dwCreateDisposition = OPEN_EXISTING; + + dwAccess = GENERIC_READ | GENERIC_WRITE; + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + + if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES) + dwCreateDisposition = OPEN_EXISTING; + else + dwCreateDisposition = CREATE_NEW; + + handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL, + dwCreateDisposition, 0, NULL); + + ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile); + + return (INT_PTR)handle; +} + +static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv) +{ + HANDLE handle = (HANDLE)hf; + DWORD dwRead; + BOOL res; + + res = ReadFile(handle, memory, cb, &dwRead, NULL); + ok(res, "Failed to ReadFile\n"); + + return dwRead; +} + +static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv) +{ + HANDLE handle = (HANDLE)hf; + DWORD dwWritten; + BOOL res; + + res = WriteFile(handle, memory, cb, &dwWritten, NULL); + ok(res, "Failed to WriteFile\n"); + + return dwWritten; +} + +static int CDECL fci_close(INT_PTR hf, int *err, void *pv) +{ + HANDLE handle = (HANDLE)hf; + ok(CloseHandle(handle), "Failed to CloseHandle\n"); + + return 0; +} + +static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv) +{ + HANDLE handle = (HANDLE)hf; + DWORD ret; + + ret = SetFilePointer(handle, dist, NULL, seektype); + ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n"); + + return ret; +} + +static int CDECL fci_delete(char *pszFile, int *err, void *pv) +{ + BOOL ret = DeleteFileA(pszFile); + ok(ret, "Failed to DeleteFile %s\n", pszFile); + + return 0; +} + +static void init_functionpointers(void) +{ + HMODULE hmsi = GetModuleHandleA("msi.dll"); + HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + +#define GET_PROC(mod, func) \ + p ## func = (void*)GetProcAddress(mod, #func); \ + if(!p ## func) \ + trace("GetProcAddress(%s) failed\n", #func); + + GET_PROC(hmsi, MsiQueryComponentStateA); + GET_PROC(hmsi, MsiSourceListEnumSourcesA); + GET_PROC(hmsi, MsiSourceListGetInfoA); + GET_PROC(hmsi, MsiGetComponentPathExA); + + GET_PROC(hadvapi32, ConvertSidToStringSidA); + GET_PROC(hadvapi32, GetTokenInformation); + GET_PROC(hadvapi32, OpenProcessToken); + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hkernel32, IsWow64Process) + + hsrclient = LoadLibraryA("srclient.dll"); + GET_PROC(hsrclient, SRRemoveRestorePoint); + GET_PROC(hsrclient, SRSetRestorePointA); + +#undef GET_PROC +} + +static BOOL is_process_limited(void) +{ + HANDLE token; + + if (!pOpenProcessToken || !pGetTokenInformation) return FALSE; + + if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) + { + BOOL ret; + TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; + DWORD size; + + ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); + CloseHandle(token); + return (ret && type == TokenElevationTypeLimited); + } + return FALSE; +} + +static char *get_user_sid(void) +{ + HANDLE token; + DWORD size = 0; + TOKEN_USER *user; + char *usersid = NULL; + + if (!pConvertSidToStringSidA) + { + win_skip("ConvertSidToStringSidA is not available\n"); + return NULL; + } + OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); + GetTokenInformation(token, TokenUser, NULL, size, &size); + + user = HeapAlloc(GetProcessHeap(), 0, size); + GetTokenInformation(token, TokenUser, user, size, &size); + pConvertSidToStringSidA(user->User.Sid, &usersid); + HeapFree(GetProcessHeap(), 0, user); + + CloseHandle(token); + return usersid; +} + +static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv) +{ + LPSTR tempname; + + tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH); + GetTempFileNameA(".", "xx", 0, tempname); + + if (tempname && (strlen(tempname) < (unsigned)cbTempName)) + { + lstrcpyA(pszTempName, tempname); + HeapFree(GetProcessHeap(), 0, tempname); + return TRUE; + } + + HeapFree(GetProcessHeap(), 0, tempname); + + return FALSE; +} + +static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime, + USHORT *pattribs, int *err, void *pv) +{ + BY_HANDLE_FILE_INFORMATION finfo; + FILETIME filetime; + HANDLE handle; + DWORD attrs; + BOOL res; + + handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + + ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName); + + res = GetFileInformationByHandle(handle, &finfo); + ok(res, "Expected GetFileInformationByHandle to succeed\n"); + + FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime); + FileTimeToDosDateTime(&filetime, pdate, ptime); + + attrs = GetFileAttributes(pszName); + ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n"); + + return (INT_PTR)handle; +} + +static BOOL add_file(HFCI hfci, const char *file, TCOMP compress) +{ + char path[MAX_PATH]; + char filename[MAX_PATH]; + + lstrcpyA(path, CURR_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, file); + + lstrcpyA(filename, file); + + return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet, + progress, get_open_info, compress); +} + +static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size) +{ + ZeroMemory(pCabParams, sizeof(CCAB)); + + pCabParams->cb = max_size; + pCabParams->cbFolderThresh = FOLDER_THRESHOLD; + pCabParams->setID = 0xbeef; + pCabParams->iCab = 1; + lstrcpyA(pCabParams->szCabPath, CURR_DIR); + lstrcatA(pCabParams->szCabPath, "\\"); + lstrcpyA(pCabParams->szCab, name); +} + +static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files) +{ + CCAB cabParams; + LPCSTR ptr; + HFCI hfci; + ERF erf; + BOOL res; + + set_cab_parameters(&cabParams, name, max_size); + + hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open, + fci_read, fci_write, fci_close, fci_seek, fci_delete, + get_temp_file, &cabParams, NULL); + + ok(hfci != NULL, "Failed to create an FCI context\n"); + + ptr = files; + while (*ptr) + { + res = add_file(hfci, ptr, tcompTYPE_MSZIP); + ok(res, "Failed to add file: %s\n", ptr); + ptr += lstrlen(ptr) + 1; + } + + res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress); + ok(res, "Failed to flush the cabinet\n"); + + res = FCIDestroy(hfci); + ok(res, "Failed to destroy the cabinet\n"); +} + +static BOOL get_user_dirs(void) +{ + HKEY hkey; + DWORD type, size; + + if (RegOpenKey(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hkey)) + return FALSE; + + size = MAX_PATH; + if (RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size)) + { + RegCloseKey(hkey); + return FALSE; + } + + RegCloseKey(hkey); + return TRUE; +} + +static BOOL get_system_dirs(void) +{ + HKEY hkey; + DWORD type, size; + + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion", &hkey)) + return FALSE; + + size = MAX_PATH; + if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) && + RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size)) + { + RegCloseKey(hkey); + return FALSE; + } + + size = MAX_PATH; + if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) && + RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) + { + RegCloseKey(hkey); + return FALSE; + } + + RegCloseKey(hkey); + + if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) + return FALSE; + + return TRUE; +} + +static void create_file_data(LPCSTR name, LPCSTR data, DWORD size) +{ + HANDLE file; + DWORD written; + + file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (file == INVALID_HANDLE_VALUE) + return; + + WriteFile(file, data, strlen(data), &written, NULL); + + if (size) + { + SetFilePointer(file, size, NULL, FILE_BEGIN); + SetEndOfFile(file); + } + + CloseHandle(file); +} + +#define create_file(name, size) create_file_data(name, name, size) + +static void create_test_files(void) +{ + CreateDirectoryA("msitest", NULL); + create_file("msitest\\one.txt", 100); + CreateDirectoryA("msitest\\first", NULL); + create_file("msitest\\first\\two.txt", 100); + CreateDirectoryA("msitest\\second", NULL); + create_file("msitest\\second\\three.txt", 100); + + create_file("four.txt", 100); + create_file("five.txt", 100); + create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0"); + + create_file("msitest\\filename", 100); + create_file("msitest\\service.exe", 100); + + DeleteFileA("four.txt"); + DeleteFileA("five.txt"); +} + +static BOOL delete_pf(const CHAR *rel_path, BOOL is_file) +{ + CHAR path[MAX_PATH]; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, rel_path); + + if (is_file) + return DeleteFileA(path); + else + return RemoveDirectoryA(path); +} + +static void delete_test_files(void) +{ + DeleteFileA("msitest.msi"); + DeleteFileA("msitest.cab"); + DeleteFileA("msitest\\second\\three.txt"); + DeleteFileA("msitest\\first\\two.txt"); + DeleteFileA("msitest\\one.txt"); + DeleteFileA("msitest\\service.exe"); + DeleteFileA("msitest\\filename"); + RemoveDirectoryA("msitest\\second"); + RemoveDirectoryA("msitest\\first"); + RemoveDirectoryA("msitest"); +} + +static void write_file(const CHAR *filename, const char *data, int data_size) +{ + DWORD size; + HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + WriteFile(hf, data, data_size, &size, NULL); + CloseHandle(hf); +} + +static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template) +{ + MSIHANDLE summary; + UINT r; + + r = MsiGetSummaryInformationA(db, NULL, 5, &summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL, + "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* write the summary changes back to the stream */ + r = MsiSummaryInfoPersist(summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + MsiCloseHandle(summary); +} + +#define create_database(name, tables, num_tables) \ + create_database_wordcount(name, tables, num_tables, 100, 0, ";1033"); + +#define create_database_template(name, tables, num_tables, version, template) \ + create_database_wordcount(name, tables, num_tables, version, 0, template); + +static void create_database_wordcount(const CHAR *name, const msi_table *tables, + int num_tables, INT version, INT wordcount, + const char *template) +{ + MSIHANDLE db; + UINT r; + int j; + + r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* import the tables into the database */ + for (j = 0; j < num_tables; j++) + { + const msi_table *table = &tables[j]; + + write_file(table->filename, table->data, (table->size - 1) * sizeof(char)); + + r = MsiDatabaseImportA(db, CURR_DIR, table->filename); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + DeleteFileA(table->filename); + } + + write_msi_summary_info(db, version, wordcount, template); + + r = MsiDatabaseCommit(db); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + MsiCloseHandle(db); +} + +static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status) +{ + RESTOREPOINTINFOA spec; + + spec.dwEventType = event_type; + spec.dwRestorePtType = APPLICATION_INSTALL; + spec.llSequenceNumber = status->llSequenceNumber; + lstrcpyA(spec.szDescription, "msitest restore point"); + + return pSRSetRestorePointA(&spec, status); +} + +static void remove_restore_point(DWORD seq_number) +{ + DWORD res; + + res = pSRRemoveRestorePoint(seq_number); + if (res != ERROR_SUCCESS) + trace("Failed to remove the restore point : %08x\n", res); +} + +static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + +static BOOL file_exists(LPCSTR file) +{ + return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES; +} + +static BOOL pf_exists(LPCSTR file) +{ + CHAR path[MAX_PATH]; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, file); + + return file_exists(path); +} + +static void delete_pfmsitest_files(void) +{ + SHFILEOPSTRUCT shfl; + CHAR path[MAX_PATH+11]; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\msitest\\*"); + path[strlen(path) + 1] = '\0'; + + shfl.hwnd = NULL; + shfl.wFunc = FO_DELETE; + shfl.pFrom = path; + shfl.pTo = NULL; + shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI; + + SHFileOperation(&shfl); + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\msitest"); + RemoveDirectoryA(path); +} + +static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line) +{ + char val[MAX_PATH]; + DWORD size, type; + LONG res; + + size = MAX_PATH; + val[0] = '\0'; + res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size); + + if (res != ERROR_SUCCESS || + (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ)) + { + ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); + return; + } + + if (!expected) + ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val); + else + { + if (bcase) + ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val); + else + ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val); + } +} + +static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line) +{ + DWORD val, size, type; + LONG res; + + size = sizeof(DWORD); + res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); + + if (res != ERROR_SUCCESS || type != REG_DWORD) + { + ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); + return; + } + + ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val); +} + +static void check_reg_dword4(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, + DWORD expected4, DWORD line) +{ + DWORD val, size, type; + LONG res; + + size = sizeof(DWORD); + res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); + + if (res != ERROR_SUCCESS || type != REG_DWORD) + { + ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); + return; + } + + ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4, + "Expected %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, val); +} + +static void check_reg_dword5(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, + DWORD expected4, DWORD expected5, DWORD line) +{ + DWORD val, size, type; + LONG res; + + size = sizeof(DWORD); + res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); + + if (res != ERROR_SUCCESS || type != REG_DWORD) + { + ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); + return; + } + + ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4 || + val == expected5, + "Expected %d, %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, expected5, val); +} + +#define CHECK_REG_STR(prodkey, name, expected) \ + check_reg_str(prodkey, name, expected, TRUE, __LINE__); + +#define CHECK_DEL_REG_STR(prodkey, name, expected) \ + check_reg_str(prodkey, name, expected, TRUE, __LINE__); \ + RegDeleteValueA(prodkey, name); + +#define CHECK_REG_ISTR(prodkey, name, expected) \ + check_reg_str(prodkey, name, expected, FALSE, __LINE__); + +#define CHECK_DEL_REG_ISTR(prodkey, name, expected) \ + check_reg_str(prodkey, name, expected, FALSE, __LINE__); \ + RegDeleteValueA(prodkey, name); + +#define CHECK_REG_DWORD(prodkey, name, expected) \ + check_reg_dword(prodkey, name, expected, __LINE__); + +#define CHECK_DEL_REG_DWORD(prodkey, name, expected) \ + check_reg_dword(prodkey, name, expected, __LINE__); \ + RegDeleteValueA(prodkey, name); + +#define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \ + check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); + +#define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \ + check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \ + RegDeleteValueA(prodkey, name); + +#define CHECK_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \ + check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__); + +#define CHECK_DEL_REG_DWORD5(prodkey, name, expected1, expected2, expected3, expected4 ,expected5) \ + check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \ + RegDeleteValueA(prodkey, name); + +static void get_date_str(LPSTR date) +{ + SYSTEMTIME systime; + + static const char date_fmt[] = "%d%02d%02d"; + GetLocalTime(&systime); + sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay); +} + +static void test_register_product(void) +{ + UINT r; + LONG res; + HKEY hkey, props, usage; + LPSTR usersid; + char date[MAX_PATH], temp[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH]; + DWORD size, type; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; + static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion" + "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; + static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" + "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" + "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2"; + static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes" + "\\51AAE0C44620A5E4788506E91F249BD2"; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + if (!(usersid = get_user_sid())) + return; + + get_date_str(date); + GetTempPath(MAX_PATH, temp); + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); + + /* RegisterProduct */ + r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST"); + CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1"); + CHECK_DEL_REG_STR(hkey, "InstallDate", date); + CHECK_DEL_REG_STR(hkey, "InstallSource", temp); + CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(hkey, "Publisher", "Wine"); + CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL); + CHECK_DEL_REG_STR(hkey, "Comments", NULL); + CHECK_DEL_REG_STR(hkey, "Contact", NULL); + CHECK_DEL_REG_STR(hkey, "HelpLink", NULL); + CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL); + CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL); + CHECK_DEL_REG_STR(hkey, "Readme", NULL); + CHECK_DEL_REG_STR(hkey, "Size", NULL); + CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL); + CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL); + CHECK_DEL_REG_DWORD(hkey, "Language", 1033); + CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); + CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1); + CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1); + CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24); + } + + delete_key(hkey, "", access); + RegCloseKey(hkey); + + sprintf(keypath, userdata, usersid); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = sizeof(path); + RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size); + DeleteFileA(path); + RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */ + + CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST"); + CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1"); + CHECK_DEL_REG_STR(props, "InstallDate", date); + CHECK_DEL_REG_STR(props, "InstallSource", temp); + CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(props, "Publisher", "Wine"); + CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL); + CHECK_DEL_REG_STR(props, "Comments", NULL); + CHECK_DEL_REG_STR(props, "Contact", NULL); + CHECK_DEL_REG_STR(props, "HelpLink", NULL); + CHECK_DEL_REG_STR(props, "HelpTelephone", NULL); + CHECK_DEL_REG_STR(props, "InstallLocation", NULL); + CHECK_DEL_REG_STR(props, "Readme", NULL); + CHECK_DEL_REG_STR(props, "Size", NULL); + CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL); + CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL); + CHECK_DEL_REG_DWORD(props, "Language", 1033); + CHECK_DEL_REG_DWORD(props, "Version", 0x1010001); + CHECK_DEL_REG_DWORD(props, "VersionMajor", 1); + CHECK_DEL_REG_DWORD(props, "VersionMinor", 1); + CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1); + todo_wine + { + CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24); + } + + delete_key(props, "", access); + RegCloseKey(props); + + res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage); + todo_wine + { + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + delete_key(usage, "", access); + RegCloseKey(usage); + delete_key(hkey, "", access); + RegCloseKey(hkey); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); + + delete_key(hkey, "", access); + RegCloseKey(hkey); + + /* RegisterProduct, machine */ + r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST"); + CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1"); + CHECK_DEL_REG_STR(hkey, "InstallDate", date); + CHECK_DEL_REG_STR(hkey, "InstallSource", temp); + CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(hkey, "Publisher", "Wine"); + CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL); + CHECK_DEL_REG_STR(hkey, "Comments", NULL); + CHECK_DEL_REG_STR(hkey, "Contact", NULL); + CHECK_DEL_REG_STR(hkey, "HelpLink", NULL); + CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL); + CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL); + CHECK_DEL_REG_STR(hkey, "Readme", NULL); + CHECK_DEL_REG_STR(hkey, "Size", NULL); + CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL); + CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL); + CHECK_DEL_REG_DWORD(hkey, "Language", 1033); + CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); + CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1); + CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1); + CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24); + } + + delete_key(hkey, "", access); + RegCloseKey(hkey); + + sprintf(keypath, userdata, "S-1-5-18"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = sizeof(path); + RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size); + DeleteFileA(path); + RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */ + + CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST"); + CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1"); + CHECK_DEL_REG_STR(props, "InstallDate", date); + CHECK_DEL_REG_STR(props, "InstallSource", temp); + CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(props, "Publisher", "Wine"); + CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL); + CHECK_DEL_REG_STR(props, "Comments", NULL); + CHECK_DEL_REG_STR(props, "Contact", NULL); + CHECK_DEL_REG_STR(props, "HelpLink", NULL); + CHECK_DEL_REG_STR(props, "HelpTelephone", NULL); + CHECK_DEL_REG_STR(props, "InstallLocation", NULL); + CHECK_DEL_REG_STR(props, "Readme", NULL); + CHECK_DEL_REG_STR(props, "Size", NULL); + CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL); + CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL); + CHECK_DEL_REG_DWORD(props, "Language", 1033); + CHECK_DEL_REG_DWORD(props, "Version", 0x1010001); + CHECK_DEL_REG_DWORD(props, "VersionMajor", 1); + CHECK_DEL_REG_DWORD(props, "VersionMinor", 1); + CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1); + todo_wine + { + CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24); + } + + delete_key(props, "", access); + RegCloseKey(props); + + res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage); + todo_wine + { + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + delete_key(usage, "", access); + RegCloseKey(usage); + delete_key(hkey, "", access); + RegCloseKey(hkey); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); + + delete_key(hkey, "", access); + RegCloseKey(hkey); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + HeapFree(GetProcessHeap(), 0, usersid); +} + +static void test_publish_product(void) +{ + UINT r; + LONG res; + LPSTR usersid; + HKEY sourcelist, net, props; + HKEY hkey, patches, media; + CHAR keypath[MAX_PATH]; + CHAR temp[MAX_PATH]; + CHAR path[MAX_PATH]; + BOOL old_installer = FALSE; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Installer\\UserData\\%s\\Products" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes" + "\\51AAE0C44620A5E4788506E91F249BD2"; + static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Installer\\Products" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR machprod[] = "Software\\Classes\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR machup[] = "Software\\Classes\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2"; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + if (!(usersid = get_user_sid())) + return; + + GetTempPath(MAX_PATH, temp); + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); + + /* PublishProduct, current user */ + r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + sprintf(keypath, prodpath, usersid); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + if (res == ERROR_FILE_NOT_FOUND) + { + res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey); + if (res == ERROR_SUCCESS) + { + win_skip("Windows Installer < 3.0 detected\n"); + RegCloseKey(hkey); + old_installer = TRUE; + goto currentuser; + } + else + { + win_skip("Install failed, no need to continue\n"); + return; + } + } + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches); + todo_wine + { + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_DEL_REG_STR(patches, "AllPatches", NULL); + } + + delete_key(patches, "", access); + RegCloseKey(patches); + delete_key(hkey, "", access); + RegCloseKey(hkey); + +currentuser: + res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST"); + CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F"); + CHECK_DEL_REG_DWORD(hkey, "Language", 1033); + CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); + if (!old_installer) + CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0); + CHECK_DEL_REG_DWORD(hkey, "Assignment", 0); + CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184); + CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0); + CHECK_DEL_REG_STR(hkey, "Clients", ":"); + + res = RegOpenKeyA(hkey, "SourceList", &sourcelist); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + lstrcpyA(path, "n;1;"); + lstrcatA(path, temp); + CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path); + CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi"); + + res = RegOpenKeyA(sourcelist, "Net", &net); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(net, "1", temp); + + RegDeleteKeyA(net, ""); + RegCloseKey(net); + + res = RegOpenKeyA(sourcelist, "Media", &media); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(media, "1", "DISK1;"); + + RegDeleteKeyA(media, ""); + RegCloseKey(media); + RegDeleteKeyA(sourcelist, ""); + RegCloseKey(sourcelist); + RegDeleteKeyA(hkey, ""); + RegCloseKey(hkey); + + res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); + + RegDeleteKeyA(hkey, ""); + RegCloseKey(hkey); + + /* PublishProduct, machine */ + r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1"); + if (old_installer) + goto machprod; + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + sprintf(keypath, prodpath, "S-1-5-18"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches); + todo_wine + { + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_DEL_REG_STR(patches, "AllPatches", NULL); + } + + delete_key(patches, "", access); + RegCloseKey(patches); + delete_key(hkey, "", access); + RegCloseKey(hkey); + +machprod: + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machprod, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST"); + CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F"); + CHECK_DEL_REG_DWORD(hkey, "Language", 1033); + CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); + if (!old_installer) + CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0); + todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1); + CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184); + CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0); + CHECK_DEL_REG_STR(hkey, "Clients", ":"); + + res = RegOpenKeyExA(hkey, "SourceList", 0, access, &sourcelist); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + lstrcpyA(path, "n;1;"); + lstrcatA(path, temp); + CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path); + CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi"); + + res = RegOpenKeyExA(sourcelist, "Net", 0, access, &net); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(net, "1", temp); + + res = delete_key(net, "", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(net); + + res = RegOpenKeyExA(sourcelist, "Media", 0, access, &media); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(media, "1", "DISK1;"); + + res = delete_key(media, "", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(media); + res = delete_key(sourcelist, "", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(sourcelist); + res = delete_key(hkey, "", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(hkey); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machup, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); + + res = delete_key(hkey, "", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(hkey); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + HeapFree(GetProcessHeap(), 0, usersid); +} + +static void test_publish_features(void) +{ + UINT r; + LONG res; + HKEY hkey; + LPSTR usersid; + CHAR keypath[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR udfeatpath[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Installer\\UserData\\%s\\Products" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features"; + static const CHAR udpridpath[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Installer\\UserData\\%s\\Products" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion" + "\\Installer\\Features"; + static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features" + "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + if (!(usersid = get_user_sid())) + return; + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); + + /* PublishFeatures, current user */ + r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(hkey, "feature", ""); + CHECK_REG_STR(hkey, "montecristo", ""); + + RegDeleteValueA(hkey, "feature"); + RegDeleteValueA(hkey, "montecristo"); + delete_key(hkey, "", access); + RegCloseKey(hkey); + + sprintf(keypath, udfeatpath, usersid); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE"); + CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE"); + + RegDeleteValueA(hkey, "feature"); + RegDeleteValueA(hkey, "montecristo"); + delete_key(hkey, "", access); + RegCloseKey(hkey); + sprintf(keypath, udpridpath, usersid); + delete_key(HKEY_LOCAL_MACHINE, keypath, access); + + /* PublishFeatures, machine */ + r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(hkey, "feature", ""); + CHECK_REG_STR(hkey, "montecristo", ""); + + RegDeleteValueA(hkey, "feature"); + RegDeleteValueA(hkey, "montecristo"); + delete_key(hkey, "", access); + RegCloseKey(hkey); + + sprintf(keypath, udfeatpath, "S-1-5-18"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE"); + CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE"); + + RegDeleteValueA(hkey, "feature"); + RegDeleteValueA(hkey, "montecristo"); + delete_key(hkey, "", access); + RegCloseKey(hkey); + sprintf(keypath, udpridpath, "S-1-5-18"); + delete_key(HKEY_LOCAL_MACHINE, keypath, access); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + HeapFree(GetProcessHeap(), 0, usersid); +} + +static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name) +{ + DWORD len = 0; + LPSTR val; + LONG r; + + r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len); + if (r != ERROR_SUCCESS) + return NULL; + + len += sizeof (WCHAR); + val = HeapAlloc(GetProcessHeap(), 0, len); + if (!val) return NULL; + val[0] = 0; + RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len); + return val; +} + +static void get_owner_company(LPSTR *owner, LPSTR *company) +{ + LONG res; + HKEY hkey; + REGSAM access = KEY_ALL_ACCESS; + + *owner = *company = NULL; + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + res = RegOpenKeyA(HKEY_CURRENT_USER, + "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey); + if (res == ERROR_SUCCESS) + { + *owner = reg_get_val_str(hkey, "DefName"); + *company = reg_get_val_str(hkey, "DefCompany"); + RegCloseKey(hkey); + } + + if (!*owner || !*company) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion", 0, access, &hkey); + if (res == ERROR_SUCCESS) + { + *owner = reg_get_val_str(hkey, "RegisteredOwner"); + *company = reg_get_val_str(hkey, "RegisteredOrganization"); + RegCloseKey(hkey); + } + } + + if (!*owner || !*company) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey); + if (res == ERROR_SUCCESS) + { + *owner = reg_get_val_str(hkey, "RegisteredOwner"); + *company = reg_get_val_str(hkey, "RegisteredOrganization"); + RegCloseKey(hkey); + } + } +} + +static void test_register_user(void) +{ + UINT r; + LONG res; + HKEY props; + LPSTR usersid; + LPSTR owner, company; + CHAR keypath[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR keypropsfmt[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" + "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties"; + static const CHAR keypridfmt[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" + "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + if (!(usersid = get_user_sid())) + return; + + get_owner_company(&owner, &company); + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* RegisterUser, per-user */ + r = MsiInstallProductA(msifile, "REGISTER_USER=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + sprintf(keypath, keypropsfmt, usersid); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(props, "ProductID", "none"); + CHECK_REG_STR(props, "RegCompany", company); + CHECK_REG_STR(props, "RegOwner", owner); + + RegDeleteValueA(props, "ProductID"); + RegDeleteValueA(props, "RegCompany"); + RegDeleteValueA(props, "RegOwner"); + delete_key(props, "", access); + RegCloseKey(props); + sprintf(keypath, keypridfmt, usersid); + delete_key(HKEY_LOCAL_MACHINE, keypath, access); + + /* RegisterUser, machine */ + r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + sprintf(keypath, keypropsfmt, "S-1-5-18"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + CHECK_REG_STR(props, "ProductID", "none"); + CHECK_REG_STR(props, "RegCompany", company); + CHECK_REG_STR(props, "RegOwner", owner); + + RegDeleteValueA(props, "ProductID"); + RegDeleteValueA(props, "RegCompany"); + RegDeleteValueA(props, "RegOwner"); + delete_key(props, "", access); + RegCloseKey(props); + sprintf(keypath, keypridfmt, "S-1-5-18"); + delete_key(HKEY_LOCAL_MACHINE, keypath, access); + +error: + HeapFree(GetProcessHeap(), 0, company); + HeapFree(GetProcessHeap(), 0, owner); + + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + LocalFree(usersid); +} + +static void test_process_components(void) +{ + UINT r; + LONG res; + DWORD size; + HKEY comp, hkey; + LPSTR usersid; + CHAR val[MAX_PATH]; + CHAR keypath[MAX_PATH]; + CHAR program_files_maximus[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR keyfmt[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" + "UserData\\%s\\Components\\%s"; + static const CHAR compkey[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components"; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + if (!(usersid = get_user_sid())) + return; + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* ProcessComponents, per-user */ + r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + lstrcpyA(program_files_maximus,PROG_FILES_DIR); + lstrcatA(program_files_maximus,"\\msitest\\maximus"); + + ok(!lstrcmpiA(val, program_files_maximus), + "Expected \"%s\", got \"%s\"\n", program_files_maximus, val); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + delete_key(comp, "", access); + RegCloseKey(comp); + + sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!lstrcmpA(val, "01\\msitest\\augustus"), + "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + delete_key(comp, "", access); + RegCloseKey(comp); + + /* ProcessComponents, machine */ + r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!lstrcmpiA(val, program_files_maximus), + "Expected \"%s\", got \"%s\"\n", program_files_maximus, val); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + delete_key(comp, "", access); + RegCloseKey(comp); + + sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058"); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!lstrcmpA(val, "01\\msitest\\augustus"), + "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + delete_key(comp, "", access); + RegCloseKey(comp); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + LocalFree(usersid); +} + +static void test_publish(void) +{ + UINT r; + LONG res; + HKEY uninstall, prodkey, uninstall_32node = NULL; + INSTALLSTATE state; + CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; + char date[MAX_PATH], temp[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; + + static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + static const CHAR subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + + if (!pMsiQueryComponentStateA) + { + win_skip("MsiQueryComponentStateA is not available\n"); + return; + } + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + get_date_str(date); + GetTempPath(MAX_PATH, temp); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* nothing published */ + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* PublishProduct and RegisterProduct */ + r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + if (is_wow64 && res == ERROR_FILE_NOT_FOUND) /* XP - Vista, Wow64 */ + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24); + } + + RegCloseKey(prodkey); + + r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File deleted\n"); + ok(pf_exists("msitest"), "File deleted\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* complete install */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24); + } + + RegCloseKey(prodkey); + + /* no UnpublishFeatures */ + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); + ok(!pf_exists("msitest"), "Directory not deleted\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* complete install */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24); + } + + RegCloseKey(prodkey); + + /* UnpublishFeatures, only feature removed. Only works when entire product is removed */ + r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File deleted\n"); + ok(pf_exists("msitest"), "Directory deleted\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24); + } + + RegCloseKey(prodkey); + + /* complete install */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -20, 10, 24); + } + + RegCloseKey(prodkey); + + /* UnpublishFeatures, both features removed */ + r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); + ok(!pf_exists("msitest"), "Directory not deleted\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* complete install */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + + if (is_64bit) + { + res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + else + { + res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + } + + CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); + CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); + CHECK_REG_STR(prodkey, "InstallDate", date); + CHECK_REG_STR(prodkey, "InstallSource", temp); + CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "Publisher", "Wine"); + CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); + CHECK_REG_STR(prodkey, "Comments", NULL); + CHECK_REG_STR(prodkey, "Contact", NULL); + CHECK_REG_STR(prodkey, "HelpLink", NULL); + CHECK_REG_STR(prodkey, "HelpTelephone", NULL); + CHECK_REG_STR(prodkey, "InstallLocation", NULL); + CHECK_REG_STR(prodkey, "Readme", NULL); + CHECK_REG_STR(prodkey, "Size", NULL); + CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); + CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); + CHECK_REG_DWORD(prodkey, "Language", 1033); + CHECK_REG_DWORD(prodkey, "Version", 0x1010001); + CHECK_REG_DWORD(prodkey, "VersionMajor", 1); + CHECK_REG_DWORD(prodkey, "VersionMinor", 1); + CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); + todo_wine + { + CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24); + } + + RegCloseKey(prodkey); + + /* complete uninstall */ + r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); + ok(!pf_exists("msitest"), "Directory not deleted\n"); + + state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + /* make sure 'Program Files\msitest' is removed */ + delete_pfmsitest_files(); + +error: + RegCloseKey(uninstall); + RegCloseKey(uninstall_32node); + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); +} + +static void test_publish_sourcelist(void) +{ + UINT r; + DWORD size; + CHAR value[MAX_PATH]; + CHAR path[MAX_PATH]; + CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; + + if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA) + { + win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n"); + return; + } + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + + create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + /* nothing published */ + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + /* after RegisterProduct */ + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + /* after ProcessComponents */ + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + /* after PublishFeatures */ + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); + + r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\maximus"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + /* after PublishProduct */ + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value); + ok(size == 11, "Expected 11, got %d\n", size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value); + ok(size == 0, "Expected 0, got %d\n", size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value); + ok(size == 0, "Expected 0, got %d\n", size); + + lstrcpyA(path, CURR_DIR); + lstrcatA(path, "\\"); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); + ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value); + ok(size == 1, "Expected 1, got %d\n", size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); + ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); + ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); + ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); + ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); + + size = MAX_PATH; + lstrcpyA(value, "aaa"); + r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size); + ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); + ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); + ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); + + /* complete uninstall */ + r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); + ok(!pf_exists("msitest"), "Directory not deleted\n"); + + /* make sure 'Program Files\msitest' is removed */ + delete_pfmsitest_files(); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); +} + +static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file) +{ + CHAR path[MAX_PATH]; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, file); + + if (is_file) + create_file_data(path, data, 500); + else + CreateDirectoryA(path, NULL); +} + +#define create_pf(file, is_file) create_pf_data(file, file, is_file) + +static void test_remove_files(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\hydrogen", 500); + create_file("msitest\\helium", 500); + create_file("msitest\\lithium", 500); + + create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); + ok(!pf_exists("msitest\\helium"), "File installed\n"); + ok(pf_exists("msitest\\lithium"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n"); + ok(!pf_exists("msitest\\helium"), "File not deleted\n"); + ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); + ok(delete_pf("msitest", FALSE), "Directory deleted\n"); + + create_pf("msitest", FALSE); + create_pf("msitest\\hydrogen", TRUE); + create_pf("msitest\\helium", TRUE); + create_pf("msitest\\lithium", TRUE); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); + ok(pf_exists("msitest\\helium"), "File not installed\n"); + ok(pf_exists("msitest\\lithium"), "File not installed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n"); + ok(delete_pf("msitest\\helium", TRUE), "File deleted\n"); + ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); + ok(delete_pf("msitest", FALSE), "Directory deleted\n"); + + create_pf("msitest", FALSE); + create_pf("msitest\\furlong", TRUE); + create_pf("msitest\\firkin", TRUE); + create_pf("msitest\\fortnight", TRUE); + create_pf("msitest\\becquerel", TRUE); + create_pf("msitest\\dioptre", TRUE); + create_pf("msitest\\attoparsec", TRUE); + create_pf("msitest\\storeys", TRUE); + create_pf("msitest\\block", TRUE); + create_pf("msitest\\siriometer", TRUE); + create_pf("msitest\\cabout", FALSE); + create_pf("msitest\\cabout\\blocker", TRUE); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); + ok(!pf_exists("msitest\\helium"), "File installed\n"); + ok(pf_exists("msitest\\lithium"), "File not installed\n"); + ok(!pf_exists("msitest\\furlong"), "File not deleted\n"); + ok(!pf_exists("msitest\\firkin"), "File not deleted\n"); + ok(!pf_exists("msitest\\fortnight"), "File not deleted\n"); + ok(pf_exists("msitest\\becquerel"), "File not installed\n"); + ok(pf_exists("msitest\\dioptre"), "File not installed\n"); + ok(pf_exists("msitest\\attoparsec"), "File not installed\n"); + ok(!pf_exists("msitest\\storeys"), "File not deleted\n"); + ok(!pf_exists("msitest\\block"), "File not deleted\n"); + ok(!pf_exists("msitest\\siriometer"), "File not deleted\n"); + ok(pf_exists("msitest\\cabout"), "Directory removed\n"); + ok(pf_exists("msitest"), "File not installed\n"); + + create_pf("msitest\\furlong", TRUE); + create_pf("msitest\\firkin", TRUE); + create_pf("msitest\\fortnight", TRUE); + create_pf("msitest\\storeys", TRUE); + create_pf("msitest\\block", TRUE); + create_pf("msitest\\siriometer", TRUE); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n"); + ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n"); + ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); + ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n"); + ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n"); + ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n"); + ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n"); + ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n"); + ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n"); + ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n"); + ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n"); + ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n"); + ok(pf_exists("msitest\\cabout"), "Directory deleted\n"); + ok(pf_exists("msitest"), "Directory deleted\n"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n"); + ok(!delete_pf("msitest\\helium", TRUE), "File installed\n"); + ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n"); + ok(pf_exists("msitest\\cabout"), "Directory deleted\n"); + ok(pf_exists("msitest"), "Directory deleted\n"); + + delete_pf("msitest\\cabout\\blocker", TRUE); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n"); + delete_pf("msitest", FALSE); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\hydrogen"); + DeleteFile("msitest\\helium"); + DeleteFile("msitest\\lithium"); + RemoveDirectory("msitest"); +} + +static void test_move_files(void) +{ + UINT r; + char props[MAX_PATH]; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\augustus", 100); + create_file("cameroon", 100); + create_file("djibouti", 100); + create_file("egypt", 100); + create_file("finland", 100); + create_file("gambai", 100); + create_file("honduras", 100); + create_file("msitest\\india", 100); + create_file("japan", 100); + create_file("kenya", 100); + CreateDirectoryA("latvia", NULL); + create_file("nauru", 100); + create_file("peru", 100); + create_file("apple", 100); + create_file("application", 100); + create_file("ape", 100); + create_file("foo", 100); + create_file("fao", 100); + create_file("fbod", 100); + create_file("budding", 100); + create_file("buddy", 100); + create_file("bud", 100); + create_file("bar", 100); + create_file("bur", 100); + create_file("bird", 100); + + create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* if the source or dest property is not a full path, + * windows tries to access it as a network resource + */ + + sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" " + "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"", + CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR); + + r = MsiInstallProductA(msifile, props); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); + ok(!delete_pf("msitest\\dest", TRUE), "File copied\n"); + ok(delete_pf("msitest\\canada", TRUE), "File not copied\n"); + ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n"); + ok(!delete_pf("msitest\\france", TRUE), "File moved\n"); + ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n"); + ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n"); + ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n"); + ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n"); + ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n"); + ok(delete_pf("msitest\\poland", TRUE), "File not moved\n"); + /* either apple or application will be moved depending on directory order */ + if (!delete_pf("msitest\\apple", TRUE)) + ok(delete_pf("msitest\\application", TRUE), "File not moved\n"); + else + ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n"); + ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\ape", TRUE), "File moved\n"); + /* either fao or foo will be moved depending on directory order */ + if (delete_pf("msitest\\foo", TRUE)) + ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n"); + else + ok(delete_pf("msitest\\fao", TRUE), "File not moved\n"); + ok(delete_pf("msitest\\single", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n"); + ok(delete_pf("msitest\\budding", TRUE), "File not moved\n"); + ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\bud", TRUE), "File moved\n"); + ok(delete_pf("msitest\\bar", TRUE), "File not moved\n"); + ok(delete_pf("msitest\\bur", TRUE), "File not moved\n"); + ok(!delete_pf("msitest\\bird", TRUE), "File moved\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + ok(DeleteFileA("cameroon"), "File moved\n"); + ok(!DeleteFileA("djibouti"), "File not moved\n"); + ok(DeleteFileA("egypt"), "File moved\n"); + ok(DeleteFileA("finland"), "File moved\n"); + ok(DeleteFileA("gambai"), "File moved\n"); + ok(!DeleteFileA("honduras"), "File not moved\n"); + ok(DeleteFileA("msitest\\india"), "File moved\n"); + ok(DeleteFileA("japan"), "File moved\n"); + ok(!DeleteFileA("kenya"), "File not moved\n"); + ok(RemoveDirectoryA("latvia"), "Directory moved\n"); + ok(!DeleteFileA("nauru"), "File not moved\n"); + ok(!DeleteFileA("peru"), "File not moved\n"); + ok(!DeleteFileA("apple"), "File not moved\n"); + ok(!DeleteFileA("application"), "File not moved\n"); + ok(DeleteFileA("ape"), "File moved\n"); + ok(!DeleteFileA("foo"), "File not moved\n"); + ok(!DeleteFileA("fao"), "File not moved\n"); + ok(DeleteFileA("fbod"), "File moved\n"); + ok(!DeleteFileA("budding"), "File not moved\n"); + ok(!DeleteFileA("buddy"), "File not moved\n"); + ok(DeleteFileA("bud"), "File moved\n"); + ok(!DeleteFileA("bar"), "File not moved\n"); + ok(!DeleteFileA("bur"), "File not moved\n"); + ok(DeleteFileA("bird"), "File moved\n"); + +error: + DeleteFile("cameroon"); + DeleteFile("djibouti"); + DeleteFile("egypt"); + DeleteFile("finland"); + DeleteFile("gambai"); + DeleteFile("honduras"); + DeleteFile("japan"); + DeleteFile("kenya"); + DeleteFile("nauru"); + DeleteFile("peru"); + DeleteFile("apple"); + DeleteFile("application"); + DeleteFile("ape"); + DeleteFile("foo"); + DeleteFile("fao"); + DeleteFile("fbod"); + DeleteFile("budding"); + DeleteFile("buddy"); + DeleteFile("bud"); + DeleteFile("bar"); + DeleteFile("bur"); + DeleteFile("bird"); + DeleteFile("msitest\\india"); + DeleteFile("msitest\\augustus"); + RemoveDirectory("latvia"); + RemoveDirectory("msitest"); + DeleteFile(msifile); +} + +static void test_duplicate_files(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* fails if the destination folder is not a valid property */ + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n"); + ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n"); + ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\this\\doesnot", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\this", FALSE), "Directory not created\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); + DeleteFile(msifile); +} + +static void test_write_registry_values(void) +{ + UINT r; + LONG res; + HKEY hkey; + DWORD type, size; + CHAR path[MAX_PATH]; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\augustus", 500); + + create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + if (is_64bit) + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey); + else + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + size = MAX_PATH; + type = REG_MULTI_SZ; + memset(path, 'a', MAX_PATH); + res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n"); + ok(size == 15, "Expected 15, got %d\n", size); + ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type); + + RegDeleteValueA(hkey, "Value"); + RegCloseKey(hkey); + RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); + +error: + DeleteFile(msifile); + DeleteFile("msitest\\augustus"); + RemoveDirectory("msitest"); +} + +static void test_envvar(void) +{ + static const char *results[] = + { + "1;2", /* MSITESTVAR11 */ + "1", /* MSITESTVAR12 */ + "1;2", /* MSITESTVAR13 */ + ";1;", /* MSITESTVAR14 */ + ";;1;;", /* MSITESTVAR15 */ + " 1 ", /* MSITESTVAR16 */ + ";;2;;1", /* MSITESTVAR17 */ + "1;;2;;", /* MSITESTVAR18 */ + "1", /* MSITESTVAR19 */ + "1", /* MSITESTVAR20 */ + NULL + }; + UINT r; + HKEY env; + LONG res; + DWORD type, size; + char buffer[16]; + UINT i; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table)); + + res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + type = REG_NONE; + size = sizeof(buffer); + buffer[0] = 0; + res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer); + + res = RegDeleteValueA(env, "MSITESTVAR1"); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + type = REG_NONE; + size = sizeof(buffer); + buffer[0] = 0; + res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer); + + res = RegDeleteValueA(env, "MSITESTVAR2"); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR3"); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR4"); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR5"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR6"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR7"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR8"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR9"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR10"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + i = 11; + while (results[i - 11]) + { + char name[20]; + sprintf(name, "MSITESTVAR%d", i); + + type = REG_NONE; + size = sizeof(buffer); + buffer[0] = 0; + res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res); + ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type); + ok(!lstrcmp(buffer, results[i - 11]), "%d: Expected %s, got %s\n", i, results[i - 11], buffer); + + res = RegDeleteValueA(env, name); + ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res); + i++; + } + + delete_pf("msitest\\cabout\\new\\five.txt", TRUE); + delete_pf("msitest\\cabout\\new", FALSE); + delete_pf("msitest\\cabout\\four.txt", TRUE); + delete_pf("msitest\\cabout", FALSE); + delete_pf("msitest\\changed\\three.txt", TRUE); + delete_pf("msitest\\changed", FALSE); + delete_pf("msitest\\first\\two.txt", TRUE); + delete_pf("msitest\\first", FALSE); + delete_pf("msitest\\filename", TRUE); + delete_pf("msitest\\one.txt", TRUE); + delete_pf("msitest\\service.exe", TRUE); + delete_pf("msitest", FALSE); + +error: + RegDeleteValueA(env, "MSITESTVAR1"); + RegDeleteValueA(env, "MSITESTVAR2"); + RegCloseKey(env); + + delete_test_files(); + DeleteFile(msifile); +} + +static void test_create_remove_folder(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + CreateDirectoryA("msitest\\first", NULL); + CreateDirectoryA("msitest\\second", NULL); + create_file("msitest\\first\\one.txt", 1000); + create_file("msitest\\second\\two.txt", 1000); + create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(pf_exists("msitest\\first\\one.txt"), "file not installed\n"); + ok(pf_exists("msitest\\first"), "directory not created\n"); + ok(pf_exists("msitest\\second\\two.txt"), "file not installed\n"); + ok(pf_exists("msitest\\second"), "directory not created\n"); + ok(pf_exists("msitest\\third"), "directory not created\n"); + ok(pf_exists("msitest"), "directory not created\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!pf_exists("msitest\\first\\one.txt"), "file not removed\n"); + ok(!pf_exists("msitest\\first"), "directory not removed\n"); + ok(!pf_exists("msitest\\second\\two.txt"), "file not removed\n"); + ok(!pf_exists("msitest\\second"), "directory not removed\n"); + ok(!pf_exists("msitest\\third"), "directory not removed\n"); + todo_wine ok(!pf_exists("msitest"), "directory not removed\n"); + +error: + DeleteFileA("msitest\\first\\one.txt"); + DeleteFileA("msitest\\second\\two.txt"); + RemoveDirectoryA("msitest\\first"); + RemoveDirectoryA("msitest\\second"); + RemoveDirectoryA("msitest"); + DeleteFile(msifile); +} + +static void test_start_services(void) +{ + UINT r; + SC_HANDLE scm, service; + BOOL ret; + DWORD error = ERROR_SUCCESS; + + scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (!scm && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } + ok(scm != NULL, "Failed to open the SC Manager\n"); + if (!scm) return; + + service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS); + if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) + { + win_skip("The 'Spooler' service does not exist\n"); + CloseServiceHandle(scm); + return; + } + ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError()); + if (!service) { + CloseServiceHandle(scm); + return; + } + + ret = StartService(service, 0, NULL); + if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING) + { + skip("Spooler service not available, skipping test\n"); + CloseServiceHandle(service); + CloseServiceHandle(scm); + return; + } + + CloseServiceHandle(service); + CloseServiceHandle(scm); + + create_test_files(); + create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + + delete_test_files(); + DeleteFile(msifile); + + if (error == ERROR_SUCCESS) + { + SERVICE_STATUS status; + + scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS); + + ret = ControlService(service, SERVICE_CONTROL_STOP, &status); + ok(ret, "ControlService failed %u\n", GetLastError()); + + CloseServiceHandle(service); + CloseServiceHandle(scm); + } +} + +static void test_delete_services(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: + delete_test_files(); + DeleteFile(msifile); +} + +static void test_self_registration(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: + delete_test_files(); + DeleteFile(msifile); +} + +static void test_register_font(void) +{ + static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; + static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"; + LONG ret; + HKEY key; + UINT r; + REGSAM access = KEY_ALL_ACCESS; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\font.ttf", 1000); + create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont1, 0, access, &key); + if (ret) + RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont2, 0, access, &key); + + ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL); + ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret); + + RegDeleteValueA(key, "msi test font"); + RegCloseKey(key); + +error: + DeleteFileA("msitest\\font.ttf"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_validate_product_id(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "PIDKEY=123-1234567"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: + delete_test_files(); + DeleteFile(msifile); +} + +static void test_install_remove_odbc(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\ODBCdriver.dll", 1000); + create_file("msitest\\ODBCdriver2.dll", 1000); + create_file("msitest\\ODBCtranslator.dll", 1000); + create_file("msitest\\ODBCtranslator2.dll", 1000); + create_file("msitest\\ODBCsetup.dll", 1000); + create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n"); + ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n"); + ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n"); + ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n"); + ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\ODBCdriver.dll"); + DeleteFileA("msitest\\ODBCdriver2.dll"); + DeleteFileA("msitest\\ODBCtranslator.dll"); + DeleteFileA("msitest\\ODBCtranslator2.dll"); + DeleteFileA("msitest\\ODBCsetup.dll"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_register_typelib(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\typelib.dll", 1000); + create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\typelib.dll"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_create_remove_shortcut(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\target.txt", 1000); + create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(pf_exists("msitest\\target.txt"), "file not created\n"); + ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n"); + todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\target.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_publish_components(void) +{ + static char keypath[] = + "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA"; + + UINT r; + LONG res; + HKEY key; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\english.txt", 1000); + create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key); + ok(res == ERROR_SUCCESS, "components key not created %d\n", res); + + res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL); + ok(res == ERROR_SUCCESS, "value not found %d\n", res); + RegCloseKey(key); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key); + ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res); + + ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\english.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_remove_duplicate_files(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\original.txt", 1000); + create_file("msitest\\original2.txt", 1000); + create_file("msitest\\original3.txt", 1000); + create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(pf_exists("msitest\\original.txt"), "file not created\n"); + ok(pf_exists("msitest\\original2.txt"), "file not created\n"); + ok(!pf_exists("msitest\\original3.txt"), "file created\n"); + ok(pf_exists("msitest\\duplicate.txt"), "file not created\n"); + ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n"); + ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n"); + ok(delete_pf("msitest", FALSE), "directory removed\n"); + +error: + DeleteFileA("msitest\\original.txt"); + DeleteFileA("msitest\\original2.txt"); + DeleteFileA("msitest\\original3.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_remove_registry_values(void) +{ + UINT r; + LONG res; + HKEY key; + REGSAM access = KEY_ALL_ACCESS; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\registry.txt", 1000); + create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table)); + + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, NULL, 0, access, NULL, &key, NULL); + RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2); + RegCloseKey(key); + + RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL); + RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2); + RegCloseKey(key); + + RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, NULL, 0, access, NULL, &key, NULL); + RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8); + RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2); + RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2); + RegCloseKey(key); + + RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, NULL, 0, access, NULL, &key, NULL); + RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8); + RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2); + RegCloseKey(key); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, access, &key); + ok(res == ERROR_SUCCESS, "key removed\n"); + RegCloseKey(key); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key2", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + else + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(key); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key1", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + else + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, access, &key); + ok(res == ERROR_SUCCESS, "key removed\n"); + RegCloseKey(key); + + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, access, &key); + ok(res == ERROR_SUCCESS, "key removed\n"); + RegCloseKey(key); + + if (is_64bit) + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + else + { + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + } + + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access); + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access); + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine", access); + + ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", access); + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access); + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access); + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", access); + + DeleteFileA("msitest\\registry.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_find_related_products(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\product.txt", 1000); + create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* install again, so it finds the upgrade code */ + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\product.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_remove_ini_values(void) +{ + UINT r; + DWORD len; + char inifile[MAX_PATH], buf[0x10]; + HANDLE file; + BOOL ret; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\inifile.txt", 1000); + create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table)); + + lstrcpyA(inifile, PROG_FILES_DIR); + lstrcatA(inifile, "\\msitest"); + ret = CreateDirectoryA(inifile, NULL); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + lstrcatA(inifile, "\\test.ini"); + file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL); + CloseHandle(file); + + ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile); + ok(ret, "failed to write profile string %u\n", GetLastError()); + + ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile); + ok(ret, "failed to write profile string %u\n", GetLastError()); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile); + ok(len == 6, "got %u expected 6\n", len); + + len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile); + ok(!len, "got %u expected 0\n", len); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile); + ok(!len, "got %u expected 0\n", len); + + len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile); + ok(!len, "got %u expected 0\n", len); + + todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n"); + ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n"); + ok(delete_pf("msitest", FALSE), "directory removed\n"); + +error: + DeleteFileA("msitest\\inifile.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_remove_env_strings(void) +{ + UINT r; + LONG res; + HKEY key; + DWORD type, size; + char buffer[0x10]; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\envvar.txt", 1000); + create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); + ok(!res, "failed to open environment key %d\n", res); + + RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2); + RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2); + RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2); + RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2); + RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2); + + RegCloseKey(key); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); + ok(!res, "failed to open environment key %d\n", res); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + + RegCloseKey(key); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); + ok(!res, "failed to open environment key %d\n", res); + + res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + RegDeleteValueA(key, "MSITESTVAR3"); + + res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + type = REG_NONE; + buffer[0] = 0; + size = sizeof(buffer); + res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); + ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); + RegDeleteValueA(key, "MSITESTVAR5"); + + ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + RegDeleteValueA(key, "MSITESTVAR1"); + RegDeleteValueA(key, "MSITESTVAR2"); + RegDeleteValueA(key, "MSITESTVAR3"); + RegDeleteValueA(key, "MSITESTVAR4"); + RegDeleteValueA(key, "MSITESTVAR5"); + RegCloseKey(key); + + DeleteFileA("msitest\\envvar.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_register_class_info(void) +{ + UINT r; + LONG res; + HKEY hkey; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\class.txt", 1000); + create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + if (is_64bit) + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + else + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + if (is_64bit) + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + else + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\class.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_register_extension_info(void) +{ + UINT r; + LONG res; + HKEY hkey; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\extension.txt", 1000); + create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\extension.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_register_mime_info(void) +{ + UINT r; + LONG res; + HKEY hkey; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\mime.txt", 1000); + create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey); + ok(res == ERROR_SUCCESS, "key not created\n"); + RegCloseKey(hkey); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); + + ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + +error: + DeleteFileA("msitest\\mime.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +static void test_publish_assemblies(void) +{ + static const char manifest[] = + ""; + static const char manifest_local[] = + ""; + static const char classes_path_dotnet[] = + "Installer\\Assemblies\\Global"; + static const char classes_path_dotnet_local[] = + "Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt"; + static const char classes_path_dotnet_local_wow64[] = + "Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt"; + static const char classes_path_win32[] = + "Installer\\Win32Assemblies\\Global"; + static const char classes_path_win32_local[] = + "Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt"; + static const char classes_path_win32_local_wow64[] = + "Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt"; + static const char path_dotnet[] = + "Software\\Microsoft\\Installer\\Assemblies\\Global"; + static const char path_dotnet_local[] = + "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt"; + static const char path_dotnet_local_wow64[] = + "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt"; + static const char path_win32[] = + "Software\\Microsoft\\Installer\\Win32Assemblies\\Global"; + static const char path_win32_local[] = + "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt"; + static const char path_win32_local_wow64[] = + "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt"; + static const char name_dotnet[] = + "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\"," + "version=\"1.0.0.0\",culture=\"neutral\""; + static const char name_dotnet_local[] = + "Wine.Dotnet.Local.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\"," + "version=\"1.0.0.0\",culture=\"neutral\""; + static const char name_win32[] = + "Wine.Win32.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\"," + "type=\"win32\",version=\"1.0.0.0\""; + static const char name_win32_local[] = + "Wine.Win32.Local.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\"," + "type=\"win32\",version=\"1.0.0.0\""; + UINT r; + LONG res; + HKEY hkey; + const char *path; + int access; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\win32.txt", 1000); + create_file("msitest\\win32_local.txt", 1000); + create_file("msitest\\dotnet.txt", 1000); + create_file("msitest\\dotnet_local.txt", 1000); + create_file_data("msitest\\manifest.txt", manifest, 0); + create_file_data("msitest\\manifest_local.txt", manifest_local, 0); + create_file("msitest\\application_win32.txt", 1000); + create_file("msitest\\application_dotnet.txt", 1000); + create_database(msifile, pa_tables, sizeof(pa_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto done; + } + if (r == ERROR_INSTALL_FAILURE) + { + skip("No support for installing side-by-side assemblies\n"); + goto done; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]"); + RegCloseKey(hkey); + + path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local; + res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox"); + RegCloseKey(hkey); + + res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */, + "Expected ERROR_SUCCESS, got %d\n", res); + if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%"); + RegCloseKey(hkey); + + path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local; + res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */, + "Expected ERROR_SUCCESS, got %d\n", res); + if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!"); + RegCloseKey(hkey); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res); + if (res == ERROR_SUCCESS) + { + res = RegDeleteValueA(hkey, name_dotnet); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegCloseKey(hkey); + } + + path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local; + res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res); + if (res == ERROR_SUCCESS) + { + res = RegDeleteValueA(hkey, name_win32); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegCloseKey(hkey); + } + + path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local; + res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + r = MsiInstallProductA(msifile, "ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + access = KEY_QUERY_VALUE; + res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey); + if (res == ERROR_FILE_NOT_FOUND && is_wow64) /* Vista WOW64 */ + { + trace("Using 64-bit registry view for HKCR\\Installer\n"); + access = KEY_QUERY_VALUE | KEY_WOW64_64KEY; + res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey); + } + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]"); + RegCloseKey(hkey); + + path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local; + res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox"); + RegCloseKey(hkey); + + res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_win32, 0, access, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */, + "Expected ERROR_SUCCESS, got %d\n", res); + if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%"); + RegCloseKey(hkey); + + path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local; + res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */, + "Expected ERROR_SUCCESS, got %d\n", res); + if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!"); + RegCloseKey(hkey); + + r = MsiInstallProductA(msifile, "REMOVE=ALL ALLUSERS=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_dotnet, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res); + if (res == ERROR_SUCCESS) + { + res = RegDeleteValueA(hkey, name_dotnet); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegCloseKey(hkey); + } + + path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local; + res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_win32, &hkey); + ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res); + if (res == ERROR_SUCCESS) + { + res = RegDeleteValueA(hkey, name_win32); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegCloseKey(hkey); + } + + path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local; + res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + +done: + DeleteFileA("msitest\\win32.txt"); + DeleteFileA("msitest\\win32_local.txt"); + DeleteFileA("msitest\\dotnet.txt"); + DeleteFileA("msitest\\dotnet_local.txt"); + DeleteFileA("msitest\\manifest.txt"); + DeleteFileA("msitest\\manifest_local.txt"); + DeleteFileA("msitest\\application_win32.txt"); + DeleteFileA("msitest\\application_dotnet.txt"); + delete_test_files(); + DeleteFile(msifile); +} + +START_TEST(action) +{ + DWORD len; + char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH]; + STATEMGRSTATUS status; + BOOL ret = FALSE; + + init_functionpointers(); + + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + + GetCurrentDirectoryA(MAX_PATH, prev_path); + GetTempPath(MAX_PATH, temp_path); + SetCurrentDirectoryA(temp_path); + + lstrcpyA(CURR_DIR, temp_path); + len = lstrlenA(CURR_DIR); + + if(len && (CURR_DIR[len - 1] == '\\')) + CURR_DIR[len - 1] = 0; + + ok(get_system_dirs(), "failed to retrieve system dirs\n"); + ok(get_user_dirs(), "failed to retrieve user dirs\n"); + + /* Create a restore point ourselves so we circumvent the multitude of restore points + * that would have been created by all the installation and removal tests. + * + * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the + * creation of restore points. + */ + if (pSRSetRestorePointA && !pMsiGetComponentPathExA) + { + memset(&status, 0, sizeof(status)); + ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status); + } + + /* Create only one log file and don't append. We have to pass something + * for the log mode for this to work. The logfile needs to have an absolute + * path otherwise we still end up with some extra logfiles as some tests + * change the current directory. + */ + lstrcpyA(log_file, temp_path); + lstrcatA(log_file, "\\msitest.log"); + MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0); + + test_register_product(); + test_publish_product(); + test_publish_features(); + test_register_user(); + test_process_components(); + test_publish(); + test_publish_sourcelist(); + test_remove_files(); + test_move_files(); + test_duplicate_files(); + test_write_registry_values(); + test_envvar(); + test_create_remove_folder(); + test_start_services(); + test_delete_services(); + test_self_registration(); + test_register_font(); + test_validate_product_id(); + test_install_remove_odbc(); + test_register_typelib(); + test_create_remove_shortcut(); + test_publish_components(); + test_remove_duplicate_files(); + test_remove_registry_values(); + test_find_related_products(); + test_remove_ini_values(); + test_remove_env_strings(); + test_register_class_info(); + test_register_extension_info(); + test_register_mime_info(); + test_publish_assemblies(); + + DeleteFileA(log_file); + + if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) + { + ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status); + if (ret) + remove_restore_point(status.llSequenceNumber); + } + FreeLibrary(hsrclient); + + SetCurrentDirectoryA(prev_path); +} diff --git a/rostests/winetests/msi/automation.c b/rostests/winetests/msi/automation.c index bad4882fac7..8ae18bd9511 100644 --- a/rostests/winetests/msi/automation.c +++ b/rostests/winetests/msi/automation.c @@ -32,16 +32,22 @@ #include "wine/test.h" +static BOOL is_wow64; + +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static const char *msifile = "winetest-automation.msi"; static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','-','a','u','t','o','m','a','t','i','o','n','.','m','s','i',0}; static const WCHAR szMSITEST[] = { 'M','S','I','T','E','S','T',0 }; -static const WCHAR szProductCode[] = { '{','F','1','C','3','A','F','5','0','-','8','B','5','6','-','4','A','6','9','-','A','0','0','C','-','0','0','7','7','3','F','E','4','2','F','3','0','}',0 }; +static const WCHAR szProductCode[] = { '{','8','3','7','4','5','0','f','a','-','a','3','9','b','-','4','b','c','8','-','b','3','2','1','-','0','8','b','3','9','3','f','7','8','4','b','3','}',0 }; static const WCHAR szUpgradeCode[] = { '{','C','E','0','6','7','E','8','D','-','2','E','1','A','-','4','3','6','7','-','B','7','3','4','-','4','E','B','2','B','D','A','D','6','5','6','5','}',0 }; static const WCHAR szProductInfoException[] = { 'P','r','o','d','u','c','t','I','n','f','o',',','P','r','o','d','u','c','t',',','A','t','t','r','i','b','u','t','e',0 }; static const WCHAR WINE_INSTALLPROPERTY_PACKAGENAMEW[] = {'P','a','c','k','a','g','e','N','a','m','e',0}; static const WCHAR WINE_INSTALLPROPERTY_PRODUCTNAMEW[] = {'P','r','o','d','u','c','t','N','a','m','e',0}; +static const WCHAR WINE_INSTALLPROPERTY_LOCALPACKAGEW[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0}; static FILETIME systemtime; static CHAR CURR_DIR[MAX_PATH]; static EXCEPINFO excepinfo; @@ -74,7 +80,7 @@ static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" "MSITESTDIR\tProgramFilesFolder\tmsitest\n" "NEWDIR\tCABOUTDIR\tnew\n" "ProgramFilesFolder\tTARGETDIR\t.\n" - "TARGETDIR\t\tSourceDir"; + "TARGETDIR\t\tSourceDir\n"; static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" @@ -120,7 +126,7 @@ static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "InstallInitialize\t\t1500\n" "InstallValidate\t\t1400\n" "LaunchConditions\t\t100\n" - "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000"; + "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000\n"; static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" "i2\ti4\tL64\tS255\tS32\tS72\n" @@ -136,22 +142,23 @@ static const CHAR property_dat[] = "Property\tValue\n" "InstallMode\tTypical\n" "Manufacturer\tWine\n" "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" - "ProductCode\t{F1C3AF50-8B56-4A69-A00C-00773FE42F30}\n" + "ProductCode\t{837450fa-a39b-4bc8-b321-08b393f784b3}\n" "ProductID\tnone\n" "ProductLanguage\t1033\n" "ProductName\tMSITEST\n" "ProductVersion\t1.1.1\n" "PROMPTROLLBACKCOST\tP\n" "Setup\tSetup\n" - "UpgradeCode\t{CE067E8D-2E1A-4367-B734-4EB2BDAD6565}"; + "UpgradeCode\t{CE067E8D-2E1A-4367-B734-4EB2BDAD6565}\n" + "MSIFASTINSTALL\t1\n"; static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" "s72\ti2\tl255\tL255\tL0\ts72\n" "Registry\tRegistry\n" - "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n" - "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n" - "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n" - "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent"; + "Apples\t1\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n" + "Oranges\t1\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n" + "regdata\t1\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n" + "OrderTest\t1\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent\n"; typedef struct _msi_table { @@ -199,6 +206,29 @@ static const msi_summary_info summary_info[] = ADD_INFO_FILETIME(PID_LASTPRINTED, &systemtime) }; +static void init_functionpointers(void) +{ + HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + +#define GET_PROC(dll, func) \ + p ## func = (void *)GetProcAddress(dll, #func); \ + if(!p ## func) \ + trace("GetProcAddress(%s) failed\n", #func); + + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hkernel32, IsWow64Process) + +#undef GET_PROC +} + +static LONG delete_key_portable( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + /* * Database Helpers */ @@ -273,6 +303,7 @@ static void create_database(const CHAR *name, const msi_table *tables, int num_t static BOOL create_package(LPWSTR path) { + static const WCHAR slashW[] = {'\\',0}; DWORD len; /* Prepare package */ @@ -286,9 +317,8 @@ static BOOL create_package(LPWSTR path) if (!len) return FALSE; - /* lstrcatW does not work on win95 */ - path[len - 1] = '\\'; - memcpy(&path[len], szMsifile, sizeof(szMsifile)); + lstrcatW(path, slashW); + lstrcatW(path, szMsifile); return TRUE; } @@ -386,17 +416,6 @@ static void delete_test_files(void) /* ok-like statement which takes two unicode strings or one unicode and one ANSI string as arguments */ static CHAR string1[MAX_PATH], string2[MAX_PATH]; -/* lstrcmpW is not supported on Win9x */ -static int strcmp_ww(const WCHAR* str1, const WCHAR* str2) -{ - CHAR str1A[MAX_PATH], str2A[MAX_PATH]; - - WideCharToMultiByte(CP_ACP, 0, str1, -1, str1A, MAX_PATH, NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, str2, -1, str2A, MAX_PATH, NULL, NULL); - - return lstrcmpA(str1A, str2A); -} - #define ok_w2(format, szString1, szString2) \ \ do { \ @@ -460,7 +479,7 @@ static DISPID get_dispid( IDispatch *disp, const char *name ) str = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR) ); if (str) { - len = MultiByteToWideChar(CP_ACP, 0, name, -1, str, len ); + MultiByteToWideChar(CP_ACP, 0, name, -1, str, len ); r = IDispatch_GetIDsOfNames( disp, &IID_NULL, &str, 1, 0, &id ); HeapFree(GetProcessHeap(), 0, str); if (r != S_OK) @@ -470,113 +489,79 @@ static DISPID get_dispid( IDispatch *disp, const char *name ) return id; } +typedef struct { + DISPID did; + const char *name; + BOOL todo; +} get_did_t; + +static const get_did_t get_did_data[] = { + { 1, "CreateRecord" }, + { 2, "OpenPackage" }, + { 3, "OpenProduct" }, + { 4, "OpenDatabase" }, + { 5, "SummaryInformation" }, + { 6, "UILevel" }, + { 7, "EnableLog" }, + { 8, "InstallProduct" }, + { 9, "Version" }, + { 10, "LastErrorRecord" }, + { 11, "RegistryValue" }, + { 12, "Environment" }, + { 13, "FileAttributes" }, + { 15, "FileSize" }, + { 16, "FileVersion" }, + { 17, "ProductState" }, + { 18, "ProductInfo" }, + { 19, "ConfigureProduct", TRUE }, + { 20, "ReinstallProduct", TRUE }, + { 21, "CollectUserInfo", TRUE }, + { 22, "ApplyPatch", TRUE }, + { 23, "FeatureParent", TRUE }, + { 24, "FeatureState", TRUE }, + { 25, "UseFeature", TRUE }, + { 26, "FeatureUsageCount", TRUE }, + { 27, "FeatureUsageDate", TRUE }, + { 28, "ConfigureFeature", TRUE }, + { 29, "ReinstallFeature", TRUE }, + { 30, "ProvideComponent", TRUE }, + { 31, "ComponentPath", TRUE }, + { 32, "ProvideQualifiedComponent", TRUE }, + { 33, "QualifierDescription", TRUE }, + { 34, "ComponentQualifiers", TRUE }, + { 35, "Products" }, + { 36, "Features", TRUE }, + { 37, "Components", TRUE }, + { 38, "ComponentClients", TRUE }, + { 39, "Patches", TRUE }, + { 40, "RelatedProducts" }, + { 41, "PatchInfo", TRUE }, + { 42, "PatchTransforms", TRUE }, + { 43, "AddSource", TRUE }, + { 44, "ClearSourceList", TRUE }, + { 45, "ForceSourceListResolution", TRUE }, + { 46, "ShortcutTarget", TRUE }, + { 47, "FileHash", TRUE }, + { 48, "FileSignatureInfo", TRUE }, + { 0 } +}; + static void test_dispid(void) { + const get_did_t *ptr = get_did_data; DISPID dispid; - dispid = get_dispid(pInstaller, "CreateRecord"); - ok(dispid == 1, "Expected 1, got %d\n", dispid); - dispid = get_dispid(pInstaller, "OpenPackage"); - ok(dispid == 2, "Expected 2, got %d\n", dispid); - dispid = get_dispid(pInstaller, "OpenProduct"); - ok(dispid == 3, "Expected 3, got %d\n", dispid); - dispid = get_dispid(pInstaller, "OpenDatabase"); - ok(dispid == 4, "Expected 4, got %d\n", dispid); - dispid = get_dispid(pInstaller, "SummaryInformation"); - ok(dispid == 5, "Expected 5, got %d\n", dispid); - dispid = get_dispid( pInstaller, "UILevel" ); - ok(dispid == 6, "Expected 6, got %d\n", dispid); - dispid = get_dispid(pInstaller, "EnableLog"); - ok(dispid == 7, "Expected 7, got %d\n", dispid); - dispid = get_dispid(pInstaller, "InstallProduct"); - ok(dispid == 8, "Expected 8, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Version"); - ok(dispid == 9, "Expected 9, got %d\n", dispid); - dispid = get_dispid(pInstaller, "LastErrorRecord"); - ok(dispid == 10, "Expected 10, got %d\n", dispid); - dispid = get_dispid(pInstaller, "RegistryValue"); - ok(dispid == 11, "Expected 11, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Environment"); - ok(dispid == 12, "Expected 12, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileAttributes"); - ok(dispid == 13, "Expected 13, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileSize"); - ok(dispid == 15, "Expected 15, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileVersion"); - ok(dispid == 16, "Expected 16, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ProductState"); - ok(dispid == 17, "Expected 17, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ProductInfo"); - ok(dispid == 18, "Expected 18, got %d\n", dispid); - todo_wine + while (ptr->name) { - dispid = get_dispid(pInstaller, "ConfigureProduct"); - ok(dispid == 19, "Expected 19, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ReinstallProduct"); - ok(dispid == 20 , "Expected 20, got %d\n", dispid); - dispid = get_dispid(pInstaller, "CollectUserInfo"); - ok(dispid == 21, "Expected 21, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ApplyPatch"); - ok(dispid == 22, "Expected 22, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FeatureParent"); - ok(dispid == 23, "Expected 23, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FeatureState"); - ok(dispid == 24, "Expected 24, got %d\n", dispid); - dispid = get_dispid(pInstaller, "UseFeature"); - ok(dispid == 25, "Expected 25, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FeatureUsageCount"); - ok(dispid == 26, "Expected 26, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FeatureUsageDate"); - ok(dispid == 27, "Expected 27, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ConfigureFeature"); - ok(dispid == 28, "Expected 28, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ReinstallFeature"); - ok(dispid == 29, "Expected 29, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ProvideComponent"); - ok(dispid == 30, "Expected 30, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ComponentPath"); - ok(dispid == 31, "Expected 31, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ProvideQualifiedComponent"); - ok(dispid == 32, "Expected 32, got %d\n", dispid); - dispid = get_dispid(pInstaller, "QualifierDescription"); - ok(dispid == 33, "Expected 33, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ComponentQualifiers"); - ok(dispid == 34, "Expected 34, got %d\n", dispid); - } - dispid = get_dispid(pInstaller, "Products"); - ok(dispid == 35, "Expected 35, got %d\n", dispid); - todo_wine - { - dispid = get_dispid(pInstaller, "Features"); - ok(dispid == 36, "Expected 36, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Components"); - ok(dispid == 37, "Expected 37, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ComponentClients"); - ok(dispid == 38, "Expected 38, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Patches"); - ok(dispid == 39, "Expected 39, got %d\n", dispid); - } - dispid = get_dispid(pInstaller, "RelatedProducts"); - ok(dispid == 40, "Expected 40, got %d\n", dispid); - todo_wine - { - dispid = get_dispid(pInstaller, "PatchInfo"); - ok(dispid == 41, "Expected 41, got %d\n", dispid); - dispid = get_dispid(pInstaller, "PatchTransforms"); - ok(dispid == 42, "Expected 42, got %d\n", dispid); - dispid = get_dispid(pInstaller, "AddSource"); - ok(dispid == 43, "Expected 43, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ClearSourceList"); - ok(dispid == 44, "Expected 44, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ForceSourceListResolution"); - ok(dispid == 45, "Expected 45, got %d\n", dispid); - dispid = get_dispid(pInstaller, "ShortcutTarget"); - ok(dispid == 46, "Expected 46, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileHash"); - ok(dispid == 47, "Expected 47, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileSignatureInfo"); - ok(dispid == 48, "Expected 48, got %d\n", dispid); + dispid = get_dispid(pInstaller, ptr->name); + if (ptr->todo) + todo_wine + ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid); + else + ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid); + ptr++; } + dispid = get_dispid(pInstaller, "RemovePatches"); ok(dispid == 49 || dispid == -1, "Expected 49 or -1, got %d\n", dispid); dispid = get_dispid(pInstaller, "ApplyMultiplePatches"); @@ -632,10 +617,10 @@ static void test_dispatch(void) /* Test invoking this function (without parameters passed) */ if (0) /* All of these crash MSI on Windows XP */ { - hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL); - hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, &excepinfo, NULL); + IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL); + IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, &excepinfo, NULL); VariantInit(&varresult); - hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, &varresult, &excepinfo, NULL); + IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, &varresult, &excepinfo, NULL); } /* Try with NULL params */ @@ -733,6 +718,12 @@ static void test_dispatch(void) V_VT(&vararg[0]) = VT_BSTR; V_BSTR(&vararg[0]) = SysAllocString(path); hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + if (hr == DISP_E_EXCEPTION) + { + skip("OpenPackage failed, insufficient rights?\n"); + DeleteFileW(path); + return; + } ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); VariantClear(&vararg[0]); VariantClear(&varresult); @@ -836,7 +827,7 @@ static HRESULT invoke(IDispatch *pDispatch, LPCSTR szName, WORD wFlags, DISPPARA len = MultiByteToWideChar(CP_ACP, 0, szName, -1, NULL, 0 ); name = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR) ); if (!name) return E_FAIL; - len = MultiByteToWideChar(CP_ACP, 0, szName, -1, name, len ); + MultiByteToWideChar(CP_ACP, 0, szName, -1, name, len ); hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); HeapFree(GetProcessHeap(), 0, name); ok(hr == S_OK, "IDispatch::GetIDsOfNames returned 0x%08x\n", hr); @@ -925,9 +916,7 @@ static HRESULT Installer_RegistryValueW(HKEY hkey, LPCWSTR szKey, LPCWSTR szValu V_BSTR(&vararg) = SysAllocString(szValue); hr = Installer_RegistryValue(hkey, szKey, vararg, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - /* lstrcpyW is not implemented on Win95 (lstrlenW is though) */ - memcpy(szString, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -943,8 +932,7 @@ static HRESULT Installer_RegistryValueI(HKEY hkey, LPCWSTR szKey, int iValue, LP V_I4(&vararg) = iValue; hr = Installer_RegistryValue(hkey, szKey, vararg, &varresult, vtResult); - if (SUCCEEDED(hr) && vtResult == VT_BSTR) - memcpy(szString, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (SUCCEEDED(hr) && vtResult == VT_BSTR) lstrcpyW(szString, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -1035,8 +1023,7 @@ static HRESULT Installer_ProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, LPW V_BSTR(&vararg[0]) = SysAllocString(szAttribute); hr = invoke(pInstaller, "ProductInfo", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - memcpy(szString, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -1075,12 +1062,25 @@ static HRESULT Installer_VersionGet(LPWSTR szVersion) HRESULT hr; hr = invoke(pInstaller, "Version", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - memcpy(szVersion, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szVersion, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } +static HRESULT Installer_UILevelPut(int level) +{ + VARIANT varresult; + VARIANTARG vararg; + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dispparams = {&vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1}; + + VariantInit(&vararg); + V_VT(&vararg) = VT_I4; + V_I4(&vararg) = level; + + return invoke(pInstaller, "UILevel", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY); +} + static HRESULT Session_Installer(IDispatch *pSession, IDispatch **pInst) { VARIANT varresult; @@ -1104,8 +1104,7 @@ static HRESULT Session_PropertyGet(IDispatch *pSession, LPCWSTR szName, LPWSTR s V_BSTR(&vararg[0]) = SysAllocString(szName); hr = invoke(pSession, "Property", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - memcpy(szReturn, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szReturn, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -1404,8 +1403,7 @@ static HRESULT Record_StringDataGet(IDispatch *pRecord, int iField, LPWSTR szStr V_I4(&vararg[0]) = iField; hr = invoke(pRecord, "StringData", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - memcpy(szString, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -1482,8 +1480,7 @@ static HRESULT StringList_Item(IDispatch *pStringList, int iIndex, LPWSTR szStri V_I4(&vararg[0]) = iIndex; hr = invoke(pStringList, "Item", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); - if (V_BSTR(&varresult)) - memcpy(szString, V_BSTR(&varresult), (lstrlenW(V_BSTR(&varresult)) + 1) * sizeof(WCHAR)); + if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult)); VariantClear(&varresult); return hr; } @@ -1837,7 +1834,7 @@ static void test_Session(IDispatch *pSession) memset(stringw, 0, sizeof(stringw)); hr = Session_PropertyGet(pSession, szProductName, stringw); ok(hr == S_OK, "Session_PropertyGet failed, hresult 0x%08x\n", hr); - if (strcmp_ww(stringw, szMSITEST) != 0) + if (lstrcmpW(stringw, szMSITEST) != 0) { len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL); ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); @@ -1850,7 +1847,7 @@ static void test_Session(IDispatch *pSession) memset(stringw, 0, sizeof(stringw)); hr = Session_PropertyGet(pSession, szProductName, stringw); ok(hr == S_OK, "Session_PropertyGet failed, hresult 0x%08x\n", hr); - if (strcmp_ww(stringw, szProductName) != 0) + if (lstrcmpW(stringw, szProductName) != 0) { len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL); ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); @@ -2054,7 +2051,8 @@ static void test_Installer_RegistryValue(void) "RegSetValueExW failed\n"); ok(!RegSetValueExW(hkey,szThree,0,REG_BINARY, (const BYTE *)qw, 4), "RegSetValueExW failed\n"); - ok(SetEnvironmentVariableA("MSITEST", "Four"), "SetEnvironmentVariableA failed %d\n", GetLastError()); + bRet = SetEnvironmentVariableA("MSITEST", "Four"); + ok(bRet, "SetEnvironmentVariableA failed %d\n", GetLastError()); ok(!RegSetValueExW(hkey,szFour,0,REG_EXPAND_SZ, (const BYTE *)szExpand, sizeof(szExpand)), "RegSetValueExW failed\n"); ok(!RegSetValueExW(hkey,szFive,0,REG_MULTI_SZ, (const BYTE *)szFive, sizeof(szFive)), @@ -2209,7 +2207,7 @@ static void test_Installer_Products(BOOL bProductInstalled) ok(iValue == INSTALLSTATE_DEFAULT || iValue == INSTALLSTATE_ADVERTISED, "Installer_ProductState returned %d, expected %d or %d\n", iValue, INSTALLSTATE_DEFAULT, INSTALLSTATE_ADVERTISED); /* Not found our product code yet? Check */ - if (!bProductFound && !strcmp_ww(szString, szProductCode)) + if (!bProductFound && !lstrcmpW(szString, szProductCode)) bProductFound = TRUE; /* IEnumVARIANT::Next */ @@ -2239,7 +2237,7 @@ static void test_Installer_Products(BOOL bProductInstalled) if (0) /* Crashes on Windows XP */ { /* IEnumVARIANT::Clone, NULL pointer */ - hr = IEnumVARIANT_Clone(pEnum, NULL); + IEnumVARIANT_Clone(pEnum, NULL); } /* IEnumVARIANT::Clone */ @@ -2314,30 +2312,30 @@ static void test_Installer_Products(BOOL bProductInstalled) /* Delete a registry subkey, including all its subkeys (RegDeleteKey does not work on keys with subkeys without * deleting the subkeys first) */ -static UINT delete_registry_key(HKEY hkeyParent, LPCSTR subkey) +static UINT delete_registry_key(HKEY hkeyParent, LPCSTR subkey, REGSAM access) { UINT ret; CHAR *string = NULL; HKEY hkey; DWORD dwSize; - ret = RegOpenKey(hkeyParent, subkey, &hkey); + ret = RegOpenKeyEx(hkeyParent, subkey, 0, access, &hkey); if (ret != ERROR_SUCCESS) return ret; ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &dwSize, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS) return ret; if (!(string = HeapAlloc(GetProcessHeap(), 0, ++dwSize))) return ERROR_NOT_ENOUGH_MEMORY; while (RegEnumKeyA(hkey, 0, string, dwSize) == ERROR_SUCCESS) - delete_registry_key(hkey, string); + delete_registry_key(hkey, string, access); RegCloseKey(hkey); HeapFree(GetProcessHeap(), 0, string); - RegDeleteKeyA(hkeyParent, subkey); + delete_key_portable(hkeyParent, subkey, access); return ERROR_SUCCESS; } /* Find a specific registry subkey at any depth within the given key and subkey and return its parent key. */ -static UINT find_registry_key(HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, HKEY *phkey) +static UINT find_registry_key(HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, REGSAM access, HKEY *phkey) { UINT ret; CHAR *string = NULL; @@ -2348,7 +2346,7 @@ static UINT find_registry_key(HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, HK *phkey = 0; - ret = RegOpenKey(hkeyParent, subkey, &hkey); + ret = RegOpenKeyEx(hkeyParent, subkey, 0, access, &hkey); if (ret != ERROR_SUCCESS) return ret; ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &dwSize, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS) return ret; @@ -2362,7 +2360,7 @@ static UINT find_registry_key(HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, HK *phkey = hkey; found = TRUE; } - else if (find_registry_key(hkey, string, findkey, phkey) == ERROR_SUCCESS) found = TRUE; + else if (find_registry_key(hkey, string, findkey, access, phkey) == ERROR_SUCCESS) found = TRUE; } if (*phkey != hkey) RegCloseKey(hkey); @@ -2380,14 +2378,22 @@ static void test_Installer_InstallProduct(void) DWORD num, size, type; int iValue, iCount; IDispatch *pStringList = NULL; + REGSAM access = KEY_ALL_ACCESS; + + if (is_wow64) + access |= KEY_WOW64_64KEY; create_test_files(); + /* Avoid an interactive dialog in case of insufficient privileges. */ + hr = Installer_UILevelPut(INSTALLUILEVEL_NONE); + ok(hr == S_OK, "Expected UILevel property put invoke to return S_OK, got 0x%08x\n", hr); + /* Installer::InstallProduct */ hr = Installer_InstallProduct(szMsifile, NULL); if (hr == DISP_E_EXCEPTION) { - skip("Installer object not supported.\n"); + skip("InstallProduct failed, insufficient rights?\n"); delete_test_files(); return; } @@ -2446,20 +2452,24 @@ static void test_Installer_InstallProduct(void) IDispatch_Release(pStringList); } + hr = Installer_ProductInfo(szProductCode, WINE_INSTALLPROPERTY_LOCALPACKAGEW, szString); + ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr); + DeleteFileW( szString ); + /* Check & clean up installed files & registry keys */ ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; @@ -2487,40 +2497,36 @@ static void test_Installer_InstallProduct(void) RegCloseKey(hkey); - res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + res = RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Remove registry keys written by RegisterProduct standard action */ - res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}"); + res = delete_key_portable(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{837450fa-a39b-4bc8-b321-08b393f784b3}", + KEY_WOW64_32KEY); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656"); + res = delete_key_portable(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656", access); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = find_registry_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData", "05FA3C1F65B896A40AC00077F34EF203", &hkey); - ok(res == ERROR_SUCCESS || - broken(res == ERROR_FILE_NOT_FOUND), /* win9x */ - "Expected ERROR_SUCCESS, got %d\n", res); - if (res == ERROR_SUCCESS) - { - res = delete_registry_key(hkey, "05FA3C1F65B896A40AC00077F34EF203"); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegCloseKey(hkey); + res = find_registry_key(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData", "af054738b93a8cb43b12803b397f483b", access, &hkey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\05FA3C1F65B896A40AC00077F34EF203"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - } - else - { - /* win9x defaults to a per-machine install. */ - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\05FA3C1F65B896A40AC00077F34EF203"); - } + res = delete_registry_key(hkey, "af054738b93a8cb43b12803b397f483b", access); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + RegCloseKey(hkey); + + res = delete_key_portable(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\af054738b93a8cb43b12803b397f483b", access); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); /* Remove registry keys written by PublishProduct standard action */ res = RegOpenKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Installer", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = delete_registry_key(hkey, "Products\\05FA3C1F65B896A40AC00077F34EF203"); + res = delete_registry_key(hkey, "Products\\af054738b93a8cb43b12803b397f483b", KEY_ALL_ACCESS); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegDeleteKeyA(hkey, "UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656"); @@ -2528,7 +2534,7 @@ static void test_Installer_InstallProduct(void) RegCloseKey(hkey); - /* Delete installation files we installed */ + /* Delete installation files we created */ delete_test_files(); } @@ -2592,6 +2598,12 @@ static void test_Installer(void) /* Installer::OpenPackage */ hr = Installer_OpenPackage(szPath, 0, &pSession); + if (hr == DISP_E_EXCEPTION) + { + skip("OpenPackage failed, insufficient rights?\n"); + DeleteFileW(szPath); + return; + } ok(hr == S_OK, "Installer_OpenPackage failed, hresult 0x%08x\n", hr); if (hr == S_OK) { @@ -2663,6 +2675,11 @@ START_TEST(automation) CLSID clsid; IUnknown *pUnk; + init_functionpointers(); + + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + GetSystemTimeAsFileTime(&systemtime); GetCurrentDirectoryA(MAX_PATH, prev_path); diff --git a/rostests/winetests/msi/db.c b/rostests/winetests/msi/db.c index 5e8505ad109..d33eb0c857e 100644 --- a/rostests/winetests/msi/db.c +++ b/rostests/winetests/msi/db.c @@ -96,6 +96,9 @@ static void test_msidatabase(void) res = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY, &hdb ); ok( res == ERROR_SUCCESS , "Failed to open database\n" ); + res = MsiDatabaseCommit( hdb ); + ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); + res = MsiCloseHandle( hdb ); ok( res == ERROR_SUCCESS , "Failed to close database\n" ); @@ -182,6 +185,22 @@ static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query ) return r; } +static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query ) +{ + MSIHANDLE hview = 0; + UINT r; + + r = MsiDatabaseOpenViewW(hdb, query, &hview); + if( r != ERROR_SUCCESS ) + return r; + + r = MsiViewExecute(hview, hrec); + if( r == ERROR_SUCCESS ) + r = MsiViewClose(hview); + MsiCloseHandle(hview); + return r; +} + static UINT create_component_table( MSIHANDLE hdb ) { return run_query( hdb, 0, @@ -278,7 +297,7 @@ make_add_entry(binary, static void test_msiinsert(void) { - MSIHANDLE hdb = 0, hview = 0, hrec = 0; + MSIHANDLE hdb = 0, hview = 0, hview2 = 0, hrec = 0; UINT r; const char *query; char buf[80]; @@ -303,6 +322,14 @@ static void test_msiinsert(void) r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + query = "SELECT * FROM phone WHERE number = '8675309'"; + r = MsiDatabaseOpenView(hdb, query, &hview2); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + r = MsiViewExecute(hview2, 0); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + r = MsiViewFetch(hview2, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); + /* insert a value into it */ query = "INSERT INTO `phone` ( `id`, `name`, `number` )" "VALUES('1', 'Abe', '8675309')"; @@ -315,6 +342,20 @@ static void test_msiinsert(void) r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + r = MsiViewFetch(hview2, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); + r = MsiViewExecute(hview2, 0); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + r = MsiViewFetch(hview2, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %u\n", r); + + r = MsiCloseHandle(hrec); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + r = MsiViewClose(hview2); + ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); + r = MsiCloseHandle(hview2); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + query = "SELECT * FROM `phone` WHERE `id` = 1"; r = do_query(hdb, query, &hrec); ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); @@ -686,6 +727,36 @@ static void test_msibadqueries(void) r = try_query( hdb, "select * from 'c'"); ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); + r = try_query( hdb, "select `c`.`b` from `c` order by `c`.`order`"); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.b` from `c`"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.`b from `c`"); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.b from `c`"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c.`b` from `c`"); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "select c`.`b` from `c`"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "select c.`b` from `c`"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.`b` from c`"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.`b` from `c"); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "select `c`.`b` from c"); + ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); @@ -738,6 +809,19 @@ static void test_viewmodify(void) r = run_query( hdb, 0, query ); ok(r == ERROR_SUCCESS, "query failed\n"); + query = "CREATE TABLE `_Validation` ( " + "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, " + "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, " + "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), " + "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)"; + r = run_query( hdb, 0, query ); + ok(r == ERROR_SUCCESS, "query failed\n"); + + query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) " + "VALUES('phone', 'id', 'N')"; + r = run_query( hdb, 0, query ); + ok(r == ERROR_SUCCESS, "query failed\n"); + /* check what the error function reports without doing anything */ sz = 0; /* passing NULL as the 3rd param make function to crash on older platforms */ @@ -792,6 +876,13 @@ static void test_viewmodify(void) r = MsiViewModify(hview, -1, hrec ); ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n"); + sz = sizeof buffer; + buffer[0] = 'x'; + err = MsiViewGetError( hview, buffer, &sz ); + ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); + ok(buffer[0] == 0, "buffer not cleared\n"); + ok(sz == 0, "size not zero\n"); + r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "failed to close record\n"); @@ -810,6 +901,20 @@ static void test_viewmodify(void) r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); + /* validate it */ + r = MsiViewExecute(hview, 0); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + + r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec ); + ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r); + + sz = sizeof buffer; + buffer[0] = 'x'; + err = MsiViewGetError( hview, buffer, &sz ); + ok(err == MSIDBERROR_DUPLICATEKEY, "MsiViewGetError returned %u\n", err); + ok(!strcmp(buffer, "id"), "expected \"id\" c, got \"%s\"\n", buffer); + ok(sz == 2, "size not 2\n"); + /* insert the same thing again */ r = MsiViewExecute(hview, 0); ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); @@ -1998,7 +2103,7 @@ static const CHAR suminfo[] = "PropertyId\tValue\n" "4\tWineHQ\n" "5\tInstaller\n" "6\tInstaller comments\n" - "7\tIntel;1033\n" + "7\tIntel;1033,2057\n" "9\t{12345678-1234-1234-1234-123456789012}\n" "12\t2009/04/12 15:46:11\n" "13\t2009/04/12 15:46:11\n" @@ -2107,8 +2212,8 @@ static void test_suminfo_import(void) r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); - ok(!strcmp(str_value, "Intel;1033"), - "Expected \"Intel;1033\", got %s\n", str_value); + ok(!strcmp(str_value, "Intel;1033,2057"), + "Expected \"Intel;1033,2057\", got %s\n", str_value); size = sizeof(str_value); r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size); @@ -2170,24 +2275,17 @@ static void test_msiimport(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = add_table_to_db(hdb, endlines1); - if (r == ERROR_FUNCTION_FAILED) - { - /* win9x doesn't handle this case */ - skip("endlines not handled correctly.\n"); - MsiCloseHandle(hdb); - DeleteFileA(msifile); - return; - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = add_table_to_db(hdb, endlines2); - ok(r == ERROR_FUNCTION_FAILED, - "Expected ERROR_FUNCTION_FAILED, got %d\n", r); + ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); query = "SELECT * FROM `TestTable`"; r = MsiDatabaseOpenView(hdb, query, &view); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 9, "Expected 9, got %d\n", count); ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n"); @@ -2202,6 +2300,7 @@ static void test_msiimport(void) MsiCloseHandle(rec); r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 9, "Expected 9, got %d\n", count); ok(check_record(rec, 1, "s255"), "Expected s255\n"); @@ -2247,6 +2346,7 @@ static void test_msiimport(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 2, "Expected 2, got %d\n", count); ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n"); @@ -2255,6 +2355,7 @@ static void test_msiimport(void) MsiCloseHandle(rec); r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 2, "Expected 2, got %d\n", count); ok(check_record(rec, 1, "s255"), "Expected s255\n"); @@ -2294,6 +2395,7 @@ static void test_msiimport(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 6, "Expected 6, got %d\n", count); ok(check_record(rec, 1, "A"), "Expected A\n"); @@ -2305,6 +2407,7 @@ static void test_msiimport(void) MsiCloseHandle(rec); r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 6, "Expected 6, got %d\n", count); ok(check_record(rec, 1, "s72"), "Expected s72\n"); @@ -2877,7 +2980,7 @@ static UINT set_summary_info(MSIHANDLE hdb) ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL, - ";1033"); + ";1033,2057"); ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL, @@ -2916,6 +3019,7 @@ static MSIHANDLE create_package_db(LPCSTR filename) ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); res = set_summary_info(hdb); + ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); res = create_directory_table(hdb); ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); @@ -2923,27 +3027,31 @@ static MSIHANDLE create_package_db(LPCSTR filename) return hdb; } -static MSIHANDLE package_from_db(MSIHANDLE hdb) +static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) { UINT res; - CHAR szPackage[10]; + CHAR szPackage[12]; MSIHANDLE hPackage; - sprintf(szPackage,"#%i",hdb); - res = MsiOpenPackage(szPackage,&hPackage); + sprintf(szPackage, "#%u", hdb); + res = MsiOpenPackage(szPackage, &hPackage); if (res != ERROR_SUCCESS) - return 0; + return res; res = MsiCloseHandle(hdb); if (res != ERROR_SUCCESS) - return 0; + { + MsiCloseHandle(hPackage); + return res; + } - return hPackage; + *handle = hPackage; + return ERROR_SUCCESS; } static void test_try_transform(void) { - MSIHANDLE hdb, hview, hrec, hpkg; + MSIHANDLE hdb, hview, hrec, hpkg = 0; LPCSTR query; UINT r; DWORD sz; @@ -3117,8 +3225,13 @@ static void test_try_transform(void) MsiCloseHandle(hview); /* check that the property was added */ - hpkg = package_from_db(hdb); - ok(hpkg != 0, "Expected non-NULL hpkg\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); sz = MAX_PATH; r = MsiGetProperty(hpkg, "prop", buffer, &sz); @@ -3126,8 +3239,9 @@ static void test_try_transform(void) ok(!lstrcmp(buffer, "val"), "Expected val, got %s\n", buffer); MsiCloseHandle(hpkg); - MsiCloseHandle(hdb); +error: + MsiCloseHandle(hdb); DeleteFile(msifile); DeleteFile(mstfile); } @@ -3833,7 +3947,7 @@ static void test_join(void) /* primary key cannot be updated */ r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); - todo_wine ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r ); + ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r ); MsiCloseHandle(hrec); MsiViewClose(hview); @@ -4191,6 +4305,7 @@ static void test_integers(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 8, "Expected 8, got %d\n", count); ok(check_record(rec, 1, "one"), "Expected one\n"); @@ -4204,6 +4319,7 @@ static void test_integers(void) MsiCloseHandle(rec); r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); count = MsiRecordGetFieldCount(rec); ok(count == 8, "Expected 8, got %d\n", count); ok(check_record(rec, 1, "I2"), "Expected I2\n"); @@ -4919,6 +5035,172 @@ static void test_rows_order(void) DeleteFile(msifile); } +static void test_collation(void) +{ + static const WCHAR query1[] = + {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', + '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', + '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0}; + static const WCHAR query2[] = + {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', + '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', + '(','\'',0xe5,'\'',',','\'','D','\'',')',0}; + static const WCHAR query3[] = + {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ', + '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',', + ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ', + 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0}; + static const WCHAR query4[] = + {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ', + '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', + 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; + static const WCHAR query5[] = + {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ', + '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', + 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; + static const WCHAR query6[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E', + ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0}; + static const WCHAR letter_C[] = {'C',0}; + static const WCHAR letter_D[] = {'D',0}; + static const WCHAR letter_a_ring[] = {'a',0x30a,0}; + static const WCHAR letter_a_with_ring[] = {0xe5,0}; + const char *query; + MSIHANDLE hdb = 0, hview = 0, hrec = 0; + UINT r; + char buffer[100]; + WCHAR bufferW[100]; + DWORD sz; + + r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); + ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); + + query = "CREATE TABLE `bar` ( " + "`foo` LONGCHAR NOT NULL, " + "`baz` LONGCHAR NOT NULL " + "PRIMARY KEY `foo` )"; + r = run_query(hdb, 0, query); + ok(r == ERROR_SUCCESS, "failed to create table\n"); + + r = run_query(hdb, 0, query); + ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r); + + r = run_query(hdb, 0, "INSERT INTO `bar` " + "( `foo`, `baz` ) VALUES ( '\2', 'A' )"); + ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); + + r = run_query(hdb, 0, "INSERT INTO `bar` " + "( `foo`, `baz` ) VALUES ( '\1', 'B' )"); + ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); + + r = run_queryW(hdb, 0, query1); + ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); + + r = run_queryW(hdb, 0, query2); + ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); + + r = run_queryW(hdb, 0, query3); + ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); + + r = run_queryW(hdb, 0, query4); + ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); + + r = run_queryW(hdb, 0, query5); + ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); + + query = "SELECT * FROM `bar`"; + r = MsiDatabaseOpenView(hdb, query, &hview); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + r = MsiViewExecute(hview, 0); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); + sz = sizeof(buffer); + r = MsiRecordGetString(hrec, 1, buffer, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmp(buffer, "\2"), "Expected \\2, got '%s'\n", buffer); + sz = sizeof(buffer); + r = MsiRecordGetString(hrec, 2, buffer, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmp(buffer, "A"), "Expected A, got '%s'\n", buffer); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); + sz = sizeof(buffer); + r = MsiRecordGetString(hrec, 1, buffer, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmp(buffer, "\1"), "Expected \\1, got '%s'\n", buffer); + sz = sizeof(buffer); + r = MsiRecordGetString(hrec, 2, buffer, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmp(buffer, "B"), "Expected B, got '%s'\n", buffer); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)), + "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW)); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW)); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), + "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); + MsiCloseHandle(hrec); + + r = MsiViewClose(hview); + ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); + r = MsiCloseHandle(hview); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + + r = MsiDatabaseOpenViewW(hdb, query6, &hview); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + r = MsiViewExecute(hview, 0); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), + "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); + sz = sizeof(bufferW) / sizeof(bufferW[0]); + r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); + + r = MsiViewClose(hview); + ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); + r = MsiCloseHandle(hview); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + + r = MsiCloseHandle(hdb); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + + DeleteFile(msifile); +} + static void test_select_markers(void) { MSIHANDLE hdb = 0, rec, view, res; @@ -5063,6 +5345,7 @@ static void test_select_markers(void) static void test_viewmodify_update(void) { MSIHANDLE hdb = 0, hview = 0, hrec = 0; + UINT i, test_max, offset, count; const char *query; UINT r; @@ -5229,6 +5512,90 @@ static void test_viewmodify_update(void) r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)"; + r = run_query( hdb, 0, query ); + ok(r == ERROR_SUCCESS, "query failed\n"); + + query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)"; + r = MsiDatabaseOpenView( hdb, query, &hview ); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + + test_max = 100; + offset = 1234; + for(i = 0; i < test_max; i++) + { + + hrec = MsiCreateRecord( 2 ); + MsiRecordSetInteger( hrec, 1, test_max - i ); + MsiRecordSetInteger( hrec, 2, i ); + + r = MsiViewExecute( hview, hrec ); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + + r = MsiCloseHandle( hrec ); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + } + + r = MsiViewClose( hview ); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + r = MsiCloseHandle( hview ); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + + /* Update. */ + query = "SELECT * FROM `table2` ORDER BY `B`"; + r = MsiDatabaseOpenView( hdb, query, &hview); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + r = MsiViewExecute( hview, 0 ); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + + count = 0; + while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) + { + UINT b = MsiRecordGetInteger( hrec, 2 ); + + r = MsiRecordSetInteger( hrec, 2, b + offset); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + + r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec ); + ok(r == ERROR_SUCCESS, "Got %d\n", r); + + r = MsiCloseHandle(hrec); + ok(r == ERROR_SUCCESS, "failed to close record\n"); + count++; + } + ok(count == test_max, "Got count %d\n", count); + + r = MsiViewClose(hview); + ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); + r = MsiCloseHandle(hview); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + + /* Recheck. */ + query = "SELECT * FROM `table2` ORDER BY `B`"; + r = MsiDatabaseOpenView( hdb, query, &hview); + ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); + r = MsiViewExecute( hview, 0 ); + ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); + + count = 0; + while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) + { + UINT a = MsiRecordGetInteger( hrec, 1 ); + UINT b = MsiRecordGetInteger( hrec, 2 ); + ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n", + a, b, test_max - a + offset, b); + + r = MsiCloseHandle(hrec); + ok(r == ERROR_SUCCESS, "failed to close record\n"); + count++; + } + ok(count == test_max, "Got count %d\n", count); + + r = MsiViewClose(hview); + ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); + r = MsiCloseHandle(hview); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + r = MsiCloseHandle( hdb ); ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); } @@ -5488,16 +5855,13 @@ static void test_stringtable(void) sz = sizeof(buffer); r = MsiRecordGetString(hrec, 2, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmp(buffer, "one"), "Expected one, got %s\n", buffer); + ok(!lstrcmp(buffer, "one"), "Expected one, got '%s'\n", buffer); r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewFetch(hview, &hrec); - todo_wine - { - ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); - } + ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); r = MsiViewClose(hview); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -5525,7 +5889,7 @@ static void test_stringtable(void) sz = sizeof(buffer); r = MsiRecordGetString(hrec, 2, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmp(buffer, "two"), "Expected two, got %s\n", buffer); + ok(!lstrcmp(buffer, "two"), "Expected two, got '%s'\n", buffer); r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -5542,7 +5906,7 @@ static void test_stringtable(void) sz = sizeof(buffer); r = MsiRecordGetString(hrec, 2, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmp(buffer, "five"), "Expected five, got %s\n", buffer); + ok(!lstrcmp(buffer, "five"), "Expected five, got '%s'\n", buffer); r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -5570,11 +5934,8 @@ static void test_stringtable(void) hr = IStream_Read(stm, data, MAX_PATH, &read); ok(hr == S_OK, "Expected S_OK, got %d\n", hr); - todo_wine - { - ok(read == 4, "Expected 4, got %d\n", read); - ok(!memcmp(data, data10, read), "Unexpected data\n"); - } + ok(read == 4, "Expected 4, got %d\n", read); + todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n"); hr = IStream_Release(stm); ok(hr == S_OK, "Expected S_OK, got %d\n", hr); @@ -6780,6 +7141,7 @@ static void test_forcecodepage(void) UINT r; DeleteFile(msifile); + GetCurrentDirectoryA(MAX_PATH, CURR_DIR); r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -6817,7 +7179,24 @@ static void test_forcecodepage(void) read_file_data("forcecodepage.idt", buffer); ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), - "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"", buffer); + "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); + + create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); + + r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + read_file_data("forcecodepage.idt", buffer); + ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), + "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); + + create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0); + + r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); + ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_SUCCESS, got %d\n", r); MsiCloseHandle(hdb); DeleteFileA(msifile); @@ -7172,8 +7551,7 @@ static void test_storages_table(void) static void test_dbtopackage(void) { MSIHANDLE hdb, hpkg; - CHAR package[10]; - CHAR buf[MAX_PATH]; + CHAR package[12], buf[MAX_PATH]; DWORD size; UINT r; @@ -7192,8 +7570,13 @@ static void test_dbtopackage(void) r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - sprintf(package, "#%i", hdb); + sprintf(package, "#%u", hdb); r = MsiOpenPackage(package, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* property is not set yet */ @@ -7251,7 +7634,7 @@ static void test_dbtopackage(void) r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - sprintf(package, "#%i", hdb); + sprintf(package, "#%u", hdb); r = MsiOpenPackage(package, &hpkg); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -7292,8 +7675,10 @@ static void test_dbtopackage(void) ok(size == 0, "Expected 0, got %d\n", size); } - MsiCloseHandle(hdb); MsiCloseHandle(hpkg); + +error: + MsiCloseHandle(hdb); DeleteFileA(msifile); } @@ -7847,10 +8232,12 @@ static void test_dbmerge(void) size = MAX_PATH; r = MsiRecordGetString(hrec, 1, buf, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); size = MAX_PATH; r = MsiRecordGetString(hrec, 2, buf, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "NumRowMergeConflicts"), "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf); @@ -7861,10 +8248,12 @@ static void test_dbmerge(void) size = MAX_PATH; r = MsiRecordGetString(hrec, 1, buf, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf); size = MAX_PATH; r = MsiRecordGetString(hrec, 2, buf, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf); MsiCloseHandle(hrec); @@ -7965,10 +8354,7 @@ static void test_dbmerge(void) GetCurrentDirectoryA(MAX_PATH, buf); r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); query = "DROP TABLE `One`"; r = run_query(hdb, 0, query); @@ -8214,7 +8600,7 @@ static void test_select_with_tablenames(void) DeleteFileA(msifile); } -UINT ordervals[6][3] = +static const UINT ordervals[6][3] = { { MSI_NULL_INTEGER, 12, 13 }, { 1, 2, 3 }, @@ -8480,6 +8866,7 @@ static void test_columnorder(void) query = "SELECT * FROM `T`"; r = do_query(hdb, query, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "kiwi"); @@ -8705,6 +9092,7 @@ static void test_columnorder(void) query = "SELECT * FROM `Z`"; r = do_query(hdb, query, &rec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiRecordGetInteger(rec, 1); ok(r == 2, "Expected 2, got %d\n", r); @@ -8870,6 +9258,7 @@ static void test_createtable(void) size = sizeof(buffer); res = MsiRecordGetString(hrec, 1, buffer, &size ); todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + MsiCloseHandle( hrec ); res = MsiViewClose( htab ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -8899,10 +9288,12 @@ static void test_createtable(void) res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + buffer[0] = 0; size = sizeof(buffer); res = MsiRecordGetString(hrec, 1, buffer, &size ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); ok(!strcmp(buffer,"b"), "b != %s\n", buffer); + MsiCloseHandle( hrec ); res = MsiViewClose( htab ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -8926,6 +9317,7 @@ static void test_createtable(void) res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + buffer[0] = 0; size = sizeof(buffer); res = MsiRecordGetString(hrec, 1, buffer, &size ); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -8950,6 +9342,288 @@ static void test_createtable(void) DeleteFileA(msifile); } +static void test_embedded_nulls(void) +{ + static const char control_table[] = + "Dialog\tText\n" + "s72\tL0\n" + "Control\tDialog\n" + "LicenseAgreementDlg\ttext\x11\x19text\0text"; + UINT r, sz; + MSIHANDLE hdb, hrec; + char buffer[32]; + + r = MsiOpenDatabaseA( msifile, MSIDBOPEN_CREATE, &hdb ); + ok( r == ERROR_SUCCESS, "failed to open database %u\n", r ); + + GetCurrentDirectoryA( MAX_PATH, CURR_DIR ); + write_file( "temp_file", control_table, sizeof(control_table) ); + r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" ); + ok( r == ERROR_SUCCESS, "failed to import table %u\n", r ); + DeleteFileA( "temp_file" ); + + r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec ); + ok( r == ERROR_SUCCESS, "query failed %u\n", r ); + + buffer[0] = 0; + sz = sizeof(buffer); + r = MsiRecordGetStringA( hrec, 1, buffer, &sz ); + ok( r == ERROR_SUCCESS, "failed to get string %u\n", r ); + ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer ); + + MsiCloseHandle( hrec ); + MsiCloseHandle( hdb ); + DeleteFileA( msifile ); +} + +static void test_select_column_names(void) +{ + MSIHANDLE hdb = 0, rec, rec2, view; + char buffer[32]; + UINT r, size; + + DeleteFile(msifile); + + r = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb ); + ok( r == ERROR_SUCCESS , "failed to open database: %u\n", r ); + + r = try_query( hdb, "CREATE TABLE `t` (`a` CHAR NOT NULL, `b` CHAR PRIMARY KEY `a`)"); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `t`.`b` FROM `t` WHERE `t`.`b` = `x`" ); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT '', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT *, `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); + todo_wine ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT 'b', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY `b`" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY 'b'" ); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT 't'.'b' FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT 'b' FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '1', '2' )" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '3', '4' )" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = MsiDatabaseOpenView( hdb, "SELECT '' FROM `t`", &view ); + ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); + + r = MsiViewExecute( view, 0 ); + ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec ); + ok( r == 1, "got %u\n", r ); + r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec2 ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec2 ); + ok( r == 1, "got %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec2, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + MsiCloseHandle( rec2 ); + r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec2 ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec2 ); + ok( r == 1, "got %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec2, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "f0" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec2 ); + + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); + MsiCloseHandle( rec ); + + MsiViewClose( view ); + MsiCloseHandle( view ); + + r = MsiDatabaseOpenView( hdb, "SELECT `a`, '' FROM `t`", &view ); + ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); + + r = MsiViewExecute( view, 0 ); + ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec ); + ok( r == 2, "got %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 2, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); + MsiCloseHandle( rec ); + + MsiViewClose( view ); + MsiCloseHandle( view ); + + r = MsiDatabaseOpenView( hdb, "SELECT '', `a` FROM `t`", &view ); + ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); + + r = MsiViewExecute( view, 0 ); + ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec ); + ok( r == 2, "got %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 2, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 2, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); + MsiCloseHandle( rec ); + + MsiViewClose( view ); + MsiCloseHandle( view ); + + r = MsiDatabaseOpenView( hdb, "SELECT `a`, '', `b` FROM `t`", &view ); + ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); + + r = MsiViewExecute( view, 0 ); + ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + r = MsiRecordGetFieldCount( rec ); + ok( r == 3, "got %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 2, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 3, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "2" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 1, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 2, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !buffer[0], "got \"%s\"\n", buffer ); + size = sizeof(buffer); + memset( buffer, 0x55, sizeof(buffer) ); + r = MsiRecordGetStringA( rec, 3, buffer, &size ); + ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); + ok( !lstrcmpA( buffer, "4" ), "got \"%s\"\n", buffer ); + MsiCloseHandle( rec ); + + r = MsiViewFetch( view, &rec ); + ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); + MsiCloseHandle( rec ); + + MsiViewClose( view ); + MsiCloseHandle( view ); + + r = try_query( hdb, "SELECT '' FROM `t` WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `` FROM `t` WHERE `t`.`b` = 'x'" ); + todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `b` FROM 't' WHERE `t`.`b` = 'x'" ); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `b` FROM `t` WHERE 'b' = 'x'" ); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT `t`.`b`, `` FROM `t` WHERE `t`.`b` = 'x'" ); + todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); + + r = MsiCloseHandle( hdb ); + ok(r == ERROR_SUCCESS , "failed to close database: %u\n", r); +} START_TEST(db) { @@ -9003,4 +9677,7 @@ START_TEST(db) test_columnorder(); test_suminfo_import(); test_createtable(); + test_collation(); + test_embedded_nulls(); + test_select_column_names(); } diff --git a/rostests/winetests/msi/format.c b/rostests/winetests/msi/format.c index 3d4029cb0ac..3ecfc66ad25 100644 --- a/rostests/winetests/msi/format.c +++ b/rostests/winetests/msi/format.c @@ -201,15 +201,20 @@ static MSIHANDLE create_package_db(void) DeleteFile(msifile); /* create an empty database */ - res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb ); - ok( res == ERROR_SUCCESS , "Failed to create database\n" ); + res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATEDIRECT, &hdb ); + ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); if( res != ERROR_SUCCESS ) - return hdb; + return 0; res = MsiDatabaseCommit( hdb ); ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); + if( res != ERROR_SUCCESS ) + return 0; res = set_summary_info(hdb); + ok( res == ERROR_SUCCESS , "Failed to set summary info %u\n", res ); + if( res != ERROR_SUCCESS ) + return 0; res = run_query( hdb, "CREATE TABLE `Directory` ( " @@ -217,25 +222,31 @@ static MSIHANDLE create_package_db(void) "`Directory_Parent` CHAR(255), " "`DefaultDir` CHAR(255) NOT NULL " "PRIMARY KEY `Directory`)" ); - ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); + ok( res == ERROR_SUCCESS , "Failed to create directory table %u\n", res ); return hdb; } -static MSIHANDLE package_from_db(MSIHANDLE hdb) +static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) { UINT res; - CHAR szPackage[10]; + CHAR szPackage[12]; MSIHANDLE hPackage; - sprintf(szPackage,"#%i",hdb); - res = MsiOpenPackage(szPackage,&hPackage); - ok( res == ERROR_SUCCESS , "Failed to open package\n" ); + sprintf(szPackage, "#%u", hdb); + res = MsiOpenPackage(szPackage, &hPackage); + if (res != ERROR_SUCCESS) + return res; res = MsiCloseHandle(hdb); - ok( res == ERROR_SUCCESS , "Failed to close db handle\n" ); + if (res != ERROR_SUCCESS) + { + MsiCloseHandle(hPackage); + return res; + } - return hPackage; + *handle = hPackage; + return ERROR_SUCCESS; } static void create_test_file(const CHAR *name) @@ -250,22 +261,21 @@ static void create_test_file(const CHAR *name) CloseHandle(file); } -static MSIHANDLE helper_createpackage( const char *szName ) +static UINT helper_createpackage( const char *szName, MSIHANDLE *handle ) { - MSIHANDLE hdb = 0; + MSIHANDLE hPackage, suminfo, hdb = 0; UINT res; - CHAR szPackage[10]; - MSIHANDLE hPackage; - MSIHANDLE suminfo; DeleteFile(szName); /* create an empty database */ - res = MsiOpenDatabase(szName, MSIDBOPEN_CREATE, &hdb ); - ok( res == ERROR_SUCCESS , "Failed to create database\n" ); + res = MsiOpenDatabase(szName, MSIDBOPEN_CREATEDIRECT, &hdb ); + ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); + if (res != ERROR_SUCCESS) + return res; res = MsiDatabaseCommit( hdb ); - ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); + ok( res == ERROR_SUCCESS , "Failed to commit database %u\n", res ); /* build summary info */ res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo); @@ -303,14 +313,15 @@ static MSIHANDLE helper_createpackage( const char *szName ) res = MsiCloseHandle( suminfo); ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); - sprintf(szPackage,"#%i",hdb); - res = MsiOpenPackage(szPackage,&hPackage); - ok( res == ERROR_SUCCESS , "Failed to open package\n" ); + res = package_from_db( hdb, &hPackage ); + MsiCloseHandle(hdb); - res = MsiCloseHandle( hdb ); - ok( res == ERROR_SUCCESS , "Failed to close database\n" ); + if (res != ERROR_SUCCESS) + DeleteFileA( szName ); + else + *handle = hPackage; - return hPackage; + return res; } static void test_createpackage(void) @@ -318,11 +329,16 @@ static void test_createpackage(void) MSIHANDLE hPackage = 0; UINT res; - hPackage = helper_createpackage( msifile ); - ok ( hPackage != 0, " Failed to create package\n"); + res = helper_createpackage( msifile, &hPackage ); + if (res == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + return; + } + ok( res == ERROR_SUCCESS, "Failed to create package %u\n", res ); - res = MsiCloseHandle( hPackage); - ok( res == ERROR_SUCCESS , "Failed to close package\n" ); + res = MsiCloseHandle( hPackage ); + ok( res == ERROR_SUCCESS , "Failed to close package %u\n", res ); DeleteFile( msifile ); } @@ -457,7 +473,9 @@ static void test_formatrecord(void) /* now put something in the first field */ r = MsiRecordSetString(hrec, 0, "[1] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -468,6 +486,7 @@ static void test_formatrecord(void) /* empty string */ r = MsiRecordSetString(hrec, 0, ""); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); @@ -477,7 +496,9 @@ static void test_formatrecord(void) /* play games with recursive lookups */ r = MsiRecordSetString(hrec, 0, "[[1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -487,7 +508,9 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[[1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "[2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -497,8 +520,11 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"[[2]] hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[[[3]]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -513,9 +539,13 @@ static void test_formatrecord(void) ok( hrec, "failed to create record\n"); r = MsiRecordSetString(hrec, 0, "[[3][1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -525,10 +555,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[[3][4][1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -538,10 +573,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -552,10 +592,15 @@ static void test_formatrecord(void) /* incorrect formats */ r = MsiRecordSetString(hrec, 0, "[[[3][[4]][1]] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -565,10 +610,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"[[[3][[4]][1]] [2]"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -581,10 +631,15 @@ static void test_formatrecord(void) /* play games with {} */ r = MsiRecordSetString(hrec, 0, "{[3][1]} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -594,10 +649,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"12 hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[{[3][1]}] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -608,10 +668,15 @@ static void test_formatrecord(void) r = MsiRecordSetString(hrec, 0, "{test} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -621,10 +686,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{test} hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[test]} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -634,10 +704,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{[test]} hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[1][2][3][4]} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -647,10 +722,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer," hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[1][2][3][dummy]} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -660,10 +740,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[1][2][3][4][dummy]} [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -673,10 +758,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3][4][dummy]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -686,10 +776,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{{2hey}1[dummy]}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]{[4][dummy]}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hey"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -699,10 +794,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]} {[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -712,10 +812,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{{12}3} {12}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[1][2]} {{[1][2]}[3]} {[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -725,10 +830,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -738,10 +848,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -751,10 +866,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{blah} 12 {{12}3} {12}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{[1]}[2]} {[4]}{[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -764,10 +884,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"{{1}2} {}{12}"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{[1]}} {[4]}{[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -777,10 +902,15 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "{{{[1]}} {[4]}{[1][2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "1"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "3"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 12, "big"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -793,7 +923,9 @@ static void test_formatrecord(void) /* now put play games with escaping */ r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -804,7 +936,9 @@ static void test_formatrecord(void) /* now put play games with escaping */ r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -813,28 +947,32 @@ static void test_formatrecord(void) ok( sz == 12, "size wrong\n"); ok( 0 == strcmp(buffer,"boo hoo [\\x]"), "wrong output\n"); - MsiRecordSetString(hrec, 0, "[\\x]"); + r = MsiRecordSetString(hrec, 0, "[\\x]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 4, "size wrong: %d\n", sz); ok( 0 == strcmp(buffer,"[\\x]"), "wrong output: %s\n", buffer); - MsiRecordSetString(hrec, 0, "{\\x}"); + r = MsiRecordSetString(hrec, 0, "{\\x}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 4, "size wrong: %d\n", sz); ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer); - MsiRecordSetString(hrec, 0, "[abc\\x]"); + r = MsiRecordSetString(hrec, 0, "[abc\\x]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 7, "size wrong: %d\n", sz); ok( 0 == strcmp(buffer,"[abc\\x]"), "wrong output: %s\n", buffer); - MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]"); + r = MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); @@ -843,7 +981,9 @@ static void test_formatrecord(void) /* now try other formats without a package */ r = MsiRecordSetString(hrec, 0, "[1] [2] [property]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -853,7 +993,9 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"boo hoo [property]"), "wrong output\n"); r = MsiRecordSetString(hrec, 0, "[1] [~] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -863,6 +1005,7 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"boo [~] hoo"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetInteger(hrec, 1, 123456); ok( r == ERROR_SUCCESS, "set integer failed\n"); sz = sizeof buffer; @@ -872,6 +1015,7 @@ static void test_formatrecord(void) ok( 0 == strcmp(buffer,"123456"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[~]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -879,6 +1023,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 2, "size wrong\n"); @@ -887,6 +1032,7 @@ static void test_formatrecord(void) /* MsiFormatRecord doesn't seem to handle a negative too well */ r = MsiRecordSetString(hrec, 0, "[-1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -894,6 +1040,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -901,6 +1048,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[0]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -908,6 +1056,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[100]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -915,8 +1064,11 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1] [2]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 7, "size wrong\n"); @@ -924,6 +1076,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -931,6 +1084,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{foo}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 5, "size wrong\n"); @@ -938,7 +1092,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{boo [1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 7, "size wrong\n"); @@ -946,7 +1102,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{[1]}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -954,7 +1112,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{ {[1]}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -965,7 +1125,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{[1]} }"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 8, "size wrong\n"); @@ -973,7 +1135,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ [1]}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -981,7 +1145,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{[1] }}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -989,6 +1155,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{a}{b}{c }{ d}{any text}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -996,6 +1163,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{a} }"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 6, "size wrong\n"); @@ -1003,22 +1171,23 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{a} {b}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); ok( 0 == strcmp(buffer,""), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); - todo_wine { r = MsiRecordSetString(hrec, 0, "{{a} b}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); - ok( sz == 0, "size wrong\n"); - ok( 0 == strcmp(buffer,""), "wrong output\n"); - } + todo_wine ok( sz == 0, "size wrong\n"); + todo_wine ok( 0 == strcmp(buffer,""), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{a b}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 0, "size wrong\n"); @@ -1026,6 +1195,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{ }"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -1033,32 +1203,33 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, " {{a}}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 2, "size wrong\n"); ok( 0 == strcmp(buffer," }"), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); - todo_wine { r = MsiRecordSetString(hrec, 0, "{{ almost {{ any }} text }}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); - ok( sz == 8, "size wrong\n"); - ok( 0 == strcmp(buffer," text }}"), "wrong output\n"); - } + todo_wine ok( sz == 8, "size wrong\n"); + todo_wine ok( 0 == strcmp(buffer," text }}"), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); - todo_wine { r = MsiRecordSetString(hrec, 0, "{{ } { hidden ][ [ }}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); - ok( sz == 0, "size wrong\n"); - ok( 0 == strcmp(buffer,""), "wrong output\n"); - } + todo_wine ok( sz == 0, "size wrong\n"); + todo_wine ok( 0 == strcmp(buffer,""), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[ 1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -1066,33 +1237,39 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[01]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); ok( 0 == strcmp(buffer,"hoo"), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); - todo_wine { r = MsiRecordSetString(hrec, 0, "{{test}} [01"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); - ok( sz == 4, "size wrong\n"); - ok( 0 == strcmp(buffer," [01"), "wrong output\n"); - } + todo_wine ok( sz == 4, "size wrong\n"); + todo_wine ok( 0 == strcmp(buffer," [01"), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[\\[]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); ok( 0 == strcmp(buffer,"[\\[]"), "wrong output\n"); ok( r == ERROR_SUCCESS, "format failed\n"); - MsiRecordSetString(hrec, 0, "[\\[]"); - MsiRecordSetString(hrec, 1, "hoo"); + r = MsiRecordSetString(hrec, 0, "[\\[]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof(buffer); r = MsiFormatRecord(0, hrec, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -1100,7 +1277,9 @@ static void test_formatrecord(void) ok(!lstrcmpA(buffer, "[\\[]"), "Expected \"[\\[]\", got \"%s\"\n", buffer); r = MsiRecordSetString(hrec, 0, "[foo]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 5, "size wrong\n"); @@ -1108,7 +1287,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[01.]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 5, "size wrong\n"); @@ -1117,6 +1298,7 @@ static void test_formatrecord(void) SetEnvironmentVariable("FOO", "BAR"); r = MsiRecordSetString(hrec, 0, "[%FOO]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 6, "size wrong\n"); @@ -1124,7 +1306,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 6, "size wrong\n"); @@ -1132,7 +1316,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ {[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 8, "size wrong\n"); @@ -1140,7 +1326,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ {[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 8, "size wrong\n"); @@ -1148,7 +1336,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ {{[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 9, "size wrong\n"); @@ -1156,7 +1346,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -1164,6 +1356,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ {{a}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 7, "size wrong\n"); @@ -1171,6 +1364,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{ {{a}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 7, "size wrong\n"); @@ -1178,7 +1372,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "0{1{2{3{4[1]5}6}7}8}9"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1189,7 +1385,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1200,7 +1398,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1211,7 +1411,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1.} [1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 9, "size wrong\n"); @@ -1222,8 +1424,11 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[{[1]}]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1234,8 +1439,11 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1][}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1246,8 +1454,11 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "[2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -1255,7 +1466,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[{{boo}}1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); @@ -1266,8 +1479,11 @@ static void test_formatrecord(void) } r = MsiRecordSetString(hrec, 0, "[{{boo}}1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 0, "[1{{boo}}]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -1275,7 +1491,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1]{{boo} }}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1286,7 +1504,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1{{boo}}]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1297,7 +1517,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{{[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 6, "size wrong: got %u, expected 3\n", sz); @@ -1305,7 +1527,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1{{bo}o}}]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 13, "size wrong\n"); @@ -1313,6 +1537,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1{{b{o}o}}]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1323,7 +1548,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{ {[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1335,7 +1562,9 @@ static void test_formatrecord(void) /* {} inside a substitution does strange things... */ r = MsiRecordSetString(hrec, 0, "[[1]{}]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1346,7 +1575,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[[1]{}[1]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1357,7 +1588,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[a[1]b[1]c{}d[1]e]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1368,7 +1601,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[a[1]b"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 6, "size wrong\n"); @@ -1376,7 +1611,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "a[1]b]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -1384,7 +1621,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "]a[1]b"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -1392,7 +1631,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "]a[1]b"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 4, "size wrong\n"); @@ -1400,7 +1641,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "\\[1]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 2, "size wrong\n"); @@ -1408,7 +1651,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "\\{[1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "2"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 2, "size wrong\n"); @@ -1416,7 +1661,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "a{b[1]c}d"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 2, "size wrong\n"); @@ -1424,7 +1671,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{a[0]b}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 9, "size wrong\n"); @@ -1432,6 +1681,7 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[foo]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); ok( sz == 5, "size wrong\n"); @@ -1439,7 +1689,9 @@ static void test_formatrecord(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "{[1][-1][1]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(0, hrec, buffer, &sz); todo_wine @@ -1451,70 +1703,80 @@ static void test_formatrecord(void) /* nested braces */ sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{abcd}"); + r = MsiRecordSetString(hrec, 0, "{abcd}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 6, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}"); + r = MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 23, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{a[one]bc[two]de[one]f}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}"); + r = MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 23, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{a[one]bc[bad]de[two]f}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{[bad]}"); + r = MsiRecordSetString(hrec, 0, "{[bad]}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 7, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{[bad]}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */ + r = MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */ + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 14, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{abc{d[one]ef}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}"); + r = MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 15, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{abc{d[one]ef}}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}"); + r = MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 5, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}"); + r = MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 0, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{def}hi{jk}}"); + r = MsiRecordSetString(hrec, 0, "{{def}hi{jk}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 0, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{{def}}hi{jk}}"); + r = MsiRecordSetString(hrec, 0, "{{{def}}hi{jk}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); todo_wine @@ -1524,7 +1786,8 @@ static void test_formatrecord(void) } sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{def}hi{{jk}}}"); + r = MsiRecordSetString(hrec, 0, "{{def}hi{{jk}}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); todo_wine @@ -1534,42 +1797,48 @@ static void test_formatrecord(void) } sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{def}{jk}}"); + r = MsiRecordSetString(hrec, 0, "{{def}{jk}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 0, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{def}}"); + r = MsiRecordSetString(hrec, 0, "{{def}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 0, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{a{b}c}"); + r = MsiRecordSetString(hrec, 0, "{a{b}c}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 7, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{a{b}c}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{a{b}}"); + r = MsiRecordSetString(hrec, 0, "{a{b}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 6, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{a{b}}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{b}c}"); + r = MsiRecordSetString(hrec, 0, "{{b}c}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 6, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"{{b}c}"), "wrong output (%s)\n",buffer); sz = sizeof buffer; - MsiRecordSetString(hrec, 0, "{{{{}}}}"); + r = MsiRecordSetString(hrec, 0, "{{{{}}}}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); todo_wine @@ -1581,15 +1850,18 @@ static void test_formatrecord(void) sz = sizeof buffer; MsiRecordSetInteger(hrec, 1, 100); MsiRecordSetInteger(hrec, 2, -100); - MsiRecordSetString(hrec, 0, "[1] [2]"); + r = MsiRecordSetString(hrec, 0, "[1] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed\n"); ok( sz == 8, "size wrong(%i)\n",sz); ok( 0 == strcmp(buffer,"100 -100"), "wrong output (%s)\n",buffer); sz = sizeof(buffer); - MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}"); - MsiRecordSetString(hrec, 1, "one"); + r = MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 1, "one"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(sz == 33, "Expected 33, got %d\n",sz); @@ -1597,8 +1869,10 @@ static void test_formatrecord(void) "Expected \"one {[noprop] [twoprop]} {abcdef}\", got \"%s\"\n", buffer); sz = sizeof(buffer); - MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}"); - MsiRecordSetString(hrec, 1, "one"); + r = MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 1, "one"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(sz == 29, "Expected 29, got %d\n",sz); @@ -1606,8 +1880,10 @@ static void test_formatrecord(void) "Expected \"one {[noprop] [one]} {abcdef}\", got \"%s\"\n", buffer); sz = sizeof(buffer); - MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}"); - MsiRecordSetString(hrec, 1, "one"); + r = MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 1, "one"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiFormatRecord(0, hrec, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(sz == 20, "Expected 20, got %d\n",sz); @@ -1625,8 +1901,13 @@ static void test_formatrecord_package(void) UINT r; DWORD sz=100; - package = helper_createpackage( msifile ); - ok(package!=0, "Unable to create package\n"); + r = helper_createpackage( msifile, &package ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + return; + } + ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r ); hrec = MsiCreateRecord(12); ok( hrec, "failed to create record\n"); @@ -1638,17 +1919,29 @@ static void test_formatrecord_package(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec,0,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,1,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,2,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,3,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,4,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,5,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,6,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,7,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,8,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,9,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,10,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,11,NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec,12,NULL); ok( r == ERROR_SUCCESS, "set string failed\n"); @@ -1662,11 +1955,17 @@ static void test_formatrecord_package(void) ok( r == ERROR_SUCCESS, "failed to set propertY: %d\n", r); r = MsiRecordSetString(hrec, 0, NULL); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "[2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "stuff"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "prop"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 4, "[prop]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 5, "[noprop]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; r = MsiFormatRecord(package, hrec, buffer, &sz); ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r); @@ -1680,7 +1979,9 @@ static void test_formatrecord_package(void) /* now put play games with escaping */ r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1690,7 +1991,9 @@ static void test_formatrecord_package(void) ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1831,7 +2134,9 @@ static void test_formatrecord_package(void) /* null characters */ r = MsiRecordSetString(hrec, 0, "[1] [~] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1842,9 +2147,12 @@ static void test_formatrecord_package(void) ok(!lstrcmpA(&buffer[5], " hoo"), "Expected \" hoo\", got \"%s\"\n", &buffer[5]); - MsiRecordSetString(hrec, 0, "[1] [~abc] [2]"); - MsiRecordSetString(hrec, 1, "boo"); - MsiRecordSetString(hrec, 2, "hoo"); + r = MsiRecordSetString(hrec, 0, "[1] [~abc] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); + r = MsiRecordSetString(hrec, 2, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof(buffer); r = MsiFormatRecord(package, hrec, buffer, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -1855,7 +2163,9 @@ static void test_formatrecord_package(void) r = MsiSetProperty(package,"dummy","Bork"); ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1865,7 +2175,9 @@ static void test_formatrecord_package(void) ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n"); r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1876,12 +2188,17 @@ static void test_formatrecord_package(void) /* nesting tests */ r = MsiSetProperty(package,"dummya","foo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiSetProperty(package,"dummyb","baa"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiSetProperty(package,"adummyc","whoa"); ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "a"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "b"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "c"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1891,11 +2208,15 @@ static void test_formatrecord_package(void) ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer); r = MsiSetProperty(package,"dummya","1"); + ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiSetProperty(package,"dummyb","[2]"); ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "aaa"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "bbb"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "ccc"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1908,13 +2229,19 @@ static void test_formatrecord_package(void) } r = MsiSetProperty(package,"dummya","1"); + ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiSetProperty(package,"dummyb","a"); + ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiSetProperty(package,"dummyc","\\blath"); + ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiSetProperty(package,"dummyd","[\\blath]"); ok( r == ERROR_SUCCESS, "set property failed\n"); r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "aaa"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "bbb"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "ccc"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1924,8 +2251,11 @@ static void test_formatrecord_package(void) ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer); r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "yeah"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -1938,8 +2268,11 @@ static void test_formatrecord_package(void) } r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 1, "boo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 2, "hoo"); + ok( r == ERROR_SUCCESS, "set string failed\n"); r = MsiRecordSetString(hrec, 3, "\\help"); ok( r == ERROR_SUCCESS, "set string failed\n"); sz = sizeof buffer; @@ -2120,7 +2453,7 @@ static void test_formatrecord_package(void) static void test_formatrecord_tables(void) { - MSIHANDLE hdb, hpkg, hrec; + MSIHANDLE hdb, hrec, hpkg = 0; CHAR buf[MAX_PATH]; CHAR curr_dir[MAX_PATH]; CHAR expected[MAX_PATH]; @@ -2186,19 +2519,26 @@ static void test_formatrecord_tables(void) ok( r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r); r = add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" ); - ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r); + ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); r = add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" ); - ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r); + ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); r = add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" ); - ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r); + ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" ); - ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r); + ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + MsiCloseHandle( hdb ); + DeleteFile( msifile ); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle( hdb ); @@ -2244,6 +2584,8 @@ static void test_formatrecord_tables(void) ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); ok( !lstrcmp( buf, "1: " ), "Expected '1: ', got %s\n", buf ); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r); @@ -2381,12 +2723,18 @@ static void test_formatrecord_tables(void) static void test_processmessage(void) { - MSIHANDLE hrec; - MSIHANDLE package; - int r; + MSIHANDLE hrec, package; + UINT r; - package = helper_createpackage( msifile ); - ok(package!=0, "Unable to create package\n"); + MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL); + + r = helper_createpackage( msifile, &package ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + return; + } + ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r ); hrec = MsiCreateRecord(3); ok( hrec, "failed to create record\n"); diff --git a/rostests/winetests/msi/install.c b/rostests/winetests/msi/install.c index 365c8a68184..8e4e4b79ecc 100644 --- a/rostests/winetests/msi/install.c +++ b/rostests/winetests/msi/install.c @@ -42,20 +42,28 @@ static UINT (WINAPI *pMsiSourceListEnumSourcesA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD); static UINT (WINAPI *pMsiSourceListGetInfoA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD); +static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA) + (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD); static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*); +static BOOL (WINAPI *pGetTokenInformation)( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD ); +static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE ); +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static HMODULE hsrclient = 0; static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD); static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*); -static BOOL on_win9x = FALSE; +static BOOL is_wow64; +static const BOOL is_64bit = sizeof(void *) > sizeof(int); static const char *msifile = "msitest.msi"; static const char *msifile2 = "winetest2.msi"; static const char *mstfile = "winetest.mst"; static CHAR CURR_DIR[MAX_PATH]; static CHAR PROG_FILES_DIR[MAX_PATH]; +static CHAR PROG_FILES_DIR_NATIVE[MAX_PATH]; static CHAR COMMON_FILES_DIR[MAX_PATH]; static CHAR APP_DATA_DIR[MAX_PATH]; static CHAR WINDOWS_DIR[MAX_PATH]; @@ -164,7 +172,8 @@ static const CHAR property_dat[] = "Property\tValue\n" "AdminProperties\tPOSTADMIN\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" - "SERVDISP\tTestServiceDisp\n"; + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; static const CHAR aup_property_dat[] = "Property\tValue\n" "s72\tl0\n" @@ -187,7 +196,8 @@ static const CHAR aup_property_dat[] = "Property\tValue\n" "AdminProperties\tPOSTADMIN\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" - "SERVDISP\tTestServiceDisp\n"; + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; static const CHAR aup2_property_dat[] = "Property\tValue\n" "s72\tl0\n" @@ -210,7 +220,8 @@ static const CHAR aup2_property_dat[] = "Property\tValue\n" "AdminProperties\tPOSTADMIN\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" - "SERVDISP\tTestServiceDisp\n"; + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; static const CHAR icon_property_dat[] = "Property\tValue\n" "s72\tl0\n" @@ -232,56 +243,14 @@ static const CHAR icon_property_dat[] = "Property\tValue\n" "AdminProperties\tPOSTADMIN\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" - "SERVDISP\tTestServiceDisp\n"; + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n" "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n" "Shortcut\tShortcut\n" "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n"; -static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n" - "s72\tl255\tL255\ts72\n" - "Environment\tEnvironment\n" - "Var1\t=-MSITESTVAR1\t1\tOne\n" - "Var2\tMSITESTVAR2\t1\tOne\n" - "Var3\t=-MSITESTVAR3\t1\tOne\n" - "Var4\tMSITESTVAR4\t1\tOne\n" - "Var5\t-MSITESTVAR5\t\tOne\n" - "Var6\tMSITESTVAR6\t\tOne\n" - "Var7\t!-MSITESTVAR7\t\tOne\n" - "Var8\t!-*MSITESTVAR8\t\tOne\n" - "Var9\t=-MSITESTVAR9\t\tOne\n" - "Var10\t=MSITESTVAR10\t\tOne\n" - "Var11\t+-MSITESTVAR11\t[~];1\tOne\n" - "Var12\t+-MSITESTVAR11\t[~];2\tOne\n" - "Var13\t+-MSITESTVAR12\t[~];1\tOne\n" - "Var14\t=MSITESTVAR13\t[~];1\tOne\n" - "Var15\t=MSITESTVAR13\t[~];2\tOne\n" - "Var16\t=MSITESTVAR14\t;1;\tOne\n" - "Var17\t=MSITESTVAR15\t;;1;;\tOne\n" - "Var18\t=MSITESTVAR16\t 1 \tOne\n" - "Var19\t+-MSITESTVAR17\t1\tOne\n" - "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n" - "Var21\t+-MSITESTVAR18\t1\tOne\n" - "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n" - "Var23\t+-MSITESTVAR19\t1\tOne\n" - "Var24\t+-MSITESTVAR19\t[~]2\tOne\n" - "Var25\t+-MSITESTVAR20\t1\tOne\n" - "Var26\t+-MSITESTVAR20\t2[~]\tOne\n"; - -/* Expected results, starting from MSITESTVAR11 onwards */ -static const CHAR *environment_dat_results[] = {"1;2", /*MSITESTVAR11*/ - "1", /*MSITESTVAR12*/ - "1;2", /*MSITESTVAR13*/ - ";1;", /*MSITESTVAR14*/ - ";;1;;", /*MSITESTVAR15*/ - " 1 ", /*MSITESTVAR16*/ - ";;2;;1", /*MSITESTVAR17*/ - "1;;2;;", /*MSITESTVAR18*/ - "1", /*MSITESTVAR19*/ - "1", /*MSITESTVAR20*/ - NULL}; - static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n" "s38\ti2\tS255\n" "Condition\tFeature_\tLevel\n" @@ -308,7 +277,8 @@ static const CHAR up_property_dat[] = "Property\tValue\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" "SERVDISP\tTestServiceDisp\n" - "RemovePreviousVersions\t1\n"; + "RemovePreviousVersions\t1\n" + "MSIFASTINSTALL\t1\n"; static const CHAR up2_property_dat[] = "Property\tValue\n" "s72\tl0\n" @@ -330,7 +300,8 @@ static const CHAR up2_property_dat[] = "Property\tValue\n" "AdminProperties\tPOSTADMIN\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" - "SERVDISP\tTestServiceDisp\n"; + "SERVDISP\tTestServiceDisp\n" + "MSIFASTINSTALL\t1\n"; static const CHAR up3_property_dat[] = "Property\tValue\n" "s72\tl0\n" @@ -353,15 +324,16 @@ static const CHAR up3_property_dat[] = "Property\tValue\n" "ROOTDRIVE\tC:\\\n" "SERVNAME\tTestService\n" "SERVDISP\tTestServiceDisp\n" - "RemovePreviousVersions\t1\n"; + "RemovePreviousVersions\t1\n" + "MSIFASTINSTALL\t1\n"; static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" "s72\ti2\tl255\tL255\tL0\ts72\n" "Registry\tRegistry\n" - "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n" - "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n" - "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n" - "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent"; + "Apples\t1\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n" + "Oranges\t1\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n" + "regdata\t1\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n" + "OrderTest\t1\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent"; static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t" "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n" @@ -374,30 +346,6 @@ static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArgument "ServiceControl\tServiceControl\n" "ServiceControl\tTestService\t8\t\t0\tservice_comp"; -static const CHAR sss_service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n" - "s72\tl255\ti2\tL255\tI2\ts72\n" - "ServiceControl\tServiceControl\n" - "ServiceControl\tSpooler\t1\t\t0\tservice_comp"; - -static const CHAR sss_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "CostFinalize\t\t1000\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "ResolveSource\t\t950\n" - "MoveFiles\t\t1700\n" - "InstallFiles\t\t4000\n" - "DuplicateFiles\t\t4500\n" - "WriteEnvironmentStrings\t\t4550\n" - "CreateShortcuts\t\t4600\n" - "StartServices\t\t5000\n" - "DeleteServices\t\t5500\n" - "InstallFinalize\t\t6600\n" - "InstallInitialize\t\t1500\n" - "InstallValidate\t\t1400\n" - "LaunchConditions\t\t100\n"; - /* tables for test_continuouscabs */ static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" @@ -567,6 +515,18 @@ static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISCom "CustomAction\tAction\n" "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n"; +static const CHAR pv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "CostFinalize\t\t1000\n" + "InstallValidate\t\t1400\n" + "InstallInitialize\t\t1500\n" + "InstallFiles\t\t4000\n" + "InstallFinalize\t\t6600\n"; + static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -683,30 +643,6 @@ static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n" "InstallFinalize\t\t6600"; -static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n" - "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n"; - -static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n" - "augustus\taugustus\taugustus\t500\t\t\t8192\t2"; - -static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" - "i2\ti4\tL64\tS255\tS32\tS72\n" - "Media\tDiskId\n" - "1\t2\t\t\tDISK1\t\n"; - -static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "feature\tmaximus\n" - "feature\taugustus\n" - "montecristo\tmaximus"; - static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -745,20 +681,6 @@ static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAtt "Component\tComponent\n" "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n"; -static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n" - "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n" - "lithium\t\tMSITESTDIR\t2\t\tlithium\n"; - -static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "feature\thydrogen\n" - "feature\thelium\n" - "feature\tlithium"; - static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" "File\tFile\n" @@ -784,49 +706,14 @@ static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "PublishProduct\t\t6400\n" "InstallFinalize\t\t6600"; -static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n" - "s72\ts72\tS255\ts72\tI2\n" - "RemoveFile\tFileKey\n" - "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n" - "firkin\thelium\tfirkin\tMSITESTDIR\t1\n" - "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n" - "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n" - "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n" - "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n" - "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n" - "block\thelium\tblock\tMSITESTDIR\t3\n" - "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n" - "nanoacre\thydrogen\t\tCABOUTDIR\t3\n"; - -static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n" - "s72\ts72\tS255\tS255\tS72\ts72\ti2\n" - "MoveFile\tFileKey\n" - "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n" - "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n" - "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n" - "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n" - "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n" - "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n" - "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n" - "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n" - "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n" - "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n" - "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n" - "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n" - "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n" - "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n" - "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n" - "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n" - "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n" - "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n"; - static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n" "augustus\t\tMSITESTDIR\t0\t1\taugustus\n" "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n" - "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n"; + "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n" + "tiberius\t\tMSITESTDIR\t0\t\ttiberius\n"; static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" @@ -834,7 +721,8 @@ static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n" "augustus\taugustus\taugustus\t500\t\t\t0\t2\n" "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n" - "gaius\tgaius\tgaius\t500\t\t\t16384\t4"; + "gaius\tgaius\tgaius\t500\t\t\t16384\t4\n" + "tiberius\ttiberius\ttiberius\t500\t\t\t0\t5\n"; static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" "i2\ti4\tL64\tS255\tS32\tS72\n" @@ -842,40 +730,19 @@ static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tV "1\t1\t\ttest1.cab\tDISK1\t\n" "2\t2\t\ttest2.cab\tDISK2\t\n" "3\t3\t\ttest3.cab\tDISK3\t\n" - "4\t4\t\ttest3.cab\tDISK3\t\n"; + "4\t4\t\ttest3.cab\tDISK3\t\n" + "5\t5\t\ttest4.cab\tDISK4\t\n"; static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n" "s72\ti2\ti4\ti4\ti4\ti4\n" "MsiFileHash\tFile_\n" "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824"; -static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" - "s72\tS72\tl255\n" - "Directory\tDirectory\n" - "THIS\tMSITESTDIR\tthis\n" - "DOESNOT\tTHIS\tdoesnot\n" - "NONEXISTENT\tDOESNOT\texist\n" - "MSITESTDIR\tProgramFilesFolder\tmsitest\n" - "ProgramFilesFolder\tTARGETDIR\t.\n" - "TARGETDIR\t\tSourceDir"; - -static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n" - "s72\ts72\ts72\tS255\tS72\n" - "DuplicateFile\tFileKey\n" - "maximus\tmaximus\tmaximus\taugustus\t\n" - "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n" - "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n"; - static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; -static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" - "s72\ti2\tl255\tL255\tL0\ts72\n" - "Registry\tRegistry\n" - "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus"; - static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -1113,331 +980,6 @@ static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISCom "CustomAction\tAction\n" "TestAllUsersProp\t19\t\tTest failed\t\n"; -static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n" - "s72\ts72\n" - "CreateFolder\tDirectory_\tComponent_\n" - "FIRSTDIR\tOne\n"; - -static const CHAR cf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "CostFinalize\t\t1000\n" - "ValidateProductID\t\t700\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "RemoveFiles\t\t3500\n" - "CreateFolders\t\t3700\n" - "InstallExecute\t\t3800\n" - "TestCreateFolders\t\t3900\n" - "InstallFiles\t\t4000\n" - "RegisterUser\t\t6000\n" - "RegisterProduct\t\t6100\n" - "PublishFeatures\t\t6300\n" - "PublishProduct\t\t6400\n" - "InstallFinalize\t\t6600\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "UnpublishFeatures\t\t1800\n" - "InstallValidate\t\t1400\n" - "LaunchConditions\t\t100\n"; - -static const CHAR cf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" - "s72\ti2\tS64\tS0\tS255\n" - "CustomAction\tAction\n" - "TestCreateFolders\t19\t\tHalts installation\t\n"; - -static const CHAR rf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "CostFinalize\t\t1000\n" - "ValidateProductID\t\t700\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "RemoveFiles\t\t3500\n" - "CreateFolders\t\t3600\n" - "RemoveFolders\t\t3700\n" - "InstallExecute\t\t3800\n" - "TestCreateFolders\t\t3900\n" - "InstallFiles\t\t4000\n" - "RegisterUser\t\t6000\n" - "RegisterProduct\t\t6100\n" - "PublishFeatures\t\t6300\n" - "PublishProduct\t\t6400\n" - "InstallFinalize\t\t6600\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "UnpublishFeatures\t\t1800\n" - "InstallValidate\t\t1400\n" - "LaunchConditions\t\t100\n"; - - -static const CHAR sr_selfreg_dat[] = "File_\tCost\n" - "s72\tI2\n" - "SelfReg\tFile_\n" - "one.txt\t1\n"; - -static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "CostFinalize\t\t1000\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "ResolveSource\t\t950\n" - "MoveFiles\t\t1700\n" - "SelfUnregModules\t\t3900\n" - "InstallFiles\t\t4000\n" - "DuplicateFiles\t\t4500\n" - "WriteEnvironmentStrings\t\t4550\n" - "CreateShortcuts\t\t4600\n" - "InstallFinalize\t\t6600\n" - "InstallInitialize\t\t1500\n" - "InstallValidate\t\t1400\n" - "LaunchConditions\t\t100\n"; - -static const CHAR font_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" - "i2\ti4\tL64\tS255\tS32\tS72\n" - "Media\tDiskId\n" - "1\t3\t\t\tDISK1\t\n"; - -static const CHAR font_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n"; - -static const CHAR font_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR font_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n"; - -static const CHAR font_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "fonts\tfonts\n"; - -static const CHAR font_dat[] = "File_\tFontTitle\n" - "s72\tS128\n" - "Font\tFile_\n" - "font.ttf\tmsi test font\n"; - -static const CHAR font_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "ValidateProductID\t\t700\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "UnpublishFeatures\t\t1800\n" - "RemoveFiles\t\t3500\n" - "InstallFiles\t\t4000\n" - "RegisterFonts\t\t4100\n" - "UnregisterFonts\t\t4200\n" - "RegisterUser\t\t6000\n" - "RegisterProduct\t\t6100\n" - "PublishFeatures\t\t6300\n" - "PublishProduct\t\t6400\n" - "InstallFinalize\t\t6600"; - -static const CHAR vp_property_dat[] = "Property\tValue\n" - "s72\tl0\n" - "Property\tProperty\n" - "HASUIRUN\t0\n" - "INSTALLLEVEL\t3\n" - "InstallMode\tTypical\n" - "Manufacturer\tWine\n" - "PIDTemplate\t###-#######\n" - "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" - "ProductLanguage\t1033\n" - "ProductName\tMSITEST\n" - "ProductVersion\t1.1.1\n" - "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"; - -static const CHAR vp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" - "s72\ti2\tS64\tS0\tS255\n" - "CustomAction\tAction\n" - "SetProductID1\t51\tProductID\t1\t\n" - "SetProductID2\t51\tProductID\t2\t\n" - "TestProductID1\t19\t\t\tHalts installation\n" - "TestProductID2\t19\t\t\tHalts installation\n"; - -static const CHAR vp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "SetProductID1\tSET_PRODUCT_ID=1\t3000\n" - "SetProductID2\tSET_PRODUCT_ID=2\t3100\n" - "ValidateProductID\t\t3200\n" - "InstallExecute\t\t3300\n" - "TestProductID1\tProductID=1\t3400\n" - "TestProductID2\tProductID=\"123-1234567\"\t3500\n" - "InstallFiles\t\t4000\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR odbc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n" - "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n" - "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n" - "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n" - "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n"; - -static const CHAR odbc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR odbc_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "odbc\todbc\n"; - -static const CHAR odbc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n"; - -static const CHAR odbc_driver_dat[] = "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n" - "s72\ts72\ts255\ts72\tS72\n" - "ODBCDriver\tDriver\n" - "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n" - "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n"; - -static const CHAR odbc_translator_dat[] = "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n" - "s72\ts72\ts255\ts72\tS72\n" - "ODBCTranslator\tTranslator\n" - "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n" - "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n"; - -static const CHAR odbc_datasource_dat[] = "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n" - "s72\ts72\ts255\ts255\ti2\n" - "ODBCDataSource\tDataSource\n" - "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n"; - -static const CHAR odbc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "InstallODBC\t\t3000\n" - "RemoveODBC\t\t3100\n" - "RemoveFiles\t\t3900\n" - "InstallFiles\t\t4000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" - "i2\ti4\tL64\tS255\tS32\tS72\n" - "Media\tDiskId\n" - "1\t5\t\t\tDISK1\t\n"; - -static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n"; - -static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "typelib\ttypelib\n"; - -static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n"; - -static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n" - "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n" - "TypeLib\tLibID\tLanguage\tComponent_\n" - "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n"; - -static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n" - "UnregisterTypeLibraries\t\t3100\n" - "RegisterProduct\t\t5100\n" - "PublishFeatures\t\t5200\n" - "PublishProduct\t\t5300\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR crs_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR crs_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR crs_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "shortcut\tshortcut\n"; - -static const CHAR crs_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n"; - -static const CHAR crs_shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n" - "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n" - "Shortcut\tShortcut\n" - "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n"; - -static const CHAR crs_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RemoveShortcuts\t\t3000\n" - "CreateShortcuts\t\t3100\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - static const CHAR fo_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" "File\tFile\n" @@ -1495,452 +1037,205 @@ static const CHAR fo_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "PublishProduct\t\t5200\n" "InstallFinalize\t\t6000\n"; -static const CHAR pub_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR pub_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR pub_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "publish\tpublish\n"; - -static const CHAR pub_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n"; - -static const CHAR pub_publish_component_dat[] = "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n" - "s38\ts255\ts72\tL255\ts38\n" - "PublishComponent\tComponentId\tQualifier\tComponent_\n" - "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n"; - -static const CHAR pub_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "PublishComponents\t\t3000\n" - "UnpublishComponents\t\t3100\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR rd_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" +static const CHAR sd_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" "File\tFile\n" - "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n" - "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n" - "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n"; + "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n"; -static const CHAR rd_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" +static const CHAR sd_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" "Feature\tFeature\n" - "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n"; + "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n"; -static const CHAR rd_feature_comp_dat[] = "Feature_\tComponent_\n" +static const CHAR sd_feature_comp_dat[] = "Feature_\tComponent_\n" "s38\ts72\n" "FeatureComponents\tFeature_\tComponent_\n" - "duplicate\tduplicate\n"; + "sourcedir\tsourcedir\n"; -static const CHAR rd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" +static const CHAR sd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" - "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n" - "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n"; + "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n"; -static const CHAR rd_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n" - "s72\ts72\ts72\tS255\tS72\n" - "DuplicateFile\tFileKey\n" - "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n" - "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n" - "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n"; +static const CHAR sd_install_ui_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallUISequence\tAction\n" + "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n" + "AppSearch\t\t100\n" + "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n" + "LaunchConditions\tnot Installed \t110\n" + "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n" + "FindRelatedProducts\t\t120\n" + "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n" + "CCPSearch\t\t130\n" + "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n" + "RMCCPSearch\t\t140\n" + "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n" + "ValidateProductID\t\t150\n" + "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n" + "CostInitialize\t\t800\n" + "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n" + "FileCost\t\t900\n" + "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n" + "IsolateComponents\t\t1000\n" + "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n" + "CostFinalize\t\t1100\n" + "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n" + "MigrateFeatureStates\t\t1200\n" + "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n" + "ExecuteAction\t\t1300\n" + "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n"; -static const CHAR rd_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" +static const CHAR sd_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n" + "LaunchConditions\t\t100\n" + "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n" + "ValidateProductID\t\t700\n" + "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n" + "CostInitialize\t\t800\n" + "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n" + "ResolveSource\tResolveSource and not Installed\t850\n" + "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n" + "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n" + "FileCost\t\t900\n" + "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n" + "IsolateComponents\t\t1000\n" + "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n" + "CostFinalize\t\t1100\n" + "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n" + "MigrateFeatureStates\t\t1200\n" + "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n" + "InstallValidate\t\t1400\n" + "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n" + "InstallInitialize\t\t1500\n" + "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n" + "ProcessComponents\t\t1600\n" + "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n" + "UnpublishFeatures\t\t1800\n" + "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n" + "RemoveFiles\t\t3500\n" + "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n" + "InstallFiles\t\t4000\n" + "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n" + "RegisterUser\t\t6000\n" + "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n" + "RegisterProduct\t\t6100\n" + "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n" + "PublishFeatures\t\t6300\n" + "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n" + "PublishProduct\t\t6400\n" + "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n" + "InstallExecute\t\t6500\n" + "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n" + "InstallFinalize\t\t6600\n" + "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n"; + +static const CHAR sd_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "TestSourceDirProp1\t19\t\tTest 1 failed\t\n" + "TestSourceDirProp2\t19\t\tTest 2 failed\t\n" + "TestSourceDirProp3\t19\t\tTest 3 failed\t\n" + "TestSourceDirProp4\t19\t\tTest 4 failed\t\n" + "TestSourceDirProp5\t19\t\tTest 5 failed\t\n" + "TestSourceDirProp6\t19\t\tTest 6 failed\t\n" + "TestSourceDirProp7\t19\t\tTest 7 failed\t\n" + "TestSourceDirProp8\t19\t\tTest 8 failed\t\n" + "TestSourceDirProp9\t19\t\tTest 9 failed\t\n" + "TestSourceDirProp10\t19\t\tTest 10 failed\t\n" + "TestSourceDirProp11\t19\t\tTest 11 failed\t\n" + "TestSourceDirProp12\t19\t\tTest 12 failed\t\n" + "TestSourceDirProp13\t19\t\tTest 13 failed\t\n" + "TestSourceDirProp14\t19\t\tTest 14 failed\t\n" + "TestSourceDirProp15\t19\t\tTest 15 failed\t\n" + "TestSourceDirProp16\t19\t\tTest 16 failed\t\n" + "TestSourceDirProp17\t19\t\tTest 17 failed\t\n" + "TestSourceDirProp18\t19\t\tTest 18 failed\t\n" + "TestSourceDirProp19\t19\t\tTest 19 failed\t\n" + "TestSourceDirProp20\t19\t\tTest 20 failed\t\n" + "TestSourceDirProp21\t19\t\tTest 21 failed\t\n" + "TestSourceDirProp22\t19\t\tTest 22 failed\t\n" + "TestSourceDirProp23\t19\t\tTest 23 failed\t\n" + "TestSourceDirProp24\t19\t\tTest 24 failed\t\n" + "TestSourceDirProp25\t19\t\tTest 25 failed\t\n" + "TestSourceDirProp26\t19\t\tTest 26 failed\t\n" + "TestSourceDirProp27\t19\t\tTest 27 failed\t\n" + "TestSourceDirProp28\t19\t\tTest 28 failed\t\n" + "TestSourceDirProp29\t19\t\tTest 29 failed\t\n" + "TestSourceDirProp30\t19\t\tTest 30 failed\t\n" + "TestSourceDirProp31\t19\t\tTest 31 failed\t\n" + "TestSourceDirProp32\t19\t\tTest 32 failed\t\n" + "TestSourceDirProp33\t19\t\tTest 33 failed\t\n" + "TestSourceDirProp34\t19\t\tTest 34 failed\t\n" + "TestSourceDirProp35\t19\t\tTest 35 failed\t\n"; + +static const CHAR cl_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "TestCommandlineProp\t19\t\tTest1\t\n"; + +static const CHAR cl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "s72\tS255\tI2\n" "InstallExecuteSequence\tAction\n" "LaunchConditions\t\t100\n" + "ValidateProductID\t\t700\n" "CostInitialize\t\t800\n" "FileCost\t\t900\n" "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" + "TestCommandlineProp\tP=\"one\"\t1100\n" "InstallInitialize\t\t1500\n" "ProcessComponents\t\t1600\n" - "RemoveDuplicateFiles\t\t1900\n" - "InstallFiles\t\t2000\n" - "DuplicateFiles\t\t2100\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; + "InstallValidate\t\t1400\n" + "InstallFinalize\t\t5000\n"; -static const CHAR rrv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n"; +static const CHAR uc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "upgradecode.txt\tupgradecode\tupgradecode.txt\t1000\t\t\t8192\t1\n"; -static const CHAR rrv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n"; +static const CHAR uc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "upgradecode\t\t\tupgradecode feature\t1\t2\tMSITESTDIR\t0\n"; -static const CHAR rrv_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "registry\tregistry\n"; +static const CHAR uc_feature_comp_dat[] = "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "upgradecode\tupgradecode\n"; -static const CHAR rrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n"; +static const CHAR uc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "upgradecode\t{6952B732-2FCB-4E47-976F-989FCBD7EDFB}\tMSITESTDIR\t0\t\tupgradecode.txt\n"; -static const CHAR rrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" - "s72\ti2\tl255\tL255\tL0\ts72\n" - "Registry\tRegistry\n" - "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n" - "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n" - "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n"; +static const CHAR uc_property_dat[] = "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "INSTALLLEVEL\t3\n" + "ProductCode\t{E5FB1241-F547-4BA7-A60E-8E75797268D4}\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "UpgradeCode\t#UPGEADECODE#\n" + "MSIFASTINSTALL\t1\n"; -static const CHAR rrv_remove_registry_dat[] = "RemoveRegistry\tRoot\tKey\tName\tComponent_\n" - "s72\ti2\tl255\tL255\ts72\n" - "RemoveRegistry\tRemoveRegistry\n" - "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n" - "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n" - "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n"; - -static const CHAR rrv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RemoveRegistryValues\t\t3000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR frp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR frp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR frp_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "product\tproduct\n"; - -static const CHAR frp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n"; - -static const CHAR frp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" - "s72\ti2\tS64\tS0\tS255\n" - "CustomAction\tAction\n" - "TestProp\t19\t\t\tPROP set\n"; - -static const CHAR frp_upgrade_dat[] = "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n" - "s38\tS20\tS20\tS255\ti4\tS255\ts72\n" - "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n" - "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n"; - -static const CHAR frp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "FindRelatedProducts\t\t50\n" - "TestProp\tPROP AND NOT REMOVE\t51\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR riv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR riv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR riv_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "inifile\tinifile\n"; - -static const CHAR riv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n"; - -static const CHAR riv_ini_file_dat[] = "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n" - "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n" - "IniFile\tIniFile\n" - "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n"; - -static const CHAR riv_remove_ini_file_dat[] = "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n" - "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n" - "RemoveIniFile\tRemoveIniFile\n" - "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n"; - -static const CHAR riv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RemoveIniValues\t\t3000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR res_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR res_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR res_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "envvar\tenvvar\n"; - -static const CHAR res_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n"; - -static const CHAR res_environment_dat[] = "Environment\tName\tValue\tComponent_\n" - "s72\tl255\tL255\ts72\n" - "Environment\tEnvironment\n" - "var1\t=-MSITESTVAR1\t1\tenvvar\n" - "var2\t=+-MSITESTVAR2\t1\tenvvar\n" - "var3\t=MSITESTVAR3\t1\tenvvar\n" - "var4\t=-MSITESTVAR4\t\tenvvar\n" - "var5\t=MSITESTVAR5\t\tenvvar\n"; - -static const CHAR res_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "RemoveEnvironmentStrings\t\t3000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR rci_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR rci_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR rci_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "class\tclass\n"; - -static const CHAR rci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n"; - -static const CHAR rci_appid_dat[] = "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n" - "s38\tS255\tS255\tS255\tS255\tI2\tI2\n" - "AppId\tAppId\n" - "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n"; - -static const CHAR rci_class_dat[] = "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n" - "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n" - "Class\tCLSID\tContext\tComponent_\n" - "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n"; - -static const CHAR rci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "UnregisterClassInfo\t\t3000\n" - "RegisterClassInfo\t\t4000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR rei_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR rei_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR rei_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "extension\textension\n"; - -static const CHAR rei_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n"; - -static const CHAR rei_extension_dat[] = "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n" - "s255\ts72\tS255\tS64\ts38\n" - "Extension\tExtension\tComponent_\n" - "extension\textension\tProg.Id.1\t\textension\n"; - -static const CHAR rei_verb_dat[] = "Extension_\tVerb\tSequence\tCommand\tArgument\n" - "s255\ts32\tI2\tL255\tL255\n" - "Verb\tExtension_\tVerb\n" - "extension\tOpen\t1\t&Open\t/argument\n"; - -static const CHAR rei_progid_dat[] = "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n" - "s255\tS255\tS38\tL255\tS72\tI2\n" - "ProgId\tProgId\n" - "Prog.Id.1\t\t\tdescription\t\t\n"; - -static const CHAR rei_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "UnregisterExtensionInfo\t\t3000\n" - "RegisterExtensionInfo\t\t4000\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; - -static const CHAR rmi_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" - "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" - "File\tFile\n" - "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n"; - -static const CHAR rmi_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" - "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" - "Feature\tFeature\n" - "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n"; - -static const CHAR rmi_feature_comp_dat[] = "Feature_\tComponent_\n" - "s38\ts72\n" - "FeatureComponents\tFeature_\tComponent_\n" - "mime\tmime\n"; - -static const CHAR rmi_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" - "s72\tS38\ts72\ti2\tS255\tS72\n" - "Component\tComponent\n" - "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n"; - -static const CHAR rmi_extension_dat[] = "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n" - "s255\ts72\tS255\tS64\ts38\n" - "Extension\tExtension\tComponent_\n" - "mime\tmime\t\tmime/type\tmime\n"; - -static const CHAR rmi_verb_dat[] = "Extension_\tVerb\tSequence\tCommand\tArgument\n" - "s255\ts32\tI2\tL255\tL255\n" - "Verb\tExtension_\tVerb\n" - "mime\tOpen\t1\t&Open\t/argument\n"; - -static const CHAR rmi_mime_dat[] = "ContentType\tExtension_\tCLSID\n" - "s64\ts255\tS38\n" - "MIME\tContentType\n" - "mime/type\tmime\t\n"; - -static const CHAR rmi_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" - "s72\tS255\tI2\n" - "InstallExecuteSequence\tAction\n" - "LaunchConditions\t\t100\n" - "CostInitialize\t\t800\n" - "FileCost\t\t900\n" - "CostFinalize\t\t1000\n" - "InstallValidate\t\t1400\n" - "InstallInitialize\t\t1500\n" - "ProcessComponents\t\t1600\n" - "RemoveFiles\t\t1700\n" - "InstallFiles\t\t2000\n" - "UnregisterExtensionInfo\t\t3000\n" - "UnregisterMIMEInfo\t\t3500\n" - "RegisterExtensionInfo\t\t4000\n" - "RegisterMIMEInfo\t\t4500\n" - "RegisterProduct\t\t5000\n" - "PublishFeatures\t\t5100\n" - "PublishProduct\t\t5200\n" - "InstallFinalize\t\t6000\n"; +static const CHAR uc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t200\n" + "FileCost\t\t300\n" + "CostFinalize\t\t400\n" + "InstallInitialize\t\t500\n" + "ProcessComponents\t\t600\n" + "InstallValidate\t\t700\n" + "RemoveFiles\t\t800\n" + "InstallFiles\t\t900\n" + "RegisterProduct\t\t1000\n" + "PublishFeatures\t\t1100\n" + "PublishProduct\t\t1200\n" + "InstallFinalize\t\t1300\n"; typedef struct _msi_table { @@ -1992,19 +1287,6 @@ static const msi_table ps_tables[] = ADD_TABLE(condition) }; -static const msi_table env_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property), - ADD_TABLE(environment) -}; - static const msi_table up_tables[] = { ADD_TABLE(component), @@ -2284,30 +1566,6 @@ static const msi_table spf_tables[] = ADD_TABLE(spf_install_ui_seq), }; -static const msi_table pp_tables[] = -{ - ADD_TABLE(ci_component), - ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(rof_feature_comp), - ADD_TABLE(rof_file), - ADD_TABLE(pp_install_exec_seq), - ADD_TABLE(rof_media), - ADD_TABLE(property), -}; - -static const msi_table ppc_tables[] = -{ - ADD_TABLE(ppc_component), - ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(ppc_feature_comp), - ADD_TABLE(ppc_file), - ADD_TABLE(pp_install_exec_seq), - ADD_TABLE(ppc_media), - ADD_TABLE(property), -}; - static const msi_table lus0_tables[] = { ADD_TABLE(ci_component), @@ -2394,32 +1652,6 @@ static const msi_table amp_tables[] = ADD_TABLE(property), }; -static const msi_table rem_tables[] = -{ - ADD_TABLE(rem_component), - ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(rem_feature_comp), - ADD_TABLE(rem_file), - ADD_TABLE(rem_install_exec_seq), - ADD_TABLE(rof_media), - ADD_TABLE(property), - ADD_TABLE(rem_remove_files), -}; - -static const msi_table mov_tables[] = -{ - ADD_TABLE(cwd_component), - ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(ci2_feature_comp), - ADD_TABLE(ci2_file), - ADD_TABLE(install_exec_seq), - ADD_TABLE(rof_media), - ADD_TABLE(property), - ADD_TABLE(mov_move_file), -}; - static const msi_table mc_tables[] = { ADD_TABLE(mc_component), @@ -2433,32 +1665,6 @@ static const msi_table mc_tables[] = ADD_TABLE(mc_file_hash), }; -static const msi_table df_tables[] = -{ - ADD_TABLE(rof_component), - ADD_TABLE(df_directory), - ADD_TABLE(rof_feature), - ADD_TABLE(rof_feature_comp), - ADD_TABLE(rof_file), - ADD_TABLE(install_exec_seq), - ADD_TABLE(rof_media), - ADD_TABLE(property), - ADD_TABLE(df_duplicate_file), -}; - -static const msi_table wrv_tables[] = -{ - ADD_TABLE(wrv_component), - ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(ci2_feature_comp), - ADD_TABLE(ci2_file), - ADD_TABLE(install_exec_seq), - ADD_TABLE(rof_media), - ADD_TABLE(property), - ADD_TABLE(wrv_registry), -}; - static const msi_table sf_tables[] = { ADD_TABLE(wrv_component), @@ -2645,261 +1851,16 @@ static const msi_table fiuc_tables[] = ADD_TABLE(property), }; -static const msi_table cf_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(cf_create_folders), - ADD_TABLE(cf_install_exec_seq), - ADD_TABLE(cf_custom_action), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rf_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(cf_create_folders), - ADD_TABLE(rf_install_exec_seq), - ADD_TABLE(cf_custom_action), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table sss_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(sss_install_exec_seq), - ADD_TABLE(sss_service_control), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table sds_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(sss_install_exec_seq), - ADD_TABLE(service_control), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table sr_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(sr_selfreg), - ADD_TABLE(sr_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table font_tables[] = -{ - ADD_TABLE(font_component), - ADD_TABLE(directory), - ADD_TABLE(font_feature), - ADD_TABLE(font_feature_comp), - ADD_TABLE(font_file), - ADD_TABLE(font), - ADD_TABLE(font_install_exec_seq), - ADD_TABLE(font_media), - ADD_TABLE(property) -}; - -static const msi_table vp_tables[] = -{ - ADD_TABLE(component), - ADD_TABLE(directory), - ADD_TABLE(feature), - ADD_TABLE(feature_comp), - ADD_TABLE(file), - ADD_TABLE(vp_custom_action), - ADD_TABLE(vp_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(vp_property) -}; - -static const msi_table odbc_tables[] = -{ - ADD_TABLE(odbc_component), - ADD_TABLE(directory), - ADD_TABLE(odbc_feature), - ADD_TABLE(odbc_feature_comp), - ADD_TABLE(odbc_file), - ADD_TABLE(odbc_driver), - ADD_TABLE(odbc_translator), - ADD_TABLE(odbc_datasource), - ADD_TABLE(odbc_install_exec_seq), - ADD_TABLE(odbc_media), - ADD_TABLE(property) -}; - -static const msi_table tl_tables[] = -{ - ADD_TABLE(tl_component), - ADD_TABLE(directory), - ADD_TABLE(tl_feature), - ADD_TABLE(tl_feature_comp), - ADD_TABLE(tl_file), - ADD_TABLE(tl_typelib), - ADD_TABLE(tl_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table crs_tables[] = -{ - ADD_TABLE(crs_component), - ADD_TABLE(directory), - ADD_TABLE(crs_feature), - ADD_TABLE(crs_feature_comp), - ADD_TABLE(crs_file), - ADD_TABLE(crs_shortcut), - ADD_TABLE(crs_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table pub_tables[] = +static const msi_table sd_tables[] = { ADD_TABLE(directory), - ADD_TABLE(pub_component), - ADD_TABLE(pub_feature), - ADD_TABLE(pub_feature_comp), - ADD_TABLE(pub_file), - ADD_TABLE(pub_publish_component), - ADD_TABLE(pub_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rd_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(rd_component), - ADD_TABLE(rd_feature), - ADD_TABLE(rd_feature_comp), - ADD_TABLE(rd_file), - ADD_TABLE(rd_duplicate_file), - ADD_TABLE(rd_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rrv_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(rrv_component), - ADD_TABLE(rrv_feature), - ADD_TABLE(rrv_feature_comp), - ADD_TABLE(rrv_file), - ADD_TABLE(rrv_registry), - ADD_TABLE(rrv_remove_registry), - ADD_TABLE(rrv_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table frp_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(frp_component), - ADD_TABLE(frp_feature), - ADD_TABLE(frp_feature_comp), - ADD_TABLE(frp_file), - ADD_TABLE(frp_upgrade), - ADD_TABLE(frp_custom_action), - ADD_TABLE(frp_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table riv_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(riv_component), - ADD_TABLE(riv_feature), - ADD_TABLE(riv_feature_comp), - ADD_TABLE(riv_file), - ADD_TABLE(riv_ini_file), - ADD_TABLE(riv_remove_ini_file), - ADD_TABLE(riv_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table res_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(res_component), - ADD_TABLE(res_feature), - ADD_TABLE(res_feature_comp), - ADD_TABLE(res_file), - ADD_TABLE(res_environment), - ADD_TABLE(res_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rci_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(rci_component), - ADD_TABLE(rci_feature), - ADD_TABLE(rci_feature_comp), - ADD_TABLE(rci_file), - ADD_TABLE(rci_appid), - ADD_TABLE(rci_class), - ADD_TABLE(rci_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rei_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(rei_component), - ADD_TABLE(rei_feature), - ADD_TABLE(rei_feature_comp), - ADD_TABLE(rei_file), - ADD_TABLE(rei_extension), - ADD_TABLE(rei_verb), - ADD_TABLE(rei_progid), - ADD_TABLE(rei_install_exec_seq), - ADD_TABLE(media), - ADD_TABLE(property) -}; - -static const msi_table rmi_tables[] = -{ - ADD_TABLE(directory), - ADD_TABLE(rmi_component), - ADD_TABLE(rmi_feature), - ADD_TABLE(rmi_feature_comp), - ADD_TABLE(rmi_file), - ADD_TABLE(rmi_extension), - ADD_TABLE(rmi_verb), - ADD_TABLE(rmi_mime), - ADD_TABLE(rmi_install_exec_seq), + ADD_TABLE(sd_component), + ADD_TABLE(sd_feature), + ADD_TABLE(sd_feature_comp), + ADD_TABLE(sd_file), + ADD_TABLE(sd_install_exec_seq), + ADD_TABLE(sd_install_ui_seq), + ADD_TABLE(sd_custom_action), ADD_TABLE(media), ADD_TABLE(property) }; @@ -2930,6 +1891,43 @@ static const msi_table icon_base_tables[] = ADD_TABLE(icon_property), }; +static const msi_table pv_tables[] = +{ + ADD_TABLE(rof_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(rof_feature_comp), + ADD_TABLE(rof_file), + ADD_TABLE(pv_install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property) +}; + +static const msi_table cl_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(cl_custom_action), + ADD_TABLE(cl_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + +static const msi_table uc_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(uc_component), + ADD_TABLE(uc_feature), + ADD_TABLE(uc_feature_comp), + ADD_TABLE(uc_file), + ADD_TABLE(uc_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(uc_property) +}; + /* cabinet definitions */ /* make the max size large so there is only one cab file */ @@ -3044,6 +2042,7 @@ static void init_functionpointers(void) { HMODULE hmsi = GetModuleHandleA("msi.dll"); HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); #define GET_PROC(mod, func) \ p ## func = (void*)GetProcAddress(mod, #func); \ @@ -3054,8 +2053,13 @@ static void init_functionpointers(void) GET_PROC(hmsi, MsiSetExternalUIRecord); GET_PROC(hmsi, MsiSourceListEnumSourcesA); GET_PROC(hmsi, MsiSourceListGetInfoA); + GET_PROC(hmsi, MsiGetComponentPathExA); GET_PROC(hadvapi32, ConvertSidToStringSidA); + GET_PROC(hadvapi32, GetTokenInformation); + GET_PROC(hadvapi32, OpenProcessToken); + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hkernel32, IsWow64Process) hsrclient = LoadLibraryA("srclient.dll"); GET_PROC(hsrclient, SRRemoveRestorePoint); @@ -3064,41 +2068,23 @@ static void init_functionpointers(void) #undef GET_PROC } -static BOOL check_win9x(void) -{ - SC_HANDLE scm; - - scm = OpenSCManager(NULL, NULL, GENERIC_ALL); - if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) - return TRUE; - - CloseServiceHandle(scm); - - return FALSE; -} - -static LPSTR get_user_sid(LPSTR *usersid) +static BOOL is_process_limited(void) { HANDLE token; - BYTE buf[1024]; - DWORD size; - PTOKEN_USER user; - if (!pConvertSidToStringSidA) + if (!pOpenProcessToken || !pGetTokenInformation) return FALSE; + + if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { - win_skip("ConvertSidToStringSidA is not available\n"); - return NULL; - } + BOOL ret; + TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; + DWORD size; - *usersid = NULL; - OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - size = sizeof(buf); - GetTokenInformation(token, TokenUser, buf, size, &size); - user = (PTOKEN_USER)buf; - pConvertSidToStringSidA(user->User.Sid, usersid); - ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError()); - CloseHandle(token); - return *usersid; + ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); + CloseHandle(token); + return (ret && type == TokenElevationTypeLimited); + } + return FALSE; } static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val) @@ -3253,14 +2239,21 @@ static BOOL get_system_dirs(void) } size = MAX_PATH; - if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) { + if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) && + RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) { + RegCloseKey(hkey); + return FALSE; + } + + size = MAX_PATH; + if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size)) { RegCloseKey(hkey); return FALSE; } RegCloseKey(hkey); - if(GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH) != ERROR_SUCCESS) + if(!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE; return TRUE; @@ -3322,6 +2315,20 @@ static BOOL delete_pf(const CHAR *rel_path, BOOL is_file) return RemoveDirectoryA(path); } +static BOOL delete_pf_native(const CHAR *rel_path, BOOL is_file) +{ + CHAR path[MAX_PATH]; + + lstrcpyA(path, PROG_FILES_DIR_NATIVE); + lstrcatA(path, "\\"); + lstrcatA(path, rel_path); + + if (is_file) + return DeleteFileA(path); + else + return RemoveDirectoryA(path); +} + static BOOL delete_cf(const CHAR *rel_path, BOOL is_file) { CHAR path[MAX_PATH]; @@ -3336,6 +2343,29 @@ static BOOL delete_cf(const CHAR *rel_path, BOOL is_file) return RemoveDirectoryA(path); } +static BOOL compare_pf_data(const char *filename, const char *data, DWORD size) +{ + DWORD read; + HANDLE handle; + BOOL ret = FALSE; + char *buffer, path[MAX_PATH]; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, filename); + + handle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + buffer = HeapAlloc(GetProcessHeap(), 0, size); + if (buffer) + { + ReadFile(handle, buffer, size, &read, NULL); + if (read == size && !memcmp(data, buffer, size)) ret = TRUE; + HeapFree(GetProcessHeap(), 0, buffer); + } + CloseHandle(handle); + return ret; +} + static void delete_test_files(void) { DeleteFileA("msitest.msi"); @@ -3361,7 +2391,7 @@ static void write_file(const CHAR *filename, const char *data, int data_size) CloseHandle(hf); } -static void write_msi_summary_info(MSIHANDLE db, INT wordcount) +static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template) { MSIHANDLE summary; UINT r; @@ -3369,14 +2399,14 @@ static void write_msi_summary_info(MSIHANDLE db, INT wordcount) r = MsiGetSummaryInformationA(db, NULL, 5, &summary); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033"); + r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL, "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL); + r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL); @@ -3393,10 +2423,14 @@ static void write_msi_summary_info(MSIHANDLE db, INT wordcount) } #define create_database(name, tables, num_tables) \ - create_database_wordcount(name, tables, num_tables, 0); + create_database_wordcount(name, tables, num_tables, 100, 0, ";1033"); + +#define create_database_template(name, tables, num_tables, version, template) \ + create_database_wordcount(name, tables, num_tables, version, 0, template); static void create_database_wordcount(const CHAR *name, const msi_table *tables, - int num_tables, INT wordcount) + int num_tables, INT version, INT wordcount, + const char *template) { MSIHANDLE db; UINT r; @@ -3418,7 +2452,7 @@ static void create_database_wordcount(const CHAR *name, const msi_table *tables, DeleteFileA(table->filename); } - write_msi_summary_info(db, wordcount); + write_msi_summary_info(db, version, wordcount, template); r = MsiDatabaseCommit(db); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -3465,6 +2499,13 @@ static void remove_restore_point(DWORD seq_number) trace("Failed to remove the restore point : %08x\n", res); } +static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + static void test_MsiInstallProduct(void) { UINT r; @@ -3472,13 +2513,19 @@ static void test_MsiInstallProduct(void) LONG res; HKEY hkey; DWORD num, size, type; + REGSAM access = KEY_ALL_ACCESS; - if (on_win9x) + if (is_process_limited()) { - win_skip("Services are not implemented on Win9x and WinMe\n"); + skip("process is limited\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + /* szPackagePath is NULL */ r = MsiInstallProductA(NULL, "INSTALL=ALL"); ok(r == ERROR_INVALID_PARAMETER, @@ -3499,22 +2546,27 @@ static void test_MsiInstallProduct(void) /* install, don't publish */ r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", 0, access, &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; @@ -3542,28 +2594,28 @@ static void test_MsiInstallProduct(void) check_service_is_installed(); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + delete_key(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", access); /* not published, reinstall */ r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table)); @@ -3572,21 +2624,21 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table)); @@ -3595,21 +2647,21 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table)); @@ -3618,21 +2670,21 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); + RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table)); @@ -3641,19 +2693,19 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table)); @@ -3663,19 +2715,19 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table)); @@ -3685,19 +2737,19 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table)); @@ -3707,19 +2759,19 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table)); @@ -3729,25 +2781,27 @@ static void test_MsiInstallProduct(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); + res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +error: delete_test_files(); + DeleteFileA(msifile); } static void test_MsiSetComponentState(void) @@ -3765,7 +2819,14 @@ static void test_MsiSetComponentState(void) lstrcat(path, "\\"); lstrcat(path, msifile); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiOpenPackage(path, &package); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); r = MsiDoAction(package, "CostInitialize"); @@ -3786,8 +2847,9 @@ static void test_MsiSetComponentState(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); MsiCloseHandle(package); - CoUninitialize(); +error: + CoUninitialize(); DeleteFileA(msifile); } @@ -3909,20 +2971,23 @@ static void test_continuouscabs(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_cc_test_files(); create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table)); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); - if (r == ERROR_SUCCESS) /* win9x has a problem with this */ - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); delete_cab_files(); DeleteFile(msifile); @@ -3933,13 +2998,19 @@ static void test_continuouscabs(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: delete_cab_files(); DeleteFile(msifile); } @@ -3962,13 +3033,18 @@ static void test_caborder(void) create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0"); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n"); ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n"); todo_wine { ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n"); - ok(!delete_pf("msitest", FALSE), "File is installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory is created\n"); } delete_cab_files(); @@ -3982,7 +3058,7 @@ static void test_caborder(void) ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n"); ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n"); ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n"); - ok(!delete_pf("msitest", FALSE), "File is installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory is created\n"); delete_cab_files(); DeleteFile(msifile); @@ -3993,7 +3069,7 @@ static void test_caborder(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n"); - ok(!delete_pf("msitest", FALSE), "File is installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory is created\n"); todo_wine { ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n"); @@ -4013,9 +3089,10 @@ static void test_caborder(void) { ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n"); ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n"); - ok(!delete_pf("msitest", FALSE), "File is installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory is created\n"); } +error: delete_cab_files(); DeleteFile("imperator"); DeleteFile("maximus"); @@ -4028,6 +3105,12 @@ static void test_mixedmedia(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\maximus", 500); create_file("msitest\\augustus", 500); @@ -4040,12 +3123,18 @@ static void test_mixedmedia(void) create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0"); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ DeleteFile("msitest\\maximus"); DeleteFile("msitest\\augustus"); @@ -4065,15 +3154,14 @@ static void test_samesequence(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); - if (r == ERROR_SUCCESS) /* win9x has a problem with this */ + ok(r == ERROR_SUCCESS || broken(r == ERROR_INSTALL_FAILURE), "Expected ERROR_SUCCESS, got %u\n", r); + if (r == ERROR_SUCCESS) { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); } - delete_cab_files(); DeleteFile(msifile); } @@ -4088,15 +3176,14 @@ static void test_uiLevelFlags(void) MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL); r = MsiInstallProductA(msifile, NULL); - if (r == ERROR_SUCCESS) /* win9x has a problem with this */ + ok(r == ERROR_SUCCESS || broken(r == ERROR_INSTALL_FAILURE), "Expected ERROR_SUCCESS, got %u\n", r); + if (r == ERROR_SUCCESS) { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); } - delete_cab_files(); DeleteFile(msifile); } @@ -4124,6 +3211,12 @@ static void test_readonlyfile(void) HANDLE file; CHAR path[MAX_PATH]; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\maximus", 500); create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table)); @@ -4142,11 +3235,17 @@ static void test_readonlyfile(void) CloseHandle(file); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(file_matches(path), "Expected file to be overwritten\n"); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ DeleteFile("msitest\\maximus"); RemoveDirectory("msitest"); @@ -4161,6 +3260,12 @@ static void test_readonlyfile_cab(void) CHAR path[MAX_PATH]; CHAR buf[16]; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("maximus", 500); create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0"); @@ -4182,6 +3287,11 @@ static void test_readonlyfile_cab(void) CloseHandle(file); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); memset( buf, 0, sizeof(buf) ); @@ -4193,8 +3303,9 @@ static void test_readonlyfile_cab(void) } ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ delete_cab_files(); DeleteFile("msitest\\maximus"); @@ -4274,6 +3385,11 @@ static void test_lastusedsource(void) ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); lstrcpyA(path, CURR_DIR); @@ -4284,11 +3400,8 @@ static void test_lastusedsource(void) r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - todo_wine - { ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); - } r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -4313,11 +3426,8 @@ static void test_lastusedsource(void) r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - todo_wine - { ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); - } r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -4341,11 +3451,8 @@ static void test_lastusedsource(void) r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - todo_wine - { ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); - } r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -4357,6 +3464,7 @@ static void test_lastusedsource(void) ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r); ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); +error: /* Delete the files in the temp (current) folder */ delete_cab_files(); DeleteFile("msitest\\maximus"); @@ -4370,6 +3478,12 @@ static void test_setdirproperty(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\maximus", 500); create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table)); @@ -4377,10 +3491,16 @@ static void test_setdirproperty(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_cf("msitest", FALSE), "File not installed\n"); + ok(delete_cf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ DeleteFile(msifile); DeleteFile("msitest\\maximus"); @@ -4391,6 +3511,12 @@ static void test_cabisextracted(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\gaius", 500); create_file("maximus", 500); @@ -4406,13 +3532,19 @@ static void test_cabisextracted(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ delete_cab_files(); DeleteFile(msifile); @@ -4428,6 +3560,12 @@ static void test_concurrentinstall(void) UINT r; CHAR path[MAX_PATH]; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); CreateDirectoryA("msitest\\msitest", NULL); create_file("msitest\\maximus", 500); @@ -4442,11 +3580,17 @@ static void test_concurrentinstall(void) MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(path); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); if (!delete_pf("msitest\\augustus", TRUE)) trace("concurrent installs not supported\n"); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); DeleteFile(path); @@ -4454,8 +3598,9 @@ static void test_concurrentinstall(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: DeleteFile(msifile); DeleteFile("msitest\\msitest\\augustus"); DeleteFile("msitest\\maximus"); @@ -4469,6 +3614,12 @@ static void test_setpropertyfolder(void) CHAR path[MAX_PATH]; DWORD attr; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + lstrcpyA(path, PROG_FILES_DIR); lstrcatA(path, "\\msitest\\added"); @@ -4480,21 +3631,27 @@ static void test_setpropertyfolder(void) MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); attr = GetFileAttributesA(path); if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\added", FALSE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\added", FALSE), "Directory not created\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); } else { trace("changing folder property not supported\n"); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); } +error: /* Delete the files in the temp (current) folder */ DeleteFile(msifile); DeleteFile("msitest\\maximus"); @@ -4530,7 +3687,7 @@ static void delete_pfmsitest_files(void) shfl.wFunc = FO_DELETE; shfl.pFrom = path; shfl.pTo = NULL; - shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT; + shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI; SHFileOperation(&shfl); @@ -4539,1631 +3696,6 @@ static void delete_pfmsitest_files(void) RemoveDirectoryA(path); } -static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line) -{ - char val[MAX_PATH]; - DWORD size, type; - LONG res; - - size = MAX_PATH; - val[0] = '\0'; - res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size); - - if (res != ERROR_SUCCESS || - (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ)) - { - ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); - return; - } - - if (!expected) - ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val); - else - { - if (bcase) - ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val); - else - ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val); - } -} - -static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line) -{ - DWORD val, size, type; - LONG res; - - size = sizeof(DWORD); - res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); - - if (res != ERROR_SUCCESS || type != REG_DWORD) - { - ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); - return; - } - - ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val); -} - -static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line) -{ - DWORD val, size, type; - LONG res; - - size = sizeof(DWORD); - res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); - - if (res != ERROR_SUCCESS || type != REG_DWORD) - { - ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); - return; - } - - ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val); -} - -static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line) -{ - DWORD val, size, type; - LONG res; - - size = sizeof(DWORD); - res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size); - - if (res != ERROR_SUCCESS || type != REG_DWORD) - { - ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n"); - return; - } - - ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3, - "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val); -} - -#define CHECK_REG_STR(prodkey, name, expected) \ - check_reg_str(prodkey, name, expected, TRUE, __LINE__); - -#define CHECK_DEL_REG_STR(prodkey, name, expected) \ - check_reg_str(prodkey, name, expected, TRUE, __LINE__); \ - RegDeleteValueA(prodkey, name); - -#define CHECK_REG_ISTR(prodkey, name, expected) \ - check_reg_str(prodkey, name, expected, FALSE, __LINE__); - -#define CHECK_DEL_REG_ISTR(prodkey, name, expected) \ - check_reg_str(prodkey, name, expected, FALSE, __LINE__); \ - RegDeleteValueA(prodkey, name); - -#define CHECK_REG_DWORD(prodkey, name, expected) \ - check_reg_dword(prodkey, name, expected, __LINE__); - -#define CHECK_DEL_REG_DWORD(prodkey, name, expected) \ - check_reg_dword(prodkey, name, expected, __LINE__); \ - RegDeleteValueA(prodkey, name); - -#define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \ - check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); - -#define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \ - check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \ - RegDeleteValueA(prodkey, name); - -#define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \ - check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); - -#define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \ - check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \ - RegDeleteValueA(prodkey, name); - -static void get_date_str(LPSTR date) -{ - SYSTEMTIME systime; - - static const char date_fmt[] = "%d%02d%02d"; - GetLocalTime(&systime); - sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay); -} - -static void test_publish_registerproduct(void) -{ - UINT r; - LONG res; - HKEY hkey; - HKEY props, usage; - LPSTR usersid; - char date[MAX_PATH]; - char temp[MAX_PATH]; - char keypath[MAX_PATH]; - - static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion" - "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; - static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" - "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" - "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2"; - static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes" - "\\51AAE0C44620A5E4788506E91F249BD2"; - - if (!get_user_sid(&usersid)) - return; - - get_date_str(date); - GetTempPath(MAX_PATH, temp); - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* RegisterProduct */ - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST"); - CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1"); - CHECK_DEL_REG_STR(hkey, "InstallDate", date); - CHECK_DEL_REG_STR(hkey, "InstallSource", temp); - CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(hkey, "Publisher", "Wine"); - CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL); - CHECK_DEL_REG_STR(hkey, "Comments", NULL); - CHECK_DEL_REG_STR(hkey, "Contact", NULL); - CHECK_DEL_REG_STR(hkey, "HelpLink", NULL); - CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL); - CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL); - CHECK_DEL_REG_STR(hkey, "Readme", NULL); - CHECK_DEL_REG_STR(hkey, "Size", NULL); - CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL); - CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL); - CHECK_DEL_REG_DWORD(hkey, "Language", 1033); - CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); - CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1); - CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1); - CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4); - } - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - sprintf(keypath, userdata, usersid); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegOpenKeyA(hkey, "InstallProperties", &props); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */ - CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST"); - CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1"); - CHECK_DEL_REG_STR(props, "InstallDate", date); - CHECK_DEL_REG_STR(props, "InstallSource", temp); - CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(props, "Publisher", "Wine"); - CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL); - CHECK_DEL_REG_STR(props, "Comments", NULL); - CHECK_DEL_REG_STR(props, "Contact", NULL); - CHECK_DEL_REG_STR(props, "HelpLink", NULL); - CHECK_DEL_REG_STR(props, "HelpTelephone", NULL); - CHECK_DEL_REG_STR(props, "InstallLocation", NULL); - CHECK_DEL_REG_STR(props, "Readme", NULL); - CHECK_DEL_REG_STR(props, "Size", NULL); - CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL); - CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL); - CHECK_DEL_REG_DWORD(props, "Language", 1033); - CHECK_DEL_REG_DWORD(props, "Version", 0x1010001); - CHECK_DEL_REG_DWORD(props, "VersionMajor", 1); - CHECK_DEL_REG_DWORD(props, "VersionMinor", 1); - CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1); - todo_wine - { - CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4); - } - - RegDeleteKeyA(props, ""); - RegCloseKey(props); - - res = RegOpenKeyA(hkey, "Usage", &usage); - todo_wine - { - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - } - - RegDeleteKeyA(usage, ""); - RegCloseKey(usage); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - /* RegisterProduct, machine */ - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST"); - CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1"); - CHECK_DEL_REG_STR(hkey, "InstallDate", date); - CHECK_DEL_REG_STR(hkey, "InstallSource", temp); - CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(hkey, "Publisher", "Wine"); - CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL); - CHECK_DEL_REG_STR(hkey, "Comments", NULL); - CHECK_DEL_REG_STR(hkey, "Contact", NULL); - CHECK_DEL_REG_STR(hkey, "HelpLink", NULL); - CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL); - CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL); - CHECK_DEL_REG_STR(hkey, "Readme", NULL); - CHECK_DEL_REG_STR(hkey, "Size", NULL); - CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL); - CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL); - CHECK_DEL_REG_DWORD(hkey, "Language", 1033); - CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); - CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1); - CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1); - CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4); - } - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - sprintf(keypath, userdata, "S-1-5-18"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegOpenKeyA(hkey, "InstallProperties", &props); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */ - CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST"); - CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1"); - CHECK_DEL_REG_STR(props, "InstallDate", date); - CHECK_DEL_REG_STR(props, "InstallSource", temp); - CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(props, "Publisher", "Wine"); - CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL); - CHECK_DEL_REG_STR(props, "Comments", NULL); - CHECK_DEL_REG_STR(props, "Contact", NULL); - CHECK_DEL_REG_STR(props, "HelpLink", NULL); - CHECK_DEL_REG_STR(props, "HelpTelephone", NULL); - CHECK_DEL_REG_STR(props, "InstallLocation", NULL); - CHECK_DEL_REG_STR(props, "Readme", NULL); - CHECK_DEL_REG_STR(props, "Size", NULL); - CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL); - CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL); - CHECK_DEL_REG_DWORD(props, "Language", 1033); - CHECK_DEL_REG_DWORD(props, "Version", 0x1010001); - CHECK_DEL_REG_DWORD(props, "VersionMajor", 1); - CHECK_DEL_REG_DWORD(props, "VersionMinor", 1); - CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1); - todo_wine - { - CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4); - } - - RegDeleteKeyA(props, ""); - RegCloseKey(props); - - res = RegOpenKeyA(hkey, "Usage", &usage); - todo_wine - { - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - } - - RegDeleteKeyA(usage, ""); - RegCloseKey(usage); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - HeapFree(GetProcessHeap(), 0, usersid); -} - -static void test_publish_publishproduct(void) -{ - UINT r; - LONG res; - LPSTR usersid; - HKEY sourcelist, net, props; - HKEY hkey, patches, media; - CHAR keypath[MAX_PATH]; - CHAR temp[MAX_PATH]; - CHAR path[MAX_PATH]; - BOOL old_installer = FALSE; - - static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion" - "\\Installer\\UserData\\%s\\Products" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes" - "\\51AAE0C44620A5E4788506E91F249BD2"; - static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion" - "\\Installer\\Products" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2"; - - if (!get_user_sid(&usersid)) - return; - - GetTempPath(MAX_PATH, temp); - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* PublishProduct, current user */ - r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - sprintf(keypath, prodpath, usersid); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - if (res == ERROR_FILE_NOT_FOUND) - { - res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey); - if (res == ERROR_SUCCESS) - { - win_skip("Windows Installer < 3.0 detected\n"); - RegCloseKey(hkey); - old_installer = TRUE; - goto currentuser; - } - else - { - win_skip("Install failed, no need to continue\n"); - return; - } - } - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegOpenKeyA(hkey, "InstallProperties", &props); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(hkey, "Patches", &patches); - todo_wine - { - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(patches, "AllPatches", NULL); - } - - RegDeleteKeyA(patches, ""); - RegCloseKey(patches); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - -currentuser: - res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST"); - CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F"); - CHECK_DEL_REG_DWORD(hkey, "Language", 1033); - CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); - if (!old_installer) - CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0); - CHECK_DEL_REG_DWORD(hkey, "Assignment", 0); - CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184); - CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0); - CHECK_DEL_REG_STR(hkey, "Clients", ":"); - - res = RegOpenKeyA(hkey, "SourceList", &sourcelist); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - lstrcpyA(path, "n;1;"); - lstrcatA(path, temp); - CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path); - CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi"); - - res = RegOpenKeyA(sourcelist, "Net", &net); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(net, "1", temp); - - RegDeleteKeyA(net, ""); - RegCloseKey(net); - - res = RegOpenKeyA(sourcelist, "Media", &media); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(media, "1", "DISK1;"); - - RegDeleteKeyA(media, ""); - RegCloseKey(media); - RegDeleteKeyA(sourcelist, ""); - RegCloseKey(sourcelist); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - /* PublishProduct, machine */ - r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1"); - if (old_installer) - goto machprod; - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - sprintf(keypath, prodpath, "S-1-5-18"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegOpenKeyA(hkey, "InstallProperties", &props); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(hkey, "Patches", &patches); - todo_wine - { - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(patches, "AllPatches", NULL); - } - - RegDeleteKeyA(patches, ""); - RegCloseKey(patches); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - -machprod: - res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST"); - CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F"); - CHECK_DEL_REG_DWORD(hkey, "Language", 1033); - CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001); - if (!old_installer) - CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0); - todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1); - CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184); - CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0); - CHECK_DEL_REG_STR(hkey, "Clients", ":"); - - res = RegOpenKeyA(hkey, "SourceList", &sourcelist); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - lstrcpyA(path, "n;1;"); - lstrcatA(path, temp); - CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path); - CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi"); - - res = RegOpenKeyA(sourcelist, "Net", &net); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(net, "1", temp); - - RegDeleteKeyA(net, ""); - RegCloseKey(net); - - res = RegOpenKeyA(sourcelist, "Media", &media); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(media, "1", "DISK1;"); - - RegDeleteKeyA(media, ""); - RegCloseKey(media); - RegDeleteKeyA(sourcelist, ""); - RegCloseKey(sourcelist); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL); - - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - HeapFree(GetProcessHeap(), 0, usersid); -} - -static void test_publish_publishfeatures(void) -{ - UINT r; - LONG res; - HKEY hkey; - LPSTR usersid; - CHAR keypath[MAX_PATH]; - - static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion" - "\\Installer\\UserData\\%s\\Products" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features"; - static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion" - "\\Installer\\Features"; - static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features" - "\\84A88FD7F6998CE40A22FB59F6B9C2BB"; - - if (!get_user_sid(&usersid)) - return; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* PublishFeatures, current user */ - r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(hkey, "feature", ""); - CHECK_REG_STR(hkey, "montecristo", ""); - - RegDeleteValueA(hkey, "feature"); - RegDeleteValueA(hkey, "montecristo"); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - sprintf(keypath, udpath, usersid); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE"); - CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE"); - - RegDeleteValueA(hkey, "feature"); - RegDeleteValueA(hkey, "montecristo"); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - /* PublishFeatures, machine */ - r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(hkey, "feature", ""); - CHECK_REG_STR(hkey, "montecristo", ""); - - RegDeleteValueA(hkey, "feature"); - RegDeleteValueA(hkey, "montecristo"); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - sprintf(keypath, udpath, "S-1-5-18"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE"); - CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE"); - - RegDeleteValueA(hkey, "feature"); - RegDeleteValueA(hkey, "montecristo"); - RegDeleteKeyA(hkey, ""); - RegCloseKey(hkey); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - HeapFree(GetProcessHeap(), 0, usersid); -} - -static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name) -{ - DWORD len = 0; - LPSTR val; - LONG r; - - r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len); - if (r != ERROR_SUCCESS) - return NULL; - - len += sizeof (WCHAR); - val = HeapAlloc(GetProcessHeap(), 0, len); - if (!val) return NULL; - val[0] = 0; - RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len); - return val; -} - -static void get_owner_company(LPSTR *owner, LPSTR *company) -{ - LONG res; - HKEY hkey; - - *owner = *company = NULL; - - res = RegOpenKeyA(HKEY_CURRENT_USER, - "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey); - if (res == ERROR_SUCCESS) - { - *owner = reg_get_val_str(hkey, "DefName"); - *company = reg_get_val_str(hkey, "DefCompany"); - RegCloseKey(hkey); - } - - if (!*owner || !*company) - { - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion", &hkey); - if (res == ERROR_SUCCESS) - { - *owner = reg_get_val_str(hkey, "RegisteredOwner"); - *company = reg_get_val_str(hkey, "RegisteredOrganization"); - RegCloseKey(hkey); - } - } - - if (!*owner || !*company) - { - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey); - if (res == ERROR_SUCCESS) - { - *owner = reg_get_val_str(hkey, "RegisteredOwner"); - *company = reg_get_val_str(hkey, "RegisteredOrganization"); - RegCloseKey(hkey); - } - } -} - -static void test_publish_registeruser(void) -{ - UINT r; - LONG res; - HKEY props; - LPSTR usersid; - LPSTR owner, company; - CHAR keypath[MAX_PATH]; - - static const CHAR keyfmt[] = - "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" - "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties"; - - if (!get_user_sid(&usersid)) - return; - - get_owner_company(&owner, &company); - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* RegisterUser, per-user */ - r = MsiInstallProductA(msifile, "REGISTER_USER=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - sprintf(keypath, keyfmt, usersid); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(props, "ProductID", "none"); - CHECK_REG_STR(props, "RegCompany", company); - CHECK_REG_STR(props, "RegOwner", owner); - - RegDeleteValueA(props, "ProductID"); - RegDeleteValueA(props, "RegCompany"); - RegDeleteValueA(props, "RegOwner"); - RegDeleteKeyA(props, ""); - RegCloseKey(props); - - /* RegisterUser, machine */ - r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - sprintf(keypath, keyfmt, "S-1-5-18"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(props, "ProductID", "none"); - CHECK_REG_STR(props, "RegCompany", company); - CHECK_REG_STR(props, "RegOwner", owner); - - RegDeleteValueA(props, "ProductID"); - RegDeleteValueA(props, "RegCompany"); - RegDeleteValueA(props, "RegOwner"); - RegDeleteKeyA(props, ""); - RegCloseKey(props); - - HeapFree(GetProcessHeap(), 0, company); - HeapFree(GetProcessHeap(), 0, owner); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - LocalFree(usersid); -} - -static void test_publish_processcomponents(void) -{ - UINT r; - LONG res; - DWORD size; - HKEY comp, hkey; - LPSTR usersid; - CHAR val[MAX_PATH]; - CHAR keypath[MAX_PATH]; - CHAR program_files_maximus[MAX_PATH]; - - static const CHAR keyfmt[] = - "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" - "UserData\\%s\\Components\\%s"; - static const CHAR compkey[] = - "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components"; - - if (!get_user_sid(&usersid)) - return; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* ProcessComponents, per-user */ - r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - size = MAX_PATH; - res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", - NULL, NULL, (LPBYTE)val, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - lstrcpyA(program_files_maximus,PROG_FILES_DIR); - lstrcatA(program_files_maximus,"\\msitest\\maximus"); - - ok(!lstrcmpiA(val, program_files_maximus), - "Expected \"%s\", got \"%s\"\n", program_files_maximus, val); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); - RegDeleteKeyA(comp, ""); - RegCloseKey(comp); - - sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - size = MAX_PATH; - res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", - NULL, NULL, (LPBYTE)val, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(!lstrcmpA(val, "01\\msitest\\augustus"), - "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); - RegDeleteKeyA(comp, ""); - RegCloseKey(comp); - - /* ProcessComponents, machine */ - r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - size = MAX_PATH; - res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", - NULL, NULL, (LPBYTE)val, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(!lstrcmpiA(val, program_files_maximus), - "Expected \"%s\", got \"%s\"\n", program_files_maximus, val); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); - RegDeleteKeyA(comp, ""); - RegCloseKey(comp); - - sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - size = MAX_PATH; - res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", - NULL, NULL, (LPBYTE)val, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(!lstrcmpA(val, "01\\msitest\\augustus"), - "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); - RegDeleteKeyA(comp, ""); - RegCloseKey(comp); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - LocalFree(usersid); -} - -static void test_publish(void) -{ - UINT r; - LONG res; - HKEY uninstall, prodkey; - INSTALLSTATE state; - CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; - char date[MAX_PATH]; - char temp[MAX_PATH]; - - static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; - - if (!pMsiQueryComponentStateA) - { - win_skip("MsiQueryComponentStateA is not available\n"); - return; - } - - get_date_str(date); - GetTempPath(MAX_PATH, temp); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* nothing published */ - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* PublishProduct and RegisterProduct */ - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12); - } - - RegCloseKey(prodkey); - - r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File deleted\n"); - ok(pf_exists("msitest"), "File deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* complete install */ - r = MsiInstallProductA(msifile, "FULL=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12); - } - - RegCloseKey(prodkey); - - /* no UnpublishFeatures */ - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); - ok(!pf_exists("msitest"), "Directory not deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* complete install */ - r = MsiInstallProductA(msifile, "FULL=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12); - } - - RegCloseKey(prodkey); - - /* UnpublishFeatures, only feature removed. Only works when entire product is removed */ - r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n"); - todo_wine ok(pf_exists("msitest"), "Directory deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12); - } - - RegCloseKey(prodkey); - - /* complete install */ - r = MsiInstallProductA(msifile, "FULL=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20); - } - - RegCloseKey(prodkey); - - /* UnpublishFeatures, both features removed */ - r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); - ok(!pf_exists("msitest"), "Directory not deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* complete install */ - r = MsiInstallProductA(msifile, "FULL=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - CHECK_REG_STR(prodkey, "DisplayName", "MSITEST"); - CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1"); - CHECK_REG_STR(prodkey, "InstallDate", date); - CHECK_REG_STR(prodkey, "InstallSource", temp); - CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "Publisher", "Wine"); - CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL); - CHECK_REG_STR(prodkey, "Comments", NULL); - CHECK_REG_STR(prodkey, "Contact", NULL); - CHECK_REG_STR(prodkey, "HelpLink", NULL); - CHECK_REG_STR(prodkey, "HelpTelephone", NULL); - CHECK_REG_STR(prodkey, "InstallLocation", NULL); - CHECK_REG_STR(prodkey, "Readme", NULL); - CHECK_REG_STR(prodkey, "Size", NULL); - CHECK_REG_STR(prodkey, "URLInfoAbout", NULL); - CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL); - CHECK_REG_DWORD(prodkey, "Language", 1033); - CHECK_REG_DWORD(prodkey, "Version", 0x1010001); - CHECK_REG_DWORD(prodkey, "VersionMajor", 1); - CHECK_REG_DWORD(prodkey, "VersionMinor", 1); - CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1); - todo_wine - { - CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12); - } - - RegCloseKey(prodkey); - - /* complete uninstall */ - r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); - ok(!pf_exists("msitest"), "Directory not deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* make sure 'Program Files\msitest' is removed */ - delete_pfmsitest_files(); - - RegCloseKey(uninstall); - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); -} - -static void test_publishsourcelist(void) -{ - UINT r; - DWORD size; - CHAR value[MAX_PATH]; - CHAR path[MAX_PATH]; - CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; - - if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA) - { - win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n"); - return; - } - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - /* nothing published */ - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - /* after RegisterProduct */ - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - /* after ProcessComponents */ - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - /* after PublishFeatures */ - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); - ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value); - - r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - /* after PublishProduct */ - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value); - ok(size == 11, "Expected 11, got %d\n", size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value); - ok(size == 0, "Expected 0, got %d\n", size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value); - ok(size == 0, "Expected 0, got %d\n", size); - - lstrcpyA(path, CURR_DIR); - lstrcatA(path, "\\"); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); - ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value); - ok(size == 1, "Expected 1, got %d\n", size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size); - ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); - ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); - ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value); - ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size); - - size = MAX_PATH; - lstrcpyA(value, "aaa"); - r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size); - ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); - ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); - ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - - /* complete uninstall */ - r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); - ok(!pf_exists("msitest"), "Directory not deleted\n"); - - /* make sure 'Program Files\msitest' is removed */ - delete_pfmsitest_files(); - - DeleteFile(msifile); - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); -} - static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query) { MSIHANDLE hview = 0; @@ -6236,10 +3768,8 @@ static void generate_transform(void) r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0); ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r); -#if 0 /* not implemented in wine yet */ r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); -#endif + todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); MsiCloseHandle(hdb1); MsiCloseHandle(hdb2); @@ -6327,6 +3857,12 @@ static void test_transformprop(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -6335,9 +3871,14 @@ static void test_transformprop(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); if (0) generate_transform(); @@ -6347,8 +3888,9 @@ static void test_transformprop(void) r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: /* Delete the files in the temp (current) folder */ DeleteFile(msifile); DeleteFile(msifile2); @@ -6363,6 +3905,12 @@ static void test_currentworkingdir(void) CHAR drive[MAX_PATH], path[MAX_PATH]; LPSTR ptr; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -6379,14 +3927,19 @@ static void test_currentworkingdir(void) { ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); } sprintf(path, "%s\\%s", CURR_DIR, msifile); r = MsiInstallProductA(path, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); lstrcpyA(drive, CURR_DIR); drive[2] = '\\'; @@ -6403,10 +3956,10 @@ static void test_currentworkingdir(void) r = MsiInstallProductA(ptr, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: SetCurrentDirectoryA(CURR_DIR); - DeleteFile(msifile); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -6452,22 +4005,28 @@ static void test_admin(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n"); ok(!RemoveDirectory("c:\\msitest"), "File installed\n"); r = MsiInstallProductA(msifile, "ACTION=ADMIN"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); todo_wine { ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n"); ok(RemoveDirectory("c:\\msitest"), "File not installed\n"); } +error: DeleteFile(msifile); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -6508,6 +4067,12 @@ static void test_adminprops(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -6518,10 +4083,16 @@ static void test_adminprops(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File installed\n"); + ok(delete_pf("msitest", FALSE), "Directory created\n"); +error: DeleteFile(msifile); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -6543,271 +4114,50 @@ static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file) #define create_pf(file, is_file) create_pf_data(file, file, is_file) -static void test_removefiles(void) -{ - UINT r; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\hydrogen", 500); - create_file("msitest\\helium", 500); - create_file("msitest\\lithium", 500); - - create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); - ok(!pf_exists("msitest\\helium"), "File installed\n"); - ok(pf_exists("msitest\\lithium"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n"); - ok(!pf_exists("msitest\\helium"), "File not deleted\n"); - ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); - ok(delete_pf("msitest", FALSE), "File deleted\n"); - - create_pf("msitest", FALSE); - create_pf("msitest\\hydrogen", TRUE); - create_pf("msitest\\helium", TRUE); - create_pf("msitest\\lithium", TRUE); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); - ok(pf_exists("msitest\\helium"), "File not installed\n"); - ok(pf_exists("msitest\\lithium"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n"); - ok(delete_pf("msitest\\helium", TRUE), "File deleted\n"); - ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); - ok(delete_pf("msitest", FALSE), "File deleted\n"); - - create_pf("msitest", FALSE); - create_pf("msitest\\furlong", TRUE); - create_pf("msitest\\firkin", TRUE); - create_pf("msitest\\fortnight", TRUE); - create_pf("msitest\\becquerel", TRUE); - create_pf("msitest\\dioptre", TRUE); - create_pf("msitest\\attoparsec", TRUE); - create_pf("msitest\\storeys", TRUE); - create_pf("msitest\\block", TRUE); - create_pf("msitest\\siriometer", TRUE); - create_pf("msitest\\cabout", FALSE); - create_pf("msitest\\cabout\\blocker", TRUE); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); - ok(!pf_exists("msitest\\helium"), "File installed\n"); - ok(pf_exists("msitest\\lithium"), "File not installed\n"); - ok(!pf_exists("msitest\\furlong"), "File not deleted\n"); - ok(!pf_exists("msitest\\firkin"), "File not deleted\n"); - ok(!pf_exists("msitest\\fortnight"), "File not deleted\n"); - ok(pf_exists("msitest\\becquerel"), "File not installed\n"); - ok(pf_exists("msitest\\dioptre"), "File not installed\n"); - ok(pf_exists("msitest\\attoparsec"), "File not installed\n"); - ok(!pf_exists("msitest\\storeys"), "File not deleted\n"); - ok(!pf_exists("msitest\\block"), "File not deleted\n"); - ok(!pf_exists("msitest\\siriometer"), "File not deleted\n"); - ok(pf_exists("msitest\\cabout"), "Directory removed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - create_pf("msitest\\furlong", TRUE); - create_pf("msitest\\firkin", TRUE); - create_pf("msitest\\fortnight", TRUE); - create_pf("msitest\\storeys", TRUE); - create_pf("msitest\\block", TRUE); - create_pf("msitest\\siriometer", TRUE); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n"); - ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n"); - ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n"); - ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n"); - ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n"); - ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n"); - ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n"); - ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n"); - ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n"); - ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n"); - ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n"); - ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n"); - ok(pf_exists("msitest\\cabout"), "Directory deleted\n"); - ok(pf_exists("msitest"), "Directory deleted\n"); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n"); - ok(!delete_pf("msitest\\helium", TRUE), "File installed\n"); - ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n"); - ok(pf_exists("msitest\\cabout"), "Directory deleted\n"); - ok(pf_exists("msitest"), "Directory deleted\n"); - - delete_pf("msitest\\cabout\\blocker", TRUE); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n"); - ok(delete_pf("msitest", FALSE), "Directory deleted\n"); - - DeleteFile(msifile); - DeleteFile("msitest\\hydrogen"); - DeleteFile("msitest\\helium"); - DeleteFile("msitest\\lithium"); - RemoveDirectory("msitest"); -} - -static void test_movefiles(void) -{ - UINT r; - char props[MAX_PATH]; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\augustus", 100); - create_file("cameroon", 100); - create_file("djibouti", 100); - create_file("egypt", 100); - create_file("finland", 100); - create_file("gambai", 100); - create_file("honduras", 100); - create_file("msitest\\india", 100); - create_file("japan", 100); - create_file("kenya", 100); - CreateDirectoryA("latvia", NULL); - create_file("nauru", 100); - create_file("peru", 100); - create_file("apple", 100); - create_file("application", 100); - create_file("ape", 100); - create_file("foo", 100); - create_file("fao", 100); - create_file("fbod", 100); - create_file("budding", 100); - create_file("buddy", 100); - create_file("bud", 100); - create_file("bar", 100); - create_file("bur", 100); - create_file("bird", 100); - - create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - - /* if the source or dest property is not a full path, - * windows tries to access it as a network resource - */ - - sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" " - "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"", - CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR); - - r = MsiInstallProductA(msifile, props); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(!delete_pf("msitest\\dest", TRUE), "File copied\n"); - ok(delete_pf("msitest\\canada", TRUE), "File not copied\n"); - ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n"); - ok(!delete_pf("msitest\\france", TRUE), "File moved\n"); - ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n"); - ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n"); - ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n"); - ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n"); - ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n"); - ok(delete_pf("msitest\\poland", TRUE), "File not moved\n"); - /* either apple or application will be moved depending on directory order */ - if (!delete_pf("msitest\\apple", TRUE)) - ok(delete_pf("msitest\\application", TRUE), "File not moved\n"); - else - ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n"); - ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\ape", TRUE), "File moved\n"); - /* either fao or foo will be moved depending on directory order */ - if (delete_pf("msitest\\foo", TRUE)) - ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n"); - else - ok(delete_pf("msitest\\fao", TRUE), "File not moved\n"); - ok(delete_pf("msitest\\single", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n"); - ok(delete_pf("msitest\\budding", TRUE), "File not moved\n"); - ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\bud", TRUE), "File moved\n"); - ok(delete_pf("msitest\\bar", TRUE), "File not moved\n"); - ok(delete_pf("msitest\\bur", TRUE), "File not moved\n"); - ok(!delete_pf("msitest\\bird", TRUE), "File moved\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - ok(DeleteFileA("cameroon"), "File moved\n"); - ok(!DeleteFileA("djibouti"), "File not moved\n"); - ok(DeleteFileA("egypt"), "File moved\n"); - ok(DeleteFileA("finland"), "File moved\n"); - ok(DeleteFileA("gambai"), "File moved\n"); - ok(!DeleteFileA("honduras"), "File not moved\n"); - ok(DeleteFileA("msitest\\india"), "File moved\n"); - ok(DeleteFileA("japan"), "File moved\n"); - ok(!DeleteFileA("kenya"), "File not moved\n"); - ok(RemoveDirectoryA("latvia"), "Directory moved\n"); - ok(!DeleteFileA("nauru"), "File not moved\n"); - ok(!DeleteFileA("peru"), "File not moved\n"); - ok(!DeleteFileA("apple"), "File not moved\n"); - ok(!DeleteFileA("application"), "File not moved\n"); - ok(DeleteFileA("ape"), "File moved\n"); - ok(!DeleteFileA("foo"), "File not moved\n"); - ok(!DeleteFileA("fao"), "File not moved\n"); - ok(DeleteFileA("fbod"), "File moved\n"); - ok(!DeleteFileA("budding"), "File not moved\n"); - ok(!DeleteFileA("buddy"), "File not moved\n"); - ok(DeleteFileA("bud"), "File moved\n"); - ok(!DeleteFileA("bar"), "File not moved\n"); - ok(!DeleteFileA("bur"), "File not moved\n"); - ok(DeleteFileA("bird"), "File moved\n"); - - DeleteFile("msitest\\augustus"); - RemoveDirectory("msitest"); - DeleteFile(msifile); -} - static void test_missingcab(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); create_file("maximus", 500); + create_file("tiberius", 500); create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table)); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0"); + create_cab_file("test4.cab", MEDIA_SIZE, "tiberius\0"); create_pf("msitest", FALSE); create_pf_data("msitest\\caesar", "abcdefgh", TRUE); + create_pf_data("msitest\\tiberius", "abcdefgh", TRUE); r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS || - broken(r == ERROR_INSTALL_FAILURE), /* win9x */ - "Expected ERROR_SUCCESS, got %u\n", r); - if (r == ERROR_SUCCESS) + if (r == ERROR_INSTALL_PACKAGE_REJECTED) { - ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + skip("Not enough rights to perform tests\n"); + goto error; } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n"); + ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n"); + ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); create_pf("msitest", FALSE); create_pf_data("msitest\\caesar", "abcdefgh", TRUE); + create_pf_data("msitest\\tiberius", "abcdefgh", TRUE); create_pf("msitest\\gaius", TRUE); r = MsiInstallProductA(msifile, "GAIUS=1"); @@ -6818,87 +4168,32 @@ static void test_missingcab(void) ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); } ok(delete_pf("msitest\\caesar", TRUE), "File removed\n"); + ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n"); + ok(delete_pf("msitest\\tiberius", TRUE), "File removed\n"); ok(delete_pf("msitest\\gaius", TRUE), "File removed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: + delete_pf("msitest", FALSE); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); DeleteFile("maximus"); + DeleteFile("tiberius"); DeleteFile("test1.cab"); + DeleteFile("test4.cab"); DeleteFile(msifile); } -static void test_duplicatefiles(void) -{ - UINT r; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\maximus", 500); - create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - /* fails if the destination folder is not a valid property */ - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n"); - ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n"); - ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n"); - ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n"); - ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - DeleteFile("msitest\\maximus"); - RemoveDirectory("msitest"); - DeleteFile(msifile); -} - -static void test_writeregistryvalues(void) -{ - UINT r; - LONG res; - HKEY hkey; - DWORD type, size; - CHAR path[MAX_PATH]; - - CreateDirectoryA("msitest", NULL); - create_file("msitest\\augustus", 500); - - create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File installed\n"); - - res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - size = MAX_PATH; - type = REG_MULTI_SZ; - memset(path, 'a', MAX_PATH); - res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n"); - ok(size == 15, "Expected 15, got %d\n", size); - ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type); - - DeleteFile(msifile); - DeleteFile("msitest\\augustus"); - RemoveDirectory("msitest"); - - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine"); -} - static void test_sourcefolder(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("augustus", 500); @@ -6907,14 +4202,18 @@ static void test_sourcefolder(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); todo_wine { - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); } - RemoveDirectoryA("msitest"); r = MsiInstallProductA(msifile, NULL); @@ -6923,9 +4222,10 @@ static void test_sourcefolder(void) ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); todo_wine { - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); } +error: DeleteFile(msifile); DeleteFile("augustus"); } @@ -6934,6 +4234,12 @@ static void test_customaction51(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -6942,10 +4248,16 @@ static void test_customaction51(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File installed\n"); + ok(delete_pf("msitest", FALSE), "Directory created\n"); +error: DeleteFile(msifile); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -6955,6 +4267,12 @@ static void test_installstate(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\alpha", 500); create_file("msitest\\beta", 500); @@ -6974,6 +4292,11 @@ static void test_installstate(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\beta", TRUE), "File installed\n"); @@ -6987,7 +4310,7 @@ static void test_installstate(void) ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n"); ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n"); ok(!delete_pf("msitest\\mu", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\""); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -7003,7 +4326,7 @@ static void test_installstate(void) ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n"); ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n"); ok(!delete_pf("msitest\\mu", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\""); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -7019,7 +4342,7 @@ static void test_installstate(void) ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n"); ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n"); ok(!delete_pf("msitest\\mu", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\""); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -7035,8 +4358,9 @@ static void test_installstate(void) ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n"); ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n"); ok(!delete_pf("msitest\\mu", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); +error: DeleteFile(msifile); DeleteFile("msitest\\alpha"); DeleteFile("msitest\\beta"); @@ -7053,7 +4377,7 @@ static void test_installstate(void) RemoveDirectory("msitest"); } -struct sourcepathmap +static const struct sourcepathmap { BOOL sost; /* shortone\shorttwo */ BOOL solt; /* shortone\longtwo */ @@ -7402,12 +4726,12 @@ static void test_sourcepath(void) if (r == ERROR_SUCCESS) { ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i); - ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i); + ok(delete_pf("msitest", FALSE), "%d: Directory not created\n", i); } else { ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i); - todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i); + todo_wine ok(!delete_pf("msitest", FALSE), "%d: Directory installed\n", i); } DeleteFileA("shortone\\shorttwo\\augustus"); @@ -7431,12 +4755,12 @@ static void test_MsiConfigureProductEx(void) LONG res; DWORD type, size; HKEY props, source; - CHAR keypath[MAX_PATH * 2]; - CHAR localpack[MAX_PATH]; + CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; - if (on_win9x) + if (is_process_limited()) { - win_skip("Different registry keys on Win9x and WinMe\n"); + skip("process is limited\n"); return; } @@ -7447,6 +4771,9 @@ static void test_MsiConfigureProductEx(void) create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table)); + if (is_wow64) + access |= KEY_WOW64_64KEY; + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); /* NULL szProduct */ @@ -7497,6 +4824,11 @@ static void test_MsiConfigureProductEx(void) /* install the product, per-user unmanaged */ r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); ok(pf_exists("msitest\\helium"), "File not installed\n"); @@ -7555,7 +4887,7 @@ static void test_MsiConfigureProductEx(void) DeleteFileA(msifile); - /* local msifile is removed */ + /* msifile is removed */ r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, "PROPVAR=42"); @@ -7581,7 +4913,13 @@ static void test_MsiConfigureProductEx(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + type = REG_SZ; + size = MAX_PATH; + res = RegQueryValueExA(props, "LocalPackage", NULL, &type, + (LPBYTE)localpackage, &size); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, @@ -7602,7 +4940,7 @@ static void test_MsiConfigureProductEx(void) RegCloseKey(props); create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table)); - /* LastUsedSource (local msi package) can be used as a last resort */ + /* LastUsedSource can be used as a last resort */ r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, "PROPVAR=42"); @@ -7611,6 +4949,7 @@ static void test_MsiConfigureProductEx(void) ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n"); ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n"); ok(!delete_pf("msitest", FALSE), "Directory not removed\n"); + DeleteFileA( localpackage ); /* install the product, machine */ r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42"); @@ -7624,7 +4963,13 @@ static void test_MsiConfigureProductEx(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + type = REG_SZ; + size = MAX_PATH; + res = RegQueryValueExA(props, "LocalPackage", NULL, &type, + (LPBYTE)localpackage, &size); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, @@ -7634,13 +4979,13 @@ static void test_MsiConfigureProductEx(void) lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\"); lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source); + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); type = REG_SZ; size = MAX_PATH; res = RegQueryValueExA(source, "PackageName", NULL, &type, - (LPBYTE)localpack, &size); + (LPBYTE)packagename, &size); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(source, "PackageName", 0, REG_SZ, @@ -7658,9 +5003,14 @@ static void test_MsiConfigureProductEx(void) ok(pf_exists("msitest\\lithium"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n"); - /* restore the SourceList */ + /* restore PackageName */ res = RegSetValueExA(source, "PackageName", 0, REG_SZ, - (const BYTE *)localpack, lstrlenA(localpack) + 1); + (const BYTE *)packagename, lstrlenA(packagename) + 1); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + /* restore LocalPackage */ + res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, + (const BYTE *)localpackage, lstrlenA(localpackage) + 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* finally remove the product */ @@ -7671,21 +5021,29 @@ static void test_MsiConfigureProductEx(void) ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n"); ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n"); ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n"); - ok(!delete_pf("msitest", FALSE), "File not removed\n"); + ok(!delete_pf("msitest", FALSE), "Directory not removed\n"); - DeleteFileA(msifile); RegCloseKey(source); RegCloseKey(props); + +error: DeleteFileA("msitest\\hydrogen"); DeleteFileA("msitest\\helium"); DeleteFileA("msitest\\lithium"); RemoveDirectoryA("msitest"); + DeleteFileA(msifile); } static void test_missingcomponent(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\hydrogen", 500); create_file("msitest\\helium", 500); @@ -7697,6 +5055,11 @@ static void test_missingcomponent(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(pf_exists("msitest\\hydrogen"), "File not installed\n"); ok(pf_exists("msitest\\helium"), "File not installed\n"); @@ -7712,6 +5075,7 @@ static void test_missingcomponent(void) ok(!pf_exists("msitest\\beryllium"), "File installed\n"); ok(!delete_pf("msitest", FALSE), "Directory not removed\n"); +error: DeleteFileA(msifile); DeleteFileA("msitest\\hydrogen"); DeleteFileA("msitest\\helium"); @@ -7725,6 +5089,12 @@ static void test_sourcedirprop(void) UINT r; CHAR props[MAX_PATH]; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -7733,9 +5103,14 @@ static void test_sourcedirprop(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File installed\n"); + ok(delete_pf("msitest", FALSE), "Directory created\n"); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -7749,18 +5124,28 @@ static void test_sourcedirprop(void) r = MsiInstallProductA(msifile, props); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File installed\n"); + ok(delete_pf("msitest", FALSE), "Directory created\n"); - DeleteFile(msifile); DeleteFile("altsource\\msitest\\augustus"); RemoveDirectory("altsource\\msitest"); RemoveDirectory("altsource"); + +error: + DeleteFile("msitest\\augustus"); + RemoveDirectory("msitest"); + DeleteFile(msifile); } static void test_adminimage(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); CreateDirectoryA("msitest\\first", NULL); CreateDirectoryA("msitest\\second", NULL); @@ -7776,25 +5161,33 @@ static void test_adminimage(void) create_database_wordcount(msifile, ai_tables, sizeof(ai_tables) / sizeof(msi_table), - msidbSumInfoSourceTypeAdminImage); + 100, msidbSumInfoSourceTypeAdminImage, ";1033"); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); - DeleteFileA("msitest.msi"); +error: + DeleteFileA("msifile"); DeleteFileA("msitest\\cabout\\new\\five.txt"); DeleteFileA("msitest\\cabout\\four.txt"); DeleteFileA("msitest\\second\\three.txt"); @@ -7813,6 +5206,12 @@ static void test_propcase(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); create_file("msitest\\augustus", 500); @@ -7821,10 +5220,16 @@ static void test_propcase(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, "MyProp=42"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +error: DeleteFile(msifile); DeleteFile("msitest\\augustus"); RemoveDirectory("msitest"); @@ -7895,10 +5300,23 @@ static void test_shortcut(void) UINT r; HRESULT hr; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_test_files(); create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table)); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -7917,173 +5335,80 @@ static void test_shortcut(void) CoUninitialize(); - delete_pf("msitest\\cabout\\new\\five.txt", TRUE); - delete_pf("msitest\\cabout\\new", FALSE); - delete_pf("msitest\\cabout\\four.txt", TRUE); - delete_pf("msitest\\cabout", FALSE); - delete_pf("msitest\\changed\\three.txt", TRUE); - delete_pf("msitest\\changed", FALSE); - delete_pf("msitest\\first\\two.txt", TRUE); - delete_pf("msitest\\first", FALSE); - delete_pf("msitest\\filename", TRUE); - delete_pf("msitest\\one.txt", TRUE); - delete_pf("msitest\\service.exe", TRUE); - delete_pf("msitest\\Shortcut.lnk", TRUE); - delete_pf("msitest", FALSE); - delete_test_files(); -} - -static void test_envvar(void) -{ - UINT r; - HKEY env; - LONG res; - DWORD type, size; - char buffer[16]; - UINT i; - - if (on_win9x) - { - win_skip("Environment variables are handled differently on Win9x and WinMe\n"); - return; - } - - create_test_files(); - create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table)); - - res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - type = REG_NONE; - size = sizeof(buffer); - buffer[0] = 0; - res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer); - - res = RegDeleteValueA(env, "MSITESTVAR1"); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - type = REG_NONE; - size = sizeof(buffer); - buffer[0] = 0; - res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer); - - res = RegDeleteValueA(env, "MSITESTVAR2"); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR3"); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR4"); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR5"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR6"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR7"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR8"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR9"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegDeleteValueA(env, "MSITESTVAR10"); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - i = 11; - while (environment_dat_results[(i-11)]) { - char name[20]; - sprintf(name, "MSITESTVAR%d", i); - - type = REG_NONE; - size = sizeof(buffer); - buffer[0] = 0; - res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res); - ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type); - ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n", - i, environment_dat_results[(i-11)], buffer); - - res = RegDeleteValueA(env, name); - ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res); - i++; - } - - - RegCloseKey(env); - delete_pf("msitest\\cabout\\new\\five.txt", TRUE); - delete_pf("msitest\\cabout\\new", FALSE); - delete_pf("msitest\\cabout\\four.txt", TRUE); - delete_pf("msitest\\cabout", FALSE); - delete_pf("msitest\\changed\\three.txt", TRUE); - delete_pf("msitest\\changed", FALSE); - delete_pf("msitest\\first\\two.txt", TRUE); - delete_pf("msitest\\first", FALSE); - delete_pf("msitest\\filename", TRUE); - delete_pf("msitest\\one.txt", TRUE); - delete_pf("msitest\\service.exe", TRUE); - delete_pf("msitest", FALSE); + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + while (!delete_pf("msitest\\Shortcut.lnk", TRUE) && GetLastError() == ERROR_SHARING_VIOLATION) Sleep(1000); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: delete_test_files(); + DeleteFile(msifile); } static void test_preselected(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_test_files(); create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table)); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiInstallProductA(msifile, "ADDLOCAL=One"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n"); + ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n"); + ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\changed", FALSE), "File installed\n"); + ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\first", FALSE), "File installed\n"); + ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); + +error: delete_test_files(); + DeleteFile(msifile); } static void test_installed_prop(void) @@ -8091,12 +5416,23 @@ static void test_installed_prop(void) static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}"; UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_test_files(); create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table)); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, "FULL=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); r = MsiInstallProductA(msifile, "FULL=1"); @@ -8106,28 +5442,36 @@ static void test_installed_prop(void) ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +error: delete_test_files(); + DeleteFile(msifile); } static void test_allusers_prop(void) { UINT r; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_test_files(); create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table)); @@ -8135,20 +5479,25 @@ static void test_allusers_prop(void) /* ALLUSERS property unset */ r = MsiInstallProductA(msifile, "FULL=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -8158,24 +5507,22 @@ static void test_allusers_prop(void) create_test_files(); create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table)); - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - /* ALLUSERS property set to 1 */ r = MsiInstallProductA(msifile, "FULL=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -8185,24 +5532,22 @@ static void test_allusers_prop(void) create_test_files(); create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table)); - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - /* ALLUSERS property set to 2 */ r = MsiInstallProductA(msifile, "FULL=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -8212,35 +5557,13 @@ static void test_allusers_prop(void) create_test_files(); create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table)); - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */ r = MsiInstallProductA(msifile, "FULL=1"); - if (r == ERROR_SUCCESS) - { - /* Win9x/WinMe */ - win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "File not installed\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - delete_test_files(); - } - else - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); +error: + delete_test_files(); + DeleteFile(msifile); } static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager"; @@ -8249,37 +5572,34 @@ static char rename_ops[] = "PendingFileRenameOperations"; static void process_pending_renames(HKEY hkey) { char *buf, *src, *dst, *buf2, *buf2ptr; - DWORD size, buf2len = 0; + DWORD size; LONG ret; BOOL found = FALSE; ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size); - buf = HeapAlloc(GetProcessHeap(), 0, size); - buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - buf[0] = 0; + ok(!ret, "RegQueryValueExA failed %d\n", ret); + + buf = HeapAlloc(GetProcessHeap(), 0, size + 1); + buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1); ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size); - ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError()); + buf[size] = 0; + ok(!ret, "RegQueryValueExA failed %d\n", ret); + if (ret) return; for (src = buf; *src; src = dst + strlen(dst) + 1) { DWORD flags = MOVEFILE_COPY_ALLOWED; + BOOL fileret; dst = src + strlen(src) + 1; if (!strstr(src, "msitest")) { lstrcpyA(buf2ptr, src); - buf2len += strlen(src) + 1; buf2ptr += strlen(src) + 1; - if (*dst) - { - lstrcpyA(buf2ptr, dst); - buf2ptr += strlen(dst) + 1; - buf2len += strlen(dst) + 1; - } - buf2ptr++; - buf2len++; + lstrcpyA(buf2ptr, dst); + buf2ptr += strlen(dst) + 1; continue; } @@ -8294,19 +5614,20 @@ static void process_pending_renames(HKEY hkey) if (*dst) { if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4; - ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError()); + fileret = MoveFileExA(src, dst, flags); + ok(fileret, "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError()); } else - ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError()); + { + fileret = DeleteFileA(src); + ok(fileret, "Failed to delete file %s (%u)\n", src, GetLastError()); + } } ok(found, "Expected a 'msitest' entry\n"); if (*buf2) - { - buf2len++; - RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len); - } + RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2ptr + 1 - buf2); else RegDeleteValueA(hkey, rename_ops); @@ -8339,9 +5660,9 @@ static void test_file_in_use(void) HKEY hkey; char path[MAX_PATH]; - if (on_win9x) + if (is_process_limited()) { - win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n"); + skip("process is limited\n"); return; } @@ -8361,6 +5682,11 @@ static void test_file_in_use(void) file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r); ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n"); CloseHandle(file); @@ -8376,8 +5702,14 @@ static void test_file_in_use(void) r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +error: + RegCloseKey(hkey); + + delete_pf("msitest\\maximus", TRUE); + delete_pf("msitest", FALSE); DeleteFileA("msitest\\maximus"); delete_test_files(); + DeleteFile(msifile); } static void test_file_in_use_cab(void) @@ -8387,9 +5719,9 @@ static void test_file_in_use_cab(void) HKEY hkey; char path[MAX_PATH]; - if (on_win9x) + if (is_process_limited()) { - win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n"); + skip("process is limited\n"); return; } @@ -8412,6 +5744,11 @@ static void test_file_in_use_cab(void) file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r); ok(!file_matches_data(path, "maximus"), "Expected file not to match\n"); CloseHandle(file); @@ -8427,8 +5764,15 @@ static void test_file_in_use_cab(void) r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +error: + RegCloseKey(hkey); + + delete_pf("msitest\\maximus", TRUE); + delete_pf("msitest", FALSE); + DeleteFileA("msitest\\maximus"); delete_cab_files(); delete_test_files(); + DeleteFile(msifile); } static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg) @@ -8512,6 +5856,13 @@ static void test_MsiSetExternalUI(void) static void test_feature_override(void) { UINT r; + REGSAM access = KEY_ALL_ACCESS; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } create_test_files(); create_file("msitest\\override.txt", 1000); @@ -8519,7 +5870,17 @@ static void test_feature_override(void) create_file("msitest\\notpreselected.txt", 1000); create_database(msifile, fo_tables, sizeof(fo_tables) / sizeof(msi_table)); + if (is_wow64) + access |= KEY_WOW64_64KEY; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiInstallProductA(msifile, "ADDLOCAL=override"); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(pf_exists("msitest\\override.txt"), "file not installed\n"); @@ -8563,869 +5924,14 @@ static void test_feature_override(void) ok(delete_pf("msitest", FALSE), "directory removed\n"); } + delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", access); + +error: DeleteFileA("msitest\\override.txt"); DeleteFileA("msitest\\preselected.txt"); DeleteFileA("msitest\\notpreselected.txt"); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest"); - delete_test_files(); -} - -static void test_create_folder(void) -{ - UINT r; - - create_test_files(); - create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "Directory created\n"); - - r = MsiInstallProductA(msifile, "LOCAL=Two"); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "Directory created\n"); - - delete_test_files(); -} - -static void test_remove_folder(void) -{ - UINT r; - - create_test_files(); - create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "Directory created\n"); - - r = MsiInstallProductA(msifile, "LOCAL=Two"); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); - ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); - ok(!delete_pf("msitest", FALSE), "Directory created\n"); - - delete_test_files(); -} - -static void test_start_services(void) -{ - UINT r; - SC_HANDLE scm, service; - BOOL ret; - DWORD error = ERROR_SUCCESS; - - if (on_win9x) - { - win_skip("Services are not implemented on Win9x and WinMe\n"); - return; - } - scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - ok(scm != NULL, "Failed to open the SC Manager\n"); - if (!scm) return; - - service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS); - if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) - { - win_skip("The 'Spooler' service does not exist\n"); - CloseServiceHandle(scm); - return; - } - ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError()); - if (!service) { - CloseServiceHandle(scm); - return; - } - - ret = StartService(service, 0, NULL); - if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING) - { - skip("Terminal service not available, skipping test\n"); - CloseServiceHandle(service); - CloseServiceHandle(scm); - return; - } - - CloseServiceHandle(service); - CloseServiceHandle(scm); - - create_test_files(); - create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); - - delete_test_files(); - - if (error == ERROR_SUCCESS) - { - SERVICE_STATUS status; - - scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS); - - ret = ControlService(service, SERVICE_CONTROL_STOP, &status); - ok(ret, "ControlService failed %u\n", GetLastError()); - - CloseServiceHandle(service); - CloseServiceHandle(scm); - } -} - -static void test_delete_services(void) -{ - UINT r; - - create_test_files(); - create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); - - delete_test_files(); -} - -static void test_self_registration(void) -{ - UINT r; - - create_test_files(); - create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); - - delete_test_files(); -} - -static void test_register_font(void) -{ - static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; - static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"; - LONG ret; - HKEY key; - UINT r; - - create_test_files(); - create_file("msitest\\font.ttf", 1000); - create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key); - if (ret) - RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key); - - ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL); - ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL); - ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret); - - RegDeleteValueA(key, "msi test font"); - RegCloseKey(key); - DeleteFileA("msitest\\font.ttf"); - delete_test_files(); -} - -static void test_validate_product_id(void) -{ - UINT r; - - create_test_files(); - create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1"); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - r = MsiInstallProductA(msifile, "PIDKEY=123-1234567"); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); - - delete_test_files(); -} - -static void test_install_remove_odbc(void) -{ - UINT r; - - create_test_files(); - create_file("msitest\\ODBCdriver.dll", 1000); - create_file("msitest\\ODBCdriver2.dll", 1000); - create_file("msitest\\ODBCtranslator.dll", 1000); - create_file("msitest\\ODBCtranslator2.dll", 1000); - create_file("msitest\\ODBCsetup.dll", 1000); - create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n"); - ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n"); - ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n"); - ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n"); - ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\ODBCdriver.dll"); - DeleteFileA("msitest\\ODBCdriver2.dll"); - DeleteFileA("msitest\\ODBCtranslator.dll"); - DeleteFileA("msitest\\ODBCtranslator2.dll"); - DeleteFileA("msitest\\ODBCsetup.dll"); - delete_test_files(); -} - -static void test_register_typelib(void) -{ - UINT r; - - create_test_files(); - create_file("msitest\\typelib.dll", 1000); - create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1"); - ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\typelib.dll"); - delete_test_files(); -} - -static void test_create_remove_shortcut(void) -{ - UINT r; - - create_test_files(); - create_file("msitest\\target.txt", 1000); - create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(pf_exists("msitest\\target.txt"), "file not created\n"); - ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n"); - todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\target.txt"); - delete_test_files(); -} - -static void test_publish_components(void) -{ - static char keypath[] = - "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA"; - - UINT r; - LONG res; - HKEY key; - - create_test_files(); - create_file("msitest\\english.txt", 1000); - create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key); - ok(res == ERROR_SUCCESS, "components key not created %d\n", res); - - res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL); - ok(res == ERROR_SUCCESS, "value not found %d\n", res); - RegCloseKey(key); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key); - ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res); - - ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\english.txt"); - delete_test_files(); -} - -static void test_remove_duplicate_files(void) -{ - UINT r; - - create_test_files(); - create_file("msitest\\original.txt", 1000); - create_file("msitest\\original2.txt", 1000); - create_file("msitest\\original3.txt", 1000); - create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(pf_exists("msitest\\original.txt"), "file not created\n"); - ok(pf_exists("msitest\\original2.txt"), "file not created\n"); - ok(!pf_exists("msitest\\original3.txt"), "file created\n"); - ok(pf_exists("msitest\\duplicate.txt"), "file not created\n"); - ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n"); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n"); - ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n"); - ok(delete_pf("msitest", FALSE), "directory removed\n"); - - DeleteFileA("msitest\\original.txt"); - DeleteFileA("msitest\\original2.txt"); - DeleteFileA("msitest\\original3.txt"); - delete_test_files(); -} - -static void test_remove_registry_values(void) -{ - UINT r; - LONG res; - HKEY key; - - create_test_files(); - create_file("msitest\\registry.txt", 1000); - create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key); - RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2); - RegCloseKey(key); - - RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key); - RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2); - RegCloseKey(key); - - RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key); - RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8); - RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2); - RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2); - RegCloseKey(key); - - RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key); - RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8); - RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2); - RegCloseKey(key); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key); - ok(res == ERROR_SUCCESS, "key removed\n"); - RegCloseKey(key); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - RegCloseKey(key); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key); - ok(res == ERROR_SUCCESS, "key removed\n"); - RegCloseKey(key); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key); - ok(res == ERROR_SUCCESS, "key removed\n"); - RegCloseKey(key); - - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA"); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2"); - RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine"); - - ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\registry.txt"); - delete_test_files(); -} - -static void test_find_related_products(void) -{ - UINT r; - - create_test_files(); - create_file("msitest\\product.txt", 1000); - create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - /* install again, so it finds the upgrade code */ - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\product.txt"); - delete_test_files(); -} - -static void test_remove_ini_values(void) -{ - UINT r; - DWORD len; - char inifile[MAX_PATH], buf[0x10]; - HANDLE file; - BOOL ret; - - create_test_files(); - create_file("msitest\\inifile.txt", 1000); - create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table)); - - lstrcpyA(inifile, PROG_FILES_DIR); - lstrcatA(inifile, "\\msitest"); - CreateDirectoryA(inifile, NULL); - lstrcatA(inifile, "\\test.ini"); - file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL); - CloseHandle(file); - - ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile); - ok(ret, "failed to write profile string %u\n", GetLastError()); - - ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile); - ok(ret, "failed to write profile string %u\n", GetLastError()); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile); - ok(len == 6, "got %u expected 6\n", len); - - len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile); - ok(!len, "got %u expected 0\n", len); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile); - ok(!len, "got %u expected 0\n", len); - - len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile); - ok(!len, "got %u expected 0\n", len); - - todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n"); - ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n"); - ok(delete_pf("msitest", FALSE), "directory removed\n"); - - DeleteFileA("msitest\\inifile.txt"); - delete_test_files(); -} - -static void test_remove_env_strings(void) -{ - UINT r; - LONG res; - HKEY key; - DWORD type, size; - char buffer[0x10]; - - if (on_win9x) - { - win_skip("Environment variables are handled differently on win9x and winme\n"); - return; - } - - create_test_files(); - create_file("msitest\\envvar.txt", 1000); - create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); - ok(!res, "failed to open environment key %d\n", res); - - RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2); - RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2); - RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2); - RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2); - RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2); - - RegCloseKey(key); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); - ok(!res, "failed to open environment key %d\n", res); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - - RegCloseKey(key); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); - ok(!res, "failed to open environment key %d\n", res); - - res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - RegDeleteValueA(key, "MSITESTVAR3"); - - res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - type = REG_NONE; - buffer[0] = 0; - size = sizeof(buffer); - res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - ok(type == REG_SZ, "expected REG_SZ, got %u\n", type); - ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer); - RegDeleteValueA(key, "MSITESTVAR5"); - - RegCloseKey(key); - - ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\envvar.txt"); - delete_test_files(); -} - -static void test_register_class_info(void) -{ - UINT r; - LONG res; - HKEY hkey; - - create_test_files(); - create_file("msitest\\class.txt", 1000); - create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\class.txt"); - delete_test_files(); -} - -static void test_register_extension_info(void) -{ - UINT r; - LONG res; - HKEY hkey; - - create_test_files(); - create_file("msitest\\extension.txt", 1000); - create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\extension.txt"); - delete_test_files(); -} - -static void test_register_mime_info(void) -{ - UINT r; - LONG res; - HKEY hkey; - - create_test_files(); - create_file("msitest\\mime.txt", 1000); - create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table)); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiInstallProductA(msifile, NULL); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey); - ok(res == ERROR_SUCCESS, "key not created\n"); - RegCloseKey(hkey); - - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - - res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey); - ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n"); - - ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n"); - ok(!delete_pf("msitest", FALSE), "directory not removed\n"); - - DeleteFileA("msitest\\mime.txt"); delete_test_files(); + DeleteFile(msifile); } static void test_icon_table(void) @@ -9433,11 +5939,19 @@ static void test_icon_table(void) MSIHANDLE hdb = 0, record; LPCSTR query; UINT res; - CHAR path[MAX_PATH], win9xpath[MAX_PATH]; + CHAR path[MAX_PATH]; static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}"; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_database(msifile, icon_base_tables, sizeof(icon_base_tables) / sizeof(msi_table)); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb); ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res); @@ -9449,7 +5963,6 @@ static void test_icon_table(void) record = MsiCreateRecord(1); res = MsiRecordSetStream(record, 1, "icon.ico"); ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res); - DeleteFile("icon.ico"); query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)"; res = run_query(hdb, record, query); @@ -9457,6 +5970,7 @@ static void test_icon_table(void) res = MsiCloseHandle(record); ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res); + DeleteFileA("icon.ico"); res = MsiDatabaseCommit(hdb); ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res); res = MsiCloseHandle(hdb); @@ -9464,6 +5978,12 @@ static void test_icon_table(void) /* per-user */ res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); + if (res == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res); lstrcpyA(path, APP_DATA_DIR); @@ -9475,32 +5995,627 @@ static void test_icon_table(void) res = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n"); + ok(!file_exists(path), "Per-user icon file not removed (%s)\n", path); /* system-wide */ res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1"); ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res); - /* win9x with MSI 2.0 installs the icon to a different folder, same as above */ - lstrcpyA(win9xpath, APP_DATA_DIR); - lstrcatA(path, "\\"); - lstrcatA(path, "Microsoft\\Installer\\"); - lstrcatA(path, prodcode); - lstrcatA(path, "\\testicon"); - lstrcpyA(path, WINDOWS_DIR); lstrcatA(path, "\\"); lstrcatA(path, "Installer\\"); lstrcatA(path, prodcode); lstrcatA(path, "\\testicon"); - ok(file_exists(path) || file_exists(win9xpath), - "System-wide icon file isn't where it's expected (%s)\n", path); + ok(file_exists(path), "System-wide icon file isn't where it's expected (%s)\n", path); res = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n"); + ok(!file_exists(path), "System-wide icon file not removed (%s)\n", path); delete_pfmsitest_files(); + DeleteFile(msifile); +} + +static void test_sourcedir_props(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_file("msitest\\sourcedir.txt", 1000); + create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); + + /* full UI, no ResolveSource action */ + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + /* full UI, ResolveSource action */ + r = MsiInstallProductA(msifile, "ResolveSource=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* no UI, no ResolveSource action */ + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + /* no UI, ResolveSource action */ + r = MsiInstallProductA(msifile, "ResolveSource=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + DeleteFileA("msitest\\sourcedir.txt"); + DeleteFile(msifile); +} + +static void test_package_validation(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;1033"); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel,9999;9999"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel,1033;9999"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel,9999;1033"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel64,9999;1033"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel32,1033;1033"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel32,9999;1033"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;9999"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); + + if (GetSystemDefaultLangID() == MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US )) + { + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;9"); + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;1024"); + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + } + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel32;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); + + if (is_64bit && !is_wow64) + { + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + } + else if (is_wow64) + { + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r); + ok(!delete_pf_native("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf_native("msitest", FALSE), "directory exists\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf_native("msitest\\maximus", TRUE), "file exists\n"); + ok(delete_pf_native("msitest", FALSE), "directory exists\n"); + } + else + { + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n"); + ok(delete_pf("msitest", FALSE), "directory does not exist\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); + + DeleteFile(msifile); + create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0"); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); + } + +error: + /* Delete the files in the temp (current) folder */ + DeleteFile(msifile); + DeleteFile("msitest\\maximus"); + RemoveDirectory("msitest"); +} + +static void test_command_line_parsing(void) +{ + UINT r; + const char *cmd; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + cmd = " "; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "="; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "=="; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "one"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "=one"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P="; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = " P="; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P= "; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=\"\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"\"\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=\"\"\"\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\" "; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P= \""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P= \"\" "; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\" \""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=one"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P= one"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P=\"one"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=one\""; + r = MsiInstallProductA(msifile, cmd); + todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"one\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P= \"one\" "; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P=\"one\"\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=\"\"one\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=\"\"one\"\""; + r = MsiInstallProductA(msifile, cmd); + todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r); + + cmd = "P=\"one two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"\"\"one\"\" two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"\"\"one\"\" two\" Q=three"; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"\" Q=\"two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"one\" Q=\"two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P=\"one=two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "Q=\"\" P=\"one\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + cmd = "P=\"\"\"one\"\"\" Q=\"two\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"one \"\"two\"\"\" Q=\"three\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + cmd = "P=\"\"\"one\"\" two\" Q=\"three\""; + r = MsiInstallProductA(msifile, cmd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + DeleteFile(msifile); + RemoveDirectory("msitest"); +} + +static void test_upgrade_code(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\upgradecode.txt", 1000); + create_database(msifile, uc_tables, sizeof(uc_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(pf_exists("msitest\\upgradecode.txt"), "file not installed\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(!delete_pf("msitest\\upgradecode.txt", TRUE), "file not removed\n"); + ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + DeleteFileA("msitest\\upgradecode.txt"); + RemoveDirectoryA("msitest"); + DeleteFile(msifile); +} + +static void test_MsiGetFeatureInfo(void) +{ + UINT r; + MSIHANDLE package; + char title[32], help[32], path[MAX_PATH]; + DWORD attrs, title_len, help_len; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) ); + + strcpy( path, CURR_DIR ); + strcat( path, "\\" ); + strcat( path, msifile ); + + r = MsiOpenPackage( path, &package ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFileA( msifile ); + return; + } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL ); + ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); + + r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL ); + ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); + + r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL ); + ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + + r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL ); + ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r); + + title_len = help_len = 0; + r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(title_len == 3, "expected 3, got %u\n", title_len); + ok(help_len == 15, "expected 15, got %u\n", help_len); + + title[0] = help[0] = 0; + title_len = help_len = 0; + r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len ); + ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r); + ok(title_len == 3, "expected 3, got %u\n", title_len); + ok(help_len == 15, "expected 15, got %u\n", help_len); + + attrs = 0; + title[0] = help[0] = 0; + title_len = sizeof(title); + help_len = sizeof(help); + r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs); + ok(title_len == 3, "expected 3, got %u\n", title_len); + ok(help_len == 15, "expected 15, got %u\n", help_len); + ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title); + ok(!strcmp(help, "The One Feature"), "expected \"The One Feature\", got \"%s\"\n", help); + + attrs = 0; + title[0] = help[0] = 0; + title_len = sizeof(title); + help_len = sizeof(help); + r = MsiGetFeatureInfoA( package, "feature", &attrs, title, &title_len, help, &help_len ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs); + ok(!title_len, "expected 0, got %u\n", title_len); + ok(!help_len, "expected 0, got %u\n", help_len); + ok(!title[0], "expected \"\", got \"%s\"\n", title); + ok(!help[0], "expected \"\", got \"%s\"\n", help); + + MsiCloseHandle( package ); + DeleteFileA( msifile ); +} + +static void test_MsiSetFeatureAttributes(void) +{ + UINT r; + DWORD attrs; + char path[MAX_PATH]; + MSIHANDLE package; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) ); + + strcpy( path, CURR_DIR ); + strcat( path, "\\" ); + strcat( path, msifile ); + + r = MsiOpenPackage( path, &package ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFileA( msifile ); + return; + } + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r); + + r = MsiDoAction( package, "CostInitialize" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", 0 ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0xdeadbeef; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, + "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, + "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs); + + r = MsiDoAction( package, "FileCost" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + attrs = 0; + r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE, + "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs); + + r = MsiDoAction( package, "CostFinalize" ); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL ); + ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r); + + MsiCloseHandle( package ); + DeleteFileA( msifile ); } START_TEST(install) @@ -9512,7 +6627,8 @@ START_TEST(install) init_functionpointers(); - on_win9x = check_win9x(); + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); GetCurrentDirectoryA(MAX_PATH, prev_path); GetTempPath(MAX_PATH, temp_path); @@ -9524,13 +6640,16 @@ START_TEST(install) if(len && (CURR_DIR[len - 1] == '\\')) CURR_DIR[len - 1] = 0; - get_system_dirs(); - get_user_dirs(); + ok(get_system_dirs(), "failed to retrieve system dirs\n"); + ok(get_user_dirs(), "failed to retrieve user dirs\n"); /* Create a restore point ourselves so we circumvent the multitude of restore points * that would have been created by all the installation and removal tests. + * + * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the + * creation of restore points. */ - if (pSRSetRestorePointA) + if (pSRSetRestorePointA && !pMsiGetComponentPathExA) { memset(&status, 0, sizeof(status)); ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status); @@ -9559,22 +6678,11 @@ START_TEST(install) test_cabisextracted(); test_concurrentinstall(); test_setpropertyfolder(); - test_publish_registerproduct(); - test_publish_publishproduct(); - test_publish_publishfeatures(); - test_publish_registeruser(); - test_publish_processcomponents(); - test_publish(); - test_publishsourcelist(); test_transformprop(); test_currentworkingdir(); test_admin(); test_adminprops(); - test_removefiles(); - test_movefiles(); test_missingcab(); - test_duplicatefiles(); - test_writeregistryvalues(); test_sourcefolder(); test_customaction51(); test_installstate(); @@ -9586,7 +6694,6 @@ START_TEST(install) test_propcase(); test_int_widths(); test_shortcut(); - test_envvar(); test_lastusedsource(); test_preselected(); test_installed_prop(); @@ -9595,30 +6702,17 @@ START_TEST(install) test_MsiSetExternalUI(); test_allusers_prop(); test_feature_override(); - test_create_folder(); - test_remove_folder(); - test_start_services(); - test_delete_services(); - test_self_registration(); - test_register_font(); - test_validate_product_id(); - test_install_remove_odbc(); - test_register_typelib(); - test_create_remove_shortcut(); - test_publish_components(); - test_remove_duplicate_files(); - test_remove_registry_values(); - test_find_related_products(); - test_remove_ini_values(); - test_remove_env_strings(); - test_register_class_info(); - test_register_extension_info(); - test_register_mime_info(); test_icon_table(); + test_sourcedir_props(); + test_package_validation(); + test_command_line_parsing(); + test_upgrade_code(); + test_MsiGetFeatureInfo(); + test_MsiSetFeatureAttributes(); DeleteFileA(log_file); - if (pSRSetRestorePointA && ret) + if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) { ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status); if (ret) diff --git a/rostests/winetests/msi/msi.c b/rostests/winetests/msi/msi.c index b377320131e..6ba0e115f6b 100644 --- a/rostests/winetests/msi/msi.c +++ b/rostests/winetests/msi/msi.c @@ -29,9 +29,12 @@ #include "wine/test.h" +static BOOL is_wow64; static const char msifile[] = "winetest.msi"; static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*); +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static INSTALLSTATE (WINAPI *pMsiGetComponentPathA) (LPCSTR, LPCSTR, LPSTR, DWORD*); @@ -57,6 +60,7 @@ static void init_functionpointers(void) { HMODULE hmsi = GetModuleHandleA("msi.dll"); HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); #define GET_PROC(dll, func) \ p ## func = (void *)GetProcAddress(dll, #func); \ @@ -74,6 +78,8 @@ static void init_functionpointers(void) GET_PROC(hmsi, MsiGetPatchInfoExA) GET_PROC(hadvapi32, ConvertSidToStringSidA) + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hkernel32, IsWow64Process) #undef GET_PROC } @@ -223,6 +229,13 @@ static void test_usefeature(void) ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n"); } +static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + static void test_null(void) { MSIHANDLE hpkg; @@ -231,6 +244,10 @@ static void test_null(void) DWORD dwType, cbData; LPBYTE lpData = NULL; INSTALLSTATE state; + REGSAM access = KEY_ALL_ACCESS; + + if (is_wow64) + access |= KEY_WOW64_64KEY; r = pMsiOpenPackageExW(NULL, 0, &hpkg); ok( r == ERROR_INVALID_PARAMETER,"wrong error\n"); @@ -257,7 +274,12 @@ static void test_null(void) * necessary registry values */ /* empty product string */ - r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey); + r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey); + if (r == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok( r == ERROR_SUCCESS, "wrong error %d\n", r); r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData); @@ -275,6 +297,13 @@ static void test_null(void) } r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test")); + if (r == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + HeapFree(GetProcessHeap(), 0, lpData); + RegCloseKey(hkey); + return; + } ok( r == ERROR_SUCCESS, "wrong error %d\n", r); r = MsiGetProductInfoA("", "", NULL, NULL); @@ -297,7 +326,8 @@ static void test_null(void) ok( r == ERROR_SUCCESS, "wrong error %d\n", r); /* empty attribute */ - r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey); + r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", + 0, NULL, 0, access, NULL, &hkey, NULL); ok( r == ERROR_SUCCESS, "wrong error %d\n", r); r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test")); @@ -309,7 +339,8 @@ static void test_null(void) r = RegCloseKey(hkey); ok( r == ERROR_SUCCESS, "wrong error %d\n", r); - r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}"); + r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", + access & KEY_WOW64_64KEY); ok( r == ERROR_SUCCESS, "wrong error %d\n", r); } @@ -453,9 +484,7 @@ static void test_MsiGetFileHash(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE); - ok(ret == 0 || - broken(ret != 0), /* win95 */ - "Hash incorrect\n"); + ok(!ret, "Hash incorrect\n"); DeleteFile(name); } @@ -513,23 +542,23 @@ static void create_test_guid(LPSTR prodcode, LPSTR squashed) WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); } -static void get_user_sid(LPSTR *usersid) +static char *get_user_sid(void) { HANDLE token; - DWORD size; - PTOKEN_USER user; + DWORD size = 0; + TOKEN_USER *user; + char *usersid = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - - size = 0; GetTokenInformation(token, TokenUser, NULL, size, &size); + user = HeapAlloc(GetProcessHeap(), 0, size); - GetTokenInformation(token, TokenUser, user, size, &size); - pConvertSidToStringSidA(user->User.Sid, usersid); - + pConvertSidToStringSidA(user->User.Sid, &usersid); HeapFree(GetProcessHeap(), 0, user); + CloseHandle(token); + return usersid; } static void test_MsiQueryProductState(void) @@ -542,39 +571,66 @@ static void test_MsiQueryProductState(void) LONG res; HKEY userkey, localkey, props; HKEY prodkey; - DWORD data; + DWORD data, error; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(NULL); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* empty prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(""); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* garbage prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA("garbage"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* guid without brackets */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* guid with brackets */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}"); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); /* same length as guid, but random */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93"); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* MSIINSTALLCONTEXT_USERUNMANAGED */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); @@ -583,75 +639,114 @@ static void test_MsiQueryProductState(void) ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"); lstrcatA(keypath, prodcode); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + RegDeleteKeyA(userkey, ""); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local uninstall key exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); data = 1; res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD)); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* WindowsInstaller value exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); RegDeleteValueA(localkey, "WindowsInstaller"); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); lstrcatA(keypath, usersid); lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local product key exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); - res = RegCreateKeyA(localkey, "InstallProperties", &props); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* install properties key exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); data = 1; res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD)); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* WindowsInstaller value exists */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); data = 2; res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD)); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* WindowsInstaller value is not 1 */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); RegDeleteKeyA(userkey, ""); /* user product key does not exist */ + SetLastError(0xdeadbeef); state = MsiQueryProductStateA(prodcode); + error = GetLastError(); ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); RegDeleteValueA(props, "WindowsInstaller"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(localkey); RegDeleteKeyA(userkey, ""); RegCloseKey(userkey); @@ -663,7 +758,7 @@ static void test_MsiQueryProductState(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); @@ -675,14 +770,14 @@ static void test_MsiQueryProductState(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); - res = RegCreateKeyA(localkey, "InstallProperties", &props); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); @@ -698,11 +793,11 @@ static void test_MsiQueryProductState(void) ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); RegDeleteValueA(props, "WindowsInstaller"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(localkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_MACHINE */ @@ -710,7 +805,7 @@ static void test_MsiQueryProductState(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); @@ -720,14 +815,14 @@ static void test_MsiQueryProductState(void) lstrcatA(keypath, "S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); - res = RegCreateKeyA(localkey, "InstallProperties", &props); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryProductStateA(prodcode); @@ -743,11 +838,11 @@ static void test_MsiQueryProductState(void) ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); RegDeleteValueA(props, "WindowsInstaller"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(localkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); LocalFree(usersid); @@ -817,47 +912,82 @@ static void test_MsiQueryFeatureState(void) INSTALLSTATE state; LPSTR usersid; LONG res; + REGSAM access = KEY_ALL_ACCESS; + DWORD error; create_test_guid(prodcode, prod_squashed); compose_base85_guid(component, comp_base85, comp_squashed); compose_base85_guid(component, comp_base85 + 20, comp_squashed2); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(NULL, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* empty prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA("", "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* garbage prodcode */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA("garbage", "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* guid without brackets */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* guid with brackets */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); /* same length as guid, but random */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* NULL szFeature */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, NULL); + error = GetLastError(); ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* empty szFeature */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, ""); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); /* feature key does not exist yet */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); /* MSIINSTALLCONTEXT_USERUNMANAGED */ @@ -868,15 +998,23 @@ static void test_MsiQueryFeatureState(void) ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* feature key exists */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* feature value exists */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); lstrcatA(keypath, usersid); @@ -884,43 +1022,71 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\Features"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + RegDeleteKeyA(userkey, ""); + RegCloseKey(userkey); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* userdata features key exists */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); lstrcatA(keypath, usersid); lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); @@ -928,63 +1094,95 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed2); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_LOCAL */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_SOURCE */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* bad INSTALLSTATE_SOURCE */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_SOURCE */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* bad INSTALLSTATE_SOURCE */ + SetLastError(0xdeadbeef); state = MsiQueryFeatureStateA(prodcode, "feature"); + error = GetLastError(); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */, + "expected ERROR_SUCCESS, got %u\n", error); RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey2, prod_squashed); - RegDeleteKeyA(compkey, ""); - RegDeleteKeyA(compkey2, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); + delete_key(compkey2, "", access & KEY_WOW64_64KEY); RegDeleteValueA(localkey, "feature"); RegDeleteValueA(userkey, "feature"); RegDeleteKeyA(userkey, ""); @@ -1000,7 +1198,7 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, "\\Installer\\Features\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* feature key exists */ @@ -1020,7 +1218,7 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\Features"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* userdata features key exists */ @@ -1056,7 +1254,7 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); @@ -1064,7 +1262,7 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed2); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryFeatureStateA(prodcode, "feature"); @@ -1090,11 +1288,11 @@ static void test_MsiQueryFeatureState(void) RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey2, prod_squashed); - RegDeleteKeyA(compkey, ""); - RegDeleteKeyA(compkey2, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); + delete_key(compkey2, "", access & KEY_WOW64_64KEY); RegDeleteValueA(localkey, "feature"); RegDeleteValueA(userkey, "feature"); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); RegCloseKey(compkey2); RegCloseKey(localkey); @@ -1105,7 +1303,7 @@ static void test_MsiQueryFeatureState(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* feature key exists */ @@ -1124,7 +1322,7 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\Features"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* userdata features key exists */ @@ -1159,14 +1357,14 @@ static void test_MsiQueryFeatureState(void) lstrcatA(keypath, "S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); lstrcatA(keypath, "S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed2); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MsiQueryFeatureStateA(prodcode, "feature"); @@ -1192,11 +1390,11 @@ static void test_MsiQueryFeatureState(void) RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey2, prod_squashed); - RegDeleteKeyA(compkey, ""); - RegDeleteKeyA(compkey2, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); + delete_key(compkey2, "", access & KEY_WOW64_64KEY); RegDeleteValueA(localkey, "feature"); RegDeleteValueA(userkey, "feature"); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); RegCloseKey(compkey2); RegCloseKey(localkey); @@ -1217,6 +1415,8 @@ static void test_MsiQueryComponentState(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; + DWORD error; static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef; @@ -1228,61 +1428,94 @@ static void test_MsiQueryComponentState(void) create_test_guid(prodcode, prod_squashed); compose_base85_guid(component, comp_base85, comp_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProductCode */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* empty szProductCode */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* random szProductCode */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* GUID-length szProductCode */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* GUID-length with brackets */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* actual GUID */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* create local system product key */ @@ -1290,101 +1523,130 @@ static void test_MsiQueryComponentState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local system product key exists */ state = MAGIC_ERROR; r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* LocalPackage value exists */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* component key exists */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* component\product exists */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + error = GetLastError(); ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); /* NULL component, product exists */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state); + error = GetLastError(); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_LOCAL */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_SOURCE */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* bad INSTALLSTATE_SOURCE */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* INSTALLSTATE_SOURCE */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* bad INSTALLSTATE_SOURCE */ state = MAGIC_ERROR; + SetLastError(0xdeadbeef); r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state); + error = GetLastError(); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error); RegDeleteValueA(prodkey, "LocalPackage"); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegCloseKey(compkey); @@ -1415,7 +1677,7 @@ static void test_MsiQueryComponentState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11); @@ -1433,7 +1695,7 @@ static void test_MsiQueryComponentState(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* component key exists */ @@ -1486,7 +1748,7 @@ static void test_MsiQueryComponentState(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); state = MAGIC_ERROR; @@ -1494,7 +1756,7 @@ static void test_MsiQueryComponentState(void) ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); @@ -1503,7 +1765,7 @@ static void test_MsiQueryComponentState(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11); @@ -1516,9 +1778,9 @@ static void test_MsiQueryComponentState(void) RegDeleteValueA(prodkey, "LocalPackage"); RegDeleteValueA(prodkey, "ManagedLocalPackage"); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegCloseKey(compkey); LocalFree(usersid); @@ -1537,11 +1799,15 @@ static void test_MsiGetComponentPath(void) INSTALLSTATE state; LPSTR usersid; DWORD size, val; + REGSAM access = KEY_ALL_ACCESS; LONG res; create_test_guid(prodcode, prod_squashed); compose_base85_guid(component, comp_base85, comp_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProduct */ size = MAX_PATH; @@ -1597,7 +1863,13 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local system component key exists */ @@ -1634,7 +1906,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); val = 1; @@ -1674,9 +1946,9 @@ static void test_MsiGetComponentPath(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(installprop, "WindowsInstaller"); - RegDeleteKeyA(installprop, ""); + delete_key(installprop, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); RegCloseKey(installprop); DeleteFileA("C:\\imapath"); @@ -1687,7 +1959,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed component key exists */ @@ -1724,7 +1996,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); val = 1; @@ -1764,9 +2036,9 @@ static void test_MsiGetComponentPath(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(installprop, "WindowsInstaller"); - RegDeleteKeyA(installprop, ""); + delete_key(installprop, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); RegCloseKey(installprop); DeleteFileA("C:\\imapath"); @@ -1777,7 +2049,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed product key exists */ @@ -1797,7 +2069,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed component key exists */ @@ -1834,7 +2106,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, prod_squashed); lstrcatA(keypath, "\\InstallProperties"); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); val = 1; @@ -1874,10 +2146,10 @@ static void test_MsiGetComponentPath(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(prodkey, ""); - RegDeleteKeyA(compkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(installprop, "WindowsInstaller"); - RegDeleteKeyA(installprop, ""); + delete_key(installprop, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegCloseKey(compkey); RegCloseKey(installprop); @@ -1906,7 +2178,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user unmanaged component key exists */ @@ -1957,7 +2229,7 @@ static void test_MsiGetComponentPath(void) RegDeleteValueA(compkey, prod_squashed); RegDeleteKeyA(prodkey, ""); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegCloseKey(compkey); DeleteFileA("C:\\imapath"); @@ -1965,7 +2237,7 @@ static void test_MsiGetComponentPath(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local classes product key exists */ @@ -1983,7 +2255,7 @@ static void test_MsiGetComponentPath(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user component key exists */ @@ -2033,8 +2305,8 @@ static void test_MsiGetComponentPath(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(compkey, prod_squashed); - RegDeleteKeyA(prodkey, ""); - RegDeleteKeyA(compkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegCloseKey(compkey); DeleteFileA("C:\\imapath"); @@ -2056,11 +2328,15 @@ static void test_MsiGetProductCode(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(prodcode2, prod2_squashed); compose_base85_guid(component, comp_base85, comp_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* szComponent is NULL */ lstrcpyA(product, "prod"); @@ -2110,7 +2386,13 @@ static void test_MsiGetProductCode(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user unmanaged component key exists */ @@ -2137,7 +2419,7 @@ static void test_MsiGetProductCode(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed product key of first product exists */ @@ -2146,7 +2428,7 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); @@ -2167,7 +2449,7 @@ static void test_MsiGetProductCode(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local classes product key exists */ @@ -2176,7 +2458,7 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); @@ -2185,7 +2467,7 @@ static void test_MsiGetProductCode(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod2_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed product key of second product exists */ @@ -2194,18 +2476,18 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey, prod2_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user component key exists */ @@ -2232,7 +2514,7 @@ static void test_MsiGetProductCode(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed product key of first product exists */ @@ -2241,7 +2523,7 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); @@ -2262,7 +2544,7 @@ static void test_MsiGetProductCode(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local classes product key exists */ @@ -2271,7 +2553,7 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); @@ -2280,7 +2562,7 @@ static void test_MsiGetProductCode(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod2_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user managed product key of second product exists */ @@ -2289,11 +2571,11 @@ static void test_MsiGetProductCode(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey, prod2_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); LocalFree(usersid); } @@ -2313,11 +2595,15 @@ static void test_MsiEnumClients(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(prodcode2, prod2_squashed); compose_base85_guid(component, comp_base85, comp_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szComponent */ product[0] = '\0'; @@ -2347,7 +2633,13 @@ static void test_MsiEnumClients(void) lstrcatA(keypath, "\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user unmanaged component key exists */ @@ -2410,14 +2702,14 @@ static void test_MsiEnumClients(void) RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey, prod2_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\"); lstrcatA(keypath, comp_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user local component key exists */ @@ -2480,7 +2772,7 @@ static void test_MsiEnumClients(void) RegDeleteValueA(compkey, prod_squashed); RegDeleteValueA(compkey, prod2_squashed); - RegDeleteKeyA(compkey, ""); + delete_key(compkey, "", access & KEY_WOW64_64KEY); RegCloseKey(compkey); LocalFree(usersid); } @@ -2753,10 +3045,14 @@ static void test_MsiGetProductInfo(void) CHAR keypath[MAX_PATH]; LPSTR usersid; DWORD sz, val = 42; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(packcode, pack_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProduct */ sz = MAX_PATH; @@ -2856,7 +3152,13 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product code exists */ @@ -2868,7 +3170,7 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); @@ -2876,7 +3178,7 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user product code exists */ @@ -2893,7 +3195,7 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* both local and managed product code exist */ @@ -2905,7 +3207,7 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -2974,9 +3276,9 @@ static void test_MsiGetProductInfo(void) RegDeleteValueA(propkey, "IMadeThis"); RegDeleteValueA(propkey, "HelpLink"); - RegDeleteKeyA(propkey, ""); - RegDeleteKeyA(localkey, ""); - RegDeleteKeyA(prodkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); + delete_key(localkey, "", access & KEY_WOW64_64KEY); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(propkey); RegCloseKey(localkey); RegCloseKey(prodkey); @@ -3001,7 +3303,7 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user product key exists */ @@ -3013,7 +3315,7 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -3036,8 +3338,8 @@ static void test_MsiGetProductInfo(void) ok(sz == 4, "Expected 4, got %d\n", sz); RegDeleteValueA(propkey, "HelpLink"); - RegDeleteKeyA(propkey, ""); - RegDeleteKeyA(localkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegDeleteKeyA(prodkey, ""); RegCloseKey(propkey); RegCloseKey(localkey); @@ -3046,7 +3348,7 @@ static void test_MsiGetProductInfo(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* classes product key exists */ @@ -3063,7 +3365,7 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user product key exists */ @@ -3075,7 +3377,7 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -3087,8 +3389,8 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - RegDeleteKeyA(propkey, ""); - RegDeleteKeyA(localkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(propkey); RegCloseKey(localkey); @@ -3096,7 +3398,7 @@ static void test_MsiGetProductInfo(void) lstrcatA(keypath, "S-1-5-18\\\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Local System product key exists */ @@ -3108,7 +3410,7 @@ static void test_MsiGetProductInfo(void) ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -3877,7 +4179,7 @@ static void test_MsiGetProductInfo(void) "Expected buf to be unchanged, got \"%s\"\n", buf); ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists, but PackageName val does not exist */ @@ -3994,8 +4296,8 @@ static void test_MsiGetProductInfo(void) RegDeleteValueA(propkey, "Version"); RegDeleteValueA(propkey, "ProductIcon"); RegDeleteValueA(propkey, "AuthorizedLUAApp"); - RegDeleteKeyA(propkey, ""); - RegDeleteKeyA(localkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegDeleteValueA(prodkey, "InstanceType"); RegDeleteValueA(prodkey, "Transforms"); RegDeleteValueA(prodkey, "Language"); @@ -4006,8 +4308,8 @@ static void test_MsiGetProductInfo(void) RegDeleteValueA(prodkey, "ProductIcon"); RegDeleteValueA(prodkey, "AuthorizedLUAApp"); RegDeleteValueA(source, "PackageName"); - RegDeleteKeyA(source, ""); - RegDeleteKeyA(prodkey, ""); + delete_key(source, "", access & KEY_WOW64_64KEY); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(propkey); RegCloseKey(localkey); RegCloseKey(source); @@ -4029,6 +4331,7 @@ static void test_MsiGetProductInfoEx(void) CHAR keypath[MAX_PATH]; LPSTR usersid; DWORD sz; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiGetProductInfoExA) { @@ -4038,7 +4341,10 @@ static void test_MsiGetProductInfoEx(void) create_test_guid(prodcode, prod_squashed); create_test_guid(packcode, pack_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProductCode */ sz = MAX_PATH; @@ -4162,7 +4468,13 @@ static void test_MsiGetProductInfoEx(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user product key exists */ @@ -4176,7 +4488,7 @@ static void test_MsiGetProductInfoEx(void) ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -4658,7 +4970,7 @@ static void test_MsiGetProductInfoEx(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ @@ -4678,7 +4990,7 @@ static void test_MsiGetProductInfoEx(void) lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); sz = MAX_PATH; @@ -4686,7 +4998,14 @@ static void test_MsiGetProductInfoEx(void) r = pMsiGetProductInfoExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_PRODUCTSTATE, buf, &sz); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r); + if (r == ERROR_UNKNOWN_PRODUCT) + { + win_skip("skipping remaining tests for MsiGetProductInfoEx\n"); + delete_key(prodkey, "", access); + RegCloseKey(prodkey); + return; + } ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf); ok(sz == 1, "Expected 1, got %d\n", sz); @@ -5069,7 +5388,7 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(prodkey, "HelpTelephone"); RegDeleteValueA(prodkey, "HelpLink"); RegDeleteValueA(prodkey, "LocalPackage"); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_USERMANAGED */ @@ -5079,7 +5398,7 @@ static void test_MsiGetProductInfoEx(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local user product key exists */ @@ -5093,7 +5412,7 @@ static void test_MsiGetProductInfoEx(void) ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -5482,9 +5801,9 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(propkey, "HelpTelephone"); RegDeleteValueA(propkey, "HelpLink"); RegDeleteValueA(propkey, "ManagedLocalPackage"); - RegDeleteKeyA(propkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); RegCloseKey(propkey); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(localkey); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\"); @@ -5492,7 +5811,7 @@ static void test_MsiGetProductInfoEx(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ @@ -5505,7 +5824,7 @@ static void test_MsiGetProductInfoEx(void) ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf); ok(sz == 1, "Expected 1, got %d\n", sz); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); @@ -5544,7 +5863,7 @@ static void test_MsiGetProductInfoEx(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5); @@ -5925,9 +6244,9 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(userkey, "InstallDate"); RegDeleteValueA(userkey, "HelpTelephone"); RegDeleteValueA(userkey, "HelpLink"); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_MACHINE */ @@ -5946,7 +6265,7 @@ static void test_MsiGetProductInfoEx(void) lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local system product key exists */ @@ -5960,7 +6279,7 @@ static void test_MsiGetProductInfoEx(void) ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz); - res = RegCreateKeyA(localkey, "InstallProperties", &propkey); + res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -6349,15 +6668,15 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(propkey, "HelpTelephone"); RegDeleteValueA(propkey, "HelpLink"); RegDeleteValueA(propkey, "LocalPackage"); - RegDeleteKeyA(propkey, ""); + delete_key(propkey, "", access & KEY_WOW64_64KEY); RegCloseKey(propkey); - RegDeleteKeyA(localkey, ""); + delete_key(localkey, "", access & KEY_WOW64_64KEY); RegCloseKey(localkey); lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local classes product key exists */ @@ -6748,7 +7067,7 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(prodkey, "InstallDate"); RegDeleteValueA(prodkey, "HelpTelephone"); RegDeleteValueA(prodkey, "HelpLink"); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); LocalFree(usersid); } @@ -6772,9 +7091,13 @@ static void test_MsiGetUserInfo(void) HKEY prodkey, userprod, props; LPSTR usersid; LONG res; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProduct */ INIT_USERINFO(); @@ -6942,7 +7265,13 @@ static void test_MsiGetUserInfo(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -6963,10 +7292,10 @@ static void test_MsiGetUserInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegCreateKeyA(userprod, "InstallProperties", &props); + res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7089,11 +7418,11 @@ static void test_MsiGetUserInfo(void) RegDeleteValueA(props, "ProductID"); RegDeleteValueA(props, "RegCompany"); RegDeleteValueA(props, "RegOwner"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userprod, ""); + delete_key(userprod, "", access & KEY_WOW64_64KEY); RegCloseKey(userprod); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_USERUNMANAGED */ @@ -7123,10 +7452,10 @@ static void test_MsiGetUserInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegCreateKeyA(userprod, "InstallProperties", &props); + res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7207,9 +7536,9 @@ static void test_MsiGetUserInfo(void) RegDeleteValueA(props, "ProductID"); RegDeleteValueA(props, "RegCompany"); RegDeleteValueA(props, "RegOwner"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userprod, ""); + delete_key(userprod, "", access & KEY_WOW64_64KEY); RegCloseKey(userprod); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); @@ -7220,7 +7549,7 @@ static void test_MsiGetUserInfo(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* product key exists */ @@ -7240,10 +7569,10 @@ static void test_MsiGetUserInfo(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegCreateKeyA(userprod, "InstallProperties", &props); + res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7324,11 +7653,11 @@ static void test_MsiGetUserInfo(void) RegDeleteValueA(props, "ProductID"); RegDeleteValueA(props, "RegCompany"); RegDeleteValueA(props, "RegOwner"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userprod, ""); + delete_key(userprod, "", access & KEY_WOW64_64KEY); RegCloseKey(userprod); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); LocalFree(usersid); } @@ -7346,12 +7675,16 @@ static void test_MsiOpenProduct(void) DWORD size; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; GetCurrentDirectoryA(MAX_PATH, path); lstrcatA(path, "\\"); create_test_guid(prodcode, prod_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; hdb = create_package_db(prodcode); MsiCloseHandle(hdb); @@ -7413,7 +7746,13 @@ static void test_MsiOpenProduct(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -7429,7 +7768,7 @@ static void test_MsiOpenProduct(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ @@ -7439,7 +7778,7 @@ static void test_MsiOpenProduct(void) "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n"); - res = RegCreateKeyA(userkey, "InstallProperties", &props); + res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7470,11 +7809,11 @@ static void test_MsiOpenProduct(void) MsiCloseHandle(hprod); RegDeleteValueA(props, "ManagedLocalPackage"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_USERUNMANAGED */ @@ -7498,7 +7837,7 @@ static void test_MsiOpenProduct(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ @@ -7508,7 +7847,7 @@ static void test_MsiOpenProduct(void) "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n"); - res = RegCreateKeyA(userkey, "InstallProperties", &props); + res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7539,9 +7878,9 @@ static void test_MsiOpenProduct(void) MsiCloseHandle(hprod); RegDeleteValueA(props, "LocalPackage"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); @@ -7551,7 +7890,7 @@ static void test_MsiOpenProduct(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -7565,7 +7904,7 @@ static void test_MsiOpenProduct(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ @@ -7575,7 +7914,7 @@ static void test_MsiOpenProduct(void) "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n"); - res = RegCreateKeyA(userkey, "InstallProperties", &props); + res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -7612,6 +7951,11 @@ static void test_MsiOpenProduct(void) /* LocalPackage has just the package name */ hprod = 0xdeadbeef; r = MsiOpenProductA(prodcode, &hprod); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS, "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r); if (r == ERROR_SUCCESS) @@ -7634,12 +7978,13 @@ static void test_MsiOpenProduct(void) "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n"); +error: RegDeleteValueA(props, "LocalPackage"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); DeleteFileA(msifile); @@ -7657,10 +8002,14 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid DWORD size, data; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(patch, patch_squashed); + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* MSIPATCHSTATE_APPLIED */ lstrcpyA(patchcode, "apple"); @@ -7671,6 +8020,11 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED, MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod, &context, targetsid, &size); + if (r == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); ok(!lstrcmpA(patchcode, "apple"), "Expected patchcode to be unchanged, got %s\n", patchcode); @@ -7687,7 +8041,12 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -7710,7 +8069,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &patches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* patches key exists */ @@ -8031,7 +8390,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData product key exists */ @@ -8054,7 +8413,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &udpatch); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData patches key exists */ @@ -8077,7 +8436,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udpatch, patch_squashed, &hpatch); + res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* specific UserData patch key exists */ @@ -8221,16 +8580,16 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); RegDeleteValueA(hpatch, "State"); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); RegDeleteValueA(patches, "Patches"); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); } @@ -8246,10 +8605,14 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds DWORD size, data; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(patch, patch_squashed); + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* MSIPATCHSTATE_APPLIED */ lstrcpyA(patchcode, "apple"); @@ -8371,9 +8734,10 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + patch_squashed[lstrlenA(patch_squashed) + 1] = 0; res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ, (const BYTE *)patch_squashed, - lstrlenA(patch_squashed) + 1); + lstrlenA(patch_squashed) + 2); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches value exists */ @@ -8429,7 +8793,12 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds lstrcatA(keypath, "\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* userdata patch key exists */ @@ -8479,7 +8848,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData product key exists */ @@ -8502,7 +8871,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &udpatch); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData patches key exists */ @@ -8525,7 +8894,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udpatch, patch_squashed, &hpatch); + res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* specific UserData patch key exists */ @@ -8669,16 +9038,18 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); RegDeleteValueA(hpatch, "State"); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); RegDeleteValueA(patches, patch_squashed); RegDeleteValueA(patches, "Patches"); + +error: RegDeleteKeyA(patches, ""); RegCloseKey(patches); RegDeleteKeyA(prodkey, ""); @@ -8697,10 +9068,14 @@ static void test_MsiEnumPatchesEx_machine(void) DWORD size, data; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(patch, patch_squashed); + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* MSIPATCHSTATE_APPLIED */ lstrcpyA(patchcode, "apple"); @@ -8725,7 +9100,12 @@ static void test_MsiEnumPatchesEx_machine(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local product key exists */ @@ -8748,7 +9128,7 @@ static void test_MsiEnumPatchesEx_machine(void) "Expected targetsid to be unchanged, got %s\n", targetsid); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &patches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -8875,7 +9255,7 @@ static void test_MsiEnumPatchesEx_machine(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData product key exists */ @@ -8898,7 +9278,7 @@ static void test_MsiEnumPatchesEx_machine(void) "Expected \"\", got \"%s\"\n", targetsid); ok(size == 0, "Expected 0, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &udpatch); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData Patches key exists */ @@ -8921,7 +9301,7 @@ static void test_MsiEnumPatchesEx_machine(void) "Expected \"\", got \"%s\"\n", targetsid); ok(size == 0, "Expected 0, got %d\n", size); - res = RegCreateKeyA(udpatch, patch_squashed, &hpatch); + res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData Product patch key exists */ @@ -9105,16 +9485,16 @@ static void test_MsiEnumPatchesEx_machine(void) RegDeleteValueA(patches, patch_squashed); RegDeleteValueA(patches, "Patches"); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); RegDeleteValueA(hpatch, "State"); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); } @@ -9135,7 +9515,7 @@ static void test_MsiEnumPatchesEx(void) } create_test_guid(prodcode, prod_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); /* empty szProductCode */ lstrcpyA(patchcode, "apple"); @@ -9392,10 +9772,14 @@ static void test_MsiEnumPatches(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(prodcode, prod_squashed); create_test_guid(patchcode, patch_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szProduct */ size = MAX_PATH; @@ -9497,7 +9881,13 @@ static void test_MsiEnumPatches(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -9512,7 +9902,7 @@ static void test_MsiEnumPatches(void) "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &patches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* patches key exists */ @@ -9671,9 +10061,9 @@ static void test_MsiEnumPatches(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); RegDeleteValueA(patches, "Patches"); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* MSIINSTALLCONTEXT_USERUNMANAGED */ @@ -9807,7 +10197,7 @@ static void test_MsiEnumPatches(void) lstrcatA(keypath, "\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* userdata patch key exists */ @@ -9822,7 +10212,7 @@ static void test_MsiEnumPatches(void) "Expected \"whatever\", got \"%s\"\n", transforms); ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access & KEY_WOW64_64KEY); RegCloseKey(userkey); RegDeleteValueA(patches, patch_squashed); RegDeleteValueA(patches, "Patches"); @@ -9848,7 +10238,7 @@ static void test_MsiEnumPatches(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local product key exists */ @@ -9863,7 +10253,7 @@ static void test_MsiEnumPatches(void) "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &patches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -9957,7 +10347,7 @@ static void test_MsiEnumPatches(void) lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData product key exists */ @@ -9972,7 +10362,7 @@ static void test_MsiEnumPatches(void) "Expected \"whatever\", got \"%s\"\n", transforms); ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &udpatch); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData Patches key exists */ @@ -9987,7 +10377,7 @@ static void test_MsiEnumPatches(void) "Expected \"whatever\", got \"%s\"\n", transforms); ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size); - res = RegCreateKeyA(udpatch, patch_squashed, &hpatch); + res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData Product patch key exists */ @@ -10057,16 +10447,16 @@ static void test_MsiEnumPatches(void) RegDeleteValueA(patches, patch_squashed); RegDeleteValueA(patches, "Patches"); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); RegDeleteValueA(hpatch, "State"); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); LocalFree(usersid); } @@ -10082,6 +10472,7 @@ static void test_MsiGetPatchInfoEx(void) DWORD size; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiGetPatchInfoExA) { @@ -10091,7 +10482,10 @@ static void test_MsiGetPatchInfoEx(void) create_test_guid(prodcode, prod_squashed); create_test_guid(patchcode, patch_squashed); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; /* NULL szPatchCode */ lstrcpyA(val, "apple"); @@ -10334,7 +10728,13 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData product key exists */ @@ -10349,7 +10749,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "InstallProperties", &props); + res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -10363,7 +10763,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &patches); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10377,7 +10777,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(patches, patch_squashed, &hpatch); + res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10396,7 +10796,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* managed product key exists */ @@ -10410,7 +10810,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &prodpatches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10444,7 +10844,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData Patches key exists */ @@ -10630,9 +11030,9 @@ static void test_MsiGetPatchInfoEx(void) ok(size == 16, "Expected 16, got %d\n", size); RegDeleteValueA(prodpatches, patch_squashed); - RegDeleteKeyA(prodpatches, ""); + delete_key(prodpatches, "", access & KEY_WOW64_64KEY); RegCloseKey(prodpatches); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* UserData is sufficient for all properties @@ -10665,15 +11065,15 @@ static void test_MsiGetPatchInfoEx(void) RegDeleteValueA(hpatch, "Uninstallable"); RegDeleteValueA(hpatch, "Installed"); RegDeleteValueA(udpatch, "ManagedLocalPackage"); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); /* MSIINSTALLCONTEXT_USERUNMANAGED */ @@ -10694,7 +11094,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData product key exists */ @@ -10709,7 +11109,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "InstallProperties", &props); + res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -10723,7 +11123,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &patches); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10737,7 +11137,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(patches, patch_squashed, &hpatch); + res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10802,7 +11202,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData Patches key exists */ @@ -10839,7 +11239,7 @@ static void test_MsiGetPatchInfoEx(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(prodpatches, patch_squashed); - RegDeleteKeyA(prodpatches, ""); + delete_key(prodpatches, "", access & KEY_WOW64_64KEY); RegCloseKey(prodpatches); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); @@ -10869,15 +11269,15 @@ static void test_MsiGetPatchInfoEx(void) ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); RegDeleteValueA(udpatch, "LocalPackage"); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); /* MSIINSTALLCONTEXT_MACHINE */ @@ -10897,7 +11297,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local UserData product key exists */ @@ -10912,7 +11312,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "InstallProperties", &props); + res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* InstallProperties key exists */ @@ -10926,7 +11326,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(udprod, "Patches", &patches); + res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10940,7 +11340,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(patches, patch_squashed, &hpatch); + res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -10957,7 +11357,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* local product key exists */ @@ -10971,7 +11371,7 @@ static void test_MsiGetPatchInfoEx(void) "Expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - res = RegCreateKeyA(prodkey, "Patches", &prodpatches); + res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Patches key exists */ @@ -11004,7 +11404,7 @@ static void test_MsiGetPatchInfoEx(void) lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData Patches key exists */ @@ -11041,9 +11441,9 @@ static void test_MsiGetPatchInfoEx(void) ok(size == 10, "Expected 10, got %d\n", size); RegDeleteValueA(prodpatches, patch_squashed); - RegDeleteKeyA(prodpatches, ""); + delete_key(prodpatches, "", access & KEY_WOW64_64KEY); RegCloseKey(prodpatches); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access & KEY_WOW64_64KEY); RegCloseKey(prodkey); /* UserData is sufficient for all properties @@ -11071,15 +11471,15 @@ static void test_MsiGetPatchInfoEx(void) ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); RegDeleteValueA(udpatch, "LocalPackage"); - RegDeleteKeyA(udpatch, ""); + delete_key(udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(udpatch); - RegDeleteKeyA(hpatch, ""); + delete_key(hpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hpatch); - RegDeleteKeyA(patches, ""); + delete_key(patches, "", access & KEY_WOW64_64KEY); RegCloseKey(patches); - RegDeleteKeyA(props, ""); + delete_key(props, "", access & KEY_WOW64_64KEY); RegCloseKey(props); - RegDeleteKeyA(udprod, ""); + delete_key(udprod, "", access & KEY_WOW64_64KEY); RegCloseKey(udprod); LocalFree(usersid); } @@ -11094,11 +11494,15 @@ static void test_MsiGetPatchInfo(void) HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch; DWORD size; LONG res; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(patch_code, patch_squashed); create_test_guid(prod_code, prod_squashed); MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH); + if (is_wow64) + access |= KEY_WOW64_64KEY; + r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); @@ -11118,7 +11522,12 @@ static void test_MsiGetPatchInfo(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); /* product key exists */ @@ -11129,7 +11538,7 @@ static void test_MsiGetPatchInfo(void) ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size); - res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches); + res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL); ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); /* patches key exists */ @@ -11140,7 +11549,7 @@ static void test_MsiGetPatchInfo(void) ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val); ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size); - res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch); + res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL); ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); /* patch key exists */ @@ -11155,7 +11564,7 @@ static void test_MsiGetPatchInfo(void) lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); /* UserData product key exists */ @@ -11166,7 +11575,7 @@ static void test_MsiGetPatchInfo(void) ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val); ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size); - res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops); + res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL); ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); /* InstallProperties key exists */ @@ -11177,7 +11586,7 @@ static void test_MsiGetPatchInfo(void) ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val); ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size); - res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches); + res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL); ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); /* UserData Patches key exists */ @@ -11188,10 +11597,10 @@ static void test_MsiGetPatchInfo(void) ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val); ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size); - res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches); + res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch); + res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* UserData product patch key exists */ @@ -11206,7 +11615,7 @@ static void test_MsiGetPatchInfo(void) lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\"); lstrcatA(keypath, patch_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL); ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12); @@ -11241,23 +11650,23 @@ static void test_MsiGetPatchInfo(void) ok(valW[0], "expected > 0 got %u\n", valW[0]); ok(size == 11, "expected 11 got %u\n", size); - RegDeleteKeyA(hkey_udproductpatch, ""); + delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udproductpatch); - RegDeleteKeyA(hkey_udproductpatches, ""); + delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udproductpatches); - RegDeleteKeyA(hkey_udpatch, ""); + delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udpatch); - RegDeleteKeyA(hkey_patches, ""); + delete_key(hkey_patches, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_patches); - RegDeleteKeyA(hkey_product, ""); + delete_key(hkey_product, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_product); - RegDeleteKeyA(hkey_patch, ""); + delete_key(hkey_patch, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_patch); - RegDeleteKeyA(hkey_udpatches, ""); + delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udpatches); - RegDeleteKeyA(hkey_udprops, ""); + delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udprops); - RegDeleteKeyA(hkey_udproduct, ""); + delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY); RegCloseKey(hkey_udproduct); } @@ -11271,16 +11680,26 @@ static void test_MsiEnumProducts(void) char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH]; char *usersid; HKEY key1, key2, key3; + REGSAM access = KEY_ALL_ACCESS; create_test_guid(product1, product_squashed1); create_test_guid(product2, product_squashed2); create_test_guid(product3, product_squashed3); - get_user_sid(&usersid); + usersid = get_user_sid(); + + if (is_wow64) + access |= KEY_WOW64_64KEY; strcpy(keypath1, "Software\\Classes\\Installer\\Products\\"); strcat(keypath1, product_squashed1); - r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1); + r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL); + if (r == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + LocalFree(usersid); + return; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\"); @@ -11288,7 +11707,7 @@ static void test_MsiEnumProducts(void) strcat(keypath2, "\\Installer\\Products\\"); strcat(keypath2, product_squashed2); - r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2); + r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\"); @@ -11325,8 +11744,8 @@ static void test_MsiEnumProducts(void) ok(found2, "product2 not found\n"); ok(found3, "product3 not found\n"); - RegDeleteKeyA(key1, ""); - RegDeleteKeyA(key2, ""); + delete_key(key1, "", access & KEY_WOW64_64KEY); + delete_key(key2, "", access & KEY_WOW64_64KEY); RegDeleteKeyA(key3, ""); RegCloseKey(key1); RegCloseKey(key2); @@ -11334,10 +11753,54 @@ static void test_MsiEnumProducts(void) LocalFree(usersid); } +static void test_MsiGetFileSignatureInformation(void) +{ + HRESULT hr; + const CERT_CONTEXT *cert; + DWORD len; + + hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len ); + todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr); + + create_file( "signature.bin", "signature", sizeof("signature") ); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len ); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr); + + DeleteFileA( "signature.bin" ); +} + START_TEST(msi) { init_functionpointers(); + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + test_usefeature(); test_null(); test_getcomponentpath(); @@ -11364,6 +11827,6 @@ START_TEST(msi) test_MsiGetPatchInfo(); test_MsiEnumProducts(); } - test_MsiGetFileVersion(); + test_MsiGetFileSignatureInformation(); } diff --git a/rostests/winetests/msi/msi.rbuild b/rostests/winetests/msi/msi.rbuild index 67a8c078752..1533c4cbf7d 100644 --- a/rostests/winetests/msi/msi.rbuild +++ b/rostests/winetests/msi/msi.rbuild @@ -4,6 +4,7 @@ . + action.c automation.c db.c format.c diff --git a/rostests/winetests/msi/package.c b/rostests/winetests/msi/package.c index d2514ce5a7f..9808dfa7126 100644 --- a/rostests/winetests/msi/package.c +++ b/rostests/winetests/msi/package.c @@ -27,15 +27,27 @@ #include #include #include +#include #include "wine/test.h" +static BOOL is_wow64; static const char msifile[] = "winetest-package.msi"; -char CURR_DIR[MAX_PATH]; +static char CURR_DIR[MAX_PATH]; static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR); +static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD); +static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*); +static BOOL (WINAPI *pGetTokenInformation)( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD ); +static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE ); +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); +static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); +static void (WINAPI *pGetSystemInfo)(LPSYSTEM_INFO); +static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO); +static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR, UINT); static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD); static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*); @@ -44,14 +56,26 @@ static void init_functionpointers(void) { HMODULE hmsi = GetModuleHandleA("msi.dll"); HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + HMODULE hshell32 = GetModuleHandleA("shell32.dll"); HMODULE hsrclient; #define GET_PROC(mod, func) \ p ## func = (void*)GetProcAddress(mod, #func); GET_PROC(hmsi, MsiApplyMultiplePatchesA); + GET_PROC(hmsi, MsiGetComponentPathExA); + GET_PROC(hshell32, SHGetFolderPathA); GET_PROC(hadvapi32, ConvertSidToStringSidA); + GET_PROC(hadvapi32, GetTokenInformation); + GET_PROC(hadvapi32, OpenProcessToken); + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hadvapi32, RegDeleteKeyExW) + GET_PROC(hkernel32, IsWow64Process) + GET_PROC(hkernel32, GetNativeSystemInfo) + GET_PROC(hkernel32, GetSystemInfo) + GET_PROC(hkernel32, GetSystemWow64DirectoryA) hsrclient = LoadLibraryA("srclient.dll"); GET_PROC(hsrclient, SRRemoveRestorePoint); @@ -59,33 +83,58 @@ static void init_functionpointers(void) #undef GET_PROC } - -static LPSTR get_user_sid(LPSTR *usersid) +static BOOL is_process_limited(void) { HANDLE token; - BYTE buf[1024]; - DWORD size; - PTOKEN_USER user; + + if (!pOpenProcessToken || !pGetTokenInformation) return FALSE; + + if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) + { + BOOL ret; + TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; + DWORD size; + + ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); + CloseHandle(token); + return (ret && type == TokenElevationTypeLimited); + } + return FALSE; +} + +static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + +static char *get_user_sid(void) +{ + HANDLE token; + DWORD size = 0; + TOKEN_USER *user; + char *usersid = NULL; if (!pConvertSidToStringSidA) { win_skip("ConvertSidToStringSidA is not available\n"); return NULL; } - - *usersid = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - size = sizeof(buf); - GetTokenInformation(token, TokenUser, buf, size, &size); - user = (PTOKEN_USER)buf; - pConvertSidToStringSidA(user->User.Sid, usersid); - ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError()); + GetTokenInformation(token, TokenUser, NULL, size, &size); + + user = HeapAlloc(GetProcessHeap(), 0, size); + GetTokenInformation(token, TokenUser, user, size, &size); + pConvertSidToStringSidA(user->User.Sid, &usersid); + HeapFree(GetProcessHeap(), 0, user); + CloseHandle(token); - return *usersid; + return usersid; } /* RegDeleteTreeW from dlls/advapi32/registry.c */ -static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) +static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access) { LONG ret; DWORD dwMaxSubkeyLen, dwMaxValueLen; @@ -95,7 +144,7 @@ static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) if(lpszSubKey) { - ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); + ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey); if (ret) return ret; } @@ -123,12 +172,17 @@ static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL)) break; - ret = package_RegDeleteTreeW(hSubKey, lpszName); + ret = package_RegDeleteTreeW(hSubKey, lpszName, access); if (ret) goto cleanup; } if (lpszSubKey) - ret = RegDeleteKeyW(hKey, lpszSubKey); + { + if (pRegDeleteKeyExW) + ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0); + else + ret = RegDeleteKeyW(hKey, lpszSubKey); + } else while (TRUE) { @@ -210,6 +264,10 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, CHAR path[MAX_PATH]; LPCSTR prod = NULL; HKEY hkey; + REGSAM access = KEY_ALL_ACCESS; + + if (is_wow64) + access |= KEY_WOW64_64KEY; MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); squash_guid(guidW, squashedW); @@ -248,7 +306,7 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, "7D2F387510109040002000060BECB6AB", usersid); } - RegCreateKeyA(HKEY_LOCAL_MACHINE, comppath, &hkey); + RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL); lstrcpyA(path, CURR_DIR); lstrcatA(path, "\\"); @@ -257,7 +315,7 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context, RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path)); RegCloseKey(hkey); - RegCreateKeyA(HKEY_LOCAL_MACHINE, prodpath, &hkey); + RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL); RegCloseKey(hkey); } @@ -269,6 +327,10 @@ static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR CHAR squashed[MAX_PATH]; CHAR comppath[MAX_PATH]; CHAR prodpath[MAX_PATH]; + REGSAM access = KEY_ALL_ACCESS; + + if (is_wow64) + access |= KEY_WOW64_64KEY; MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH); squash_guid(guidW, squashedW); @@ -305,10 +367,10 @@ static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR } MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH); - package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW); + package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH); - package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW); + package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access); } static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec) @@ -574,10 +636,6 @@ make_add_entry(appsearch, "INSERT INTO `AppSearch` " "(`Property`, `Signature_`) VALUES( %s )") -make_add_entry(reglocator, - "INSERT INTO `RegLocator` " - "(`Signature_`, `Root`, `Key`, `Name`, `Type`) VALUES( %s )") - make_add_entry(signature, "INSERT INTO `Signature` " "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," @@ -616,6 +674,23 @@ make_add_entry(inilocator, "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " "VALUES( %s )") +static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path, + const char *name, UINT type ) +{ + const char insert[] = + "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) " + "VALUES( '%s', %u, '%s', '%s', %u )"; + char *query; + UINT sz, r; + + sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert ); + query = HeapAlloc( GetProcessHeap(), 0, sz ); + sprintf( query, insert, sig, root, path, name, type ); + r = run_query( hdb, query ); + HeapFree( GetProcessHeap(), 0, query ); + return r; +} + static UINT set_summary_info(MSIHANDLE hdb) { UINT res; @@ -670,7 +745,7 @@ static MSIHANDLE create_package_db(void) /* create an empty database */ res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb ); - ok( res == ERROR_SUCCESS , "Failed to create database\n" ); + ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); if( res != ERROR_SUCCESS ) return hdb; @@ -678,6 +753,7 @@ static MSIHANDLE create_package_db(void) ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); res = set_summary_info(hdb); + ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); res = run_query( hdb, "CREATE TABLE `Directory` ( " @@ -690,22 +766,29 @@ static MSIHANDLE create_package_db(void) return hdb; } -static MSIHANDLE package_from_db(MSIHANDLE hdb) +static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) { UINT res; - CHAR szPackage[10]; + CHAR szPackage[12]; MSIHANDLE hPackage; - sprintf(szPackage,"#%i",hdb); - res = MsiOpenPackage(szPackage,&hPackage); + sprintf(szPackage, "#%u", hdb); + res = MsiOpenPackage(szPackage, &hPackage); if (res != ERROR_SUCCESS) - return 0; + { + MsiCloseHandle(hdb); + return res; + } res = MsiCloseHandle(hdb); if (res != ERROR_SUCCESS) - return 0; + { + MsiCloseHandle(hPackage); + return res; + } - return hPackage; + *handle = hPackage; + return ERROR_SUCCESS; } static void create_test_file(const CHAR *name) @@ -809,8 +892,14 @@ static void test_createpackage(void) MSIHANDLE hPackage = 0; UINT res; - hPackage = package_from_db(create_package_db()); - ok( hPackage != 0, " Failed to create package\n"); + res = package_from_db(create_package_db(), &hPackage); + if (res == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res ); res = MsiCloseHandle( hPackage); ok( res == ERROR_SUCCESS , "Failed to close package\n" ); @@ -825,8 +914,14 @@ static void test_doaction( void ) r = MsiDoAction( -1, NULL ); ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); - hpkg = package_from_db(create_package_db()); - ok( hpkg, "failed to create package\n"); + r = package_from_db(create_package_db(), &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); r = MsiDoAction(hpkg, NULL); ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); @@ -851,8 +946,14 @@ static void test_gettargetpath_bad(void) DWORD sz; UINT r; - hpkg = package_from_db(create_package_db()); - ok( hpkg, "failed to create package\n"); + r = package_from_db(create_package_db(), &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); r = MsiGetTargetPath( 0, NULL, NULL, NULL ); ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n"); @@ -971,8 +1072,16 @@ static void test_settargetpath(void) r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" ); ok( r == S_OK, "cannot add file to the File table: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -1025,6 +1134,7 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r ); + buffer[0] = 0; sz = sizeof buffer - 1; lstrcat( tempdir, "\\" ); r = MsiGetTargetPath( hpkg, "TARGETDIR", buffer, &sz ); @@ -1035,13 +1145,29 @@ static void test_settargetpath(void) query_file_path( hpkg, "[#RootFile]", buffer ); ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer); + buffer[0] = 0; + sz = sizeof(buffer); + r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); + ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); + lstrcatA( tempdir, "TestParent\\" ); + ok( !lstrcmpi(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer ); + r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); + buffer[0] = 0; + sz = sizeof(buffer); + r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); + ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); + ok( lstrcmpi(buffer, "C:\\one\\two\\TestDir\\"), + "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer ); + + buffer[0] = 0; query_file_path( hpkg, "[#TestFile]", buffer ); ok( !lstrcmpi(buffer, "C:\\one\\two\\TestDir\\testfile.txt"), "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer ); + buffer[0] = 0; sz = sizeof buffer - 1; r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); @@ -1050,21 +1176,50 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two\\three" ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); + buffer[0] = 0; sz = sizeof buffer - 1; r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); ok( !lstrcmpi(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer); + r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\one\\\\two " ); + ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); + + buffer[0] = 0; + sz = sizeof buffer - 1; + r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); + ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); + ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer); + + r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " ); + ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); + + buffer[0] = 0; + sz = sizeof buffer - 1; + r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); + ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); + ok( !lstrcmpi(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer); + MsiCloseHandle( hpkg ); } static void test_condition(void) { + static const WCHAR cond1[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0}; + static const WCHAR cond2[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0}; + static const WCHAR cond3[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0}; + static const WCHAR cond4[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0}; MSICONDITION r; MSIHANDLE hpkg; - hpkg = package_from_db(create_package_db()); - ok( hpkg, "failed to create package\n"); + r = package_from_db(create_package_db(), &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); r = MsiEvaluateCondition(0, NULL); ok( r == MSICONDITION_ERROR, "wrong return val\n"); @@ -1773,6 +1928,22 @@ static void test_condition(void) r = MsiEvaluateCondition(hpkg, "A <= X"); ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + r = MsiEvaluateConditionW(hpkg, cond1); + ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE), + "wrong return val (%d)\n", r); + + r = MsiEvaluateConditionW(hpkg, cond2); + ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE), + "wrong return val (%d)\n", r); + + r = MsiEvaluateConditionW(hpkg, cond3); + ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE), + "wrong return val (%d)\n", r); + + r = MsiEvaluateConditionW(hpkg, cond4); + ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE), + "wrong return val (%d)\n", r); + MsiCloseHandle( hpkg ); DeleteFile(msifile); } @@ -1810,8 +1981,14 @@ static void test_props(void) "VALUES( 'MetadataCompName', 'Photoshop.dll' )"); ok( r == ERROR_SUCCESS , "Failed\n" ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); /* test invalid values */ r = MsiGetProperty( 0, NULL, NULL, NULL ); @@ -2014,8 +2191,14 @@ static void test_property_table(void) hdb = create_package_db(); ok( hdb, "failed to create package\n"); - hpkg = package_from_db(hdb); - ok( hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); @@ -2068,8 +2251,8 @@ static void test_property_table(void) r = add_property_entry(hdb, "'prop', 'val'"); ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); @@ -2190,6 +2373,11 @@ static void test_msipackage(void) /* empty szPackagePath */ r = MsiOpenPackage("", &hpack); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + return; + } todo_wine { ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -2274,8 +2462,14 @@ static void test_formatrecord2(void) DWORD sz; UINT r; - hpkg = package_from_db(create_package_db()); - ok( hpkg, "failed to create package\n"); + r = package_from_db(create_package_db(), &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r); r = MsiSetProperty(hpkg, "Manufacturer", " " ); ok( r == ERROR_SUCCESS, "set property failed\n"); @@ -2289,9 +2483,12 @@ static void test_formatrecord2(void) buffer[0] = 0; sz = sizeof buffer; r = MsiFormatRecord( hpkg, hrec, buffer, &sz ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); r = MsiRecordSetString(hrec, 0, "[foo][1]"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -2299,6 +2496,7 @@ static void test_formatrecord2(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "x[~]x"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -2306,7 +2504,9 @@ static void test_formatrecord2(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); r = MsiRecordSetString(hrec, 1, "hoo"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -2314,6 +2514,7 @@ static void test_formatrecord2(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[\\[]"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 1, "size wrong\n"); @@ -2322,6 +2523,7 @@ static void test_formatrecord2(void) SetEnvironmentVariable("FOO", "BAR"); r = MsiRecordSetString(hrec, 0, "[%FOO]"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -2329,7 +2531,9 @@ static void test_formatrecord2(void) ok( r == ERROR_SUCCESS, "format failed\n"); r = MsiRecordSetString(hrec, 0, "[[1]]"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); r = MsiRecordSetString(hrec, 1, "%FOO"); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); sz = sizeof buffer; r = MsiFormatRecord(hpkg, hrec, buffer, &sz); ok( sz == 3, "size wrong\n"); @@ -2352,6 +2556,12 @@ static void test_states(void) static const CHAR msifile3[] = "winetest3-package.msi"; static const CHAR msifile4[] = "winetest4-package.msi"; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); @@ -2361,7 +2571,7 @@ static void test_states(void) r = create_property_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r ); - r = add_property_entry( hdb, "'ProductCode', '{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}'" ); + r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" ); ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); r = add_property_entry( hdb, "'ProductLanguage', '1033'" ); @@ -2373,6 +2583,9 @@ static void test_states(void) r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" ); ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); + r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); + ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); + r = create_install_execute_sequence_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r ); @@ -2542,6 +2755,13 @@ static void test_states(void) r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" ); ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + /* msidbFeatureAttributesUIDisallowAbsent */ + r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" ); + ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + + r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" ); + ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + r = create_feature_components_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); @@ -2611,6 +2831,9 @@ static void test_states(void) r = add_feature_components_entry( hdb, "'ten', 'chi'" ); ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); + r = add_feature_components_entry( hdb, "'eleven', 'psi'" ); + ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); + r = create_file_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r ); @@ -2678,6 +2901,9 @@ static void test_states(void) r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" ); ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" ); + ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + MsiDatabaseCommit(hdb); /* these properties must not be in the saved msi file */ @@ -2696,8 +2922,14 @@ static void test_states(void) r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'"); ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle(hdb); @@ -2775,6 +3007,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -2922,6 +3161,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -2995,6 +3241,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -3142,9 +3395,31 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction( hpkg, "FileCost"); ok( r == ERROR_SUCCESS, "file cost failed\n"); + r = MsiGetFeatureState(hpkg, "one", NULL, NULL); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "one", NULL, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + + state = 0xdeadbee; + r = MsiGetFeatureState( hpkg, "one", &state, NULL); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "one", &state, &action); @@ -3215,6 +3490,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -3362,6 +3644,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); @@ -3435,6 +3724,13 @@ static void test_states(void) ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -3582,8 +3878,17 @@ static void test_states(void) ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + MsiCloseHandle( hpkg ); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + /* publish the features and components */ r = MsiInstallProduct(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -3604,8 +3909,8 @@ static void test_states(void) r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle(hdb); @@ -3679,6 +3984,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -3826,6 +4138,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -3899,6 +4218,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -4046,6 +4372,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "FileCost"); ok( r == ERROR_SUCCESS, "file cost failed\n"); @@ -4259,6 +4592,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); @@ -4332,6 +4672,13 @@ static void test_states(void) ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -4479,6 +4826,13 @@ static void test_states(void) ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + MsiCloseHandle(hpkg); /* uninstall the product */ @@ -4496,8 +4850,8 @@ static void test_states(void) r = add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten'"); ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); state = 0xdeadbee; action = 0xdeadbee; @@ -4569,6 +4923,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -4716,6 +5077,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -4789,6 +5157,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -4936,6 +5311,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "FileCost"); ok( r == ERROR_SUCCESS, "file cost failed\n"); @@ -5009,6 +5391,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -5156,6 +5545,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); @@ -5229,6 +5625,13 @@ static void test_states(void) ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); todo_wine ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -5241,7 +5644,7 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "beta", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -5304,35 +5707,35 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "lambda", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "mu", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "nu", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "xi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "omicron", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -5346,35 +5749,42 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "rho", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "sigma", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "tau", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "phi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "chi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); MsiCloseHandle(hpkg); @@ -5393,8 +5803,8 @@ static void test_states(void) r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); state = 0xdeadbee; action = 0xdeadbee; @@ -5466,6 +5876,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -5613,6 +6030,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -5686,6 +6110,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -5833,6 +6264,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "FileCost"); ok( r == ERROR_SUCCESS, "file cost failed\n"); @@ -5906,6 +6344,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -6053,6 +6498,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); @@ -6061,14 +6513,14 @@ static void test_states(void) r = MsiGetFeatureState(hpkg, "one", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "two", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6082,7 +6534,7 @@ static void test_states(void) r = MsiGetFeatureState(hpkg, "four", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6096,42 +6548,49 @@ static void test_states(void) r = MsiGetFeatureState(hpkg, "six", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "seven", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "eight", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "nine", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "ten", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); + + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6152,7 +6611,7 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "theta", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6201,7 +6660,7 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "lambda", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6222,14 +6681,14 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "xi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "omicron", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -6250,28 +6709,35 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "sigma", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "tau", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "phi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "chi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); MsiCloseHandle(hpkg); @@ -6286,8 +6752,8 @@ static void test_states(void) r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); state = 0xdeadbee; action = 0xdeadbee; @@ -6359,6 +6825,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -6506,6 +6979,13 @@ static void test_states(void) ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r ); + ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state); + ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -6579,6 +7059,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -6726,6 +7213,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "FileCost"); ok( r == ERROR_SUCCESS, "file cost failed\n"); @@ -6799,6 +7293,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -6946,6 +7447,13 @@ static void test_states(void) ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r); @@ -7019,6 +7527,13 @@ static void test_states(void) ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "eleven", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "alpha", &state, &action); @@ -7031,7 +7546,7 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "beta", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -7094,35 +7609,35 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "lambda", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "mu", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "nu", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "xi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "omicron", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; @@ -7136,35 +7651,42 @@ static void test_states(void) r = MsiGetComponentState(hpkg, "rho", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "sigma", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "tau", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "phi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); - ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "chi", &state, &action); ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); + + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetComponentState(hpkg, "psi", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state); + ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action); MsiCloseHandle(hpkg); @@ -7186,8 +7708,14 @@ static void test_getproperty(void) DWORD size; UINT r; - hPackage = package_from_db(create_package_db()); - ok( hPackage != 0, " Failed to create package\n"); + r = package_from_db(create_package_db(), &hPackage); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "Failed to create package %u\n", r ); /* set the property */ r = MsiSetProperty(hPackage, "Name", "Value"); @@ -7228,6 +7756,7 @@ static void test_removefiles(void) MSIHANDLE hpkg; UINT r; MSIHANDLE hdb; + INSTALLSTATE installed, action; hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); @@ -7262,6 +7791,9 @@ static void test_removefiles(void) r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" ); ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + r = add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" ); + ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + r = create_feature_components_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); @@ -7283,6 +7815,9 @@ static void test_removefiles(void) r = add_feature_components_entry( hdb, "'one', 'carbon'" ); ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); + r = add_feature_components_entry( hdb, "'one', 'oxygen'" ); + ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); + r = create_file_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r ); @@ -7304,11 +7839,20 @@ static void test_removefiles(void) r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" ); ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + r = add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" ); + ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + r = create_remove_file_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle( hdb ); @@ -7318,25 +7862,43 @@ static void test_removefiles(void) create_test_file( "beryllium.txt" ); create_test_file( "boron.txt" ); create_test_file( "carbon.txt" ); + create_test_file( "oxygen.txt" ); r = MsiSetProperty( hpkg, "TARGETDIR", CURR_DIR ); ok( r == ERROR_SUCCESS, "set property failed\n"); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiGetComponentState( hpkg, "oxygen", &installed, &action ); + ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); r = MsiDoAction( hpkg, "FileCost"); - ok( r == ERROR_SUCCESS, "cost finalize failed\n"); + ok( r == ERROR_SUCCESS, "file cost failed\n"); + + installed = action = 0xdeadbeef; + r = MsiGetComponentState( hpkg, "oxygen", &installed, &action ); + ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); + ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); + ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); r = MsiDoAction( hpkg, "CostFinalize"); ok( r == ERROR_SUCCESS, "cost finalize failed\n"); r = MsiDoAction( hpkg, "InstallValidate"); - ok( r == ERROR_SUCCESS, "cost finalize failed\n"); + ok( r == ERROR_SUCCESS, "install validate failed\n"); r = MsiSetComponentState( hpkg, "hydrogen", INSTALLSTATE_ABSENT ); ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); + installed = action = 0xdeadbeef; + r = MsiGetComponentState( hpkg, "hydrogen", &installed, &action ); + ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); + ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); + todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); + r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL ); ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); @@ -7352,15 +7914,37 @@ static void test_removefiles(void) r = MsiSetComponentState( hpkg, "carbon", INSTALLSTATE_SOURCE ); ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); + installed = action = 0xdeadbeef; + r = MsiGetComponentState( hpkg, "oxygen", &installed, &action ); + ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); + ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); + ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); + + r = MsiSetComponentState( hpkg, "oxygen", INSTALLSTATE_ABSENT ); + ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r); + + installed = action = 0xdeadbeef; + r = MsiGetComponentState( hpkg, "oxygen", &installed, &action ); + ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); + ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); + ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); + r = MsiDoAction( hpkg, "RemoveFiles"); ok( r == ERROR_SUCCESS, "remove files failed\n"); + installed = action = 0xdeadbeef; + r = MsiGetComponentState( hpkg, "oxygen", &installed, &action ); + ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r ); + ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed ); + ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action ); + ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n"); ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n"); ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n"); ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n"); ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n"); ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n"); + ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n"); MsiCloseHandle( hpkg ); DeleteFileA(msifile); @@ -7372,7 +7956,7 @@ static void test_appsearch(void) UINT r; MSIHANDLE hdb; CHAR prop[MAX_PATH]; - DWORD size = MAX_PATH; + DWORD size; hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); @@ -7383,33 +7967,57 @@ static void test_appsearch(void) r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" ); ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r ); + r = add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" ); + ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r ); + r = create_reglocator_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); - r = add_reglocator_entry( hdb, "'NewSignature1', 0, 'htmlfile\\shell\\open\\command', '', 1" ); + r = add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 ); + ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); + + r = create_drlocator_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create DrLocator table: %d\n", r ); + + r = add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" ); ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); r = create_signature_table( hdb ); ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r ); r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" ); - ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r ); + ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); + ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r ); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle( hdb ); + if (r != ERROR_SUCCESS) + goto done; + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiDoAction( hpkg, "AppSearch" ); ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r); + size = sizeof(prop); r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size ); ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - todo_wine - { - ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); - } + ok( lstrlenA(prop) != 0, "Expected non-zero length\n"); + size = sizeof(prop); + r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + +done: MsiCloseHandle( hpkg ); DeleteFileA(msifile); } @@ -7423,9 +8031,15 @@ static void test_appsearch_complocator(void) DWORD size; UINT r; - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) return; + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + create_test_file("FileName1"); create_test_file("FileName4"); set_component_path("FileName1", MSIINSTALLCONTEXT_MACHINE, @@ -7587,12 +8201,19 @@ static void test_appsearch_complocator(void) r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "Expected a valid package handle\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); r = MsiSetPropertyA(hpkg, "SIGPROP8", "october"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "AppSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -7686,6 +8307,9 @@ static void test_appsearch_complocator(void) delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}", MSIINSTALLCONTEXT_MACHINE, NULL); + MsiCloseHandle(hpkg); + +error: DeleteFileA("FileName1"); DeleteFileA("FileName2"); DeleteFileA("FileName3"); @@ -7696,7 +8320,6 @@ static void test_appsearch_complocator(void) DeleteFileA("FileName8.dll"); DeleteFileA("FileName9.dll"); DeleteFileA("FileName10.dll"); - MsiCloseHandle(hpkg); DeleteFileA(msifile); LocalFree(usersid); } @@ -7704,19 +8327,15 @@ static void test_appsearch_complocator(void) static void test_appsearch_reglocator(void) { MSIHANDLE hpkg, hdb; - CHAR path[MAX_PATH]; - CHAR prop[MAX_PATH]; - DWORD binary[2]; - DWORD size, val; - BOOL space, version; - HKEY hklm, classes; - HKEY hkcu, users; - LPSTR pathdata; - LPSTR pathvar; + CHAR path[MAX_PATH], prop[MAX_PATH]; + DWORD binary[2], size, val; + BOOL space, version, is_64bit = sizeof(void *) > sizeof(int); + HKEY hklm, classes, hkcu, users; + LPSTR pathdata, pathvar, ptr; LPCSTR str; - LPSTR ptr; LONG res; - UINT r; + UINT r, type = 0; + SYSTEM_INFO si; version = TRUE; if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3))) @@ -7725,6 +8344,11 @@ static void test_appsearch_reglocator(void) DeleteFileA("test.dll"); res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); res = RegSetValueExA(classes, "Value1", 0, REG_SZ, @@ -7834,11 +8458,13 @@ static void test_appsearch_reglocator(void) sprintf(path, "\"%s\\FileName1\" -option", CURR_DIR); res = RegSetValueExA(hklm, "value16", 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1); + ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); space = (strchr(CURR_DIR, ' ')) ? TRUE : FALSE; sprintf(path, "%s\\FileName1 -option", CURR_DIR); res = RegSetValueExA(hklm, "value17", 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1); + ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); hdb = create_package_db(); ok(hdb, "Expected a valid database handle\n"); @@ -7939,154 +8565,152 @@ static void test_appsearch_reglocator(void) r = create_reglocator_table(hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeRawValue; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeRawValue, REG_SZ */ - str = "'NewSignature1', 2, 'Software\\Wine', 'Value1', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, positive DWORD */ - str = "'NewSignature2', 2, 'Software\\Wine', 'Value2', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, negative DWORD */ - str = "'NewSignature3', 2, 'Software\\Wine', 'Value3', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ - str = "'NewSignature4', 2, 'Software\\Wine', 'Value4', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ - str = "'NewSignature5', 2, 'Software\\Wine', 'Value5', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */ - str = "'NewSignature6', 2, 'Software\\Wine', 'Value6', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */ - str = "'NewSignature7', 2, 'Software\\Wine', 'Value7', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */ - str = "'NewSignature8', 2, 'Software\\Wine', 'Value8', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeFileName; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeFileName, signature, file exists */ - str = "'NewSignature9', 2, 'Software\\Wine', 'Value9', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */ - str = "'NewSignature10', 2, 'Software\\Wine', 'Value10', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, no signature */ - str = "'NewSignature11', 2, 'Software\\Wine', 'Value9', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeDirectory; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */ - str = "'NewSignature12', 2, 'Software\\Wine', 'Value9', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */ - str = "'NewSignature13', 2, 'Software\\Wine', 'Value11', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeDirectory, signature, file exists */ - str = "'NewSignature14', 2, 'Software\\Wine', 'Value9', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeRawValue; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKCR, msidbLocatorTypeRawValue, REG_SZ */ - str = "'NewSignature15', 0, 'Software\\Wine', 'Value1', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKCU, msidbLocatorTypeRawValue, REG_SZ */ - str = "'NewSignature16', 1, 'Software\\Wine', 'Value1', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKU, msidbLocatorTypeRawValue, REG_SZ */ - str = "'NewSignature17', 3, 'S-1-5-18\\Software\\Wine', 'Value1', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */ - str = "'NewSignature18', 2, 'Software\\Wine', '', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */ - str = "'NewSignature19', 2, 'Software\\IDontExist', '', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */ - str = "'NewSignature20', 2, 'Software\\Wine', 'Value12', 2"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeFileName; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */ - str = "'NewSignature21', 2, 'Software\\Wine', 'Value13', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */ - str = "'NewSignature22', 2, 'Software\\Wine', 'Value14', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */ - str = "'NewSignature23', 2, 'Software\\Wine', 'Value15', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */ - str = "'NewSignature24', 2, 'Software\\Wine', 'Value11', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */ - str = "'NewSignature25', 2, 'Software\\Wine', 'Value10', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeDirectory; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */ - str = "'NewSignature26', 2, 'Software\\Wine', 'Value11', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */ - str = "'NewSignature27', 2, 'Software\\Wine', 'Value10', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */ - str = "'NewSignature28', 2, 'Software\\Wine', 'Value10', 0"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + type = msidbLocatorTypeFileName; + if (is_64bit) + type |= msidbLocatorType64bit; + /* HKLM, msidbLocatorTypeFile, file exists, in quotes */ - str = "'NewSignature29', 2, 'Software\\Wine', 'Value16', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* HKLM, msidbLocatorTypeFile, file exists, no quotes */ - str = "'NewSignature30', 2, 'Software\\Wine', 'Value17', 1"; - r = add_reglocator_entry(hdb, str); + r = add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = create_signature_table(hdb); @@ -8133,8 +8757,10 @@ static void test_appsearch_reglocator(void) r = add_signature_entry(hdb, str); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "Expected a valid package handle\n"); + r = package_from_db(hdb, &hpkg); + ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiDoAction(hpkg, "AppSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -8155,28 +8781,28 @@ static void test_appsearch_reglocator(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop); - size = ExpandEnvironmentStringsA("%PATH%", NULL, 0); - if (size == 0 && GetLastError() == ERROR_INVALID_PARAMETER) + memset(&si, 0, sizeof(si)); + if (pGetNativeSystemInfo) pGetNativeSystemInfo(&si); + + if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { - /* Workaround for Win95 */ - CHAR tempbuf[1]; - size = ExpandEnvironmentStringsA("%PATH%", tempbuf, 0); + size = ExpandEnvironmentStringsA("%PATH%", NULL, 0); + pathvar = HeapAlloc(GetProcessHeap(), 0, size); + ExpandEnvironmentStringsA("%PATH%", pathvar, size); + + size = 0; + r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + pathdata = HeapAlloc(GetProcessHeap(), 0, ++size); + r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(pathdata, pathvar), + "Expected \"%s\", got \"%s\"\n", pathvar, pathdata); + + HeapFree(GetProcessHeap(), 0, pathvar); + HeapFree(GetProcessHeap(), 0, pathdata); } - pathvar = HeapAlloc(GetProcessHeap(), 0, size); - ExpandEnvironmentStringsA("%PATH%", pathvar, size); - - size = 0; - r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - pathdata = HeapAlloc(GetProcessHeap(), 0, ++size); - r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(pathdata, pathvar), - "Expected \"%s\", got \"%s\"\n", pathvar, pathdata); - - HeapFree(GetProcessHeap(), 0, pathvar); - HeapFree(GetProcessHeap(), 0, pathdata); size = MAX_PATH; r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size); @@ -8357,7 +8983,7 @@ static void test_appsearch_reglocator(void) RegDeleteValueA(hklm, "Value15"); RegDeleteValueA(hklm, "Value16"); RegDeleteValueA(hklm, "Value17"); - RegDeleteKeyA(hklm, ""); + RegDeleteKey(hklm, ""); RegCloseKey(hklm); RegDeleteValueA(classes, "Value1"); @@ -8554,8 +9180,15 @@ static void test_appsearch_inilocator(void) r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "Expected a valid package handle\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiDoAction(hpkg, "AppSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -8632,12 +9265,14 @@ static void test_appsearch_inilocator(void) ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop); } + MsiCloseHandle(hpkg); + +error: delete_win_ini("IniFile.ini"); DeleteFileA("FileName1"); DeleteFileA("FileName2.dll"); DeleteFileA("FileName3.dll"); DeleteFileA("FileName4.dll"); - MsiCloseHandle(hpkg); DeleteFileA(msifile); } @@ -8807,7 +9442,7 @@ static void test_appsearch_drlocator(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* parent */ - r = add_reglocator_entry(hdb, "'NewSignature12', 2, 'htmlfile\\shell\\open\\nonexistent', '', 1"); + r = add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* parent is in RegLocator, no path, depth 0, no signature */ @@ -8850,8 +9485,15 @@ static void test_appsearch_drlocator(void) r = add_signature_entry(hdb, str); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "Expected a valid package handle\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiDoAction(hpkg, "AppSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -8927,6 +9569,9 @@ static void test_appsearch_drlocator(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!prop[0], "Expected \"\", got \"%s\"\n", prop); + MsiCloseHandle(hpkg); + +error: DeleteFileA("FileName1"); DeleteFileA("FileName3.dll"); DeleteFileA("FileName4.dll"); @@ -8936,7 +9581,6 @@ static void test_appsearch_drlocator(void) RemoveDirectoryA("one\\two"); RemoveDirectoryA("one"); RemoveDirectoryA("another"); - MsiCloseHandle(hpkg); DeleteFileA(msifile); } @@ -8977,6 +9621,10 @@ static void test_featureparents(void) r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" ); ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + /* msidbFeatureAttributesUIDisallowAbsent */ + r = add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" ); + ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + /* disabled because of install level */ r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" ); ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); @@ -9027,6 +9675,7 @@ static void test_featureparents(void) /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); r = add_feature_components_entry( hdb, "'zodiac', 'leo'" ); ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); @@ -9112,11 +9761,19 @@ static void test_featureparents(void) r = add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" ); ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle( hdb ); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction( hpkg, "CostInitialize"); ok( r == ERROR_SUCCESS, "cost init failed\n"); @@ -9147,6 +9804,13 @@ static void test_featureparents(void) ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "lyra", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "waters", &state, &action); @@ -9241,6 +9905,12 @@ static void test_featureparents(void) r = MsiSetFeatureState(hpkg, "orion", INSTALLSTATE_ABSENT); ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); + r = MsiSetFeatureState(hpkg, "lyra", INSTALLSTATE_ABSENT); + ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r); + + r = MsiSetFeatureState(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT); + ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetFeatureState(hpkg, "zodiac", &state, &action); @@ -9262,6 +9932,13 @@ static void test_featureparents(void) ok( state == INSTALLSTATE_ABSENT, "Expected orion INSTALLSTATE_ABSENT, got %d\n", state); ok( action == INSTALLSTATE_ABSENT, "Expected orion INSTALLSTATE_ABSENT, got %d\n", action); + state = 0xdeadbee; + action = 0xdeadbee; + r = MsiGetFeatureState(hpkg, "lyra", &state, &action); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); + ok( state == INSTALLSTATE_ABSENT, "Expected lyra INSTALLSTATE_ABSENT, got %d\n", state); + ok( action == INSTALLSTATE_ABSENT, "Expected lyra INSTALLSTATE_ABSENT, got %d\n", action); + state = 0xdeadbee; action = 0xdeadbee; r = MsiGetComponentState(hpkg, "leo", &state, &action); @@ -9346,13 +10023,17 @@ static void test_featureparents(void) static void test_installprops(void) { MSIHANDLE hpkg, hdb; - CHAR path[MAX_PATH]; - CHAR buf[MAX_PATH]; + CHAR path[MAX_PATH], buf[MAX_PATH]; DWORD size, type; LANGID langid; HKEY hkey1, hkey2; int res; UINT r; + REGSAM access = KEY_ALL_ACCESS; + SYSTEM_INFO si; + + if (is_wow64) + access |= KEY_WOW64_64KEY; GetCurrentDirectory(MAX_PATH, path); lstrcat(path, "\\"); @@ -9361,8 +10042,14 @@ static void test_installprops(void) hdb = create_package_db(); ok( hdb, "failed to create database\n"); - hpkg = package_from_db(hdb); - ok( hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle(hdb); @@ -9372,8 +10059,7 @@ static void test_installprops(void) ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf); RegOpenKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1); - - RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hkey2); + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2); size = MAX_PATH; type = REG_SZ; @@ -9385,14 +10071,10 @@ static void test_installprops(void) RegQueryValueEx(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size); } - /* win9x doesn't set this */ - if (*path) - { - size = MAX_PATH; - r = MsiGetProperty(hpkg, "USERNAME", buf, &size); - ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf); - } + size = MAX_PATH; + r = MsiGetProperty(hpkg, "USERNAME", buf, &size); + ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf); size = MAX_PATH; type = REG_SZ; @@ -9437,24 +10119,233 @@ static void test_installprops(void) ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r); trace("PackageCode = %s\n", buf); + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ComputerName", buf, &size); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); + trace("ComputerName = %s\n", buf); + langid = GetUserDefaultLangID(); sprintf(path, "%d", langid); size = MAX_PATH; r = MsiGetProperty(hpkg, "UserLanguageID", buf, &size); - ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS< got %d\n", r); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf); res = GetSystemMetrics(SM_CXSCREEN); size = MAX_PATH; r = MsiGetProperty(hpkg, "ScreenX", buf, &size); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf)); res = GetSystemMetrics(SM_CYSCREEN); size = MAX_PATH; r = MsiGetProperty(hpkg, "ScreenY", buf, &size); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf)); + if (pGetSystemInfo && pSHGetFolderPathA) + { + pGetSystemInfo(&si); + if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "Msix64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "System64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + GetSystemDirectoryA(path, MAX_PATH); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "SystemFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pGetSystemWow64DirectoryA(path, MAX_PATH); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "VersionNT64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + } + else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + { + if (!is_wow64) + { + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "Msix64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "System64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "SystemFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + GetSystemDirectoryA(path, MAX_PATH); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "VersionNT64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + } + else + { + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "Msix64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "System64Folder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + GetSystemDirectoryA(path, MAX_PATH); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "SystemFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pGetSystemWow64DirectoryA(path, MAX_PATH); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFilesFolder64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFilesFolder64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(!buf[0], "property set\n"); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path); + if (size) buf[size - 1] = 0; + ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + + buf[0] = 0; + size = MAX_PATH; + r = MsiGetProperty(hpkg, "VersionNT64", buf, &size); + ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); + ok(buf[0], "property not set\n"); + } + } + } + CloseHandle(hkey1); CloseHandle(hkey2); MsiCloseHandle(hpkg); @@ -9482,14 +10373,22 @@ static void test_launchconditions(void) r = add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" ); ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r ); - hpkg = package_from_db( hdb ); - ok( hpkg, "failed to create package\n"); + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); MsiCloseHandle( hdb ); r = MsiSetProperty( hpkg, "X", "1" ); ok( r == ERROR_SUCCESS, "failed to set property\n" ); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + /* invalid conditions are ignored */ r = MsiDoAction( hpkg, "LaunchConditions" ); ok( r == ERROR_SUCCESS, "cost init failed\n" ); @@ -9512,8 +10411,6 @@ static void test_ccpsearch(void) DWORD size = MAX_PATH; UINT r; - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - hdb = create_package_db(); ok(hdb, "failed to create package database\n"); @@ -9529,7 +10426,7 @@ static void test_ccpsearch(void) r = create_reglocator_table(hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - r = add_reglocator_entry(hdb, "'CCP_random', 0, 'htmlfile\\shell\\open\\nonexistent', '', 1"); + r = add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = create_drlocator_table(hdb); @@ -9541,11 +10438,19 @@ static void test_ccpsearch(void) r = create_signature_table(hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "CCPSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -9697,8 +10602,14 @@ static void test_complocator(void) r = add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); @@ -9736,6 +10647,8 @@ static void test_complocator(void) set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE, "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "AppSearch"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -9928,8 +10841,14 @@ static void test_MsiGetSourcePath(void) r = MsiDatabaseCommit(hdb); ok(r == ERROR_SUCCESS , "Failed to commit database\n"); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); @@ -9971,6 +10890,20 @@ static void test_MsiGetSourcePath(void) "Expected path to be unchanged, got \"%s\"\n", path); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); + ok(size == 0, "Expected 0, got %d\n", size); + + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); + ok(size == 0, "Expected 0, got %d\n", size); + /* try SourceDir */ size = MAX_PATH; lstrcpyA(path, "kiwi"); @@ -9990,6 +10923,13 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); + ok(size == 0, "Expected 0, got %d\n", size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10015,6 +10955,8 @@ static void test_MsiGetSourcePath(void) "Expected path to be unchanged, got \"%s\"\n", path); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "CostInitialize"); ok(r == ERROR_SUCCESS, "cost init failed\n"); @@ -10044,15 +10986,19 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - todo_wine - { - ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); - ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); - } + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); /* try SubDir after CostInitialize */ size = MAX_PATH; @@ -10099,6 +11045,13 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10151,6 +11104,13 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10203,6 +11163,13 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10275,6 +11242,31 @@ static void test_MsiGetSourcePath(void) ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + /* remove property */ + r = MsiSetProperty(hpkg, "SourceDir", NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + /* try SourceDir again */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + + /* set property to a valid directory */ + r = MsiSetProperty(hpkg, "SOURCEDIR", cwd); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + /* try SOURCEDIR again */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size); + ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); + ok(!lstrcmpA(path, "kiwi"), + "Expected path to be unchanged, got \"%s\"\n", path); + ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + MsiCloseHandle(hpkg); /* compressed source */ @@ -10284,8 +11276,8 @@ static void test_MsiGetSourcePath(void) set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); /* try TARGETDIR */ size = MAX_PATH; @@ -10315,6 +11307,13 @@ static void test_MsiGetSourcePath(void) ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); /* source path nor the property exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); + ok(size == 0, "Expected 0, got %d\n", size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10371,15 +11370,19 @@ static void test_MsiGetSourcePath(void) } /* source path does not exist, but the property exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - todo_wine - { - ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); - ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); - } + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); /* try SubDir after CostInitialize */ size = MAX_PATH; @@ -10428,6 +11431,13 @@ static void test_MsiGetSourcePath(void) } /* source path and the property exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10482,6 +11492,13 @@ static void test_MsiGetSourcePath(void) } /* source path and the property exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10536,6 +11553,13 @@ static void test_MsiGetSourcePath(void) } /* source path and the property exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + size = MAX_PATH; lstrcpyA(path, "kiwi"); r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); @@ -10618,14 +11642,22 @@ static void test_shortlongsource(void) MsiDatabaseCommit(hdb); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); CreateDirectoryA("one", NULL); CreateDirectoryA("four", NULL); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "CostInitialize"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -10758,8 +11790,8 @@ static void test_shortlongsource(void) set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN); - hpkg = package_from_db(hdb); - ok(hpkg, "failed to create package\n"); + r = package_from_db(hdb, &hpkg); + ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); MsiCloseHandle(hdb); @@ -10900,7 +11932,7 @@ static void test_shortlongsource(void) static void test_sourcedir(void) { MSIHANDLE hdb, hpkg; - CHAR package[10]; + CHAR package[12]; CHAR path[MAX_PATH]; CHAR cwd[MAX_PATH]; CHAR subsrc[MAX_PATH]; @@ -10920,8 +11952,13 @@ static void test_sourcedir(void) r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); ok(r == S_OK, "failed\n"); - sprintf(package, "#%i", hdb); + sprintf(package, "#%u", hdb); r = MsiOpenPackage(package, &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* properties only */ @@ -10942,6 +11979,8 @@ static void test_sourcedir(void) ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); ok(size == 0, "Expected 0, got %d\n", size); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiDoAction(hpkg, "CostInitialize"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -10999,6 +12038,23 @@ static void test_sourcedir(void) ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path); ok(size == 0, "Expected 0, got %d\n", size); + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size); + ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); + ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path); + ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size); + + /* SOURCEDIR after calling MsiGetSourcePath */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + todo_wine { + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + } + r = MsiDoAction(hpkg, "ResolveSource"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -11225,8 +12281,10 @@ static void test_sourcedir(void) "Expected path to be unchanged, got \"%s\"\n", path); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); - MsiCloseHandle(hdb); MsiCloseHandle(hpkg); + +error: + MsiCloseHandle(hdb); DeleteFileA(msifile); } @@ -11331,9 +12389,7 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line, idx, ares[idx].gothandle, (hfile != INVALID_HANDLE_VALUE)); - ok(lasterr == ares[idx].lasterr || - lasterr == 0xdeadbeef, /* win9x */ - "(%d, lasterr, %d): Expected %d, got %d\n", + ok(lasterr == ares[idx].lasterr, "(%d, lasterr, %d): Expected %d, got %d\n", line, idx, ares[idx].lasterr, lasterr); CloseHandle(hfile); @@ -11358,11 +12414,9 @@ static void test_access(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); test_file_access(msifile, create_commit); - MsiCloseHandle(hdb); test_file_access(msifile, create_close); - DeleteFileA(msifile); r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATEDIRECT, &hdb); @@ -11374,11 +12428,9 @@ static void test_access(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); test_file_access(msifile, create_commit); - MsiCloseHandle(hdb); test_file_access(msifile, create_close); - DeleteFileA(msifile); } @@ -11392,6 +12444,11 @@ static void test_emptypackage(void) UINT r; r = MsiOpenPackageA("", &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + return; + } todo_wine { ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -11555,21 +12612,16 @@ static void test_MsiGetProductProperty(void) DWORD size; LONG res; UINT r; - SC_HANDLE scm; - - scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); - if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) - { - win_skip("Different registry keys on Win9x and WinMe\n"); - return; - } - CloseServiceHandle(scm); + REGSAM access = KEY_ALL_ACCESS; GetCurrentDirectoryA(MAX_PATH, path); lstrcatA(path, "\\"); create_test_guid(prodcode, prod_squashed); + if (is_wow64) + access |= KEY_WOW64_64KEY; + r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -11608,14 +12660,20 @@ static void test_MsiGetProductProperty(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\"); lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); if (res == ERROR_ACCESS_DENIED) { skip("Not enough rights to perform tests\n"); @@ -11625,7 +12683,7 @@ static void test_MsiGetProductProperty(void) } ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - res = RegCreateKeyA(userkey, "InstallProperties", &props); + res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(val, path); @@ -11760,11 +12818,11 @@ static void test_MsiGetProductProperty(void) MsiCloseHandle(hprod); RegDeleteValueA(props, "LocalPackage"); - RegDeleteKeyA(props, ""); + delete_key(props, "", access); RegCloseKey(props); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); DeleteFileA(msifile); } @@ -11777,8 +12835,14 @@ static void test_MsiSetProperty(void) DWORD size; UINT r; - hpkg = package_from_db(create_package_db()); - ok(hpkg != 0, "Expected a valid package\n"); + r = package_from_db(create_package_db(), &hpkg); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + DeleteFile(msifile); + return; + } + ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r); /* invalid hInstall */ r = MsiSetPropertyA(0, "Prop", "Val"); @@ -11894,51 +12958,31 @@ static void test_MsiApplyMultiplePatches(void) ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); r = pMsiApplyMultiplePatchesA(";", NULL, NULL); - todo_wine - { - if (type == DRIVE_FIXED) - ok(r == ERROR_PATH_NOT_FOUND, - "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); - else - ok(r == ERROR_INVALID_NAME, - "Expected ERROR_INVALID_NAME, got %u\n", r); - } + if (type == DRIVE_FIXED) + todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); + else + ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); r = pMsiApplyMultiplePatchesA(" ;", NULL, NULL); - todo_wine - { - if (type == DRIVE_FIXED) - ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, - "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r); - else - ok(r == ERROR_INVALID_NAME, - "Expected ERROR_INVALID_NAME, got %u\n", r); - } + if (type == DRIVE_FIXED) + todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r); + else + ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); r = pMsiApplyMultiplePatchesA(";;", NULL, NULL); - todo_wine - { - if (type == DRIVE_FIXED) - ok(r == ERROR_PATH_NOT_FOUND, - "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); - else - ok(r == ERROR_INVALID_NAME, - "Expected ERROR_INVALID_NAME, got %u\n", r); - } + if (type == DRIVE_FIXED) + todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); + else + ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL); todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); r = pMsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL); - todo_wine - { - if (type == DRIVE_FIXED) - ok(r == ERROR_PATH_NOT_FOUND, - "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); - else - ok(r == ERROR_INVALID_NAME, - "Expected ERROR_INVALID_NAME, got %u\n", r); - } + if (type == DRIVE_FIXED) + todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r); + else + ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r); r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL); todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r); @@ -11958,6 +13002,231 @@ static void test_MsiApplyPatch(void) ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r); } +static void test_MsiEnumComponentCosts(void) +{ + MSIHANDLE hdb, hpkg; + char package[12], drive[3]; + DWORD len; + UINT r; + int cost, temp; + + hdb = create_package_db(); + ok( hdb, "failed to create database\n" ); + + r = create_property_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r ); + + r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" ); + ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r ); + + r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); + ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r ); + + r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); + ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r ); + + r = create_media_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r ); + + r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''"); + ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r ); + + r = create_file_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r ); + + r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" ); + ok( r == ERROR_SUCCESS, "cannot add file %u\n", r ); + + r = create_component_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r ); + + r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" ); + ok( r == ERROR_SUCCESS, "cannot add component %u\n", r ); + + r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" ); + ok( r == ERROR_SUCCESS, "cannot add component %u\n", r ); + + r = create_feature_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r ); + + r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" ); + ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r ); + + r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" ); + ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r ); + + r = create_feature_components_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r ); + + r = add_feature_components_entry( hdb, "'one', 'one'" ); + ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r ); + + r = add_feature_components_entry( hdb, "'two', 'two'" ); + ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r ); + + r = create_install_execute_sequence_table( hdb ); + ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r ); + + r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); + ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + + r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); + ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + + r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); + ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + + r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" ); + ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + + MsiDatabaseCommit( hdb ); + + sprintf( package, "#%u", hdb ); + r = MsiOpenPackageA( package, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + + r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp ); + ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r ); + + MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); + + r = MsiDoAction( hpkg, "CostInitialize" ); + ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r ); + + r = MsiDoAction( hpkg, "FileCost" ); + ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); + + r = MsiDoAction( hpkg, "CostFinalize" ); + ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r ); + + /* contrary to what msdn says InstallValidate must be called too */ + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r ); + + r = MsiDoAction( hpkg, "InstallValidate" ); + ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r ); + + len = 0; + r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r ); + + len = 0; + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + + len = 2; + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + + len = 2; + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); + ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + + /* install state doesn't seem to matter */ + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + + len = sizeof(drive); + drive[0] = 0; + cost = temp = 0xdead; + r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + ok( drive[0], "expected a drive\n" ); + ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost ); + ok( !temp, "expected temp == 0, got %d\n", temp ); + + len = sizeof(drive); + drive[0] = 0; + cost = temp = 0xdead; + r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + ok( drive[0], "expected a drive\n" ); + ok( !cost, "expected cost == 0, got %d\n", cost ); + ok( !temp, "expected temp == 0, got %d\n", temp ); + + len = sizeof(drive); + drive[0] = 0; + cost = temp = 0xdead; + r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); + ok( len == 2, "expected len == 2, got %u\n", len ); + ok( drive[0], "expected a drive\n" ); + ok( !cost, "expected cost == 0, got %d\n", cost ); + ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp ); + + /* increased index */ + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp ); + ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); + + len = sizeof(drive); + r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp ); + ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r ); + + MsiCloseHandle( hpkg ); +error: + MsiCloseHandle( hdb ); + DeleteFileA( msifile ); +} + START_TEST(package) { STATEMGRSTATUS status; @@ -11965,12 +13234,18 @@ START_TEST(package) init_functionpointers(); + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + GetCurrentDirectoryA(MAX_PATH, CURR_DIR); /* Create a restore point ourselves so we circumvent the multitude of restore points * that would have been created by all the installation and removal tests. + * + * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the + * creation of restore points. */ - if (pSRSetRestorePointA) + if (pSRSetRestorePointA && !pMsiGetComponentPathExA) { memset(&status, 0, sizeof(status)); ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status); @@ -12007,8 +13282,9 @@ START_TEST(package) test_MsiSetProperty(); test_MsiApplyMultiplePatches(); test_MsiApplyPatch(); + test_MsiEnumComponentCosts(); - if (pSRSetRestorePointA && ret) + if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) { ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status); if (ret) diff --git a/rostests/winetests/msi/patch.c b/rostests/winetests/msi/patch.c index 4e10505eb08..89d5bd0aae1 100644 --- a/rostests/winetests/msi/patch.c +++ b/rostests/winetests/msi/patch.c @@ -35,6 +35,8 @@ static UINT (WINAPI *pMsiGetPatchInfoExA)( LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCON LPCSTR, LPSTR, DWORD * ); static UINT (WINAPI *pMsiEnumPatchesExA)( LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR, MSIINSTALLCONTEXT *, LPSTR, LPDWORD ); +static BOOL (WINAPI *pGetTokenInformation)( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD ); +static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE ); static const char *msifile = "winetest-patch.msi"; static const char *mspfile = "winetest-patch.msp"; @@ -55,7 +57,8 @@ static const char property_dat[] = "ProductLanguage\t1033\n" "ProductName\tmsitest\n" "ProductVersion\t1.1.1\n" - "PATCHNEWSUMMARYSUBJECT\tInstaller Database\n"; + "PATCHNEWSUMMARYSUBJECT\tInstaller Database\n" + "MSIFASTINSTALL\t1\n"; static const char media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" @@ -138,6 +141,7 @@ static const struct msi_table tables[] = static void init_function_pointers( void ) { HMODULE hmsi = GetModuleHandleA( "msi.dll" ); + HMODULE hadvapi32 = GetModuleHandleA( "advapi32.dll" ); #define GET_PROC( mod, func ) \ p ## func = (void *)GetProcAddress( mod, #func ); \ @@ -147,9 +151,31 @@ static void init_function_pointers( void ) GET_PROC( hmsi, MsiApplyPatchA ); GET_PROC( hmsi, MsiGetPatchInfoExA ); GET_PROC( hmsi, MsiEnumPatchesExA ); + + GET_PROC( hadvapi32, GetTokenInformation ); + GET_PROC( hadvapi32, OpenProcessToken ); #undef GET_PROC } +static BOOL is_process_limited(void) +{ + HANDLE token; + + if (!pOpenProcessToken || !pGetTokenInformation) return FALSE; + + if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) + { + BOOL ret; + TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; + DWORD size; + + ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); + CloseHandle(token); + return (ret && type == TokenElevationTypeLimited); + } + return FALSE; +} + static BOOL get_program_files_dir( char *buf, char *buf2 ) { HKEY hkey; @@ -260,7 +286,7 @@ static void set_suminfo( const char *filename ) r = MsiSummaryInfoSetProperty( hsi, 7, VT_LPSTR, 0, NULL, ";1033" ); ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r ); - r = MsiSummaryInfoSetProperty( hsi, 9, VT_LPSTR, 0, NULL, "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}" ); + r = MsiSummaryInfoSetProperty( hsi, 9, VT_LPSTR, 0, NULL, "{E528DDD6-4801-4BEC-BBB6-C5EE0FD097E9}" ); ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r ); r = MsiSummaryInfoSetProperty( hsi, 14, VT_I4, 100, NULL, NULL ); @@ -681,7 +707,7 @@ static void test_simple_patch( void ) { UINT r; DWORD size; - char path[MAX_PATH], install_source[MAX_PATH]; + char path[MAX_PATH], install_source[MAX_PATH], buffer[32]; const char *query; MSIHANDLE hpackage, hdb, hview, hrec; @@ -690,6 +716,11 @@ static void test_simple_patch( void ) win_skip("MsiApplyPatchA is not available\n"); return; } + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } CreateDirectoryA( "msitest", NULL ); create_file( "msitest\\patch.txt", 1000 ); @@ -700,7 +731,11 @@ static void test_simple_patch( void ) MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); r = MsiInstallProductA( msifile, NULL ); - ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + if (r != ERROR_SUCCESS) + { + skip("Product installation failed with error code %u\n", r); + goto cleanup; + } size = get_pf_file_size( "msitest\\patch.txt" ); ok( size == 1000, "expected 1000, got %u\n", size ); @@ -749,6 +784,12 @@ static void test_simple_patch( void ) MsiViewClose( hview ); MsiCloseHandle( hview ); + buffer[0] = 0; + size = sizeof(buffer); + r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + ok( !strcmp( buffer, "Installer Database" ), "expected \'Installer Database\', got \'%s\'\n", buffer ); + MsiCloseHandle( hdb ); MsiCloseHandle( hpackage ); @@ -759,7 +800,7 @@ static void test_simple_patch( void ) if (r == ERROR_PATCH_PACKAGE_INVALID) { win_skip("Windows Installer < 3.0 detected\n"); - return; + goto uninstall; } size = get_pf_file_size( "msitest\\patch.txt" ); @@ -801,6 +842,12 @@ static void test_simple_patch( void ) MsiViewClose( hview ); MsiCloseHandle( hview ); + buffer[0] = 0; + size = sizeof(buffer); + r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + ok( !strcmp( buffer, "Installation Database" ), "expected \'Installation Database\', got \'%s\'\n", buffer ); + MsiCloseHandle( hdb ); MsiCloseHandle( hpackage ); @@ -827,6 +874,7 @@ static void test_simple_patch( void ) MsiCloseHandle( hview ); MsiCloseHandle( hdb ); +uninstall: size = sizeof(path); r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", "InstallSource", path, &size ); @@ -839,8 +887,10 @@ static void test_simple_patch( void ) ok( !delete_pf( "msitest\\patch.txt", TRUE ), "file not removed\n" ); ok( !delete_pf( "msitest", FALSE ), "directory not removed\n" ); +cleanup: DeleteFileA( msifile ); DeleteFileA( mspfile ); + DeleteFileA( "msitest\\patch.txt" ); RemoveDirectoryA( "msitest" ); } @@ -907,17 +957,85 @@ static UINT find_entry( MSIHANDLE hdb, const char *table, const char *entry ) return r; } +static INT get_integer( MSIHANDLE hdb, UINT field, const char *query) +{ + UINT r; + INT ret = -1; + MSIHANDLE hview, hrec; + + r = MsiDatabaseOpenView( hdb, query, &hview ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + + r = MsiViewExecute( hview, 0 ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + + r = MsiViewFetch( hview, &hrec ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + if (r == ERROR_SUCCESS) + { + UINT r_tmp; + ret = MsiRecordGetInteger( hrec, field ); + MsiCloseHandle( hrec ); + + r_tmp = MsiViewFetch( hview, &hrec ); + ok( r_tmp == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r); + } + + MsiViewClose( hview ); + MsiCloseHandle( hview ); + return ret; +} + +static char *get_string( MSIHANDLE hdb, UINT field, const char *query) +{ + UINT r; + static char ret[MAX_PATH]; + MSIHANDLE hview, hrec; + + ret[0] = '\0'; + + r = MsiDatabaseOpenView( hdb, query, &hview ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + + r = MsiViewExecute( hview, 0 ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + + r = MsiViewFetch( hview, &hrec ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + if (r == ERROR_SUCCESS) + { + UINT size = MAX_PATH; + r = MsiRecordGetStringA( hrec, field, ret, &size ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r); + MsiCloseHandle( hrec ); + + r = MsiViewFetch( hview, &hrec ); + ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r); + } + + MsiViewClose( hview ); + MsiCloseHandle( hview ); + return ret; +} + static void test_system_tables( void ) { UINT r; + char *cr; const char *query; MSIHANDLE hproduct, hdb, hview, hrec; + static const char patchsource[] = "MSPSRC0F96CDC04CDF4304B2837B9264889EF7"; if (!pMsiApplyPatchA) { win_skip("MsiApplyPatchA is not available\n"); return; } + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } CreateDirectoryA( "msitest", NULL ); create_file( "msitest\\patch.txt", 1000 ); @@ -928,7 +1046,11 @@ static void test_system_tables( void ) MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); r = MsiInstallProductA( msifile, NULL ); - ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + if (r != ERROR_SUCCESS) + { + skip("Product installation failed with error code %d\n", r); + goto cleanup; + } r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); @@ -973,6 +1095,9 @@ static void test_system_tables( void ) r = find_entry( hdb, "_Tables", "Media" ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); + r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `VolumeLabel`=\'DISK1\'"); + ok( r == 1, "Got %u\n", r ); + r = find_entry( hdb, "_Tables", "_Property" ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); @@ -989,7 +1114,7 @@ static void test_system_tables( void ) if (r == ERROR_PATCH_PACKAGE_INVALID) { win_skip("Windows Installer < 3.0 detected\n"); - return; + goto uninstall; } r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct ); @@ -1047,17 +1172,38 @@ static void test_system_tables( void ) r = find_entry( hdb, "_Tables", "PatchPackage" ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); + cr = get_string( hdb, 6, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL"); + todo_wine ok( !strcmp(cr, patchsource), "Expected \"%s\", got \"%s\"\n", patchsource, cr ); + + r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL"); + todo_wine ok( r == 100, "Got %u\n", r ); + + r = get_integer( hdb, 2, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL"); + todo_wine ok( r == 10000, "Got %u\n", r ); + + r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `VolumeLabel`=\'DISK1\'"); + ok( r == 1, "Got %u\n", r ); + + cr = get_string( hdb, 4, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL"); + ok( !strcmp(cr, "#CAB_msitest"), "Expected \"#CAB_msitest\", got \"%s\"\n", cr ); + + r = get_integer( hdb, 8, "SELECT * FROM `File` WHERE `File` = 'patch.txt'"); + ok( r == 10000, "Got %u\n", r ); + MsiCloseHandle( hrec ); MsiViewClose( hview ); MsiCloseHandle( hview ); MsiCloseHandle( hdb ); MsiCloseHandle( hproduct ); +uninstall: r = MsiInstallProductA( msifile, "REMOVE=ALL" ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); +cleanup: DeleteFileA( msifile ); DeleteFileA( mspfile ); + DeleteFileA( "msitest\\patch.txt" ); RemoveDirectoryA( "msitest" ); } @@ -1071,6 +1217,11 @@ static void test_patch_registration( void ) win_skip("required functions not available\n"); return; } + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } CreateDirectoryA( "msitest", NULL ); create_file( "msitest\\patch.txt", 1000 ); @@ -1081,7 +1232,11 @@ static void test_patch_registration( void ) MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL ); r = MsiInstallProductA( msifile, NULL ); - ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + if (r != ERROR_SUCCESS) + { + skip("Product installation failed with error code %d\n", r); + goto cleanup; + } r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL ); ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */ @@ -1090,7 +1245,7 @@ static void test_patch_registration( void ) if (r == ERROR_PATCH_PACKAGE_INVALID) { win_skip("Windows Installer < 3.0 detected\n"); - return; + goto uninstall; } buffer[0] = 0; @@ -1135,6 +1290,7 @@ static void test_patch_registration( void ) 0, patch_code, NULL, NULL, NULL, NULL ); ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r ); +uninstall: r = MsiInstallProductA( msifile, "REMOVE=ALL" ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); @@ -1146,8 +1302,10 @@ static void test_patch_registration( void ) INSTALLPROPERTY_LOCALPACKAGE, buffer, &size ); ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r ); +cleanup: DeleteFileA( msifile ); DeleteFileA( mspfile ); + DeleteFileA( "msitest\\patch.txt" ); RemoveDirectoryA( "msitest" ); } diff --git a/rostests/winetests/msi/record.c b/rostests/winetests/msi/record.c index 0b807797215..2de43cb053f 100644 --- a/rostests/winetests/msi/record.c +++ b/rostests/winetests/msi/record.c @@ -589,6 +589,9 @@ static void test_fieldzero(void) MsiCloseHandle(rec); + r = MsiDatabaseGetPrimaryKeysA(hdb, "nosuchtable", &rec); + ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r); + query = "SELECT * FROM `drone` WHERE `id` = 1"; r = MsiDatabaseOpenView(hdb, query, &hview); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); diff --git a/rostests/winetests/msi/source.c b/rostests/winetests/msi/source.c index 1826f2175be..74b7cf30f5a 100644 --- a/rostests/winetests/msi/source.c +++ b/rostests/winetests/msi/source.c @@ -31,8 +31,13 @@ #include "wine/test.h" +static BOOL is_wow64; + static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*); +static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); static BOOLEAN (WINAPI *pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + static UINT (WINAPI *pMsiSourceListAddMediaDiskA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCSTR, LPCSTR); static UINT (WINAPI *pMsiSourceListAddSourceExA) @@ -53,6 +58,7 @@ static void init_functionpointers(void) { HMODULE hmsi = GetModuleHandleA("msi.dll"); HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); HMODULE hsecur32 = LoadLibraryA("secur32.dll"); #define GET_PROC(dll, func) \ @@ -69,7 +75,8 @@ static void init_functionpointers(void) GET_PROC(hmsi, MsiSourceListAddSourceA) GET_PROC(hadvapi32, ConvertSidToStringSidA) - + GET_PROC(hadvapi32, RegDeleteKeyExA) + GET_PROC(hkernel32, IsWow64Process) GET_PROC(hsecur32, GetUserNameExA) #undef GET_PROC @@ -127,25 +134,28 @@ static void create_test_guid(LPSTR prodcode, LPSTR squashed) WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); } -static int get_user_sid(LPSTR *usersid) +static char *get_user_sid(void) { HANDLE token; - BYTE buf[1024]; - DWORD size; - PTOKEN_USER user; - BOOL rc; + DWORD size = 0; + TOKEN_USER *user; + char *usersid = NULL; if (!pConvertSidToStringSidA) - return 0; - rc=OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - if (!rc && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) - return 0; - size = sizeof(buf); - GetTokenInformation(token, TokenUser, buf, size, &size); - user = (PTOKEN_USER)buf; - pConvertSidToStringSidA(user->User.Sid, usersid); + { + win_skip("ConvertSidToStringSidA is not available\n"); + return NULL; + } + OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); + GetTokenInformation(token, TokenUser, NULL, size, &size); + + user = HeapAlloc(GetProcessHeap(), 0, size); + GetTokenInformation(token, TokenUser, user, size, &size); + pConvertSidToStringSidA(user->User.Sid, &usersid); + HeapFree(GetProcessHeap(), 0, user); + CloseHandle(token); - return 1; + return usersid; } static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line) @@ -198,7 +208,7 @@ static void test_MsiSourceListGetInfo(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListGetInfoA tests\n"); return; @@ -219,11 +229,6 @@ static void test_MsiSourceListGetInfo(void) MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); - /* szProductCodeOrPatchCode */ - r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, - MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); - ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); - /* guid without brackets */ r = pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); @@ -631,6 +636,13 @@ static void test_MsiSourceListGetInfo(void) LocalFree(usersid); } +static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) +{ + if (pRegDeleteKeyExA) + return pRegDeleteKeyExA( key, subkey, access, 0 ); + return RegDeleteKeyA( key, subkey ); +} + static void test_MsiSourceListAddSourceEx(void) { CHAR prodcode[MAX_PATH]; @@ -640,9 +652,9 @@ static void test_MsiSourceListAddSourceEx(void) LPSTR usersid; LONG res; UINT r; - HKEY prodkey, userkey, hkey; - HKEY url, net; + HKEY prodkey, userkey, hkey, url, net; DWORD size; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListAddSourceExA) { @@ -651,12 +663,15 @@ static void test_MsiSourceListAddSourceEx(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListAddSourceExA tests\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProductCodeOrPatchCode */ @@ -900,8 +915,12 @@ static void test_MsiSourceListAddSourceEx(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* product key exists */ r = pMsiSourceListAddSourceExA(prodcode, usersid, @@ -909,7 +928,7 @@ static void test_MsiSourceListAddSourceEx(void) MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &hkey); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); RegCloseKey(hkey); @@ -919,7 +938,7 @@ static void test_MsiSourceListAddSourceEx(void) MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - res = RegOpenKeyA(prodkey, "SourceList\\URL", &url); + res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; @@ -937,7 +956,7 @@ static void test_MsiSourceListAddSourceEx(void) MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - res = RegOpenKeyA(prodkey, "SourceList\\URL", &url); + res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; @@ -957,6 +976,7 @@ static void test_MsiSourceListAddSourceEx(void) /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */ r = pMsiSourceListAddSourceExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE, @@ -971,8 +991,13 @@ static void test_MsiSourceListAddSourceEx(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* product key exists */ r = pMsiSourceListAddSourceExA(prodcode, NULL, @@ -980,7 +1005,7 @@ static void test_MsiSourceListAddSourceEx(void) MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &hkey); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); RegCloseKey(hkey); @@ -990,7 +1015,7 @@ static void test_MsiSourceListAddSourceEx(void) MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - res = RegOpenKeyA(prodkey, "SourceList\\URL", &url); + res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; @@ -1001,7 +1026,7 @@ static void test_MsiSourceListAddSourceEx(void) RegCloseKey(url); RegCloseKey(prodkey); - HeapFree(GetProcessHeap(), 0, usersid); + LocalFree(usersid); } static void test_MsiSourceListEnumSources(void) @@ -1016,6 +1041,7 @@ static void test_MsiSourceListEnumSources(void) HKEY prodkey, userkey; HKEY url, net, source; DWORD size; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListEnumSourcesA) { @@ -1024,12 +1050,15 @@ static void test_MsiSourceListEnumSources(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListEnumSourcesA tests\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProductCodeOrPatchCode */ @@ -1362,8 +1391,12 @@ static void test_MsiSourceListEnumSources(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* user product key exists */ size = MAX_PATH; @@ -1375,7 +1408,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(userkey, "SourceList", &source); + res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -1388,7 +1421,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(source, "URL", &url); + res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* URL key exists */ @@ -1425,7 +1458,7 @@ static void test_MsiSourceListEnumSources(void) ok(size == 5, "Expected 5, got %d\n", size); RegDeleteValueA(url, "1"); - RegDeleteKeyA(url, ""); + delete_key(url, "", access); RegCloseKey(url); /* SourceList key exists */ @@ -1438,7 +1471,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(source, "Net", &net); + res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Net key exists */ @@ -1465,15 +1498,16 @@ static void test_MsiSourceListEnumSources(void) ok(size == 5, "Expected 5, got %d\n", size); RegDeleteValueA(net, "1"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: /* szUserSid is non-NULL */ size = MAX_PATH; lstrcpyA(value, "aaa"); @@ -1484,7 +1518,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - /* szUserSid is non-NULL */ + /* szUserSid is NULL */ size = MAX_PATH; lstrcpyA(value, "aaa"); r = pMsiSourceListEnumSourcesA(prodcode, NULL, @@ -1497,8 +1531,13 @@ static void test_MsiSourceListEnumSources(void) lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* user product key exists */ size = MAX_PATH; @@ -1510,7 +1549,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -1523,7 +1562,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(source, "URL", &url); + res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* URL key exists */ @@ -1560,7 +1599,7 @@ static void test_MsiSourceListEnumSources(void) ok(size == 5, "Expected 5, got %d\n", size); RegDeleteValueA(url, "1"); - RegDeleteKeyA(url, ""); + delete_key(url, "", access); RegCloseKey(url); /* SourceList key exists */ @@ -1573,7 +1612,7 @@ static void test_MsiSourceListEnumSources(void) ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value); ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size); - res = RegCreateKeyA(source, "Net", &net); + res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Net key exists */ @@ -1600,11 +1639,11 @@ static void test_MsiSourceListEnumSources(void) ok(size == 5, "Expected 5, got %d\n", size); RegDeleteValueA(net, "1"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); LocalFree(usersid); } @@ -1619,6 +1658,7 @@ static void test_MsiSourceListSetInfo(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListSetInfoA) { @@ -1627,12 +1667,15 @@ static void test_MsiSourceListSetInfo(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListSetInfoA tests\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProductCodeOrPatchCode */ @@ -1942,8 +1985,12 @@ static void test_MsiSourceListSetInfo(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* user product key exists */ r = pMsiSourceListSetInfoA(prodcode, NULL, @@ -1952,7 +1999,7 @@ static void test_MsiSourceListSetInfo(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(userkey, "SourceList", &source); + res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists, no source type */ @@ -1962,25 +2009,31 @@ static void test_MsiSourceListSetInfo(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Media key is created by MsiSourceListSetInfo */ - res = RegOpenKeyA(source, "Media", &media); + res = RegOpenKeyExA(source, "Media", 0, access, &media); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(media, "MediaPackage", "path"); RegDeleteValueA(media, "MediaPackage"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* user product key exists */ r = pMsiSourceListSetInfoA(prodcode, NULL, @@ -1989,7 +2042,7 @@ static void test_MsiSourceListSetInfo(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists, no source type */ @@ -1999,7 +2052,7 @@ static void test_MsiSourceListSetInfo(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Media key is created by MsiSourceListSetInfo */ - res = RegOpenKeyA(source, "Media", &media); + res = RegOpenKeyExA(source, "Media", 0, access, &media); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(media, "MediaPackage", "path"); @@ -2011,11 +2064,11 @@ static void test_MsiSourceListSetInfo(void) "Expected ERROR_INVALID_PARAMETER, got %d\n", r); RegDeleteValueA(media, "MediaPackage"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); LocalFree(usersid); } @@ -2030,6 +2083,7 @@ static void test_MsiSourceListAddMediaDisk(void) LPSTR usersid; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListAddMediaDiskA) { @@ -2038,12 +2092,15 @@ static void test_MsiSourceListAddMediaDisk(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListAddMediaDiskA tests\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProductCodeOrPatchCode */ @@ -2238,8 +2295,12 @@ static void test_MsiSourceListAddMediaDisk(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* user product key exists */ r = pMsiSourceListAddMediaDiskA(prodcode, usersid, @@ -2248,7 +2309,7 @@ static void test_MsiSourceListAddMediaDisk(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(userkey, "SourceList", &source); + res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -2258,26 +2319,32 @@ static void test_MsiSourceListAddMediaDisk(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Media subkey is created by MsiSourceListAddMediaDisk */ - res = RegOpenKeyA(source, "Media", &media); + res = RegOpenKeyExA(source, "Media", 0, access, &media); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(media, "1", "label;prompt"); RegDeleteValueA(media, "1"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* machine product key exists */ r = pMsiSourceListAddMediaDiskA(prodcode, NULL, @@ -2286,7 +2353,7 @@ static void test_MsiSourceListAddMediaDisk(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -2296,7 +2363,7 @@ static void test_MsiSourceListAddMediaDisk(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Media subkey is created by MsiSourceListAddMediaDisk */ - res = RegOpenKeyA(source, "Media", &media); + res = RegOpenKeyExA(source, "Media", 0, access, &media); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(media, "1", "label;prompt"); @@ -2309,11 +2376,11 @@ static void test_MsiSourceListAddMediaDisk(void) "Expected ERROR_INVALID_PARAMETER, got %d\n", r); RegDeleteValueA(media, "1"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); LocalFree(usersid); } @@ -2325,14 +2392,12 @@ static void test_MsiSourceListEnumMediaDisks(void) CHAR keypath[MAX_PATH*2]; CHAR label[MAX_PATH]; CHAR prompt[MAX_PATH]; - HKEY prodkey, userkey; - HKEY media, source; - DWORD labelsz, promptsz; + HKEY prodkey, userkey, media, source; + DWORD labelsz, promptsz, val, id; LPSTR usersid; - DWORD val; - DWORD id; LONG res; UINT r; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListEnumMediaDisksA) { @@ -2341,12 +2406,15 @@ static void test_MsiSourceListEnumMediaDisks(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListEnumMediaDisksA tests\n"); return; } + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProductCodeOrPatchCode */ @@ -2943,8 +3011,12 @@ static void test_MsiSourceListEnumMediaDisks(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* user product key exists */ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED, @@ -2953,7 +3025,7 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(userkey, "SourceList", &source); + res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -2973,7 +3045,7 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt); ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz); - res = RegCreateKeyA(source, "Media", &media); + res = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Media key exists */ @@ -3013,20 +3085,26 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(promptsz == 6, "Expected 6, got %d\n", promptsz); RegDeleteValueA(media, "2"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* machine product key exists */ r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, @@ -3035,7 +3113,7 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -3055,7 +3133,7 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt); ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz); - res = RegCreateKeyA(source, "Media", &media); + res = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* Media key exists */ @@ -3112,11 +3190,11 @@ static void test_MsiSourceListEnumMediaDisks(void) ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz); RegDeleteValueA(media, "2"); - RegDeleteKeyA(media, ""); + delete_key(media, "", access); RegCloseKey(media); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); LocalFree(usersid); } @@ -3130,9 +3208,9 @@ static void test_MsiSourceListAddSource(void) LPSTR usersid, ptr; LONG res; UINT r; - HKEY prodkey, userkey; - HKEY net, source; + HKEY prodkey, userkey, net, source; DWORD size; + REGSAM access = KEY_ALL_ACCESS; if (!pMsiSourceListAddSourceA) { @@ -3141,7 +3219,7 @@ static void test_MsiSourceListAddSource(void) } create_test_guid(prodcode, prod_squashed); - if (!get_user_sid(&usersid)) + if (!(usersid = get_user_sid())) { skip("User SID not available -> skipping MsiSourceListAddSourceA tests\n"); return; @@ -3161,6 +3239,9 @@ static void test_MsiSourceListAddSource(void) } trace("username: %s\n", username); + if (is_wow64) + access |= KEY_WOW64_64KEY; + /* GetLastError is not set by the function */ /* NULL szProduct */ @@ -3205,14 +3286,18 @@ static void test_MsiSourceListAddSource(void) lstrcatA(keypath, "\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto userunmanaged_tests; + } /* user product key exists */ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source"); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(userkey, "SourceList", &source); + res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -3220,7 +3305,7 @@ static void test_MsiSourceListAddSource(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Net key is created */ - res = RegOpenKeyA(source, "Net", &net); + res = RegOpenKeyExA(source, "Net", 0, access, &net); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* LastUsedSource does not exist and it is not created */ @@ -3230,7 +3315,7 @@ static void test_MsiSourceListAddSource(void) CHECK_REG_STR(net, "1", "source\\"); RegDeleteValueA(net, "1"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"blah", 5); @@ -3241,14 +3326,14 @@ static void test_MsiSourceListAddSource(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Net key is created */ - res = RegOpenKeyA(source, "Net", &net); + res = RegOpenKeyExA(source, "Net", 0, access, &net); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(source, "LastUsedSource", "blah"); CHECK_REG_STR(net, "1", "source\\"); RegDeleteValueA(net, "1"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"5", 2); @@ -3259,7 +3344,7 @@ static void test_MsiSourceListAddSource(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Net key is created */ - res = RegOpenKeyA(source, "Net", &net); + res = RegOpenKeyExA(source, "Net", 0, access, &net); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(source, "LastUsedSource", "5"); @@ -3288,15 +3373,16 @@ static void test_MsiSourceListAddSource(void) RegDeleteValueA(net, "1"); RegDeleteValueA(net, "2"); RegDeleteValueA(net, "3"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(userkey, ""); + delete_key(userkey, "", access); RegCloseKey(userkey); /* MSIINSTALLCONTEXT_USERUNMANAGED */ +userunmanaged_tests: r = pMsiSourceListAddSourceA(prodcode, username, 0, "source"); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); @@ -3304,7 +3390,11 @@ static void test_MsiSourceListAddSource(void) lstrcatA(keypath, prod_squashed); res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + goto machine_tests; + } /* user product key exists */ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source"); @@ -3333,20 +3423,26 @@ static void test_MsiSourceListAddSource(void) /* MSIINSTALLCONTEXT_MACHINE */ +machine_tests: r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source"); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); - res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL); + if (res != ERROR_SUCCESS) + { + skip("Product key creation failed with error code %u\n", res); + LocalFree(usersid); + return; + } /* machine product key exists */ r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source"); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); - res = RegCreateKeyA(prodkey, "SourceList", &source); + res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ @@ -3354,7 +3450,7 @@ static void test_MsiSourceListAddSource(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); /* Net key is created */ - res = RegOpenKeyA(source, "Net", &net); + res = RegOpenKeyExA(source, "Net", 0, access, &net); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); CHECK_REG_STR(net, "1", "source\\"); @@ -3368,11 +3464,11 @@ static void test_MsiSourceListAddSource(void) RegDeleteValueA(net, "2"); RegDeleteValueA(net, "1"); - RegDeleteKeyA(net, ""); + delete_key(net, "", access); RegCloseKey(net); - RegDeleteKeyA(source, ""); + delete_key(source, "", access); RegCloseKey(source); - RegDeleteKeyA(prodkey, ""); + delete_key(prodkey, "", access); RegCloseKey(prodkey); LocalFree(usersid); } @@ -3381,6 +3477,9 @@ START_TEST(source) { init_functionpointers(); + if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + test_MsiSourceListGetInfo(); test_MsiSourceListAddSourceEx(); test_MsiSourceListEnumSources(); diff --git a/rostests/winetests/msi/suminfo.c b/rostests/winetests/msi/suminfo.c index a0b225b6bd9..76dac57c4e7 100644 --- a/rostests/winetests/msi/suminfo.c +++ b/rostests/winetests/msi/suminfo.c @@ -63,7 +63,7 @@ #define PID_MSISOURCE PID_WORDCOUNT #define PID_MSIRESTRICT PID_CHARCOUNT -const char *msifile = "winetest-suminfo.msi"; +static const char *msifile = "winetest-suminfo.msi"; static const WCHAR msifileW[] = { 'w','i','n','e','t','e','s','t','-','s','u','m','i','n','f','o','.','m','s','i',0 }; @@ -86,7 +86,18 @@ static void test_suminfo(void) ok(r == ERROR_INVALID_PARAMETER, "MsiGetSummaryInformation wrong error\n"); r = MsiGetSummaryInformation(hdb, NULL, 0, &hsuminfo); - ok(r == ERROR_SUCCESS, "MsiGetSummaryInformation failed\n"); + ok(r == ERROR_SUCCESS, "MsiGetSummaryInformation failed %u\n", r); + + r = MsiCloseHandle(hsuminfo); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + + r = MsiGetSummaryInformation(0, "", 0, &hsuminfo); + todo_wine + ok(r == ERROR_INSTALL_PACKAGE_INVALID || r == ERROR_INSTALL_PACKAGE_OPEN_FAILED, + "MsiGetSummaryInformation failed %u\n", r); + + r = MsiGetSummaryInformation(hdb, "", 0, &hsuminfo); + ok(r == ERROR_SUCCESS, "MsiGetSummaryInformation failed %u\n", r); r = MsiSummaryInfoGetPropertyCount(0, NULL); ok(r == ERROR_INVALID_HANDLE, "getpropcount failed\n"); diff --git a/rostests/winetests/msi/testlist.c b/rostests/winetests/msi/testlist.c index 0691e873085..0664527c400 100644 --- a/rostests/winetests/msi/testlist.c +++ b/rostests/winetests/msi/testlist.c @@ -6,6 +6,7 @@ #define STANDALONE #include "wine/test.h" +extern void func_action(void); extern void func_automation(void); extern void func_db(void); extern void func_format(void); @@ -17,9 +18,9 @@ extern void func_record(void); extern void func_source(void); extern void func_suminfo(void); - const struct test winetest_testlist[] = { + { "action", func_action }, { "automation", func_automation }, { "db", func_db }, { "format", func_format },