Author: akhaldi
Date: Sat Nov 21 16:44:38 2015
New Revision: 69995
URL:
http://svn.reactos.org/svn/reactos?rev=69995&view=rev
Log:
[MSI] Sync with Wine Staging 1.7.55. CORE-10536
Modified:
trunk/reactos/dll/win32/msi/CMakeLists.txt
trunk/reactos/dll/win32/msi/action.c
trunk/reactos/dll/win32/msi/automation.c
trunk/reactos/dll/win32/msi/classes.c
trunk/reactos/dll/win32/msi/database.c
trunk/reactos/dll/win32/msi/dialog.c
trunk/reactos/dll/win32/msi/msi.c
trunk/reactos/dll/win32/msi/msi.spec
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/registry.c
trunk/reactos/dll/win32/msi/streams.c
trunk/reactos/dll/win32/msi/suminfo.c
trunk/reactos/dll/win32/msi/table.c
trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/msi/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/CMakeLists.t…
==============================================================================
--- trunk/reactos/dll/win32/msi/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/CMakeLists.txt [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -65,7 +65,7 @@
target_link_libraries(msi uuid ${PSEH_LIB} wine)
add_dependencies(msi msi_idlheader)
add_delay_importlibs(msi odbccp32 crypt32 wintrust)
-add_importlibs(msi advapi32 cabinet comctl32 gdi32 ole32 oleaut32 shell32 shlwapi urlmon
user32 version wininet mspatcha
+add_importlibs(msi advapi32 advapi32_vista cabinet comctl32 gdi32 ole32 oleaut32 shell32
shlwapi urlmon user32 version wininet mspatcha
#FIXME : should be in delayed imports
imagehlp
msvcrt
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 Nov 21 16:44:38 2015
@@ -239,8 +239,7 @@
len++;
break;
default:
- if (!count) in_quotes = FALSE;
- else in_quotes = TRUE;
+ if (count) in_quotes = TRUE;
len++;
break;
}
@@ -261,8 +260,7 @@
break;
default:
state = state_token;
- if (!count) in_quotes = FALSE;
- else in_quotes = TRUE;
+ if (count) in_quotes = TRUE;
len++;
break;
}
@@ -271,6 +269,7 @@
default: break;
}
if (!ignore) *out++ = *p;
+ if (!count) in_quotes = FALSE;
}
done:
@@ -313,7 +312,7 @@
ptr2 = strchrW( ptr, '=' );
if (!ptr2) return ERROR_INVALID_COMMAND_LINE;
-
+
len = ptr2 - ptr;
if (!len) return ERROR_INVALID_COMMAND_LINE;
@@ -2362,6 +2361,18 @@
TRACE("%s resolves to %s\n", debugstr_w(name),
debugstr_w(folder->ResolvedTarget));
}
+static ULONGLONG get_volume_space_required( MSIPACKAGE *package )
+{
+ MSICOMPONENT *comp;
+ ULONGLONG ret = 0;
+
+ LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
+ {
+ if (comp->Action == INSTALLSTATE_LOCAL) ret += comp->Cost;
+ }
+ return ret;
+}
+
static UINT ACTION_CostFinalize(MSIPACKAGE *package)
{
static const WCHAR query[] =
@@ -2376,6 +2387,12 @@
static const WCHAR szPrimaryVolumeSpaceAvailable[] =
{'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
'A','v','a','i','l','a','b','l','e',0};
+ static const WCHAR szPrimaryVolumeSpaceRequired[] =
+
{'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
+
'R','e','q','u','i','r','e','d',0};
+ static const WCHAR szPrimaryVolumeSpaceRemaining[] =
+
{'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
+
'R','e','m','a','i','n','i','n','g',0};
static const WCHAR szOutOfNoRbDiskSpace[] =
{'O','u','t','O','f','N','o','R','b','D','i','s','k','S','p','a','c','e',0};
MSICOMPONENT *comp;
@@ -2426,6 +2443,8 @@
if (!level) msi_set_property( package->db, szInstallLevel, szOne, -1 );
msi_free(level);
+ if ((rc = MSI_SetFeatureStates( package ))) return rc;
+
if ((primary_key = msi_dup_property( package->db, szPrimaryFolder )))
{
if ((primary_folder = msi_dup_property( package->db, primary_key )))
@@ -2433,17 +2452,23 @@
if (((primary_folder[0] >= 'A' && primary_folder[0] <=
'Z') ||
(primary_folder[0] >= 'a' && primary_folder[0] <=
'z')) && primary_folder[1] == ':')
{
+ static const WCHAR fmtW[] = {'%','l','u',0};
ULARGE_INTEGER free;
+ ULONGLONG required;
+ WCHAR buf[21];
primary_folder[2] = 0;
if (GetDiskFreeSpaceExW( primary_folder, &free, NULL, NULL ))
{
- static const WCHAR fmtW[] = {'%','l','u',0};
- WCHAR buf[21];
-
sprintfW( buf, fmtW, free.QuadPart / 512 );
msi_set_property( package->db, szPrimaryVolumeSpaceAvailable, buf,
-1 );
}
+ required = get_volume_space_required( package );
+ sprintfW( buf, fmtW, required / 512 );
+ msi_set_property( package->db, szPrimaryVolumeSpaceRequired, buf, -1
);
+
+ sprintfW( buf, fmtW, (free.QuadPart - required) / 512 );
+ msi_set_property( package->db, szPrimaryVolumeSpaceRemaining, buf, -1
);
msi_set_property( package->db, szPrimaryVolumePath, primary_folder, 2
);
}
msi_free( primary_folder );
@@ -2455,7 +2480,7 @@
msi_set_property( package->db, szOutOfDiskSpace, szZero, -1 );
msi_set_property( package->db, szOutOfNoRbDiskSpace, szZero, -1 );
- return MSI_SetFeatureStates(package);
+ return ERROR_SUCCESS;
}
static BYTE *parse_value( MSIPACKAGE *package, const WCHAR *value, DWORD len, DWORD
*type, DWORD *size )
@@ -2617,9 +2642,8 @@
return view;
}
-static HKEY open_key( const MSICOMPONENT *comp, HKEY root, const WCHAR *path, BOOL create
)
-{
- REGSAM access = KEY_ALL_ACCESS;
+static HKEY open_key( const MSICOMPONENT *comp, HKEY root, const WCHAR *path, BOOL
create, REGSAM access )
+{
WCHAR *subkey, *p, *q;
HKEY hkey, ret = NULL;
LONG res;
@@ -2641,7 +2665,7 @@
}
if (q && q[1])
{
- ret = open_key( comp, hkey, q + 1, create );
+ ret = open_key( comp, hkey, q + 1, create, access );
RegCloseKey( hkey );
}
else ret = hkey;
@@ -2866,7 +2890,7 @@
strcpyW(uikey,szRoot);
strcatW(uikey,deformated);
- if (!(hkey = open_key( comp, root_key, deformated, TRUE )))
+ if (!(hkey = open_key( comp, root_key, deformated, TRUE, KEY_QUERY_VALUE |
KEY_SET_VALUE )))
{
ERR("Could not create key %s\n", debugstr_w(deformated));
msi_free(uikey);
@@ -2957,13 +2981,17 @@
access |= get_registry_view( comp );
if (!(subkey = strdupW( path ))) return;
- for (;;)
- {
- if ((p = strrchrW( subkey, '\\' ))) *p = 0;
- hkey = open_key( comp, root, subkey, FALSE );
- if (!hkey) break;
- if (p && p[1])
+ do
+ {
+ if ((p = strrchrW( subkey, '\\' )))
+ {
+ *p = 0;
+ if (!p[1]) continue; /* trailing backslash */
+ hkey = open_key( comp, root, subkey, FALSE, access );
+ if (!hkey) break;
res = RegDeleteKeyExW( hkey, p + 1, access, 0 );
+ RegCloseKey( hkey );
+ }
else
res = RegDeleteKeyExW( root, subkey, access, 0 );
if (res)
@@ -2971,9 +2999,7 @@
TRACE("failed to delete key %s (%d)\n", debugstr_w(subkey), res);
break;
}
- if (p && p[1]) RegCloseKey( hkey );
- else break;
- }
+ } while (p);
msi_free( subkey );
}
@@ -2983,7 +3009,7 @@
HKEY hkey;
DWORD num_subkeys, num_values;
- if ((hkey = open_key( comp, root, path, FALSE )))
+ if ((hkey = open_key( comp, root, path, FALSE, KEY_SET_VALUE | KEY_QUERY_VALUE )))
{
if ((res = RegDeleteValueW( hkey, value )))
TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res);
@@ -3004,8 +3030,8 @@
LONG res;
HKEY hkey;
- if (!(hkey = open_key( comp, root, path, FALSE ))) return;
- res = SHDeleteKeyW( hkey, NULL );
+ if (!(hkey = open_key( comp, root, path, FALSE, KEY_ALL_ACCESS ))) return;
+ res = RegDeleteTreeW( hkey, NULL );
if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(path),
res);
delete_key( comp, root, path );
RegCloseKey( hkey );
@@ -3537,7 +3563,9 @@
if (!comp->KeyPath || !(file = msi_get_loaded_file(package,
comp->KeyPath)))
continue;
- row = MSI_QueryGetRecord(package->db, query, file->Sequence);
+ if (!(row = MSI_QueryGetRecord(package->db, query,
file->Sequence)))
+ return ERROR_FUNCTION_FAILED;
+
sprintfW(source, fmt, MSI_RecordGetInteger(row, 1));
ptr2 = strrchrW(source, '\\') + 1;
msiobj_release(&row->hdr);
@@ -5857,8 +5885,8 @@
if (image_path != file->TargetPath) msi_free(image_path);
done:
- CloseServiceHandle(service);
- CloseServiceHandle(hscm);
+ if (service) CloseServiceHandle(service);
+ if (hscm) CloseServiceHandle(hscm);
msi_free(name);
msi_free(disp);
msi_free(sd.lpDescription);
@@ -6032,8 +6060,8 @@
msi_ui_actiondata( package, szStartServices, uirow );
msiobj_release( &uirow->hdr );
- CloseServiceHandle(service);
- CloseServiceHandle(scm);
+ if (service) CloseServiceHandle(service);
+ if (scm) CloseServiceHandle(scm);
msi_free(name);
msi_free(args);
@@ -6142,8 +6170,8 @@
WARN("Failed to stop service (%s): %d\n", debugstr_w(name),
GetLastError());
done:
- CloseServiceHandle(service);
- CloseServiceHandle(scm);
+ if (service) CloseServiceHandle(service);
+ if (scm) CloseServiceHandle(scm);
return ERROR_SUCCESS;
}
@@ -6280,8 +6308,8 @@
msi_ui_actiondata( package, szDeleteServices, uirow );
msiobj_release( &uirow->hdr );
- CloseServiceHandle( service );
- CloseServiceHandle( scm );
+ if (service) CloseServiceHandle( service );
+ if (scm) CloseServiceHandle( scm );
msi_free( name );
msi_free( display_name );
@@ -6903,13 +6931,13 @@
{
MSIPACKAGE *package = param;
LPCWSTR name, value, component;
- LPWSTR data = NULL, newval = NULL, deformatted = NULL, ptr;
- DWORD flags, type, size;
+ WCHAR *data = NULL, *newval = NULL, *deformatted = NULL, *p, *q;
+ DWORD flags, type, size, len, len_value = 0;
UINT res;
HKEY env = NULL;
MSICOMPONENT *comp;
MSIRECORD *uirow;
- int action = 0;
+ int action = 0, found = 0;
component = MSI_RecordGetString(rec, 4);
comp = msi_get_loaded_component(package, component);
@@ -6937,7 +6965,20 @@
goto done;
}
- value = deformatted;
+ if ((value = deformatted))
+ {
+ if (flags & ENV_MOD_PREFIX)
+ {
+ p = strrchrW( value, ';' );
+ len_value = p - value;
+ }
+ else if (flags & ENV_MOD_APPEND)
+ {
+ value = strchrW( value, ';' ) + 1;
+ len_value = strlenW( value );
+ }
+ else len_value = strlenW( value );
+ }
res = open_env_key( flags, &env );
if (res != ERROR_SUCCESS)
@@ -6963,10 +7004,6 @@
res = ERROR_SUCCESS;
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)
@@ -6986,15 +7023,14 @@
goto done;
}
- data = msi_alloc(size);
- if (!data)
+ if (!(p = q = data = msi_alloc( size )))
{
msi_free(deformatted);
RegCloseKey(env);
return ERROR_OUTOFMEMORY;
}
- res = RegQueryValueExW(env, name, NULL, &type, (LPVOID)data, &size);
+ res = RegQueryValueExW( env, name, NULL, &type, (BYTE *)data, &size );
if (res != ERROR_SUCCESS)
goto done;
@@ -7007,20 +7043,28 @@
goto done;
}
- size = (lstrlenW(data) + 1) * sizeof(WCHAR);
- if (flags & ENV_MOD_MASK)
- {
- DWORD mod_size;
- int multiplier = 0;
- if (flags & ENV_MOD_APPEND) multiplier++;
- if (flags & ENV_MOD_PREFIX) multiplier++;
- mod_size = lstrlenW(value) * multiplier;
- size += mod_size * sizeof(WCHAR);
- }
-
- newval = msi_alloc(size);
- ptr = newval;
- if (!newval)
+ for (;;)
+ {
+ while (*q && *q != ';') q++;
+ len = q - p;
+ if (value && len == len_value && !memcmp( value, p, len *
sizeof(WCHAR) ) &&
+ (!p[len] || p[len] == ';'))
+ {
+ found = 1;
+ break;
+ }
+ if (!*q) break;
+ p = ++q;
+ }
+
+ if (found)
+ {
+ TRACE("string already set\n");
+ goto done;
+ }
+
+ size = (len_value + 1 + strlenW( data ) + 1) * sizeof(WCHAR);
+ if (!(p = newval = msi_alloc( size )))
{
res = ERROR_OUTOFMEMORY;
goto done;
@@ -7028,21 +7072,24 @@
if (flags & ENV_MOD_PREFIX)
{
- lstrcpyW(newval, value);
- ptr = newval + lstrlenW(value);
+ memcpy( newval, value, len_value * sizeof(WCHAR) );
+ newval[len_value] = ';';
+ p = newval + len_value + 1;
action |= 0x80000000;
}
- lstrcpyW(ptr, data);
+ strcpyW( p, data );
if (flags & ENV_MOD_APPEND)
{
- lstrcatW(newval, value);
+ p += strlenW( data );
+ *p++ = ';';
+ memcpy( p, value, (len_value + 1) * sizeof(WCHAR) );
action |= 0x40000000;
}
}
TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
- res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+ res = RegSetValueExW( env, name, 0, type, (BYTE *)newval, size );
if (res)
{
WARN("Failed to set %s to %s (%d)\n", debugstr_w(name),
debugstr_w(newval), res);
@@ -7084,8 +7131,8 @@
{
MSIPACKAGE *package = param;
LPCWSTR name, value, component;
- LPWSTR deformatted = NULL;
- DWORD flags;
+ WCHAR *p, *q, *deformatted = NULL, *new_value = NULL;
+ DWORD flags, type, size, len, len_value = 0, len_new_value;
HKEY env;
MSICOMPONENT *comp;
MSIRECORD *uirow;
@@ -7122,7 +7169,20 @@
if (value && !deformat_string( package, value, &deformatted ))
return ERROR_OUTOFMEMORY;
- value = deformatted;
+ if ((value = deformatted))
+ {
+ if (flags & ENV_MOD_PREFIX)
+ {
+ p = strchrW( value, ';' );
+ len_value = p - value;
+ }
+ else if (flags & ENV_MOD_APPEND)
+ {
+ value = strchrW( value, ';' ) + 1;
+ len_value = strlenW( value );
+ }
+ else len_value = strlenW( value );
+ }
r = open_env_key( flags, &env );
if (r != ERROR_SUCCESS)
@@ -7134,13 +7194,48 @@
if (flags & ENV_MOD_MACHINE)
action |= 0x20000000;
- TRACE("Removing %s\n", debugstr_w(name));
-
- res = RegDeleteValueW( env, name );
+ size = 0;
+ type = REG_SZ;
+ res = RegQueryValueExW( env, name, NULL, &type, NULL, &size );
+ if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
+ goto done;
+
+ if (!(new_value = msi_alloc( size ))) goto done;
+
+ res = RegQueryValueExW( env, name, NULL, &type, (BYTE *)new_value, &size );
if (res != ERROR_SUCCESS)
- {
- WARN("Failed to delete value %s (%d)\n", debugstr_w(name), res);
- r = ERROR_SUCCESS;
+ goto done;
+
+ len_new_value = size / sizeof(WCHAR) - 1;
+ p = q = new_value;
+ for (;;)
+ {
+ while (*q && *q != ';') q++;
+ len = q - p;
+ if (value && len == len_value && !memcmp( value, p, len *
sizeof(WCHAR) ))
+ {
+ if (*q == ';') q++;
+ memmove( p, q, (len_new_value - (q - new_value) + 1) * sizeof(WCHAR) );
+ break;
+ }
+ if (!*q) break;
+ p = ++q;
+ }
+
+ if (!new_value[0] || !value)
+ {
+ TRACE("removing %s\n", debugstr_w(name));
+ res = RegDeleteValueW( env, name );
+ if (res != ERROR_SUCCESS)
+ WARN("failed to delete value %s (%d)\n", debugstr_w(name), res);
+ }
+ else
+ {
+ TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(new_value));
+ size = (strlenW( new_value ) + 1) * sizeof(WCHAR);
+ res = RegSetValueExW( env, name, 0, type, (BYTE *)new_value, size );
+ if (res != ERROR_SUCCESS)
+ WARN("failed to set %s to %s (%d)\n", debugstr_w(name),
debugstr_w(new_value), res);
}
done:
@@ -7153,6 +7248,7 @@
if (env) RegCloseKey( env );
msi_free( deformatted );
+ msi_free( new_value );
return r;
}
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 Nov 21 16:44:38 2015
@@ -1421,7 +1421,7 @@
hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
if (FAILED(hr)) return hr;
V_VT(pVarResult) = VT_BOOL;
- V_BOOL(pVarResult) = MsiGetMode(This->msiHandle, V_I4(&varg0));
+ V_BOOL(pVarResult) = MsiGetMode(This->msiHandle, V_I4(&varg0)) ?
VARIANT_TRUE : VARIANT_FALSE;
} else if (wFlags & DISPATCH_PROPERTYPUT) {
hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
if (FAILED(hr)) return hr;
@@ -1816,12 +1816,36 @@
EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
- if (!(wFlags & DISPATCH_METHOD))
+ UINT ret;
+ HRESULT hr;
+ MSIHANDLE hsuminfo;
+ IDispatch *dispatch;
+ VARIANTARG varg0, varg1;
+
+ if (!(wFlags & DISPATCH_PROPERTYGET))
return DISP_E_MEMBERNOTFOUND;
- FIXME("\n");
-
- VariantInit(pVarResult);
+ VariantInit(&varg1);
+ hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr);
+ if (FAILED(hr))
+ return hr;
+
+ VariantInit(&varg0);
+ hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr);
+ if (FAILED(hr))
+ return hr;
+
+ ret = MsiGetSummaryInformationW(0, V_BSTR(&varg0), V_I4(&varg1),
&hsuminfo);
+ VariantClear(&varg0);
+ if (ret != ERROR_SUCCESS)
+ return DISP_E_EXCEPTION;
+
+ hr = create_summaryinfo(hsuminfo, &dispatch);
+ if (FAILED(hr))
+ return hr;
+
+ V_VT(pVarResult) = VT_DISPATCH;
+ V_DISPATCH(pVarResult) = dispatch;
return S_OK;
}
@@ -2013,7 +2037,7 @@
/* Return VT_BOOL clarifying whether registry key exists or not. */
case VT_EMPTY:
V_VT(pVarResult) = VT_BOOL;
- V_BOOL(pVarResult) = (ret == ERROR_SUCCESS);
+ V_BOOL(pVarResult) = (ret == ERROR_SUCCESS) ? VARIANT_TRUE : VARIANT_FALSE;
break;
/* Return the value of specified key if it exists. */
Modified: trunk/reactos/dll/win32/msi/classes.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/classes.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/classes.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/classes.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -953,7 +953,7 @@
cls->action = INSTALLSTATE_ABSENT;
- res = SHDeleteKeyW( hkey, cls->clsid );
+ res = RegDeleteTreeW( hkey, cls->clsid );
if (res != ERROR_SUCCESS)
WARN("Failed to delete class key %d\n", res);
@@ -975,7 +975,7 @@
{
strcpyW( filetype, szFileType );
strcatW( filetype, cls->clsid );
- res = SHDeleteKeyW( HKEY_CLASSES_ROOT, filetype );
+ res = RegDeleteTreeW( HKEY_CLASSES_ROOT, filetype );
msi_free( filetype );
if (res != ERROR_SUCCESS)
@@ -1148,7 +1148,7 @@
}
TRACE("Unregistering progid %s\n", debugstr_w(progid->ProgID));
- res = SHDeleteKeyW( HKEY_CLASSES_ROOT, progid->ProgID );
+ res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid->ProgID );
if (res != ERROR_SUCCESS)
TRACE("Failed to delete progid key %d\n", res);
@@ -1392,7 +1392,7 @@
{
extension[0] = '.';
strcpyW( extension + 1, ext->Extension );
- res = SHDeleteKeyW( HKEY_CLASSES_ROOT, extension );
+ res = RegDeleteTreeW( HKEY_CLASSES_ROOT, extension );
msi_free( extension );
if (res != ERROR_SUCCESS)
WARN("Failed to delete extension key %d\n", res);
@@ -1414,7 +1414,7 @@
{
strcpyW( progid_shell, progid );
strcatW( progid_shell, shellW );
- res = SHDeleteKeyW( HKEY_CLASSES_ROOT, progid_shell );
+ res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid_shell );
msi_free( progid_shell );
if (res != ERROR_SUCCESS)
WARN("Failed to delete shell key %d\n", res);
Modified: trunk/reactos/dll/win32/msi/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/database.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/database.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/database.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -35,6 +35,13 @@
*/
#define IS_INTMSIDBOPEN(x) (((ULONG_PTR)(x) >> 16) == 0)
+
+struct row_export_info
+{
+ HANDLE handle;
+ LPCWSTR folder;
+ LPCWSTR table;
+};
static void free_transforms( MSIDATABASE *db )
{
@@ -763,6 +770,8 @@
lstrcatW( path, file );
data = msi_read_text_archive( path, &len );
+ if (data == NULL)
+ return ERROR_BAD_PATHNAME;
ptr = data;
msi_parse_line( &ptr, &columns, &num_columns, &len );
@@ -901,50 +910,131 @@
return r;
}
-static UINT msi_export_record( HANDLE handle, MSIRECORD *row, UINT start )
-{
- UINT i, count, len, r = ERROR_SUCCESS;
+static UINT msi_export_field( HANDLE handle, MSIRECORD *row, UINT field )
+{
+ char *buffer;
+ BOOL bret;
+ DWORD sz;
+ UINT r;
+
+ sz = 0x100;
+ buffer = msi_alloc( sz );
+ if (!buffer)
+ return ERROR_OUTOFMEMORY;
+
+ r = MSI_RecordGetStringA( row, field, buffer, &sz );
+ if (r == ERROR_MORE_DATA)
+ {
+ char *p;
+
+ sz++; /* leave room for NULL terminator */
+ p = msi_realloc( buffer, sz );
+ if (!p)
+ {
+ msi_free( buffer );
+ return ERROR_OUTOFMEMORY;
+ }
+ buffer = p;
+
+ r = MSI_RecordGetStringA( row, field, buffer, &sz );
+ if (r != ERROR_SUCCESS)
+ {
+ msi_free( buffer );
+ return r;
+ }
+ }
+ else if (r != ERROR_SUCCESS)
+ return r;
+
+ bret = WriteFile( handle, buffer, sz, &sz, NULL );
+ msi_free( buffer );
+ if (!bret)
+ return ERROR_FUNCTION_FAILED;
+
+ return r;
+}
+
+static UINT msi_export_stream( LPCWSTR folder, LPCWSTR table, MSIRECORD *row, UINT
field,
+ UINT start )
+{
+ static const WCHAR fmt_file[] = {
'%','s','/','%','s','/','%','s',0
};
+ static const WCHAR fmt_folder[] = {
'%','s','/','%','s',0 };
+ WCHAR stream_name[256], stream_filename[MAX_PATH];
+ DWORD sz, read_size, write_size;
+ char buffer[1024];
+ HANDLE file;
+ UINT r;
+
+ /* get the name of the file */
+ sz = sizeof(stream_name)/sizeof(WCHAR);
+ r = MSI_RecordGetStringW( row, start, stream_name, &sz );
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ /* if the destination folder does not exist then create it (folder name = table name)
*/
+ snprintfW( stream_filename, sizeof(stream_filename), fmt_folder, folder, table );
+ if (GetFileAttributesW( stream_filename ) == INVALID_FILE_ATTRIBUTES)
+ {
+ if (!CreateDirectoryW( stream_filename, NULL ))
+ return ERROR_PATH_NOT_FOUND;
+ }
+
+ /* actually create the file */
+ snprintfW( stream_filename, sizeof(stream_filename), fmt_file, folder, table,
stream_name );
+ file = CreateFileW( stream_filename, GENERIC_WRITE, FILE_SHARE_READ |
FILE_SHARE_WRITE,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
+ if (file == INVALID_HANDLE_VALUE)
+ return ERROR_FILE_NOT_FOUND;
+
+ /* copy the stream to the file */
+ read_size = sizeof(buffer);
+ while (read_size == sizeof(buffer))
+ {
+ r = MSI_RecordReadStream( row, field, buffer, &read_size );
+ if (r != ERROR_SUCCESS)
+ {
+ CloseHandle( file );
+ return r;
+ }
+ if (!WriteFile( file, buffer, read_size, &write_size, NULL ) || read_size !=
write_size)
+ {
+ CloseHandle( file );
+ return ERROR_WRITE_FAULT;
+ }
+ }
+ CloseHandle( file );
+ return r;
+}
+
+static UINT msi_export_record( struct row_export_info *row_export_info, MSIRECORD *row,
UINT start )
+{
+ HANDLE handle = row_export_info->handle;
+ UINT i, count, r = ERROR_SUCCESS;
const char *sep;
- char *buffer;
DWORD sz;
- len = 0x100;
- buffer = msi_alloc( len );
- if ( !buffer )
- return ERROR_OUTOFMEMORY;
-
count = MSI_RecordGetFieldCount( row );
- for ( i=start; i<=count; i++ )
- {
- sz = len;
- r = MSI_RecordGetStringA( row, i, buffer, &sz );
- if (r == ERROR_MORE_DATA)
- {
- char *p = msi_realloc( buffer, sz + 1 );
- if (!p)
- break;
- len = sz + 1;
- buffer = p;
- }
- sz = len;
- r = MSI_RecordGetStringA( row, i, buffer, &sz );
- if (r != ERROR_SUCCESS)
- break;
-
- if (!WriteFile( handle, buffer, sz, &sz, NULL ))
- {
- r = ERROR_FUNCTION_FAILED;
- break;
- }
+ for (i = start; i <= count; i++)
+ {
+ r = msi_export_field( handle, row, i );
+ if (r == ERROR_INVALID_PARAMETER)
+ {
+ r = msi_export_stream( row_export_info->folder, row_export_info->table,
row, i, start );
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ /* exporting a binary stream, repeat the "Name" field */
+ r = msi_export_field( handle, row, start );
+ if (r != ERROR_SUCCESS)
+ return r;
+ }
+ else if (r != ERROR_SUCCESS)
+ return r;
sep = (i < count) ? "\t" : "\r\n";
if (!WriteFile( handle, sep, strlen(sep), &sz, NULL ))
- {
- r = ERROR_FUNCTION_FAILED;
- break;
- }
- }
- msi_free( buffer );
+ return ERROR_FUNCTION_FAILED;
+ }
return r;
}
@@ -968,9 +1058,25 @@
return ERROR_SUCCESS;
}
+static UINT msi_export_summaryinformation( MSIDATABASE *db, HANDLE handle )
+{
+ static const char header[] = "PropertyId\tValue\r\n"
+ "i2\tl255\r\n"
+ "_SummaryInformation\tPropertyId\r\n";
+ DWORD sz;
+
+ sz = lstrlenA(header);
+ if (!WriteFile(handle, header, sz, &sz, NULL))
+ return ERROR_WRITE_FAULT;
+
+ return msi_export_suminfo( db, handle );
+}
+
static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
LPCWSTR folder, LPCWSTR file )
{
+ static const WCHAR summaryinformation[] = {
+
'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0
};
static const WCHAR query[] = {
's','e','l','e','c','t','
','*',' ','f','r','o','m','
','%','s',0 };
static const WCHAR forcecodepage[] = {
@@ -1009,14 +1115,22 @@
goto done;
}
+ if (!strcmpW( table, summaryinformation ))
+ {
+ r = msi_export_summaryinformation( db, handle );
+ goto done;
+ }
+
r = MSI_OpenQuery( db, &view, query, table );
if (r == ERROR_SUCCESS)
{
+ struct row_export_info row_export_info = { handle, folder, table };
+
/* write out row 1, the column names */
r = MSI_ViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
if (r == ERROR_SUCCESS)
{
- msi_export_record( handle, rec, 1 );
+ msi_export_record( &row_export_info, rec, 1 );
msiobj_release( &rec->hdr );
}
@@ -1024,7 +1138,7 @@
r = MSI_ViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
if (r == ERROR_SUCCESS)
{
- msi_export_record( handle, rec, 1 );
+ msi_export_record( &row_export_info, rec, 1 );
msiobj_release( &rec->hdr );
}
@@ -1033,12 +1147,12 @@
if (r == ERROR_SUCCESS)
{
MSI_RecordSetStringW( rec, 0, table );
- msi_export_record( handle, rec, 0 );
+ msi_export_record( &row_export_info, rec, 0 );
msiobj_release( &rec->hdr );
}
/* write out row 4 onwards, the data */
- r = MSI_IterateRecords( view, 0, msi_export_row, handle );
+ r = MSI_IterateRecords( view, 0, msi_export_row, &row_export_info );
msiobj_release( &view->hdr );
}
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 Nov 21 16:44:38 2015
@@ -2672,7 +2672,7 @@
/* create the treeview control */
style = TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
- style |= WS_GROUP | WS_VSCROLL;
+ style |= WS_GROUP | WS_VSCROLL | WS_TABSTOP;
control = msi_dialog_add_control( dialog, rec, WC_TREEVIEWW, style );
if (!control)
{
@@ -3645,8 +3645,11 @@
if (!dialog->default_font)
{
dialog->default_font = strdupW(dfv);
- msiobj_release( &rec->hdr );
- if (!dialog->default_font) return -1;
+ if (!dialog->default_font)
+ {
+ msiobj_release( &rec->hdr );
+ return -1;
+ }
}
title = msi_get_deformatted_field( dialog->package, rec, 7 );
Modified: trunk/reactos/dll/win32/msi/msi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.c?rev=69…
==============================================================================
--- trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -4292,6 +4292,17 @@
}
/***********************************************************************
+ * MsiJoinTransaction [MSI.@]
+ */
+UINT WINAPI MsiJoinTransaction( MSIHANDLE handle, DWORD attrs, HANDLE *event )
+{
+ FIXME("%u %08x %p\n", handle, attrs, event);
+
+ *event = (HANDLE)0xdeadbeef;
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
* MsiEndTransaction [MSI.@]
*/
UINT WINAPI MsiEndTransaction( DWORD state )
Modified: trunk/reactos/dll/win32/msi/msi.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.spec?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/msi.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msi.spec [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -280,7 +280,7 @@
284 stdcall MsiBeginTransactionA(str long ptr ptr)
285 stdcall MsiBeginTransactionW(wstr long ptr ptr)
286 stdcall MsiEndTransaction(long)
-287 stub MsiJoinTransaction
+287 stdcall MsiJoinTransaction(long long ptr)
288 stub MsiSetOfflineContextW
289 stdcall MsiEnumComponentsExA(str long long ptr ptr ptr ptr)
290 stdcall MsiEnumComponentsExW(wstr long long ptr ptr ptr ptr)
Modified: trunk/reactos/dll/win32/msi/msipriv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msipriv.h?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -968,6 +968,7 @@
extern INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty ) DECLSPEC_HIDDEN;
extern LPWSTR msi_get_suminfo_product( IStorage *stg ) DECLSPEC_HIDDEN;
extern UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int
num_columns ) DECLSPEC_HIDDEN;
+extern UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle ) DECLSPEC_HIDDEN;
extern enum platform parse_platform( const WCHAR *str ) DECLSPEC_HIDDEN;
extern UINT msi_load_suminfo_properties( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
Modified: trunk/reactos/dll/win32/msi/msiquery.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiquery.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -335,7 +335,7 @@
if ((type & MSI_DATASIZEMASK) == 2)
MSI_RecordSetInteger(*rec, i, ival - (1<<15));
else
- MSI_RecordSetInteger(*rec, i, ival - (1<<31));
+ MSI_RecordSetInteger(*rec, i, ival - (1u<<31));
}
}
Modified: trunk/reactos/dll/win32/msi/package.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/package.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/package.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/package.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -2100,6 +2100,8 @@
MSIRECORD *row;
UINT rc = ERROR_FUNCTION_FAILED;
+ TRACE("%p %s %p %p\n", db, debugstr_w(szName), szValueBuf, pchValueBuf);
+
row = msi_get_property_row( db, szName );
if (*pchValueBuf > 0)
Modified: trunk/reactos/dll/win32/msi/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/registry.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -157,6 +157,10 @@
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s','\\',0};
+static const WCHAR szInstaller_Components[] = {
+
'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
+
'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s','\\',0};
+
static const WCHAR szUserFeatures[] = {
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
@@ -466,7 +470,7 @@
strcpyW(keypath, szUninstall);
strcatW(keypath, product);
}
- return SHDeleteKeyW(HKEY_LOCAL_MACHINE, keypath);
+ return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
}
UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT
context, HKEY *key, BOOL create)
@@ -517,7 +521,7 @@
strcpyW(keypath, szUserProducts);
strcatW(keypath, squished_pc);
- return SHDeleteKeyW(HKEY_CURRENT_USER, keypath);
+ return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
}
UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
@@ -582,7 +586,7 @@
strcpyW(keypath, szUserFeatures);
strcatW(keypath, squished_pc);
- return SHDeleteKeyW(HKEY_CURRENT_USER, keypath);
+ return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
}
static UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
@@ -634,6 +638,7 @@
UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY *key, BOOL create)
{
WCHAR squished_cc[GUID_SIZE], keypath[0x200];
+ UINT ret;
if (!squash_guid(szComponent, squished_cc)) return ERROR_FUNCTION_FAILED;
TRACE("%s squished %s\n", debugstr_w(szComponent),
debugstr_w(squished_cc));
@@ -642,7 +647,12 @@
strcatW(keypath, squished_cc);
if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
- return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
+ ret = RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
+ if (ret != ERROR_FILE_NOT_FOUND) return ret;
+
+ strcpyW(keypath, szInstaller_Components);
+ strcatW(keypath, squished_cc);
+ return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
}
UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, HKEY *key,
BOOL create)
@@ -696,7 +706,7 @@
sprintfW(keypath, szUserDataComponents_fmt, szUserSid);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return
ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, comp);
+ r = RegDeleteTreeW(hkey, comp);
RegCloseKey(hkey);
return r;
}
@@ -777,7 +787,7 @@
LocalFree(usersid);
}
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return
ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_patch);
+ r = RegDeleteTreeW(hkey, squished_patch);
RegCloseKey(hkey);
return r;
}
@@ -854,7 +864,7 @@
LocalFree(usersid);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return
ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_pc);
+ r = RegDeleteTreeW(hkey, squished_pc);
RegCloseKey(hkey);
return r;
}
@@ -870,7 +880,7 @@
TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_Products, 0, access, &hkey))
return ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_pc);
+ r = RegDeleteTreeW(hkey, squished_pc);
RegCloseKey(hkey);
return r;
}
@@ -927,7 +937,7 @@
strcpyW(keypath, szInstaller_UserUpgradeCodes);
strcatW(keypath, squished_pc);
- return SHDeleteKeyW(HKEY_CURRENT_USER, keypath);
+ return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
}
UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
@@ -941,7 +951,7 @@
TRACE("%s squished %s\n", debugstr_w(szProductCode),
debugstr_w(squished_pc));
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesProducts, 0, access,
&hkey)) return ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_pc);
+ r = RegDeleteTreeW(hkey, squished_pc);
RegCloseKey(hkey);
return r;
}
@@ -957,7 +967,7 @@
TRACE("%s squished %s\n", debugstr_w(szProductCode),
debugstr_w(squished_pc));
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesFeatures, 0, access,
&hkey)) return ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_pc);
+ r = RegDeleteTreeW(hkey, squished_pc);
RegCloseKey(hkey);
return r;
}
@@ -988,7 +998,7 @@
TRACE("%s squished %s\n", debugstr_w(szUpgradeCode),
debugstr_w(squished_pc));
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_ClassesUpgradeCodes, 0, access,
&hkey)) return ERROR_SUCCESS;
- r = SHDeleteKeyW(hkey, squished_pc);
+ r = RegDeleteTreeW(hkey, squished_pc);
RegCloseKey(hkey);
return r;
}
Modified: trunk/reactos/dll/win32/msi/streams.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/streams.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/streams.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -194,7 +194,28 @@
static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row)
{
- FIXME("(%p %d): stub!\n", view, row);
+ MSIDATABASE *db = ((MSISTREAMSVIEW *)view)->db;
+ UINT i, num_rows = db->num_streams - 1;
+ const WCHAR *name;
+ WCHAR *encname;
+ HRESULT hr;
+
+ TRACE("(%p %d)!\n", view, row);
+
+ name = msi_string_lookup( db->strings, db->streams[row].str_index, NULL );
+ if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY;
+ hr = IStorage_DestroyElement( db->storage, encname );
+ msi_free( encname );
+ if (FAILED( hr ))
+ return ERROR_FUNCTION_FAILED;
+ hr = IStream_Release( db->streams[row].stream );
+ if (FAILED( hr ))
+ return ERROR_FUNCTION_FAILED;
+
+ for (i = row; i < num_rows; i++)
+ db->streams[i] = db->streams[i + 1];
+ db->num_streams = num_rows;
+
return ERROR_SUCCESS;
}
@@ -291,6 +312,10 @@
case MSIMODIFY_UPDATE:
r = streams_modify_update(view, rec);
+ break;
+
+ case MSIMODIFY_DELETE:
+ r = STREAMS_delete_row(view, row - 1);
break;
case MSIMODIFY_VALIDATE_NEW:
@@ -298,7 +323,6 @@
case MSIMODIFY_REFRESH:
case MSIMODIFY_REPLACE:
case MSIMODIFY_MERGE:
- case MSIMODIFY_DELETE:
case MSIMODIFY_VALIDATE:
case MSIMODIFY_VALIDATE_FIELD:
case MSIMODIFY_VALIDATE_DELETE:
Modified: trunk/reactos/dll/win32/msi/suminfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/suminfo.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -20,6 +20,7 @@
#include "msipriv.h"
+#include <stdio.h>
#include <propvarutil.h>
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -999,6 +1000,117 @@
return r;
}
+static UINT save_prop( MSISUMMARYINFO *si, HANDLE handle, UINT row )
+{
+ static const char fmt_systemtime[] = "%d/%02d/%02d %02d:%02d:%02d";
+ char data[20]; /* largest string: YYYY/MM/DD hh:mm:ss */
+ static const char fmt_begin[] = "%u\t";
+ static const char data_end[] = "\r\n";
+ static const char fmt_int[] = "%u";
+ UINT r, data_type, len;
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ INT int_value;
+ awstring str;
+ DWORD sz;
+
+ str.unicode = FALSE;
+ str.str.a = NULL;
+ len = 0;
+ r = get_prop( si, row, &data_type, &int_value, &file_time, &str,
&len );
+ if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
+ return r;
+ if (data_type == VT_EMPTY)
+ return ERROR_SUCCESS; /* property not set */
+ snprintf( data, sizeof(data), fmt_begin, row );
+ sz = lstrlenA( data );
+ if (!WriteFile( handle, data, sz, &sz, NULL ))
+ return ERROR_WRITE_FAULT;
+
+ switch (data_type)
+ {
+ case VT_I2:
+ case VT_I4:
+ snprintf( data, sizeof(data), fmt_int, int_value );
+ sz = lstrlenA( data );
+ if (!WriteFile( handle, data, sz, &sz, NULL ))
+ return ERROR_WRITE_FAULT;
+ break;
+ case VT_LPSTR:
+ len++;
+ if (!(str.str.a = msi_alloc( len )))
+ return ERROR_OUTOFMEMORY;
+ r = get_prop( si, row, NULL, NULL, NULL, &str, &len );
+ if (r != ERROR_SUCCESS)
+ {
+ msi_free( str.str.a );
+ return r;
+ }
+ sz = lstrlenA( str.str.a );
+ if (!WriteFile( handle, str.str.a, sz, &sz, NULL ))
+ {
+ msi_free( str.str.a );
+ return ERROR_WRITE_FAULT;
+ }
+ msi_free( str.str.a );
+ break;
+ case VT_FILETIME:
+ if (!FileTimeToSystemTime( &file_time, &system_time ))
+ return ERROR_FUNCTION_FAILED;
+ snprintf( data, sizeof(data), fmt_systemtime, system_time.wYear,
system_time.wMonth,
+ system_time.wDay, system_time.wHour, system_time.wMinute,
+ system_time.wSecond );
+ sz = lstrlenA( data );
+ if (!WriteFile( handle, data, sz, &sz, NULL ))
+ return ERROR_WRITE_FAULT;
+ break;
+ case VT_EMPTY:
+ /* cannot reach here, property not set */
+ break;
+ default:
+ FIXME( "Unknown property variant type\n" );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ sz = lstrlenA( data_end );
+ if (!WriteFile( handle, data_end, sz, &sz, NULL ))
+ return ERROR_WRITE_FAULT;
+
+ return ERROR_SUCCESS;
+}
+
+UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle )
+{
+ UINT i, r, num_rows;
+ MSISUMMARYINFO *si;
+
+ r = msi_get_suminfo( db->storage, 0, &si );
+ if (r != ERROR_SUCCESS)
+ r = msi_get_db_suminfo( db, 0, &si );
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ num_rows = get_property_count( si->property );
+ if (!num_rows)
+ {
+ msiobj_release( &si->hdr );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ for (i = 0; i < num_rows; i++)
+ {
+ r = save_prop( si, handle, i );
+ if (r != ERROR_SUCCESS)
+ {
+ msiobj_release( &si->hdr );
+ return r;
+ }
+ }
+
+ msiobj_release( &si->hdr );
+ return ERROR_SUCCESS;
+}
+
UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE handle )
{
MSISUMMARYINFO *si;
Modified: trunk/reactos/dll/win32/msi/table.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/table.c?rev=…
==============================================================================
--- trunk/reactos/dll/win32/msi/table.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/table.c [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -792,7 +792,7 @@
/* add each column to the _Columns table */
r = TABLE_CreateView( db, szColumns, &tv );
if( r )
- return r;
+ goto err;
r = tv->ops->execute( tv, 0 );
TRACE("tv execute returned %x\n", r);
@@ -2308,8 +2308,7 @@
}
static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string_table
*st,
- IStorage *stg,
- const BYTE *rawdata, UINT bytes_per_strref )
+ IStorage *stg, const BYTE *rawdata, UINT
bytes_per_strref )
{
UINT i, val, ofs = 0;
USHORT mask;
@@ -2342,12 +2341,14 @@
r = msi_record_encoded_stream_name( tv, rec, &encname );
if ( r != ERROR_SUCCESS )
+ {
+ msiobj_release( &rec->hdr );
return NULL;
-
- r = IStorage_OpenStream( stg, encname, NULL,
- STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm );
+ }
+ r = IStorage_OpenStream( stg, encname, NULL, STGM_READ |
STGM_SHARE_EXCLUSIVE, 0, &stm );
if ( r != ERROR_SUCCESS )
{
+ msiobj_release( &rec->hdr );
msi_free( encname );
return NULL;
}
Modified: trunk/reactos/media/doc/README.WINE
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sat Nov 21 16:44:38 2015
@@ -115,7 +115,7 @@
reactos/dll/win32/msgsm32.acm # Synced to WineStaging-1.7.47
reactos/dll/win32/mshtml # Synced to WineStaging-1.7.37
reactos/dll/win32/mshtml.tlb # Synced to WineStaging-1.7.47
-reactos/dll/win32/msi # Synced to WineStaging-1.7.47
+reactos/dll/win32/msi # Synced to WineStaging-1.7.55
reactos/dll/win32/msimg32 # Synced to WineStaging-1.7.47
reactos/dll/win32/msimtf # Synced to WineStaging-1.7.47
reactos/dll/win32/msisip # Synced to WineStaging-1.7.47