Author: cwittich Date: Sat Feb 6 22:28:28 2010 New Revision: 45468
URL: http://svn.reactos.org/svn/reactos?rev=45468&view=rev Log: [MSI] sync msi to wine 1.1.38
Added: trunk/reactos/dll/win32/msi/msi_Uk.rc (with props) Modified: trunk/reactos/dll/win32/msi/action.c trunk/reactos/dll/win32/msi/appsearch.c trunk/reactos/dll/win32/msi/automation.c trunk/reactos/dll/win32/msi/cond.tab.c trunk/reactos/dll/win32/msi/cond.tab.h trunk/reactos/dll/win32/msi/cond.y trunk/reactos/dll/win32/msi/custom.c trunk/reactos/dll/win32/msi/database.c trunk/reactos/dll/win32/msi/dialog.c trunk/reactos/dll/win32/msi/events.c trunk/reactos/dll/win32/msi/files.c trunk/reactos/dll/win32/msi/helpers.c trunk/reactos/dll/win32/msi/join.c trunk/reactos/dll/win32/msi/msi.rc trunk/reactos/dll/win32/msi/msipriv.h trunk/reactos/dll/win32/msi/msiquery.c trunk/reactos/dll/win32/msi/package.c trunk/reactos/dll/win32/msi/storages.c trunk/reactos/dll/win32/msi/streams.c trunk/reactos/include/psdk/msi.h
Modified: trunk/reactos/dll/win32/msi/action.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/action.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/action.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/action.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -959,10 +959,6 @@ return ERROR_SUCCESS; }
-/* - * Also we cannot enable/disable components either, so for now I am just going - * to do all the directories for all the components. - */ static UINT ACTION_CreateFolders(MSIPACKAGE *package) { static const WCHAR ExecSeqQuery[] = @@ -981,7 +977,60 @@ rc = MSI_IterateRecords(view, NULL, ITERATE_CreateFolders, package); msiobj_release(&view->hdr);
- msi_create_component_directories( package ); + return rc; +} + +static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) +{ + MSIPACKAGE *package = param; + LPCWSTR dir; + LPWSTR full_path; + MSIRECORD *uirow; + MSIFOLDER *folder; + + dir = MSI_RecordGetString( row, 1 ); + if (!dir) + { + ERR("Unable to get folder id\n"); + return ERROR_SUCCESS; + } + + full_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder ); + if (!full_path) + { + ERR("Unable to resolve folder id %s\n", debugstr_w(dir)); + return ERROR_SUCCESS; + } + + TRACE("folder is %s\n", debugstr_w(full_path)); + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, full_path ); + ui_actiondata( package, szRemoveFolders, uirow ); + msiobj_release( &uirow->hdr ); + + RemoveDirectoryW( full_path ); + folder->State = 0; + + msi_free( full_path ); + return ERROR_SUCCESS; +} + +static UINT ACTION_RemoveFolders( MSIPACKAGE *package ) +{ + static const WCHAR query[] = + {'S','E','L','E','C','T',' ', '`','D','i','r','e','c','t','o','r','y','_','`', + ' ','F','R','O','M',' ', '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; + + MSIQUERY *view; + UINT rc; + + rc = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (rc != ERROR_SUCCESS) + return ERROR_SUCCESS; + + rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveFolders, package ); + msiobj_release( &view->hdr );
return rc; } @@ -1562,8 +1611,10 @@
while (ptr) { - if ((ptr2 && strncmpW(ptr,feature->Feature, ptr2-ptr)==0) - || (!ptr2 && strcmpW(ptr,feature->Feature)==0)) + int len = ptr2 - ptr; + + if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len)) + || (!ptr2 && !strcmpW(ptr, feature->Feature))) { msi_feature_set_state(package, feature, state); break; @@ -1583,55 +1634,57 @@ return TRUE; }
-UINT MSI_SetFeatureStates(MSIPACKAGE *package) -{ - int level; - static const WCHAR szlevel[] = - {'I','N','S','T','A','L','L','L','E','V','E','L',0}; +static BOOL process_overrides( MSIPACKAGE *package, int level ) +{ static const WCHAR szAddLocal[] = {'A','D','D','L','O','C','A','L',0}; static const WCHAR szAddSource[] = {'A','D','D','S','O','U','R','C','E',0}; static const WCHAR szAdvertise[] = {'A','D','V','E','R','T','I','S','E',0}; - BOOL override = FALSE; + BOOL ret = FALSE; + + /* all these activation/deactivation things happen in order and things + * later on the list override things earlier on the list. + * + * 0 INSTALLLEVEL processing + * 1 ADDLOCAL + * 2 REMOVE + * 3 ADDSOURCE + * 4 ADDDEFAULT + * 5 REINSTALL + * 6 ADVERTISE + * 7 COMPADDLOCAL + * 8 COMPADDSOURCE + * 9 FILEADDLOCAL + * 10 FILEADDSOURCE + * 11 FILEADDDEFAULT + */ + ret |= process_state_property( package, level, szAddLocal, INSTALLSTATE_LOCAL ); + ret |= process_state_property( package, level, szRemove, INSTALLSTATE_ABSENT ); + ret |= process_state_property( package, level, szAddSource, INSTALLSTATE_SOURCE ); + ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN ); + ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED ); + + if (ret) + MSI_SetPropertyW( package, szPreselected, szOne ); + + return ret; +} + +UINT MSI_SetFeatureStates(MSIPACKAGE *package) +{ + int level; + static const WCHAR szlevel[] = + {'I','N','S','T','A','L','L','L','E','V','E','L',0}; MSICOMPONENT* component; MSIFEATURE *feature;
- - /* I do not know if this is where it should happen.. but */ - TRACE("Checking Install Level\n");
level = msi_get_property_int(package, szlevel, 1);
- /* ok here is the _real_ rub - * all these activation/deactivation things happen in order and things - * later on the list override things earlier on the list. - * 0) INSTALLLEVEL processing - * 1) ADDLOCAL - * 2) REMOVE - * 3) ADDSOURCE - * 4) ADDDEFAULT - * 5) REINSTALL - * 6) ADVERTISE - * 7) COMPADDLOCAL - * 8) COMPADDSOURCE - * 9) FILEADDLOCAL - * 10) FILEADDSOURCE - * 11) FILEADDDEFAULT - * - * I am still ignoring a lot of these. But that is ok for now, ADDLOCAL and - * REMOVE are the big ones, since we don't handle administrative installs - * yet anyway. - */ - override |= process_state_property(package, level, szAddLocal, INSTALLSTATE_LOCAL); - override |= process_state_property(package, level, szRemove, INSTALLSTATE_ABSENT); - override |= process_state_property(package, level, szAddSource, INSTALLSTATE_SOURCE); - override |= process_state_property(package, level, szReinstall, INSTALLSTATE_UNKNOWN); - override |= process_state_property(package, level, szAdvertise, INSTALLSTATE_ADVERTISED); - - if (!override) + if (!msi_get_property_int( package, szPreselected, 0 )) { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { @@ -1661,8 +1714,6 @@ msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN); } } - else - MSI_SetPropertyW(package, szPreselected, szOne);
/* * now we want to enable or disable components base on feature @@ -1961,7 +2012,7 @@ static const WCHAR szOutOfDiskSpace[] = {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0}; MSICOMPONENT *comp; - UINT rc; + UINT rc = ERROR_SUCCESS; MSIQUERY * view; LPWSTR level;
@@ -1982,26 +2033,28 @@ TRACE("File calculations\n"); msi_check_file_install_states( package );
- TRACE("Evaluating Condition Table\n"); - - rc = MSI_DatabaseOpenViewW(package->db, ConditionQuery, &view); - if (rc == ERROR_SUCCESS) - { - rc = MSI_IterateRecords(view, NULL, ITERATE_CostFinalizeConditions, - package); - msiobj_release(&view->hdr); - } - - TRACE("Enabling or Disabling Components\n"); - LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) - { - if (MSI_EvaluateConditionW(package, comp->Condition) == MSICONDITION_FALSE) - { - TRACE("Disabling component %s\n", debugstr_w(comp->Component)); - comp->Enabled = FALSE; - } - else - comp->Enabled = TRUE; + if (!process_overrides( package, msi_get_property_int( package, szlevel, 1 ) )) + { + TRACE("Evaluating Condition Table\n"); + + rc = MSI_DatabaseOpenViewW( package->db, ConditionQuery, &view ); + if (rc == ERROR_SUCCESS) + { + rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package ); + msiobj_release( &view->hdr ); + } + + TRACE("Enabling or Disabling Components\n"); + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) + { + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; + } + else + comp->Enabled = TRUE; + } }
MSI_SetPropertyW(package,szCosting,szOne); @@ -3652,6 +3705,89 @@ return ERROR_SUCCESS; }
+static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param ) +{ + static const WCHAR regsvr32[] = + {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','"',0}; + static const WCHAR close[] = {'"',0}; + MSIPACKAGE *package = param; + LPCWSTR filename; + LPWSTR cmdline; + MSIFILE *file; + DWORD len; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + BOOL ret; + MSIRECORD *uirow; + LPWSTR uipath, p; + + memset( &si, 0, sizeof(STARTUPINFOW) ); + + filename = MSI_RecordGetString( row, 1 ); + file = get_loaded_file( package, filename ); + + if (!file) + { + ERR("Unable to find file id %s\n", debugstr_w(filename)); + return ERROR_SUCCESS; + } + + len = strlenW( regsvr32 ) + strlenW( file->TargetPath ) + 2; + + cmdline = msi_alloc( len * sizeof(WCHAR) ); + strcpyW( cmdline, regsvr32 ); + strcatW( cmdline, file->TargetPath ); + strcatW( cmdline, close ); + + TRACE("Unregistering %s\n", debugstr_w(cmdline)); + + ret = CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, c_colon, &si, &pi ); + if (ret) + { + CloseHandle( pi.hThread ); + msi_dialog_check_messages( pi.hProcess ); + CloseHandle( pi.hProcess ); + } + + msi_free( cmdline ); + + uirow = MSI_CreateRecord( 2 ); + uipath = strdupW( file->TargetPath ); + if ((p = strrchrW( uipath, '\' ))) + { + *p = 0; + MSI_RecordSetStringW( uirow, 1, ++p ); + } + MSI_RecordSetStringW( uirow, 2, uipath ); + ui_actiondata( package, szSelfUnregModules, uirow ); + msiobj_release( &uirow->hdr ); + msi_free( uipath ); + /* FIXME call ui_progress? */ + + return ERROR_SUCCESS; +} + +static UINT ACTION_SelfUnregModules( MSIPACKAGE *package ) +{ + UINT rc; + MSIQUERY *view; + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','S','e','l','f','R','e','g','`',0}; + + rc = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (rc != ERROR_SUCCESS) + { + TRACE("no SelfReg table\n"); + return ERROR_SUCCESS; + } + + MSI_IterateRecords( view, NULL, ITERATE_SelfUnregModules, package ); + msiobj_release( &view->hdr ); + + return ERROR_SUCCESS; +} + static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { MSIFEATURE *feature; @@ -4462,8 +4598,8 @@ MSIPACKAGE *package = param; MSICOMPONENT *comp; SC_HANDLE scm, service = NULL; - LPCWSTR name, *vector = NULL; - LPWSTR args; + LPCWSTR *vector = NULL; + LPWSTR name, args; DWORD event, numargs; UINT r = ERROR_FUNCTION_FAILED;
@@ -4471,9 +4607,9 @@ if (!comp || comp->Action == INSTALLSTATE_UNKNOWN || comp->Action == INSTALLSTATE_ABSENT) return ERROR_SUCCESS;
- name = MSI_RecordGetString(rec, 2); + deformat_string(package, MSI_RecordGetString(rec, 2), &name); + deformat_string(package, MSI_RecordGetString(rec, 4), &args); event = MSI_RecordGetInteger(rec, 3); - args = strdupW(MSI_RecordGetString(rec, 4));
if (!(event & msidbServiceControlEventStart)) return ERROR_SUCCESS; @@ -4488,15 +4624,16 @@ service = OpenServiceW(scm, name, SERVICE_START); if (!service) { - ERR("Failed to open service %s\n", debugstr_w(name)); + ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError()); goto done; }
vector = msi_service_args_to_vector(args, &numargs);
- if (!StartServiceW(service, numargs, vector)) - { - ERR("Failed to start service %s\n", debugstr_w(name)); + if (!StartServiceW(service, numargs, vector) && + GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) + { + ERR("Failed to start service %s (%u)\n", debugstr_w(name), GetLastError()); goto done; }
@@ -4506,6 +4643,7 @@ CloseServiceHandle(service); CloseServiceHandle(scm);
+ msi_free(name); msi_free(args); msi_free(vector); return r; @@ -4570,27 +4708,12 @@ return FALSE; }
-static UINT ITERATE_StopService(MSIRECORD *rec, LPVOID param) -{ - MSIPACKAGE *package = param; - MSICOMPONENT *comp; +static UINT stop_service( LPCWSTR name ) +{ + SC_HANDLE scm = NULL, service = NULL; SERVICE_STATUS status; SERVICE_STATUS_PROCESS ssp; - SC_HANDLE scm = NULL, service = NULL; - LPWSTR name, args; - DWORD event, needed; - - event = MSI_RecordGetInteger(rec, 3); - if (!(event & msidbServiceControlEventStop)) - return ERROR_SUCCESS; - - comp = get_loaded_component(package, MSI_RecordGetString(rec, 6)); - if (!comp || comp->Action == INSTALLSTATE_UNKNOWN || comp->Action == INSTALLSTATE_ABSENT) - return ERROR_SUCCESS; - - deformat_string(package, MSI_RecordGetString(rec, 2), &name); - deformat_string(package, MSI_RecordGetString(rec, 4), &args); - args = strdupW(MSI_RecordGetString(rec, 4)); + DWORD needed;
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!scm) @@ -4605,16 +4728,14 @@ SERVICE_ENUMERATE_DEPENDENTS); if (!service) { - WARN("Failed to open service (%s): %d\n", - debugstr_w(name), GetLastError()); + WARN("Failed to open service (%s): %d\n", debugstr_w(name), GetLastError()); goto done; }
if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &needed)) { - WARN("Failed to query service status (%s): %d\n", - debugstr_w(name), GetLastError()); + WARN("Failed to query service status (%s): %d\n", debugstr_w(name), GetLastError()); goto done; }
@@ -4629,8 +4750,28 @@ done: CloseServiceHandle(service); CloseServiceHandle(scm); - msi_free(name); - msi_free(args); + + return ERROR_SUCCESS; +} + +static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + MSICOMPONENT *comp; + LPWSTR name; + DWORD event; + + event = MSI_RecordGetInteger( rec, 3 ); + if (!(event & msidbServiceControlEventStop)) + return ERROR_SUCCESS; + + comp = get_loaded_component( package, MSI_RecordGetString( rec, 6 ) ); + if (!comp || comp->Action == INSTALLSTATE_UNKNOWN || comp->Action == INSTALLSTATE_ABSENT) + return ERROR_SUCCESS; + + deformat_string( package, MSI_RecordGetString( rec, 2 ), &name ); + stop_service( name ); + msi_free( name );
return ERROR_SUCCESS; } @@ -4650,6 +4791,69 @@
rc = MSI_IterateRecords(view, NULL, ITERATE_StopService, package); msiobj_release(&view->hdr); + + return rc; +} + +static UINT ITERATE_DeleteService( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + MSICOMPONENT *comp; + LPWSTR name = NULL; + DWORD event; + SC_HANDLE scm = NULL, service = NULL; + + event = MSI_RecordGetInteger( rec, 3 ); + if (!(event & msidbServiceControlEventDelete)) + return ERROR_SUCCESS; + + comp = get_loaded_component( package, MSI_RecordGetString(rec, 6) ); + if (!comp || comp->Action == INSTALLSTATE_UNKNOWN || comp->Action == INSTALLSTATE_ABSENT) + return ERROR_SUCCESS; + + deformat_string( package, MSI_RecordGetString(rec, 2), &name ); + stop_service( name ); + + scm = OpenSCManagerW( NULL, NULL, SC_MANAGER_ALL_ACCESS ); + if (!scm) + { + WARN("Failed to open the SCM: %d\n", GetLastError()); + goto done; + } + + service = OpenServiceW( scm, name, DELETE ); + if (!service) + { + WARN("Failed to open service (%s): %u\n", debugstr_w(name), GetLastError()); + goto done; + } + + if (!DeleteService( service )) + WARN("Failed to delete service (%s): %u\n", debugstr_w(name), GetLastError()); + +done: + CloseServiceHandle( service ); + CloseServiceHandle( scm ); + msi_free( name ); + + return ERROR_SUCCESS; +} + +static UINT ACTION_DeleteServices( MSIPACKAGE *package ) +{ + UINT rc; + MSIQUERY *view; + + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 }; + + rc = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (rc != ERROR_SUCCESS) + return ERROR_SUCCESS; + + rc = MSI_IterateRecords( view, NULL, ITERATE_DeleteService, package ); + msiobj_release( &view->hdr );
return rc; } @@ -4922,16 +5126,30 @@ LPCWSTR ptr = *value; if (!strncmpW(ptr, prefix, prefix_len)) { - *flags |= ENV_MOD_APPEND; - *value += lstrlenW(prefix); + if (ptr[prefix_len] == szSemiColon[0]) + { + *flags |= ENV_MOD_APPEND; + *value += lstrlenW(prefix); + } + else + { + *value = NULL; + } } else if (lstrlenW(*value) >= prefix_len) { ptr += lstrlenW(ptr) - prefix_len; if (!lstrcmpW(ptr, prefix)) { - *flags |= ENV_MOD_PREFIX; - /* the "[~]" will be removed by deformat_string */; + if ((ptr-1) > *value && *(ptr-1) == szSemiColon[0]) + { + *flags |= ENV_MOD_PREFIX; + /* the "[~]" will be removed by deformat_string */; + } + else + { + *value = NULL; + } } } } @@ -4977,7 +5195,7 @@ TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
res = env_set_flags(&name, &value, &flags); - if (res != ERROR_SUCCESS) + if (res != ERROR_SUCCESS || !value) goto done;
if (value && !deformat_string(package, value, &deformatted)) @@ -5023,6 +5241,9 @@ goto done; }
+ /* If we are appending but the string was empty, strip ; */ + if ((flags & ENV_MOD_APPEND) && (value[0] == szSemiColon[0])) value++; + size = (lstrlenW(value) + 1) * sizeof(WCHAR); newval = strdupW(value); if (!newval) @@ -5033,7 +5254,8 @@ } else { - if (flags & ENV_ACT_SETABSENT) + /* Contrary to MSDN, +-variable to [~];path works */ + if (flags & ENV_ACT_SETABSENT && !(flags & ENV_MOD_MASK)) { res = ERROR_SUCCESS; goto done; @@ -5063,7 +5285,7 @@ int multiplier = 0; if (flags & ENV_MOD_APPEND) multiplier++; if (flags & ENV_MOD_PREFIX) multiplier++; - mod_size = (lstrlenW(value) + 1) * multiplier; + mod_size = lstrlenW(value) * multiplier; size += mod_size * sizeof(WCHAR); }
@@ -5078,26 +5300,18 @@ if (flags & ENV_MOD_PREFIX) { lstrcpyW(newval, value); - lstrcatW(newval, szSemiColon); - ptr = newval + lstrlenW(value) + 1; + ptr = newval + lstrlenW(value); }
lstrcpyW(ptr, data);
if (flags & ENV_MOD_APPEND) { - lstrcatW(newval, szSemiColon); lstrcatW(newval, value); } } - - if (newval) - { - TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval)); - res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size); - } - else - res = ERROR_SUCCESS; + TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval)); + res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
done: if (env) RegCloseKey(env); @@ -5911,6 +6125,13 @@ return r; }
+static UINT ACTION_ScheduleReboot( MSIPACKAGE *package ) +{ + TRACE("\n"); + package->need_reboot = 1; + return ERROR_SUCCESS; +} + static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) { @@ -5973,18 +6194,6 @@ return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table ); }
-static UINT ACTION_SelfUnregModules( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'S','e','l','f','R','e','g',0 }; - return msi_unimplemented_action_stub( package, "SelfUnregModules", table ); -} - -static UINT ACTION_DeleteServices( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { - 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 }; - return msi_unimplemented_action_stub( package, "DeleteServices", table ); -} static UINT ACTION_ValidateProductID( MSIPACKAGE *package ) { static const WCHAR table[] = { @@ -6048,12 +6257,6 @@ return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); }
-static UINT ACTION_RemoveFolders( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'C','r','e','a','t','e','F','o','l','d','e','r',0 }; - return msi_unimplemented_action_stub( package, "RemoveFolders", table ); -} - static UINT ACTION_RemoveODBC( MSIPACKAGE *package ) { static const WCHAR table[] = { 'O','D','B','C','D','r','i','v','e','r',0 }; @@ -6070,6 +6273,12 @@ { static const WCHAR table[] = { 'S','h','o','r','t','c','u','t',0 }; return msi_unimplemented_action_stub( package, "RemoveShortcuts", table ); +} + +static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) +{ + static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 }; + return msi_unimplemented_action_stub( package, "SetODBCFolders", table ); }
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package ) @@ -6173,10 +6382,10 @@ { szRemoveShortcuts, ACTION_RemoveShortcuts }, { szResolveSource, ACTION_ResolveSource }, { szRMCCPSearch, ACTION_RMCCPSearch }, - { szScheduleReboot, NULL }, + { szScheduleReboot, ACTION_ScheduleReboot }, { szSelfRegModules, ACTION_SelfRegModules }, { szSelfUnregModules, ACTION_SelfUnregModules }, - { szSetODBCFolders, NULL }, + { szSetODBCFolders, ACTION_SetODBCFolders }, { szStartServices, ACTION_StartServices }, { szStopServices, ACTION_StopServices }, { szUnpublishComponents, ACTION_UnpublishComponents },
Modified: trunk/reactos/dll/win32/msi/appsearch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/appsearch.c?r... ============================================================================== --- trunk/reactos/dll/win32/msi/appsearch.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/appsearch.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -463,7 +463,7 @@ ACTION_ConvertRegValue(regType, value, sz, appValue); break; default: - FIXME("AppSearch unimplemented for type %d (key path %s, value %s)\n", + FIXME("unimplemented for type %d (key path %s, value %s)\n", type, debugstr_w(keyPath), debugstr_w(valueName)); } end:
Modified: trunk/reactos/dll/win32/msi/automation.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/automation.c?... ============================================================================== --- trunk/reactos/dll/win32/msi/automation.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/automation.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -1138,6 +1138,21 @@ return S_OK; }
+static HRESULT DatabaseImpl_LastErrorRecord(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + static HRESULT WINAPI DatabaseImpl_Invoke( AutomationObject* This, DISPID dispIdMember, @@ -1207,6 +1222,11 @@ } else return DISP_E_MEMBERNOTFOUND; break; + + case DISPID_INSTALLER_LASTERRORRECORD: + return DatabaseImpl_LastErrorRecord(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr);
default: return DISP_E_MEMBERNOTFOUND;
Modified: trunk/reactos/dll/win32/msi/cond.tab.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/cond.tab.c?re... ============================================================================== --- trunk/reactos/dll/win32/msi/cond.tab.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/cond.tab.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -119,6 +119,7 @@ #include "msiserver.h" #include "wine/debug.h" #include "wine/unicode.h" +#include "wine/list.h"
#define YYLEX_PARAM info #define YYPARSE_PARAM info @@ -133,6 +134,7 @@ LPCWSTR str; INT n; MSICONDITION result; + struct list mem; } COND_input;
struct cond_str { @@ -140,9 +142,13 @@ INT len; };
-static LPWSTR COND_GetString( const struct cond_str *str ); -static LPWSTR COND_GetLiteral( const struct cond_str *str ); +static LPWSTR COND_GetString( COND_input *info, const struct cond_str *str ); +static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str ); static int cond_lex( void *COND_lval, COND_input *info); + +static void *cond_alloc( COND_input *cond, unsigned int sz ); +static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz ); +static void cond_free( void *ptr );
static INT compare_int( INT a, INT operator, INT b ); static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ); @@ -152,8 +158,8 @@ INT r;
r = compare_string( a, op, b, convert ); - msi_free( a ); - msi_free( b ); + cond_free( a ); + cond_free( b ); return r; }
@@ -184,7 +190,7 @@
/* Line 189 of yacc.c */ -#line 188 "cond.tab.c" +#line 194 "cond.tab.c"
/* Enabling traces. */ #ifndef YYDEBUG @@ -259,7 +265,7 @@ {
/* Line 214 of yacc.c */ -#line 110 "cond.y" +#line 116 "cond.y"
struct cond_str str; LPWSTR string; @@ -268,7 +274,7 @@
/* Line 214 of yacc.c */ -#line 272 "cond.tab.c" +#line 278 "cond.tab.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -280,7 +286,7 @@
/* Line 264 of yacc.c */ -#line 284 "cond.tab.c" +#line 290 "cond.tab.c"
#ifdef short # undef short @@ -584,12 +590,12 @@ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 134, 134, 140, 147, 151, 155, 159, 163, 170, - 174, 181, 185, 189, 194, 198, 207, 216, 220, 224, - 228, 232, 237, 242, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 271, 275, 282, 291, 295, 304, 313, 326, - 338, 345, 359, 368 + 0, 140, 140, 146, 153, 157, 161, 165, 169, 176, + 180, 187, 191, 195, 200, 204, 213, 222, 226, 230, + 234, 238, 243, 248, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 277, 281, 288, 298, 302, 311, 320, 333, + 345, 358, 375, 385 }; #endif
@@ -1540,7 +1546,7 @@ case 2:
/* Line 1455 of yacc.c */ -#line 135 "cond.y" +#line 141 "cond.y" { COND_input* cond = (COND_input*) info; cond->result = (yyvsp[(1) - (1)].value); @@ -1550,7 +1556,7 @@ case 3:
/* Line 1455 of yacc.c */ -#line 140 "cond.y" +#line 146 "cond.y" { COND_input* cond = (COND_input*) info; cond->result = MSICONDITION_NONE; @@ -1560,7 +1566,7 @@ case 4:
/* Line 1455 of yacc.c */ -#line 148 "cond.y" +#line 154 "cond.y" { (yyval.value) = (yyvsp[(1) - (1)].value); ;} @@ -1569,7 +1575,7 @@ case 5:
/* Line 1455 of yacc.c */ -#line 152 "cond.y" +#line 158 "cond.y" { (yyval.value) = (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value); ;} @@ -1578,7 +1584,7 @@ case 6:
/* Line 1455 of yacc.c */ -#line 156 "cond.y" +#line 162 "cond.y" { (yyval.value) = !(yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value); ;} @@ -1587,7 +1593,7 @@ case 7:
/* Line 1455 of yacc.c */ -#line 160 "cond.y" +#line 166 "cond.y" { (yyval.value) = ( (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value) ) && !( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) ); ;} @@ -1596,7 +1602,7 @@ case 8:
/* Line 1455 of yacc.c */ -#line 164 "cond.y" +#line 170 "cond.y" { (yyval.value) = ( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) ) || ( !(yyvsp[(1) - (3)].value) && !(yyvsp[(3) - (3)].value) ); ;} @@ -1605,7 +1611,7 @@ case 9:
/* Line 1455 of yacc.c */ -#line 171 "cond.y" +#line 177 "cond.y" { (yyval.value) = (yyvsp[(1) - (1)].value); ;} @@ -1614,7 +1620,7 @@ case 10:
/* Line 1455 of yacc.c */ -#line 175 "cond.y" +#line 181 "cond.y" { (yyval.value) = (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value); ;} @@ -1623,7 +1629,7 @@ case 11:
/* Line 1455 of yacc.c */ -#line 182 "cond.y" +#line 188 "cond.y" { (yyval.value) = (yyvsp[(2) - (2)].value) ? 0 : 1; ;} @@ -1632,7 +1638,7 @@ case 12:
/* Line 1455 of yacc.c */ -#line 186 "cond.y" +#line 192 "cond.y" { (yyval.value) = (yyvsp[(1) - (1)].value) ? 1 : 0; ;} @@ -1641,17 +1647,17 @@ case 13:
/* Line 1455 of yacc.c */ -#line 190 "cond.y" +#line 196 "cond.y" { (yyval.value) = ((yyvsp[(1) - (1)].string) && (yyvsp[(1) - (1)].string)[0]) ? 1 : 0; - msi_free((yyvsp[(1) - (1)].string)); + cond_free( (yyvsp[(1) - (1)].string) ); ;} break;
case 14:
/* Line 1455 of yacc.c */ -#line 195 "cond.y" +#line 201 "cond.y" { (yyval.value) = compare_int( (yyvsp[(1) - (3)].value), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].value) ); ;} @@ -1660,35 +1666,35 @@ case 15:
/* Line 1455 of yacc.c */ -#line 199 "cond.y" +#line 205 "cond.y" { int num; if (num_from_prop( (yyvsp[(1) - (3)].string), &num )) (yyval.value) = compare_int( num, (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].value) ); else (yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE ); - msi_free((yyvsp[(1) - (3)].string)); + cond_free( (yyvsp[(1) - (3)].string) ); ;} break;
case 16:
/* Line 1455 of yacc.c */ -#line 208 "cond.y" +#line 214 "cond.y" { int num; if (num_from_prop( (yyvsp[(3) - (3)].string), &num )) (yyval.value) = compare_int( (yyvsp[(1) - (3)].value), (yyvsp[(2) - (3)].value), num ); else (yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE ); - msi_free((yyvsp[(3) - (3)].string)); + cond_free( (yyvsp[(3) - (3)].string) ); ;} break;
case 17:
/* Line 1455 of yacc.c */ -#line 217 "cond.y" +#line 223 "cond.y" { (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE ); ;} @@ -1697,7 +1703,7 @@ case 18:
/* Line 1455 of yacc.c */ -#line 221 "cond.y" +#line 227 "cond.y" { (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE ); ;} @@ -1706,7 +1712,7 @@ case 19:
/* Line 1455 of yacc.c */ -#line 225 "cond.y" +#line 231 "cond.y" { (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE ); ;} @@ -1715,7 +1721,7 @@ case 20:
/* Line 1455 of yacc.c */ -#line 229 "cond.y" +#line 235 "cond.y" { (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), FALSE ); ;} @@ -1724,27 +1730,27 @@ case 21:
/* Line 1455 of yacc.c */ -#line 233 "cond.y" +#line 239 "cond.y" { (yyval.value) = 0; - msi_free((yyvsp[(1) - (3)].string)); + cond_free( (yyvsp[(1) - (3)].string) ); ;} break;
case 22:
/* Line 1455 of yacc.c */ -#line 238 "cond.y" +#line 244 "cond.y" { (yyval.value) = 0; - msi_free((yyvsp[(3) - (3)].string)); + cond_free( (yyvsp[(3) - (3)].string) ); ;} break;
case 23:
/* Line 1455 of yacc.c */ -#line 243 "cond.y" +#line 249 "cond.y" { (yyval.value) = (yyvsp[(2) - (3)].value); ;} @@ -1753,133 +1759,133 @@ case 24:
/* Line 1455 of yacc.c */ -#line 250 "cond.y" +#line 256 "cond.y" { (yyval.value) = COND_EQ; ;} break;
case 25:
/* Line 1455 of yacc.c */ -#line 251 "cond.y" +#line 257 "cond.y" { (yyval.value) = COND_NE; ;} break;
case 26:
/* Line 1455 of yacc.c */ -#line 252 "cond.y" +#line 258 "cond.y" { (yyval.value) = COND_LT; ;} break;
case 27:
/* Line 1455 of yacc.c */ -#line 253 "cond.y" +#line 259 "cond.y" { (yyval.value) = COND_GT; ;} break;
case 28:
/* Line 1455 of yacc.c */ -#line 254 "cond.y" +#line 260 "cond.y" { (yyval.value) = COND_LE; ;} break;
case 29:
/* Line 1455 of yacc.c */ -#line 255 "cond.y" +#line 261 "cond.y" { (yyval.value) = COND_GE; ;} break;
case 30:
/* Line 1455 of yacc.c */ -#line 256 "cond.y" +#line 262 "cond.y" { (yyval.value) = COND_SS; ;} break;
case 31:
/* Line 1455 of yacc.c */ -#line 257 "cond.y" +#line 263 "cond.y" { (yyval.value) = COND_IEQ; ;} break;
case 32:
/* Line 1455 of yacc.c */ -#line 258 "cond.y" +#line 264 "cond.y" { (yyval.value) = COND_INE; ;} break;
case 33:
/* Line 1455 of yacc.c */ -#line 259 "cond.y" +#line 265 "cond.y" { (yyval.value) = COND_ILT; ;} break;
case 34:
/* Line 1455 of yacc.c */ -#line 260 "cond.y" +#line 266 "cond.y" { (yyval.value) = COND_IGT; ;} break;
case 35:
/* Line 1455 of yacc.c */ -#line 261 "cond.y" +#line 267 "cond.y" { (yyval.value) = COND_ILE; ;} break;
case 36:
/* Line 1455 of yacc.c */ -#line 262 "cond.y" +#line 268 "cond.y" { (yyval.value) = COND_IGE; ;} break;
case 37:
/* Line 1455 of yacc.c */ -#line 263 "cond.y" +#line 269 "cond.y" { (yyval.value) = COND_ISS; ;} break;
case 38:
/* Line 1455 of yacc.c */ -#line 264 "cond.y" +#line 270 "cond.y" { (yyval.value) = COND_LHS; ;} break;
case 39:
/* Line 1455 of yacc.c */ -#line 265 "cond.y" +#line 271 "cond.y" { (yyval.value) = COND_RHS; ;} break;
case 40:
/* Line 1455 of yacc.c */ -#line 266 "cond.y" +#line 272 "cond.y" { (yyval.value) = COND_ILHS; ;} break;
case 41:
/* Line 1455 of yacc.c */ -#line 267 "cond.y" +#line 273 "cond.y" { (yyval.value) = COND_IRHS; ;} break;
case 42:
/* Line 1455 of yacc.c */ -#line 272 "cond.y" +#line 278 "cond.y" { (yyval.string) = (yyvsp[(1) - (1)].string); ;} @@ -1888,7 +1894,7 @@ case 43:
/* Line 1455 of yacc.c */ -#line 276 "cond.y" +#line 282 "cond.y" { (yyval.string) = (yyvsp[(1) - (1)].string); ;} @@ -1897,9 +1903,10 @@ case 44:
/* Line 1455 of yacc.c */ -#line 283 "cond.y" - { - (yyval.string) = COND_GetLiteral(&(yyvsp[(1) - (1)].str)); +#line 289 "cond.y" + { + COND_input* cond = (COND_input*) info; + (yyval.string) = COND_GetLiteral( cond, &(yyvsp[(1) - (1)].str) ); if( !(yyval.string) ) YYABORT; ;} @@ -1908,7 +1915,7 @@ case 45:
/* Line 1455 of yacc.c */ -#line 292 "cond.y" +#line 299 "cond.y" { (yyval.value) = (yyvsp[(1) - (1)].value); ;} @@ -1917,35 +1924,35 @@ case 46:
/* Line 1455 of yacc.c */ -#line 296 "cond.y" +#line 303 "cond.y" { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action ); (yyval.value) = action; - msi_free( (yyvsp[(2) - (2)].string) ); + cond_free( (yyvsp[(2) - (2)].string) ); ;} break;
case 47:
/* Line 1455 of yacc.c */ -#line 305 "cond.y" +#line 312 "cond.y" { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action ); (yyval.value) = install; - msi_free( (yyvsp[(2) - (2)].string) ); + cond_free( (yyvsp[(2) - (2)].string) ); ;} break;
case 48:
/* Line 1455 of yacc.c */ -#line 314 "cond.y" +#line 321 "cond.y" { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; @@ -1956,58 +1963,68 @@ else (yyval.value) = action;
- msi_free( (yyvsp[(2) - (2)].string) ); + cond_free( (yyvsp[(2) - (2)].string) ); ;} break;
case 49:
/* Line 1455 of yacc.c */ -#line 327 "cond.y" +#line 334 "cond.y" { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetFeatureStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action ); (yyval.value) = install; - msi_free( (yyvsp[(2) - (2)].string) ); + cond_free( (yyvsp[(2) - (2)].string) ); ;} break;
case 50:
/* Line 1455 of yacc.c */ -#line 339 "cond.y" +#line 346 "cond.y" { COND_input* cond = (COND_input*) info; + UINT len;
(yyval.string) = msi_dup_property( cond->package, (yyvsp[(1) - (1)].string) ); - msi_free( (yyvsp[(1) - (1)].string) ); + if ((yyval.string)) + { + len = (lstrlenW((yyval.string)) + 1) * sizeof (WCHAR); + (yyval.string) = cond_track_mem( cond, (yyval.string), len ); + } + cond_free( (yyvsp[(1) - (1)].string) ); ;} break;
case 51:
/* Line 1455 of yacc.c */ -#line 346 "cond.y" - { +#line 359 "cond.y" + { + COND_input* cond = (COND_input*) info; UINT len = GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), NULL, 0 ); (yyval.string) = NULL; if (len++) { - (yyval.string) = msi_alloc( len*sizeof (WCHAR) ); + (yyval.string) = cond_alloc( cond, len*sizeof (WCHAR) ); + if( !(yyval.string) ) + YYABORT; GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), (yyval.string), len ); } - msi_free( (yyvsp[(2) - (2)].string) ); + cond_free( (yyvsp[(2) - (2)].string) ); ;} break;
case 52:
/* Line 1455 of yacc.c */ -#line 360 "cond.y" - { - (yyval.string) = COND_GetString(&(yyvsp[(1) - (1)].str)); +#line 376 "cond.y" + { + COND_input* cond = (COND_input*) info; + (yyval.string) = COND_GetString( cond, &(yyvsp[(1) - (1)].str) ); if( !(yyval.string) ) YYABORT; ;} @@ -2016,20 +2033,21 @@ case 53:
/* Line 1455 of yacc.c */ -#line 369 "cond.y" - { - LPWSTR szNum = COND_GetString(&(yyvsp[(1) - (1)].str)); +#line 386 "cond.y" + { + COND_input* cond = (COND_input*) info; + LPWSTR szNum = COND_GetString( cond, &(yyvsp[(1) - (1)].str) ); if( !szNum ) YYABORT; (yyval.value) = atoiW( szNum ); - msi_free( szNum ); - ;} - break; - - - -/* Line 1455 of yacc.c */ -#line 2033 "cond.tab.c" + cond_free( szNum ); + ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 2051 "cond.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2241,7 +2259,7 @@
/* Line 1675 of yacc.c */ -#line 378 "cond.y" +#line 396 "cond.y"
@@ -2558,11 +2576,11 @@ return rc; }
-static LPWSTR COND_GetString( const struct cond_str *str ) +static LPWSTR COND_GetString( COND_input *cond, const struct cond_str *str ) { LPWSTR ret;
- ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); + ret = cond_alloc( cond, (str->len+1) * sizeof (WCHAR) ); if( ret ) { memcpy( ret, str->data, str->len * sizeof(WCHAR)); @@ -2572,11 +2590,11 @@ return ret; }
-static LPWSTR COND_GetLiteral( const struct cond_str *str ) +static LPWSTR COND_GetLiteral( COND_input *cond, const struct cond_str *str ) { LPWSTR ret;
- ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); + ret = cond_alloc( cond, (str->len-1) * sizeof (WCHAR) ); if( ret ) { memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); @@ -2586,6 +2604,48 @@ return ret; }
+static void *cond_alloc( COND_input *cond, unsigned int sz ) +{ + struct list *mem; + + mem = msi_alloc( sizeof (struct list) + sz ); + if( !mem ) + return NULL; + + list_add_head( &(cond->mem), mem ); + return mem + 1; +} + +static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz ) +{ + void *new_ptr; + + if( !ptr ) + return ptr; + + new_ptr = cond_alloc( cond, sz ); + if( !new_ptr ) + { + msi_free( ptr ); + return NULL; + } + + memcpy( new_ptr, ptr, sz ); + msi_free( ptr ); + return new_ptr; +} + +static void cond_free( void *ptr ) +{ + struct list *mem = (struct list *)ptr - 1; + + if( ptr ) + { + list_remove( mem ); + msi_free( mem ); + } +} + static int cond_error(const char *str) { TRACE("%s\n", str ); @@ -2596,6 +2656,7 @@ { COND_input cond; MSICONDITION r; + struct list *mem, *safety;
TRACE("%s\n", debugstr_w( szCondition ) );
@@ -2606,11 +2667,22 @@ cond.str = szCondition; cond.n = 0; cond.result = MSICONDITION_ERROR; - + + list_init( &cond.mem ); + if ( !cond_parse( &cond ) ) r = cond.result; else r = MSICONDITION_ERROR; + + LIST_FOR_EACH_SAFE( mem, safety, &cond.mem ) + { + /* The tracked memory lives directly after the list struct */ + void *ptr = mem + 1; + if ( r != MSICONDITION_ERROR ) + WARN( "condition parser failed to free up some memory: %p\n", ptr ); + cond_free( ptr ); + }
TRACE("%i <- %s\n", r, debugstr_w(szCondition)); return r;
Modified: trunk/reactos/dll/win32/msi/cond.tab.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/cond.tab.h?re... ============================================================================== --- trunk/reactos/dll/win32/msi/cond.tab.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/cond.tab.h [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -87,7 +87,7 @@ {
/* Line 1676 of yacc.c */ -#line 110 "cond.y" +#line 116 "cond.y"
struct cond_str str; LPWSTR string;
Modified: trunk/reactos/dll/win32/msi/cond.y URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/cond.y?rev=45... ============================================================================== --- trunk/reactos/dll/win32/msi/cond.y [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/cond.y [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -40,6 +40,7 @@ #include "msiserver.h" #include "wine/debug.h" #include "wine/unicode.h" +#include "wine/list.h"
#define YYLEX_PARAM info #define YYPARSE_PARAM info @@ -54,6 +55,7 @@ LPCWSTR str; INT n; MSICONDITION result; + struct list mem; } COND_input;
struct cond_str { @@ -61,9 +63,13 @@ INT len; };
-static LPWSTR COND_GetString( const struct cond_str *str ); -static LPWSTR COND_GetLiteral( const struct cond_str *str ); +static LPWSTR COND_GetString( COND_input *info, const struct cond_str *str ); +static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str ); static int cond_lex( void *COND_lval, COND_input *info); + +static void *cond_alloc( COND_input *cond, unsigned int sz ); +static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz ); +static void cond_free( void *ptr );
static INT compare_int( INT a, INT operator, INT b ); static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ); @@ -73,8 +79,8 @@ INT r;
r = compare_string( a, op, b, convert ); - msi_free( a ); - msi_free( b ); + cond_free( a ); + cond_free( b ); return r; }
@@ -189,7 +195,7 @@ | value_s { $$ = ($1 && $1[0]) ? 1 : 0; - msi_free($1); + cond_free( $1 ); } | value_i operator value_i { @@ -202,7 +208,7 @@ $$ = compare_int( num, $2, $3 ); else $$ = ($2 == COND_NE || $2 == COND_INE ); - msi_free($1); + cond_free( $1 ); } | value_i operator symbol_s { @@ -211,7 +217,7 @@ $$ = compare_int( $1, $2, num ); else $$ = ($2 == COND_NE || $2 == COND_INE ); - msi_free($3); + cond_free( $3 ); } | symbol_s operator symbol_s { @@ -232,12 +238,12 @@ | literal operator value_i { $$ = 0; - msi_free($1); + cond_free( $1 ); } | value_i operator literal { $$ = 0; - msi_free($3); + cond_free( $3 ); } | COND_LPAR expression COND_RPAR { @@ -281,7 +287,8 @@ literal: COND_LITER { - $$ = COND_GetLiteral(&$1); + COND_input* cond = (COND_input*) info; + $$ = COND_GetLiteral( cond, &$1 ); if( !$$ ) YYABORT; } @@ -299,7 +306,7 @@
MSI_GetComponentStateW(cond->package, $2, &install, &action ); $$ = action; - msi_free( $2 ); + cond_free( $2 ); } | COND_QUESTION identifier { @@ -308,7 +315,7 @@
MSI_GetComponentStateW(cond->package, $2, &install, &action ); $$ = install; - msi_free( $2 ); + cond_free( $2 ); } | COND_AMPER identifier { @@ -321,7 +328,7 @@ else $$ = action;
- msi_free( $2 ); + cond_free( $2 ); } | COND_EXCLAM identifier { @@ -330,7 +337,7 @@
MSI_GetFeatureStateW(cond->package, $2, &install, &action ); $$ = install; - msi_free( $2 ); + cond_free( $2 ); } ;
@@ -338,27 +345,37 @@ identifier { COND_input* cond = (COND_input*) info; + UINT len;
$$ = msi_dup_property( cond->package, $1 ); - msi_free( $1 ); + if ($$) + { + len = (lstrlenW($$) + 1) * sizeof (WCHAR); + $$ = cond_track_mem( cond, $$, len ); + } + cond_free( $1 ); } | COND_PERCENT identifier { + COND_input* cond = (COND_input*) info; UINT len = GetEnvironmentVariableW( $2, NULL, 0 ); $$ = NULL; if (len++) { - $$ = msi_alloc( len*sizeof (WCHAR) ); + $$ = cond_alloc( cond, len*sizeof (WCHAR) ); + if( !$$ ) + YYABORT; GetEnvironmentVariableW( $2, $$, len ); } - msi_free( $2 ); + cond_free( $2 ); } ;
identifier: COND_IDENT { - $$ = COND_GetString(&$1); + COND_input* cond = (COND_input*) info; + $$ = COND_GetString( cond, &$1 ); if( !$$ ) YYABORT; } @@ -367,11 +384,12 @@ integer: COND_NUMBER { - LPWSTR szNum = COND_GetString(&$1); + COND_input* cond = (COND_input*) info; + LPWSTR szNum = COND_GetString( cond, &$1 ); if( !szNum ) YYABORT; $$ = atoiW( szNum ); - msi_free( szNum ); + cond_free( szNum ); } ;
@@ -691,11 +709,11 @@ return rc; }
-static LPWSTR COND_GetString( const struct cond_str *str ) +static LPWSTR COND_GetString( COND_input *cond, const struct cond_str *str ) { LPWSTR ret;
- ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); + ret = cond_alloc( cond, (str->len+1) * sizeof (WCHAR) ); if( ret ) { memcpy( ret, str->data, str->len * sizeof(WCHAR)); @@ -705,11 +723,11 @@ return ret; }
-static LPWSTR COND_GetLiteral( const struct cond_str *str ) +static LPWSTR COND_GetLiteral( COND_input *cond, const struct cond_str *str ) { LPWSTR ret;
- ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); + ret = cond_alloc( cond, (str->len-1) * sizeof (WCHAR) ); if( ret ) { memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); @@ -719,6 +737,48 @@ return ret; }
+static void *cond_alloc( COND_input *cond, unsigned int sz ) +{ + struct list *mem; + + mem = msi_alloc( sizeof (struct list) + sz ); + if( !mem ) + return NULL; + + list_add_head( &(cond->mem), mem ); + return mem + 1; +} + +static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz ) +{ + void *new_ptr; + + if( !ptr ) + return ptr; + + new_ptr = cond_alloc( cond, sz ); + if( !new_ptr ) + { + msi_free( ptr ); + return NULL; + } + + memcpy( new_ptr, ptr, sz ); + msi_free( ptr ); + return new_ptr; +} + +static void cond_free( void *ptr ) +{ + struct list *mem = (struct list *)ptr - 1; + + if( ptr ) + { + list_remove( mem ); + msi_free( mem ); + } +} + static int cond_error(const char *str) { TRACE("%s\n", str ); @@ -729,6 +789,7 @@ { COND_input cond; MSICONDITION r; + struct list *mem, *safety;
TRACE("%s\n", debugstr_w( szCondition ) );
@@ -739,12 +800,23 @@ cond.str = szCondition; cond.n = 0; cond.result = MSICONDITION_ERROR; - + + list_init( &cond.mem ); + if ( !cond_parse( &cond ) ) r = cond.result; else r = MSICONDITION_ERROR;
+ LIST_FOR_EACH_SAFE( mem, safety, &cond.mem ) + { + /* The tracked memory lives directly after the list struct */ + void *ptr = mem + 1; + if ( r != MSICONDITION_ERROR ) + WARN( "condition parser failed to free up some memory: %p\n", ptr ); + cond_free( ptr ); + } + TRACE("%i <- %s\n", r, debugstr_w(szCondition)); return r; }
Modified: trunk/reactos/dll/win32/msi/custom.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/custom.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -647,6 +647,28 @@ return ERROR_SUCCESS; }
+#ifdef __i386__ +extern UINT CUSTOMPROC_wrapper( MsiCustomActionEntryPoint proc, MSIHANDLE handle ); +__ASM_GLOBAL_FUNC( CUSTOMPROC_wrapper, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl 12(%ebp)\n\t" + "movl 8(%ebp),%eax\n\t" + "call *%eax\n\t" + "leave\n\t" + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ) +#else +static inline UINT CUSTOMPROC_wrapper( MsiCustomActionEntryPoint proc, MSIHANDLE handle ) +{ + return proc(handle); +} +#endif + static DWORD ACTION_CallDllFunction( const GUID *guid ) { MsiCustomActionEntryPoint fn; @@ -685,7 +707,7 @@
__TRY { - r = fn( hPackage ); + r = CUSTOMPROC_wrapper( fn, hPackage ); } __EXCEPT_PAGE_FAULT {
Modified: trunk/reactos/dll/win32/msi/database.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/database.c?re... ============================================================================== --- trunk/reactos/dll/win32/msi/database.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/database.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -51,6 +51,8 @@ * Any binary data in a table is a reference to a stream. */
+#define IS_INTMSIDBOPEN(x) (((ULONG_PTR)(x) >> 16) == 0) + typedef struct tagMSITRANSFORM { struct list entry; IStorage *stg; @@ -306,7 +308,7 @@
save_path = szDBPath; szMode = szPersist; - if( HIWORD( szPersist ) ) + if( !IS_INTMSIDBOPEN(szPersist) ) { if (!CopyFileW( szDBPath, szPersist, FALSE )) return ERROR_OPEN_FAILED; @@ -459,7 +461,7 @@ goto end; }
- if( HIWORD(szPersist) ) + if( !IS_INTMSIDBOPEN(szPersist) ) { szwPersist = strdupAtoW( szPersist ); if( !szwPersist ) @@ -471,7 +473,7 @@ r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
end: - if( HIWORD(szPersist) ) + if( !IS_INTMSIDBOPEN(szPersist) ) msi_free( szwPersist ); msi_free( szwDBPath );
Modified: trunk/reactos/dll/win32/msi/dialog.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/dialog.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/dialog.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/dialog.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -166,6 +166,8 @@ #define WM_MSI_DIALOG_CREATE (WM_USER+0x100) #define WM_MSI_DIALOG_DESTROY (WM_USER+0x101)
+#define USER_INSTALLSTATE_ALL 0x1000 + static DWORD uiThreadId; static HWND hMsiHiddenWindow;
@@ -1876,7 +1878,7 @@
/* FIXME: load strings from resources */ AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_LOCAL, "Install feature locally"); - AppendMenuA( hMenu, MF_GRAYED, 0x1000, "Install entire feature"); + AppendMenuA( hMenu, MF_ENABLED, USER_INSTALLSTATE_ALL, "Install entire feature"); AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_ADVERTISED, "Install on demand"); AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_ABSENT, "Don't install"); r = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, @@ -1897,6 +1899,37 @@ SendMessageW( hwnd, TVM_GETITEMW, 0, (LPARAM) &tvi );
return (MSIFEATURE*) tvi.lParam; +} + +static void +msi_seltree_update_feature_installstate( HWND hwnd, HTREEITEM hItem, + MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state ) +{ + msi_feature_set_state( package, feature, state ); + msi_seltree_sync_item_state( hwnd, feature, hItem ); + ACTION_UpdateComponentStates( package, feature->Feature ); +} + +static void +msi_seltree_update_siblings_and_children_installstate( HWND hwnd, HTREEITEM curr, + MSIPACKAGE *package, INSTALLSTATE state) +{ + /* update all siblings */ + do + { + MSIFEATURE *feature; + HTREEITEM child; + + feature = msi_seltree_feature_from_item( hwnd, curr ); + msi_seltree_update_feature_installstate( hwnd, curr, package, feature, state ); + + /* update this sibling's children */ + child = (HTREEITEM)SendMessageW( hwnd, TVM_GETNEXTITEM, (WPARAM)TVGN_CHILD, (LPARAM)curr ); + if (child) + msi_seltree_update_siblings_and_children_installstate( hwnd, child, + package, state ); + } + while ((curr = (HTREEITEM)SendMessageW( hwnd, TVM_GETNEXTITEM, (WPARAM)TVGN_NEXT, (LPARAM)curr ))); }
static LRESULT @@ -1931,18 +1964,22 @@
switch (r) { - case INSTALLSTATE_LOCAL: + case USER_INSTALLSTATE_ALL: + r = INSTALLSTATE_LOCAL; + /* fall-through */ case INSTALLSTATE_ADVERTISED: case INSTALLSTATE_ABSENT: - msi_feature_set_state(package, feature, r); + { + HTREEITEM child; + child = (HTREEITEM)SendMessageW( hwnd, TVM_GETNEXTITEM, (WPARAM)TVGN_CHILD, (LPARAM)hItem ); + if (child) + msi_seltree_update_siblings_and_children_installstate( hwnd, child, package, r ); + } + /* fall-through */ + case INSTALLSTATE_LOCAL: + msi_seltree_update_feature_installstate( hwnd, hItem, package, feature, r ); break; - default: - FIXME("select feature and all children\n"); - } - - /* update */ - msi_seltree_sync_item_state( hwnd, feature, hItem ); - ACTION_UpdateComponentStates( package, feature->Feature ); + }
return 0; }
Modified: trunk/reactos/dll/win32/msi/events.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/events.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/events.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/events.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -383,6 +383,28 @@ return MSI_SetPropertyW( package, szReinstallMode, argument ); }
+static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument, + msi_dialog *dialog) +{ + static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0}; + static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0}; + static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0}; + LPWSTR key, template; + UINT ret = ERROR_SUCCESS; + + template = msi_dup_property( package, szPIDTemplate ); + key = msi_dup_property( package, szPIDKEY ); + + if (key && template) + { + FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); + ret = MSI_SetPropertyW( package, szProductID, key ); + } + msi_free( template ); + msi_free( key ); + return ret; +} + static const struct _events Events[] = { { "EndDialog",ControlEvent_EndDialog }, { "NewDialog",ControlEvent_NewDialog }, @@ -398,6 +420,7 @@ { "DirectoryListUp",ControlEvent_DirectoryListUp }, { "SelectionBrowse",ControlEvent_SpawnDialog }, { "ReinstallMode",ControlEvent_ReinstallMode }, + { "ValidateProductID",ControlEvent_ValidateProductID }, { NULL,NULL }, };
Modified: trunk/reactos/dll/win32/msi/files.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/files.c?rev=4... ============================================================================== --- trunk/reactos/dll/win32/msi/files.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/files.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -365,7 +365,8 @@ debugstr_w(component));
/* the action taken was the same as the current install state */ - comp->Action = comp->Installed; + if (comp) + comp->Action = comp->Installed;
return ERROR_SUCCESS; }
Modified: trunk/reactos/dll/win32/msi/helpers.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/helpers.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/helpers.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/helpers.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -438,238 +438,6 @@ msi_free(package->script->Actions[script]); package->script->Actions[script] = NULL; package->script->ActionCount[script] = 0; -} - -static void remove_tracked_tempfiles(MSIPACKAGE* package) -{ - struct list *item, *cursor; - - LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles ) - { - MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry ); - - list_remove( &temp->entry ); - TRACE("deleting temp file %s\n", debugstr_w( temp->Path )); - if (!DeleteFileW( temp->Path )) - ERR("failed to delete %s\n", debugstr_w( temp->Path )); - msi_free( temp->Path ); - msi_free( temp ); - } -} - -static void free_feature( MSIFEATURE *feature ) -{ - struct list *item, *cursor; - - LIST_FOR_EACH_SAFE( item, cursor, &feature->Children ) - { - FeatureList *fl = LIST_ENTRY( item, FeatureList, entry ); - list_remove( &fl->entry ); - msi_free( fl ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &feature->Components ) - { - ComponentList *cl = LIST_ENTRY( item, ComponentList, entry ); - list_remove( &cl->entry ); - msi_free( cl ); - } - msi_free( feature->Feature ); - msi_free( feature->Feature_Parent ); - msi_free( feature->Directory ); - msi_free( feature->Description ); - msi_free( feature->Title ); - msi_free( feature ); -} - -static void free_extension( MSIEXTENSION *ext ) -{ - struct list *item, *cursor; - - LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs ) - { - MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry ); - - list_remove( &verb->entry ); - msi_free( verb->Verb ); - msi_free( verb->Command ); - msi_free( verb->Argument ); - msi_free( verb ); - } - - msi_free( ext->Extension ); - msi_free( ext->ProgIDText ); - msi_free( ext ); -} - -/* Called when the package is being closed */ -void ACTION_free_package_structures( MSIPACKAGE* package) -{ - INT i; - struct list *item, *cursor; - - TRACE("Freeing package action data\n"); - - remove_tracked_tempfiles(package); - - LIST_FOR_EACH_SAFE( item, cursor, &package->features ) - { - MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry ); - list_remove( &feature->entry ); - free_feature( feature ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->folders ) - { - MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry ); - - list_remove( &folder->entry ); - msi_free( folder->Parent ); - msi_free( folder->Directory ); - msi_free( folder->TargetDefault ); - msi_free( folder->SourceLongPath ); - msi_free( folder->SourceShortPath ); - msi_free( folder->ResolvedTarget ); - msi_free( folder->ResolvedSource ); - msi_free( folder->Property ); - msi_free( folder ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->components ) - { - MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry ); - - list_remove( &comp->entry ); - msi_free( comp->Component ); - msi_free( comp->ComponentId ); - msi_free( comp->Directory ); - msi_free( comp->Condition ); - msi_free( comp->KeyPath ); - msi_free( comp->FullKeypath ); - msi_free( comp ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->files ) - { - MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry ); - - list_remove( &file->entry ); - msi_free( file->File ); - msi_free( file->FileName ); - msi_free( file->ShortName ); - msi_free( file->LongName ); - msi_free( file->Version ); - msi_free( file->Language ); - msi_free( file->TargetPath ); - msi_free( file ); - } - - /* clean up extension, progid, class and verb structures */ - LIST_FOR_EACH_SAFE( item, cursor, &package->classes ) - { - MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry ); - - list_remove( &cls->entry ); - msi_free( cls->clsid ); - msi_free( cls->Context ); - msi_free( cls->Description ); - msi_free( cls->FileTypeMask ); - msi_free( cls->IconPath ); - msi_free( cls->DefInprocHandler ); - msi_free( cls->DefInprocHandler32 ); - msi_free( cls->Argument ); - msi_free( cls->ProgIDText ); - msi_free( cls ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->extensions ) - { - MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry ); - - list_remove( &ext->entry ); - free_extension( ext ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->progids ) - { - MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry ); - - list_remove( &progid->entry ); - msi_free( progid->ProgID ); - msi_free( progid->Description ); - msi_free( progid->IconPath ); - msi_free( progid ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->mimes ) - { - MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry ); - - list_remove( &mt->entry ); - msi_free( mt->clsid ); - msi_free( mt->ContentType ); - msi_free( mt ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->appids ) - { - MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry ); - - list_remove( &appid->entry ); - msi_free( appid->AppID ); - msi_free( appid->RemoteServerName ); - msi_free( appid->LocalServer ); - msi_free( appid->ServiceParameters ); - msi_free( appid->DllSurrogate ); - msi_free( appid ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info ) - { - MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry ); - - list_remove( &info->entry ); - msi_free( info->value ); - msi_free( info ); - } - - LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media ) - { - MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry ); - - list_remove( &info->entry ); - msi_free( info->volume_label ); - msi_free( info->disk_prompt ); - msi_free( info ); - } - - if (package->script) - { - for (i = 0; i < TOTAL_SCRIPTS; i++) - msi_free_action_script(package, i); - - for (i = 0; i < package->script->UniqueActionsCount; i++) - msi_free(package->script->UniqueActions[i]); - - msi_free(package->script->UniqueActions); - msi_free(package->script); - } - - if (package->patch) - { - msi_free(package->patch->patchcode); - msi_free(package->patch->transforms); - msi_free(package->patch); - } - - msi_free(package->BaseURL); - msi_free(package->PackagePath); - msi_free(package->ProductCode); - msi_free(package->ActionFormat); - msi_free(package->LastAction); - - /* cleanup control event subscriptions */ - ControlEvent_CleanupSubscriptions(package); }
/*
Modified: trunk/reactos/dll/win32/msi/join.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/join.c?rev=45... ============================================================================== --- trunk/reactos/dll/win32/msi/join.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/join.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -117,8 +117,11 @@
static UINT JOIN_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec ) { - FIXME("(%p, %d, %p): stub!\n", view, row, rec); - return ERROR_FUNCTION_FAILED; + MSIJOINVIEW *jv = (MSIJOINVIEW*)view; + + TRACE("%p %d %p\n", jv, row, rec); + + return msi_view_get_row( jv->db, view, row, rec ); }
static UINT JOIN_execute( struct tagMSIVIEW *view, MSIRECORD *record ) @@ -219,11 +222,117 @@ return ERROR_FUNCTION_FAILED; }
-static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, - MSIRECORD *rec, UINT row ) -{ - TRACE("%p %d %p\n", view, eModifyMode, rec); +static UINT join_find_row( MSIJOINVIEW *jv, MSIRECORD *rec, UINT *row ) +{ + LPCWSTR str; + UINT i, id, data; + + str = MSI_RecordGetString( rec, 1 ); + msi_string2idW( jv->db->strings, str, &id ); + + for (i = 0; i < jv->rows; i++) + { + JOIN_fetch_int( &jv->view, i, 1, &data ); + + if (data == id) + { + *row = i; + return ERROR_SUCCESS; + } + } + return ERROR_FUNCTION_FAILED; +} + +static UINT JOIN_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) +{ + MSIJOINVIEW *jv = (MSIJOINVIEW*)view; + JOINTABLE *table; + UINT i, reduced_mask = 0, r = ERROR_SUCCESS, offset = 0, col_count; + MSIRECORD *reduced; + + TRACE("%p %d %p %u %08x\n", jv, row, rec, rec->count, mask ); + + if (mask >= 1 << jv->columns) + return ERROR_INVALID_PARAMETER; + + LIST_FOR_EACH_ENTRY(table, &jv->tables, JOINTABLE, entry) + { + r = table->view->ops->get_dimensions( table->view, NULL, &col_count ); + if (r != ERROR_SUCCESS) + return r; + + reduced = MSI_CreateRecord( col_count ); + if (!reduced) + return ERROR_FUNCTION_FAILED; + + for (i = 0; i < col_count; i++) + { + r = MSI_RecordCopyField( rec, i + offset + 1, reduced, i + 1 ); + if (r != ERROR_SUCCESS) + break; + } + + offset += col_count; + reduced_mask = mask >> (jv->columns - offset) & ((1 << col_count) - 1); + + if (r == ERROR_SUCCESS) + r = table->view->ops->set_row( table->view, row, reduced, reduced_mask ); + + msiobj_release( &reduced->hdr ); + } + + return r; +} + +static UINT join_modify_update( struct tagMSIVIEW *view, MSIRECORD *rec ) +{ + MSIJOINVIEW *jv = (MSIJOINVIEW *)view; + UINT r, row; + + r = join_find_row( jv, rec, &row ); + if (r != ERROR_SUCCESS) + return r; + + return JOIN_set_row( view, row, rec, (1 << jv->columns) - 1 ); +} + +static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY mode, MSIRECORD *rec, UINT row ) +{ + UINT r; + + TRACE("%p %d %p %u\n", view, mode, rec, row); + + switch (mode) + { + case MSIMODIFY_UPDATE: + return join_modify_update( view, rec ); + + case MSIMODIFY_ASSIGN: + case MSIMODIFY_DELETE: + case MSIMODIFY_INSERT: + case MSIMODIFY_INSERT_TEMPORARY: + case MSIMODIFY_MERGE: + case MSIMODIFY_REPLACE: + case MSIMODIFY_SEEK: + case MSIMODIFY_VALIDATE: + case MSIMODIFY_VALIDATE_DELETE: + case MSIMODIFY_VALIDATE_FIELD: + case MSIMODIFY_VALIDATE_NEW: + r = ERROR_FUNCTION_FAILED; + break; + + case MSIMODIFY_REFRESH: + r = ERROR_CALL_NOT_IMPLEMENTED; + break; + + default: + WARN("%p %d %p %u - unknown mode\n", view, mode, rec, row ); + r = ERROR_INVALID_PARAMETER; + break; + } + + return r; }
static UINT JOIN_delete( struct tagMSIVIEW *view ) @@ -259,7 +368,7 @@ if (col == 0 || col > jv->columns) return ERROR_INVALID_PARAMETER;
- for (i = (UINT)*handle; i < jv->rows; i++) + for (i = PtrToUlong(*handle); i < jv->rows; i++) { if (view->ops->fetch_int( view, i, col, &row_value ) != ERROR_SUCCESS) continue;
Modified: trunk/reactos/dll/win32/msi/msi.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.rc?rev=45... ============================================================================== --- trunk/reactos/dll/win32/msi/msi.rc [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msi.rc [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -48,6 +48,7 @@ #include "msi_Si.rc" #include "msi_Sv.rc" #include "msi_Tr.rc" +#include "msi_Uk.rc" #include "msi_Zh.rc"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
Added: trunk/reactos/dll/win32/msi/msi_Uk.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi_Uk.rc?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/msi_Uk.rc (added) +++ trunk/reactos/dll/win32/msi/msi_Uk.rc [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -1,0 +1,41 @@ +/* + * Ukrainian resources for MSI + * + * Copyright 2005 Mike McCormack + * Copyright 2007 Artem Reznikov + * Copyright 2010 Igor Paliychuk + * + * 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 + */ + +#include "windef.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + 4 "Ðе вдалоÑÑ Ð²ÑдкÑиÑи вказаний Ð¿Ð°ÐºÐµÑ ÑнÑÑалÑÑÑÑ. ÐеÑевÑÑÑе ÑлÑÑ Ð´Ð¾ ÑÐ°Ð¹Ð»Ñ Ñа ÑпÑобÑйÑе знов." + 5 "ÑлÑÑ %s не знайдено" + 9 "вÑÑавÑе диÑк %s" + 10 "невÑÑÐ½Ñ Ð¿Ð°ÑамеÑÑи" + 11 "вкажÑÑÑ Ð¿Ð°Ð¿ÐºÑ, Ñо мÑÑÑиÑÑ %s" + 12 "джеÑело вÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¾Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑÑ Ð½Ðµ вказане" + 13 "меÑежевий диÑк Ð´Ð»Ñ Ð´Ð°Ð½Ð¾Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑÑ Ð½Ðµ вказаний" + 14 "можливÑÑÑÑ Ð·:" + 15 "вибеÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ, Ñо мÑÑÑиÑÑ %s" +}
Propchange: trunk/reactos/dll/win32/msi/msi_Uk.rc ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/msi/msipriv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msipriv.h?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -689,7 +689,6 @@
/* action internals */ extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ); -extern void ACTION_free_package_structures( MSIPACKAGE* ); extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR); extern UINT ACTION_ForceReboot(MSIPACKAGE *package); extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode );
Modified: trunk/reactos/dll/win32/msi/msiquery.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiquery.c?re... ============================================================================== --- trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -831,7 +831,7 @@ return ERROR_INVALID_HANDLE;
IWineMsiRemoteDatabase_Release( remote_database ); - WARN("MsiDatabaseCommit not allowed during a custom action!\n"); + WARN("not allowed during a custom action!\n");
return ERROR_SUCCESS; }
Modified: trunk/reactos/dll/win32/msi/package.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/package.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/package.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/package.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -49,6 +49,237 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
+static void remove_tracked_tempfiles( MSIPACKAGE *package ) +{ + struct list *item, *cursor; + + LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles ) + { + MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry ); + + list_remove( &temp->entry ); + TRACE("deleting temp file %s\n", debugstr_w( temp->Path )); + if (!DeleteFileW( temp->Path )) + ERR("failed to delete %s\n", debugstr_w( temp->Path )); + msi_free( temp->Path ); + msi_free( temp ); + } +} + +static void free_feature( MSIFEATURE *feature ) +{ + struct list *item, *cursor; + + LIST_FOR_EACH_SAFE( item, cursor, &feature->Children ) + { + FeatureList *fl = LIST_ENTRY( item, FeatureList, entry ); + list_remove( &fl->entry ); + msi_free( fl ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &feature->Components ) + { + ComponentList *cl = LIST_ENTRY( item, ComponentList, entry ); + list_remove( &cl->entry ); + msi_free( cl ); + } + msi_free( feature->Feature ); + msi_free( feature->Feature_Parent ); + msi_free( feature->Directory ); + msi_free( feature->Description ); + msi_free( feature->Title ); + msi_free( feature ); +} + +static void free_extension( MSIEXTENSION *ext ) +{ + struct list *item, *cursor; + + LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs ) + { + MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry ); + + list_remove( &verb->entry ); + msi_free( verb->Verb ); + msi_free( verb->Command ); + msi_free( verb->Argument ); + msi_free( verb ); + } + + msi_free( ext->Extension ); + msi_free( ext->ProgIDText ); + msi_free( ext ); +} + +static void free_package_structures( MSIPACKAGE *package ) +{ + INT i; + struct list *item, *cursor; + + TRACE("Freeing package action data\n"); + + remove_tracked_tempfiles(package); + + LIST_FOR_EACH_SAFE( item, cursor, &package->features ) + { + MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry ); + list_remove( &feature->entry ); + free_feature( feature ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->folders ) + { + MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry ); + + list_remove( &folder->entry ); + msi_free( folder->Parent ); + msi_free( folder->Directory ); + msi_free( folder->TargetDefault ); + msi_free( folder->SourceLongPath ); + msi_free( folder->SourceShortPath ); + msi_free( folder->ResolvedTarget ); + msi_free( folder->ResolvedSource ); + msi_free( folder->Property ); + msi_free( folder ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->components ) + { + MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry ); + + list_remove( &comp->entry ); + msi_free( comp->Component ); + msi_free( comp->ComponentId ); + msi_free( comp->Directory ); + msi_free( comp->Condition ); + msi_free( comp->KeyPath ); + msi_free( comp->FullKeypath ); + msi_free( comp ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->files ) + { + MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry ); + + list_remove( &file->entry ); + msi_free( file->File ); + msi_free( file->FileName ); + msi_free( file->ShortName ); + msi_free( file->LongName ); + msi_free( file->Version ); + msi_free( file->Language ); + msi_free( file->TargetPath ); + msi_free( file ); + } + + /* clean up extension, progid, class and verb structures */ + LIST_FOR_EACH_SAFE( item, cursor, &package->classes ) + { + MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry ); + + list_remove( &cls->entry ); + msi_free( cls->clsid ); + msi_free( cls->Context ); + msi_free( cls->Description ); + msi_free( cls->FileTypeMask ); + msi_free( cls->IconPath ); + msi_free( cls->DefInprocHandler ); + msi_free( cls->DefInprocHandler32 ); + msi_free( cls->Argument ); + msi_free( cls->ProgIDText ); + msi_free( cls ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->extensions ) + { + MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry ); + + list_remove( &ext->entry ); + free_extension( ext ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->progids ) + { + MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry ); + + list_remove( &progid->entry ); + msi_free( progid->ProgID ); + msi_free( progid->Description ); + msi_free( progid->IconPath ); + msi_free( progid ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->mimes ) + { + MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry ); + + list_remove( &mt->entry ); + msi_free( mt->clsid ); + msi_free( mt->ContentType ); + msi_free( mt ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->appids ) + { + MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry ); + + list_remove( &appid->entry ); + msi_free( appid->AppID ); + msi_free( appid->RemoteServerName ); + msi_free( appid->LocalServer ); + msi_free( appid->ServiceParameters ); + msi_free( appid->DllSurrogate ); + msi_free( appid ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info ) + { + MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry ); + + list_remove( &info->entry ); + msi_free( info->value ); + msi_free( info ); + } + + LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media ) + { + MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry ); + + list_remove( &info->entry ); + msi_free( info->volume_label ); + msi_free( info->disk_prompt ); + msi_free( info ); + } + + if (package->script) + { + for (i = 0; i < TOTAL_SCRIPTS; i++) + msi_free_action_script( package, i ); + + for (i = 0; i < package->script->UniqueActionsCount; i++) + msi_free( package->script->UniqueActions[i] ); + + msi_free( package->script->UniqueActions ); + msi_free( package->script ); + } + + if (package->patch) + { + msi_free( package->patch->patchcode ); + msi_free( package->patch->transforms ); + msi_free( package->patch ); + } + + msi_free( package->BaseURL ); + msi_free( package->PackagePath ); + msi_free( package->ProductCode ); + msi_free( package->ActionFormat ); + msi_free( package->LastAction ); + + /* cleanup control event subscriptions */ + ControlEvent_CleanupSubscriptions( package ); +} + static void MSI_FreePackage( MSIOBJECTHDR *arg) { MSIPACKAGE *package= (MSIPACKAGE*) arg; @@ -57,7 +288,7 @@ msi_dialog_destroy( package->dialog );
msiobj_release( &package->db->hdr ); - ACTION_free_package_structures(package); + free_package_structures(package); }
static UINT create_temp_property_table(MSIPACKAGE *package)
Modified: trunk/reactos/dll/win32/msi/storages.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/storages.c?re... ============================================================================== --- trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -452,7 +452,7 @@ UINT val, UINT *row, MSIITERHANDLE *handle) { MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; - UINT index = (UINT)*handle; + UINT index = PtrToUlong(*handle);
TRACE("(%d, %d): %d\n", *row, col, val);
@@ -470,7 +470,7 @@ index++; }
- *handle = (MSIITERHANDLE)++index; + *handle = UlongToPtr(++index); if (index >= sv->num_rows) return ERROR_NO_MORE_ITEMS;
Modified: trunk/reactos/dll/win32/msi/streams.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/streams.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -41,7 +41,6 @@ typedef struct tabSTREAM { UINT str_index; - LPWSTR name; IStream *stream; } STREAM;
@@ -72,7 +71,6 @@ { STREAM *stream; WCHAR decoded[MAX_STREAM_NAME_LEN]; - LPWSTR ptr = name;
stream = msi_alloc(sizeof(STREAM)); if (!stream) @@ -81,18 +79,11 @@ if (encoded) { decode_streamname(name, decoded); - ptr = decoded; TRACE("stream -> %s %s\n", debugstr_w(name), debugstr_w(decoded)); - } - - stream->name = strdupW(ptr); - if (!stream->name) - { - msi_free(stream); - return NULL; - } - - stream->str_index = msi_addstringW(sv->db->strings, 0, stream->name, -1, 1, StringNonPersistent); + name = decoded; + } + + stream->str_index = msi_addstringW(sv->db->strings, 0, name, -1, 1, StringNonPersistent); stream->stream = stm; return stream; } @@ -133,9 +124,9 @@ { MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
- FIXME("%p %d %p\n", sv, row, rec); - - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("%p %d %p\n", sv, row, rec); + + return msi_view_get_row( sv->db, view, row, rec ); }
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask) @@ -144,13 +135,13 @@ STREAM *stream; IStream *stm; STATSTG stat; - LPWSTR name = NULL; + LPWSTR encname = NULL, name = NULL; USHORT *data = NULL; HRESULT hr; ULONG count; UINT r = ERROR_FUNCTION_FAILED;
- TRACE("(%p, %p)\n", view, rec); + TRACE("(%p, %d, %p, %08x)\n", view, row, rec, mask);
if (row > sv->num_rows) return ERROR_FUNCTION_FAILED; @@ -167,7 +158,10 @@ }
if (stat.cbSize.QuadPart >> 32) - goto done; + { + WARN("stream too large\n"); + goto done; + }
data = msi_alloc(stat.cbSize.QuadPart); if (!data) @@ -182,7 +176,13 @@
name = strdupW(MSI_RecordGetString(rec, 1)); if (!name) - goto done; + { + WARN("failed to retrieve stream name\n"); + goto done; + } + + encname = encode_streamname(FALSE, name); + IStorage_DestroyElement(sv->db->storage, encname);
r = write_stream_data(sv->db->storage, name, data, count, FALSE); if (r != ERROR_SUCCESS) @@ -195,14 +195,20 @@ if (!stream) goto done;
- IStorage_OpenStream(sv->db->storage, name, 0, - STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); + hr = IStorage_OpenStream(sv->db->storage, encname, 0, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); + if (FAILED(hr)) + { + WARN("failed to open stream: %08x\n", hr); + goto done; + }
sv->streams[row] = stream;
done: msi_free(name); msi_free(data); + msi_free(encname);
IStream_Release(stm);
@@ -212,6 +218,9 @@ static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary) { MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view; + UINT i; + + TRACE("(%p, %p, %d, %d)\n", view, rec, row, temporary);
if (!streams_set_table_size(sv, ++sv->num_rows)) return ERROR_FUNCTION_FAILED; @@ -219,7 +228,11 @@ if (row == -1) row = sv->num_rows - 1;
- /* FIXME have to readjust rows */ + /* shift the rows to make room for the new row */ + for (i = sv->num_rows - 1; i > row; i--) + { + sv->streams[i] = sv->streams[i - 1]; + }
return STREAMS_set_row(view, row, rec, 0); } @@ -274,7 +287,7 @@ { case 1: name_ptr = Name; - if (type) *type = MSITYPE_STRING | MAX_STREAM_NAME_LEN; + if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STREAM_NAME_LEN; break;
case 2: @@ -404,8 +417,6 @@ { if (sv->streams[i]->stream) IStream_Release(sv->streams[i]->stream); - - msi_free(sv->streams[i]->name); msi_free(sv->streams[i]); } } @@ -420,9 +431,9 @@ UINT val, UINT *row, MSIITERHANDLE *handle) { MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view; - UINT index = (UINT)*handle; - - TRACE("(%d, %d): %d\n", *row, col, val); + UINT index = PtrToUlong(*handle); + + TRACE("(%p, %d, %d, %p, %p)\n", view, col, val, row, handle);
if (col == 0 || col > NUM_STREAMS_COLS) return ERROR_INVALID_PARAMETER; @@ -438,8 +449,9 @@ index++; }
- *handle = (MSIITERHANDLE)++index; - if (index >= sv->num_rows) + *handle = UlongToPtr(++index); + + if (index > sv->num_rows) return ERROR_NO_MORE_ITEMS;
return ERROR_SUCCESS; @@ -510,9 +522,16 @@ break; }
- IStorage_OpenStream(sv->db->storage, stat.pwcsName, 0, - STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); + hr = IStorage_OpenStream(sv->db->storage, stat.pwcsName, 0, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); CoTaskMemFree(stat.pwcsName); + + if (FAILED(hr)) + { + WARN("failed to open stream: %08x\n", hr); + count = -1; + break; + }
if (!streams_set_table_size(sv, ++count)) {
Modified: trunk/reactos/include/psdk/msi.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/msi.h?rev=4546... ============================================================================== --- trunk/reactos/include/psdk/msi.h [iso-8859-1] (original) +++ trunk/reactos/include/psdk/msi.h [iso-8859-1] Sat Feb 6 22:28:28 2010 @@ -597,6 +597,10 @@ UINT WINAPI MsiSourceListEnumSourcesW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPWSTR, LPDWORD); #define MsiSourceListEnumSources WINELIB_NAME_AW(MsiSourceListEnumSources)
+UINT WINAPI MsiSourceListClearSourceA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR); +UINT WINAPI MsiSourceListClearSourceW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR); +#define MsiSourceListClearSource WINELIB_NAME_AW(MsiSourceListClearSource) + UINT WINAPI MsiSourceListClearAllA(LPCSTR, LPCSTR, DWORD); UINT WINAPI MsiSourceListClearAllW(LPCWSTR, LPCWSTR, DWORD); #define MsiSourceListClearAll WINELIB_NAME_AW(MsiSourceListClearAll)