Author: cfinck Date: Sun Sep 21 10:24:30 2008 New Revision: 36384
URL: http://svn.reactos.org/svn/reactos?rev=36384&view=rev Log: Sync msi with Wine 1.1.5
Added: trunk/reactos/dll/win32/msi/storages.c (with props) Modified: trunk/reactos/dll/win32/msi/action.c trunk/reactos/dll/win32/msi/automation.c trunk/reactos/dll/win32/msi/database.c trunk/reactos/dll/win32/msi/dialog.c trunk/reactos/dll/win32/msi/files.c trunk/reactos/dll/win32/msi/helpers.c trunk/reactos/dll/win32/msi/msi.c trunk/reactos/dll/win32/msi/msi.rbuild trunk/reactos/dll/win32/msi/msipriv.h trunk/reactos/dll/win32/msi/msiquery.c trunk/reactos/dll/win32/msi/msiserver.idl trunk/reactos/dll/win32/msi/msiserver_dispids.h trunk/reactos/dll/win32/msi/package.c trunk/reactos/dll/win32/msi/query.h trunk/reactos/dll/win32/msi/suminfo.c trunk/reactos/dll/win32/msi/table.c
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] Sun Sep 21 10:24:30 2008 @@ -1486,7 +1486,7 @@ } else { - file->IsCompressed = package->WordCount & MSIWORDCOUNT_COMPRESSED; + file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed; }
if (!file->IsCompressed)
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] Sun Sep 21 10:24:30 2008 @@ -1388,6 +1388,20 @@ else return DISP_E_MEMBERNOTFOUND; break;
+ case DISPID_SESSION_MESSAGE: + if(!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); + if (FAILED(hr)) return hr; + hr = DispGetParam(pDispParams, 1, VT_DISPATCH, &varg1, puArgErr); + if (FAILED(hr)) return hr; + + V_VT(pVarResult) = VT_I4; + V_I4(pVarResult) = + MsiProcessMessage(This->msiHandle, V_I4(&varg0), ((AutomationObject *)V_DISPATCH(&varg1))->msiHandle); + break; + case DISPID_SESSION_SETINSTALLLEVEL: if (wFlags & DISPATCH_METHOD) { hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
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] Sun Sep 21 10:24:30 2008 @@ -89,6 +89,13 @@
if( !pdb ) return ERROR_INVALID_PARAMETER; + + if (szPersist - MSIDBOPEN_PATCHFILE >= MSIDBOPEN_READONLY && + szPersist - MSIDBOPEN_PATCHFILE <= MSIDBOPEN_CREATEDIRECT) + { + TRACE("Database is a patch\n"); + szPersist -= MSIDBOPEN_PATCHFILE; + }
save_path = szDBPath; szMode = szPersist;
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] Sun Sep 21 10:24:30 2008 @@ -417,6 +417,7 @@ strcpyW( control->name, name ); list_add_head( &dialog->controls, &control->entry ); control->handler = NULL; + control->update = NULL; control->property = NULL; control->value = NULL; control->hBitmap = NULL;
Modified: trunk/reactos/dll/win32/msi/files.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/files.c?rev=3... ============================================================================== --- trunk/reactos/dll/win32/msi/files.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/files.c [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -743,23 +743,12 @@ TRACE("overwriting existing file\n"); gle = ERROR_SUCCESS; } - else if (gle == ERROR_FILE_NOT_FOUND) - { - /* FIXME: this needs to be tested, I'm pretty sure it fails */ - TRACE("Source file not found\n"); - gle = ERROR_SUCCESS; - } else if (gle == ERROR_ACCESS_DENIED) { SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL);
gle = copy_file(file); TRACE("Overwriting existing file: %d\n", gle); - } - else if (!(file->Attributes & msidbFileAttributesVital)) - { - TRACE("Ignoring error for nonvital\n"); - gle = ERROR_SUCCESS; }
return gle;
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] Sun Sep 21 10:24:30 2008 @@ -323,34 +323,14 @@ } else { - /* source may be in a few different places ... check each of them */ path = NULL;
- /* try the long path directory */ - if (f->SourceLongPath) - { + if (package->WordCount & msidbSumInfoSourceTypeCompressed) + path = get_source_root( package ); + else if (package->WordCount & msidbSumInfoSourceTypeSFN) + path = build_directory_name( 3, p, f->SourceShortPath, NULL ); + else path = build_directory_name( 3, p, f->SourceLongPath, NULL ); - if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) - { - msi_free( path ); - path = NULL; - } - } - - /* try the short path directory */ - if (!path && f->SourceShortPath) - { - path = build_directory_name( 3, p, f->SourceShortPath, NULL ); - if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) - { - msi_free( path ); - path = NULL; - } - } - - /* try the root of the install */ - if (!path) - path = get_source_root( package );
TRACE("source -> %s\n", debugstr_w(path)); f->ResolvedSource = strdupW( path );
Modified: trunk/reactos/dll/win32/msi/msi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.c?rev=363... ============================================================================== --- trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -2846,7 +2846,7 @@ MD5Final( &ctx ); UnmapViewOfFile( p );
- memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData ); + memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData ); r = ERROR_SUCCESS; } CloseHandle( mapping );
Modified: trunk/reactos/dll/win32/msi/msi.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.rbuild?re... ============================================================================== --- trunk/reactos/dll/win32/msi/msi.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msi.rbuild [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -42,6 +42,7 @@ <file>select.c</file> <file>source.c</file> <file>sql.tab.c</file> + <file>storages.c</file> <file>streams.c</file> <file>string.c</file> <file>suminfo.c</file>
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] Sun Sep 21 10:24:30 2008 @@ -42,11 +42,6 @@ #define MSITYPE_KEY 0x2000 #define MSITYPE_TEMPORARY 0x4000
-/* Word Count masks */ -#define MSIWORDCOUNT_SHORTFILENAMES 0x0001 -#define MSIWORDCOUNT_COMPRESSED 0x0002 -#define MSIWORDCOUNT_ADMINISTRATIVE 0x0004 -#define MSIWORDCOUNT_PRIVILEGES 0x0008
/* Install UI level mask for AND operation to exclude flags */ #define INSTALLUILEVEL_MASK 0x0007
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] Sun Sep 21 10:24:30 2008 @@ -326,7 +326,7 @@ IStream_Release(stm); } else - ERR("failed to get stream\n"); + WARN("failed to get stream\n");
continue; }
Modified: trunk/reactos/dll/win32/msi/msiserver.idl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiserver.idl... ============================================================================== --- trunk/reactos/dll/win32/msi/msiserver.idl [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msiserver.idl [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -325,6 +325,42 @@ msiEvaluateConditionError = 3 } _MsiEvaluateCondition; /* Added underscore to avoid conflict with function name */
+ typedef enum { + msiMessageStatusError = -1, + msiMessageStatusNone = 0, + msiMessageStatusOk = 1, + msiMessageStatusCancel = 2, + msiMessageStatusAbort = 3, + msiMessageStatusRetry = 4, + msiMessageStatusIgnore = 5, + msiMessageStatusYes = 6, + msiMessageStatusNo = 7 + } MsiMessageStatus; + + typedef enum { + msiMessageTypeFatalExit = 0, + msiMessageTypeError = 0x01000000, + msiMessageTypeWarning = 0x02000000, + msiMessageTypeUser = 0x03000000, + msiMessageTypeInfo = 0x04000000, + msiMessageTypeFilesInUse = 0x05000000, + msiMessageTypeResolveSource = 0x06000000, + msiMessageTypeOutOfDiskSpace = 0x07000000, + msiMessageTypeActionStart = 0x08000000, + msiMessageTypeActionData = 0x09000000, + msiMessageTypeProgress = 0x0a000000, + msiMessageTypeCommonData = 0x0b000000, + msiMessageTypeOk = 0, + msiMessageTypeOkCancel = 1, + msiMessageTypeAbortRetryIgnore = 2, + msiMessageTypeYesNoCancel = 3, + msiMessageTypeYesNo = 4, + msiMessageTypeRetryCancel = 5, + msiMessageTypeDefault1 = 0, + msiMessageTypeDefault2 = 256, + msiMessageTypeDefault3 = 512 + } MsiMessageType; + [ uuid(000C109E-0000-0000-C000-000000000046) ] dispinterface Session { @@ -352,6 +388,10 @@ MsiDoActionStatus DoAction([in] BSTR Action); [id(DISPID_SESSION_EVALUATECONDITION)] _MsiEvaluateCondition EvaluateCondition([in] BSTR Expression); + [id(DISPID_SESSION_MESSAGE)] + MsiMessageStatus Message( + [in] MsiMessageType Kind, + [in] Record *Record); [id(DISPID_SESSION_FEATURECURRENTSTATE), propget] MsiInstallState FeatureCurrentState([in] BSTR Feature); [id(DISPID_SESSION_FEATUREREQUESTSTATE), propget]
Modified: trunk/reactos/dll/win32/msi/msiserver_dispids.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiserver_dis... ============================================================================== --- trunk/reactos/dll/win32/msi/msiserver_dispids.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msiserver_dispids.h [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -51,6 +51,7 @@ #define DISPID_SESSION_DATABASE 5 #define DISPID_SESSION_DOACTION 8 #define DISPID_SESSION_EVALUATECONDITION 10 +#define DISPID_SESSION_MESSAGE 12 #define DISPID_SESSION_FEATURECURRENTSTATE 13 #define DISPID_SESSION_FEATUREREQUESTSTATE 14 #define DISPID_SESSION_SETINSTALLLEVEL 19
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] Sun Sep 21 10:24:30 2008 @@ -797,7 +797,7 @@ return NULL; }
- if (package->WordCount & MSIWORDCOUNT_ADMINISTRATIVE) + if (package->WordCount & msidbSumInfoSourceTypeAdminImage) msi_load_admin_properties( package ); }
Modified: trunk/reactos/dll/win32/msi/query.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/query.h?rev=3... ============================================================================== --- trunk/reactos/dll/win32/msi/query.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/query.h [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -115,6 +115,8 @@
UINT STREAMS_CreateView( MSIDATABASE *db, MSIVIEW **view );
+UINT STORAGES_CreateView( MSIDATABASE *db, MSIVIEW **view ); + int sqliteGetToken(const WCHAR *z, int *tokenType);
MSIRECORD *msi_query_merge_record( UINT fields, const column_info *vl, MSIRECORD *rec );
Added: 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 (added) +++ trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -1,0 +1,560 @@ +/* + * Implementation of the Microsoft Installer (msi.dll) + * + * Copyright 2008 James Hawkins + * + * 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 <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winerror.h" +#include "ole2.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "msipriv.h" +#include "query.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msidb); + +#define NUM_STORAGES_COLS 2 +#define MAX_STORAGES_NAME_LEN 62 + +typedef struct tabSTORAGE +{ + UINT str_index; + LPWSTR name; + IStorage *storage; +} STORAGE; + +typedef struct tagMSISTORAGESVIEW +{ + MSIVIEW view; + MSIDATABASE *db; + STORAGE **storages; + UINT max_storages; + UINT num_rows; + UINT row_size; +} MSISTORAGESVIEW; + +static BOOL storages_set_table_size(MSISTORAGESVIEW *sv, UINT size) +{ + if (size >= sv->max_storages) + { + sv->max_storages *= 2; + sv->storages = msi_realloc(sv->storages, sv->max_storages * sizeof(STORAGE *)); + if (!sv->storages) + return FALSE; + } + + return TRUE; +} + +static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPWSTR name, IStorage *stg) +{ + STORAGE *storage; + + storage = msi_alloc(sizeof(STORAGE)); + if (!storage) + return NULL; + + storage->name = strdupW(name); + if (!storage->name) + { + msi_free(storage); + return NULL; + } + + storage->str_index = msi_addstringW(sv->db->strings, 0, storage->name, -1, 1, StringNonPersistent); + storage->storage = stg; + + if (storage->storage) + IStorage_AddRef(storage->storage); + + return storage; +} + +static UINT STORAGES_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + + TRACE("(%p, %d, %d, %p)\n", view, row, col, val); + + if (col != 1) + return ERROR_INVALID_PARAMETER; + + if (row >= sv->num_rows) + return ERROR_NO_MORE_ITEMS; + + *val = sv->storages[row]->str_index; + + return ERROR_SUCCESS; +} + +static UINT STORAGES_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + + TRACE("(%p, %d, %d, %p)\n", view, row, col, stm); + + if (row >= sv->num_rows) + return ERROR_FUNCTION_FAILED; + + return ERROR_INVALID_DATA; +} + +static UINT STORAGES_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec ) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + + FIXME("%p %d %p\n", sv, row, rec); + + return ERROR_CALL_NOT_IMPLEMENTED; +} + +static HRESULT stream_to_storage(IStream *stm, IStorage **stg) +{ + ILockBytes *lockbytes; + STATSTG stat; + LPVOID data; + HRESULT hr; + DWORD size, read; + ULARGE_INTEGER offset; + + hr = IStream_Stat(stm, &stat, STATFLAG_NONAME); + if (FAILED(hr)) + return hr; + + if (stat.cbSize.QuadPart >> 32) + { + ERR("Storage is too large\n"); + return E_FAIL; + } + + size = stat.cbSize.QuadPart; + data = msi_alloc(size); + if (!data) + return E_OUTOFMEMORY; + + hr = IStream_Read(stm, data, size, &read); + if (FAILED(hr) || read != size) + goto done; + + hr = CreateILockBytesOnHGlobal(NULL, TRUE, &lockbytes); + if (FAILED(hr)) + goto done; + + ZeroMemory(&offset, sizeof(ULARGE_INTEGER)); + hr = ILockBytes_WriteAt(lockbytes, offset, data, size, &read); + if (FAILED(hr) || read != size) + goto done; + + hr = StgOpenStorageOnILockBytes(lockbytes, NULL, + STGM_READWRITE | STGM_SHARE_DENY_NONE, + NULL, 0, stg); + if (FAILED(hr)) + goto done; + +done: + msi_free(data); + ILockBytes_Release(lockbytes); + return hr; +} + +static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + IStorage *stg, *substg; + IStream *stm; + LPWSTR name = NULL; + HRESULT hr; + UINT r = ERROR_FUNCTION_FAILED; + + TRACE("(%p, %p)\n", view, rec); + + if (row > sv->num_rows) + return ERROR_FUNCTION_FAILED; + + r = MSI_RecordGetIStream(rec, 2, &stm); + if (r != ERROR_SUCCESS) + return r; + + r = stream_to_storage(stm, &stg); + if (r != ERROR_SUCCESS) + { + IStream_Release(stm); + return r; + } + + name = strdupW(MSI_RecordGetString(rec, 1)); + if (!name) + { + r = ERROR_OUTOFMEMORY; + goto done; + } + + hr = IStorage_CreateStorage(sv->db->storage, name, + STGM_WRITE | STGM_SHARE_EXCLUSIVE, + 0, 0, &substg); + if (FAILED(hr)) + { + r = ERROR_FUNCTION_FAILED; + goto done; + } + + hr = IStorage_CopyTo(stg, 0, NULL, NULL, substg); + if (FAILED(hr)) + { + r = ERROR_FUNCTION_FAILED; + goto done; + } + + sv->storages[row] = create_storage(sv, name, stg); + if (!sv->storages[row]) + r = ERROR_FUNCTION_FAILED; + +done: + msi_free(name); + + IStorage_Release(substg); + IStorage_Release(stg); + IStream_Release(stm); + + return r; +} + +static UINT STORAGES_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temporary) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + + if (!storages_set_table_size(sv, ++sv->num_rows)) + return ERROR_FUNCTION_FAILED; + + return STORAGES_set_row(view, sv->num_rows - 1, rec, 0); +} + +static UINT STORAGES_delete_row(struct tagMSIVIEW *view, UINT row) +{ + FIXME("(%p %d): stub!\n", view, row); + return ERROR_SUCCESS; +} + +static UINT STORAGES_execute(struct tagMSIVIEW *view, MSIRECORD *record) +{ + TRACE("(%p, %p)\n", view, record); + return ERROR_SUCCESS; +} + +static UINT STORAGES_close(struct tagMSIVIEW *view) +{ + TRACE("(%p)\n", view); + return ERROR_SUCCESS; +} + +static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + + TRACE("(%p, %p, %p)\n", view, rows, cols); + + if (cols) *cols = NUM_STORAGES_COLS; + if (rows) *rows = sv->num_rows; + + return ERROR_SUCCESS; +} + +static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, + UINT n, LPWSTR *name, UINT *type) +{ + LPCWSTR name_ptr = NULL; + + static const WCHAR Name[] = {'N','a','m','e',0}; + static const WCHAR Data[] = {'D','a','t','a',0}; + + TRACE("(%p, %d, %p, %p)\n", view, n, name, type); + + if (n == 0 || n > NUM_STORAGES_COLS) + return ERROR_INVALID_PARAMETER; + + switch (n) + { + case 1: + name_ptr = Name; + if (type) *type = MSITYPE_STRING | MAX_STORAGES_NAME_LEN; + break; + + case 2: + name_ptr = Data; + if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE; + break; + } + + if (name) + { + *name = strdupW(name_ptr); + if (!*name) return ERROR_FUNCTION_FAILED; + } + + return ERROR_SUCCESS; +} + +static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row) +{ + LPCWSTR str; + UINT i, id, data; + + str = MSI_RecordGetString(rec, 1); + msi_string2idW(sv->db->strings, str, &id); + + for (i = 0; i < sv->num_rows; i++) + { + STORAGES_fetch_int(&sv->view, i, 1, &data); + + if (data == id) + { + *row = i; + return ERROR_SUCCESS; + } + } + + return ERROR_FUNCTION_FAILED; +} + +static UINT storages_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + UINT r, row; + + r = storages_find_row(sv, rec, &row); + if (r != ERROR_SUCCESS) + return ERROR_FUNCTION_FAILED; + + return STORAGES_set_row(view, row, rec, 0); +} + +static UINT storages_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + UINT r, row; + + r = storages_find_row(sv, rec, &row); + if (r == ERROR_SUCCESS) + return storages_modify_update(view, rec); + + return STORAGES_insert_row(view, rec, FALSE); +} + +static UINT STORAGES_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row) +{ + UINT r; + + TRACE("%p %d %p\n", view, eModifyMode, rec); + + switch (eModifyMode) + { + case MSIMODIFY_ASSIGN: + r = storages_modify_assign(view, rec); + break; + + case MSIMODIFY_INSERT: + r = STORAGES_insert_row(view, rec, FALSE); + break; + + case MSIMODIFY_UPDATE: + r = storages_modify_update(view, rec); + break; + + case MSIMODIFY_VALIDATE_NEW: + case MSIMODIFY_INSERT_TEMPORARY: + case MSIMODIFY_REFRESH: + case MSIMODIFY_REPLACE: + case MSIMODIFY_MERGE: + case MSIMODIFY_DELETE: + case MSIMODIFY_VALIDATE: + case MSIMODIFY_VALIDATE_FIELD: + case MSIMODIFY_VALIDATE_DELETE: + FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec ); + r = ERROR_CALL_NOT_IMPLEMENTED; + break; + + default: + r = ERROR_INVALID_DATA; + } + + return r; +} + +static UINT STORAGES_delete(struct tagMSIVIEW *view) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + UINT i; + + TRACE("(%p)\n", view); + + for (i = 0; i < sv->num_rows; i++) + { + if (sv->storages[i]->storage) + IStorage_Release(sv->storages[i]->storage); + + msi_free(sv->storages[i]); + } + + msi_free(sv->storages); + sv->storages = NULL; + + return ERROR_SUCCESS; +} + +static UINT STORAGES_find_matching_rows(struct tagMSIVIEW *view, UINT col, + UINT val, UINT *row, MSIITERHANDLE *handle) +{ + MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; + UINT index = (UINT)*handle; + + TRACE("(%d, %d): %d\n", *row, col, val); + + if (col == 0 || col > NUM_STORAGES_COLS) + return ERROR_INVALID_PARAMETER; + + while (index < sv->num_rows) + { + if (sv->storages[index]->str_index == val) + { + *row = index; + break; + } + + index++; + } + + *handle = (MSIITERHANDLE)++index; + if (index >= sv->num_rows) + return ERROR_NO_MORE_ITEMS; + + return ERROR_SUCCESS; +} + +static const MSIVIEWOPS storages_ops = +{ + STORAGES_fetch_int, + STORAGES_fetch_stream, + STORAGES_get_row, + STORAGES_set_row, + STORAGES_insert_row, + STORAGES_delete_row, + STORAGES_execute, + STORAGES_close, + STORAGES_get_dimensions, + STORAGES_get_column_info, + STORAGES_modify, + STORAGES_delete, + STORAGES_find_matching_rows, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static INT add_storages_to_table(MSISTORAGESVIEW *sv) +{ + STORAGE *storage = NULL; + IEnumSTATSTG *stgenum = NULL; + STATSTG stat; + HRESULT hr; + UINT count = 0, size; + + hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum); + if (FAILED(hr)) + return -1; + + sv->max_storages = 1; + sv->storages = msi_alloc(sizeof(STORAGE *)); + if (!sv->storages) + return -1; + + while (TRUE) + { + size = 0; + hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size); + if (FAILED(hr) || !size) + break; + + if (stat.type != STGTY_STORAGE) + { + CoTaskMemFree(stat.pwcsName); + continue; + } + + TRACE("enumerated storage %s\n", debugstr_w(stat.pwcsName)); + + storage = create_storage(sv, stat.pwcsName, NULL); + if (!storage) + { + count = -1; + CoTaskMemFree(stat.pwcsName); + break; + } + + IStorage_OpenStorage(sv->db->storage, stat.pwcsName, NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, + &storage->storage); + CoTaskMemFree(stat.pwcsName); + + if (!storages_set_table_size(sv, ++count)) + { + count = -1; + break; + } + + sv->storages[count - 1] = storage; + } + + IEnumSTATSTG_Release(stgenum); + return count; +} + +UINT STORAGES_CreateView(MSIDATABASE *db, MSIVIEW **view) +{ + MSISTORAGESVIEW *sv; + INT rows; + + TRACE("(%p, %p)\n", db, view); + + sv = msi_alloc(sizeof(MSISTORAGESVIEW)); + if (!sv) + return ERROR_FUNCTION_FAILED; + + sv->view.ops = &storages_ops; + sv->db = db; + + rows = add_storages_to_table(sv); + if (rows < 0) + return ERROR_FUNCTION_FAILED; + + sv->num_rows = rows; + + *view = (MSIVIEW *)sv; + + return ERROR_SUCCESS; +}
Propchange: trunk/reactos/dll/win32/msi/storages.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/msi/suminfo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/suminfo.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -443,7 +443,7 @@ if( !si ) return si;
- memset( &si->property, 0, sizeof si->property ); + memset( si->property, 0, sizeof si->property ); si->update_count = uiUpdateCount; IStorage_AddRef( stg ); si->storage = stg;
Modified: trunk/reactos/dll/win32/msi/table.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/table.c?rev=3... ============================================================================== --- trunk/reactos/dll/win32/msi/table.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/table.c [iso-8859-1] Sun Sep 21 10:24:30 2008 @@ -2109,11 +2109,14 @@ UINT r, sz;
static const WCHAR Streams[] = {'_','S','t','r','e','a','m','s',0}; + static const WCHAR Storages[] = {'_','S','t','o','r','a','g','e','s',0};
TRACE("%p %s %p\n", db, debugstr_w(name), view );
if ( !lstrcmpW( name, Streams ) ) return STREAMS_CreateView( db, view ); + else if ( !lstrcmpW( name, Storages ) ) + return STORAGES_CreateView( db, view );
sz = sizeof *tv + lstrlenW(name)*sizeof name[0] ; tv = msi_alloc_zero( sz );