Author: cwittich Date: Mon Mar 1 13:03:29 2010 New Revision: 45739
URL: http://svn.reactos.org/svn/reactos?rev=45739&view=rev Log: [MSI_WINETEST] sync msi_winetest to wine 1.1.39
Modified: trunk/rostests/winetests/msi/automation.c trunk/rostests/winetests/msi/db.c trunk/rostests/winetests/msi/install.c trunk/rostests/winetests/msi/msi.c
Modified: trunk/rostests/winetests/msi/automation.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/automation.c... ============================================================================== --- trunk/rostests/winetests/msi/automation.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/automation.c [iso-8859-1] Mon Mar 1 13:03:29 2010 @@ -1863,7 +1863,11 @@ /* Session::Mode, get */ hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTATEND, &bool); ok(hr == S_OK, "Session_ModeGet failed, hresult 0x%08x\n", hr); - todo_wine ok(!bool, "Reboot at end session mode is %d\n", bool); + ok(!bool, "Reboot at end session mode is %d\n", bool); + + hr = Session_ModeGet(pSession, MSIRUNMODE_MAINTENANCE, &bool); + ok(hr == S_OK, "Session_ModeGet failed, hresult 0x%08x\n", hr); + ok(!bool, "Maintenance mode is %d\n", bool);
/* Session::Mode, put */ hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, TRUE); @@ -1873,6 +1877,17 @@ ok(bool, "Reboot at end session mode is %d, expected 1\n", bool); hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, FALSE); /* set it again so we don't reboot */ ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr); + + hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, TRUE); + todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr); + hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTNOW, &bool); + ok(hr == S_OK, "Session_ModeGet failed, hresult 0x%08x\n", hr); + ok(bool, "Reboot now mode is %d, expected 1\n", bool); + hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, FALSE); /* set it again so we don't reboot */ + todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr); + + hr = Session_ModePut(pSession, MSIRUNMODE_MAINTENANCE, TRUE); + ok(hr == DISP_E_EXCEPTION, "Session_ModePut failed, hresult 0x%08x\n", hr);
/* Session::Database, get */ hr = Session_Database(pSession, &pDatabase);
Modified: trunk/rostests/winetests/msi/db.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/db.c?rev=457... ============================================================================== --- trunk/rostests/winetests/msi/db.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/db.c [iso-8859-1] Mon Mar 1 13:03:29 2010 @@ -683,6 +683,30 @@ r = try_query( hdb, "select * from 'c'"); ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
+ r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT * FROM \5a" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "CREATE TABLE `a\5` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT * FROM a\5" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT * FROM -a" ); + todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + + r = try_query( hdb, "SELECT * FROM a-" ); + ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); + r = MsiCloseHandle( hdb ); ok(r == ERROR_SUCCESS , "Failed to close database transact\n");
@@ -1387,7 +1411,7 @@
static void test_streamtable(void) { - MSIHANDLE hdb = 0, rec, view; + MSIHANDLE hdb = 0, rec, view, hsi; char file[MAX_PATH]; char buf[MAX_PATH]; DWORD size; @@ -1431,6 +1455,46 @@ ok( check_record( rec, 2, "Data"), "wrong record type\n");
MsiCloseHandle( rec ); + + r = MsiDatabaseOpenView( hdb, + "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &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_NO_MORE_ITEMS, "Unexpected result: %u\n", r ); + + MsiCloseHandle( rec ); + MsiViewClose( view ); + MsiCloseHandle( view ); + + /* create a summary information stream */ + r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi ); + ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r ); + + r = MsiSummaryInfoSetPropertyA( hsi, PID_SECURITY, VT_I4, 2, NULL, NULL ); + ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r ); + + r = MsiSummaryInfoPersist( hsi ); + ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r ); + + MsiCloseHandle( hsi ); + + r = MsiDatabaseOpenView( hdb, + "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &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 ); + + MsiCloseHandle( rec ); + MsiViewClose( view ); + MsiCloseHandle( view );
/* insert a file into the _Streams table */ create_file( "test.txt" );
Modified: trunk/rostests/winetests/msi/install.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/install.c?re... ============================================================================== --- trunk/rostests/winetests/msi/install.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/install.c [iso-8859-1] Mon Mar 1 13:03:29 2010 @@ -1091,7 +1091,7 @@ static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n" "s72\ts72\n" "CreateFolder\tDirectory_\tComponent_\n" - "MSITESTDIR\tOne\n"; + "FIRSTDIR\tOne\n";
static const CHAR cf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "s72\tS255\tI2\n" @@ -1169,6 +1169,289 @@ "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" + "InstallODBC\t\t3000\n" + "RemoveODBC\t\t3100\n" + "InstallFiles\t\t4000\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"; + typedef struct _msi_table { const CHAR *filename; @@ -1935,6 +2218,86 @@ 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) }; @@ -7242,23 +7605,43 @@
static void process_pending_renames(HKEY hkey) { - char *buf, *src, *dst; - DWORD size; + char *buf, *src, *dst, *buf2, *buf2ptr; + DWORD size, buf2len = 0; 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;
ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size); ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError()); - ok(strstr(buf, "msitest\maximus") != NULL, "Unexpected value "%s"\n", buf);
for (src = buf; *src; src = dst + strlen(dst) + 1) { DWORD flags = MOVEFILE_COPY_ALLOWED;
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++; + continue; + } + + found = TRUE; + if (*dst == '!') { flags |= MOVEFILE_REPLACE_EXISTING; @@ -7273,8 +7656,19 @@ else ok(DeleteFileA(src), "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); + } + else + RegDeleteValueA(hkey, rename_ops); + HeapFree(GetProcessHeap(), 0, buf); - RegDeleteValueA(hkey, rename_ops); + HeapFree(GetProcessHeap(), 0, buf2); }
static BOOL file_matches_data(LPCSTR file, LPCSTR data) @@ -7298,7 +7692,6 @@ static void test_file_in_use(void) { UINT r; - DWORD size; HANDLE file; HKEY hkey; char path[MAX_PATH]; @@ -7310,11 +7703,6 @@ }
RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey); - if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size)) - { - skip("Pending file rename operations, skipping test\n"); - return; - }
CreateDirectoryA("msitest", NULL); create_file("msitest\maximus", 500); @@ -7351,7 +7739,6 @@ static void test_file_in_use_cab(void) { UINT r; - DWORD size; HANDLE file; HKEY hkey; char path[MAX_PATH]; @@ -7363,11 +7750,6 @@ }
RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey); - if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size)) - { - skip("Pending file rename operations, skipping test\n"); - return; - }
CreateDirectoryA("msitest", NULL); create_file("maximus", 500); @@ -7532,21 +7914,9 @@ 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"); - todo_wine 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(!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"); @@ -7565,6 +7935,50 @@ 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; @@ -7697,6 +8111,194 @@ 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); + + todo_wine 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); + 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(delete_pf("msitest\ODBCdriver.dll", TRUE), "file not created\n"); + ok(delete_pf("msitest\ODBCdriver2.dll", TRUE), "file not created\n"); + ok(delete_pf("msitest\ODBCtranslator.dll", TRUE), "file not created\n"); + ok(delete_pf("msitest\ODBCtranslator2.dll", TRUE), "file not created\n"); + ok(delete_pf("msitest\ODBCsetup.dll", TRUE), "file not created\n"); + ok(delete_pf("msitest", FALSE), "directory not created\n"); + + 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"); + todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n"); + + 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"); + + 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"); + todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n"); delete_test_files(); }
@@ -7796,6 +8398,12 @@ 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();
DeleteFileA(log_file);
Modified: trunk/rostests/winetests/msi/msi.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/msi.c?rev=45... ============================================================================== --- trunk/rostests/winetests/msi/msi.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/msi.c [iso-8859-1] Mon Mar 1 13:03:29 2010 @@ -10888,6 +10888,183 @@ LocalFree(usersid); }
+static void test_MsiGetPatchInfo(void) +{ + UINT r; + char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH]; + char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH]; + WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH]; + HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct; + HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch; + DWORD size; + LONG res; + + 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); + + r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL); + ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); + + r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL); + ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); + + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r); + + size = 0; + r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size); + ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r); + + r = MsiGetPatchInfoA(patch_code, "", NULL, &size); + ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r); + + lstrcpyA(keypath, "Software\Classes\Installer\Products\"); + lstrcatA(keypath, prod_squashed); + + res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* product key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* patches key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* patch key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + + lstrcpyA(keypath, "Software\Microsoft\Windows\CurrentVersion\Installer"); + lstrcatA(keypath, "\UserData\S-1-5-18\Products\"); + lstrcatA(keypath, prod_squashed); + + res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res); + + /* UserData product key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* InstallProperties key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* UserData Patches key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + /* UserData product patch key exists */ + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r); + 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); + + lstrcpyA(keypath, "Software\Microsoft\Windows\CurrentVersion\Installer"); + lstrcatA(keypath, "\UserData\S-1-5-18\Patches\"); + lstrcatA(keypath, patch_squashed); + + res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch); + 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); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res); + + /* UserData Patch key exists */ + size = 0; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r); + ok(!lstrcmpA(val, "apple"), "expected "apple", got "%s"\n", val); + ok(size == 11, "expected 11 got %u\n", size); + + size = MAX_PATH; + lstrcpyA(val, "apple"); + r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r); + ok(!lstrcmpA(val, "c:\test.msp"), "expected "c:\test.msp", got "%s"\n", val); + ok(size == 11, "expected 11 got %u\n", size); + + size = 0; + valW[0] = 0; + r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size); + ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r); + ok(!valW[0], "expected 0 got %u\n", valW[0]); + ok(size == 11, "expected 11 got %u\n", size); + + size = MAX_PATH; + valW[0] = 0; + r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size); + ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r); + ok(valW[0], "expected > 0 got %u\n", valW[0]); + ok(size == 11, "expected 11 got %u\n", size); + + RegDeleteKeyA(hkey_udproductpatch, ""); + RegCloseKey(hkey_udproductpatch); + RegDeleteKeyA(hkey_udproductpatches, ""); + RegCloseKey(hkey_udproductpatches); + RegDeleteKeyA(hkey_udpatch, ""); + RegCloseKey(hkey_udpatch); + RegDeleteKeyA(hkey_patches, ""); + RegCloseKey(hkey_patches); + RegDeleteKeyA(hkey_product, ""); + RegCloseKey(hkey_product); + RegDeleteKeyA(hkey_patch, ""); + RegCloseKey(hkey_patch); + RegDeleteKeyA(hkey_udpatches, ""); + RegCloseKey(hkey_udpatches); + RegDeleteKeyA(hkey_udprops, ""); + RegCloseKey(hkey_udprops); + RegDeleteKeyA(hkey_udproduct, ""); + RegCloseKey(hkey_udproduct); +} + static void test_MsiEnumProducts(void) { UINT r; @@ -10985,6 +11162,7 @@ test_MsiEnumPatchesEx(); test_MsiEnumPatches(); test_MsiGetPatchInfoEx(); + test_MsiGetPatchInfo(); test_MsiEnumProducts(); }