Commit 401bd3f7 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

Start implementing actions.

parent c390bb2a
......@@ -3,10 +3,11 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = msi.dll
IMPORTS = ole32 user32 advapi32 kernel32
IMPORTS = shell32 cabinet ole32 user32 advapi32 kernel32
EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \
action.c \
create.c \
distinct.c \
handle.c \
......
......@@ -54,6 +54,7 @@ MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy, voi
info->magic = MSIHANDLE_MAGIC;
info->type = type;
info->refcount = 1;
info->destructor = destroy;
msihandletable[i] = info;
......@@ -79,6 +80,26 @@ void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
return &msihandletable[handle][1];
}
void msihandle_addref(MSIHANDLE handle)
{
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0);
TRACE("%lx\n",handle);
if( !info )
return;
info--;
if( info->magic != MSIHANDLE_MAGIC )
{
ERR("Invalid handle!\n");
return;
}
info->refcount++;
}
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
{
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0);
......@@ -96,6 +117,10 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
return ERROR_INVALID_HANDLE;
}
info->refcount--;
if (info->refcount > 0)
return ERROR_SUCCESS;
if( info->destructor )
info->destructor( &info[1] );
......
......@@ -33,6 +33,7 @@
#include "msipriv.h"
#include "objidl.h"
#include "wincrypt.h"
#include "wine/unicode.h"
#include "objbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
......@@ -302,18 +303,24 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
if( r != ERROR_SUCCESS )
return r;
return ERROR_UNKNOWN_PRODUCT;
r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* find the size of the path */
type = count = 0;
r = RegQueryValueExW( hKeyProduct, szLocalPackage,
NULL, &type, NULL, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* now alloc and fetch the path of the database to open */
path = HeapAlloc( GetProcessHeap(), 0, count );
......@@ -323,7 +330,10 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
r = RegQueryValueExW( hKeyProduct, szLocalPackage,
NULL, &type, (LPBYTE) path, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
r = MsiOpenPackageW( path, phProduct );
......@@ -345,8 +355,10 @@ UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
{
UINT rc;
FIXME("%s %p\n",debugstr_w(szPackage), phPackage);
return ERROR_CALL_NOT_IMPLEMENTED;
rc = MsiOpenDatabaseW(szPackage,MSIDBOPEN_READONLY,phPackage);
return rc;
}
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
......@@ -426,9 +438,23 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIHANDLE dbhandle;
UINT rc = ERROR_SUCCESS;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
return ERROR_CALL_NOT_IMPLEMENTED;
rc = MsiVerifyPackageW(szPackagePath);
if (rc != ERROR_SUCCESS)
return rc;
rc = MsiOpenDatabaseW(szPackagePath,MSIDBOPEN_READONLY,&dbhandle);
if (rc != ERROR_SUCCESS)
return rc;
ACTION_DoTopLevelINSTALL(dbhandle, szPackagePath, szCommandLine);
MsiCloseHandle(dbhandle);
return rc;
}
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
......@@ -511,66 +537,8 @@ UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
{
LPWSTR szwName = NULL, szwValueBuf = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
FIXME("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
if (NULL != szValueBuf && NULL == pchValueBuf) {
return ERROR_INVALID_PARAMETER;
}
if( szName )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwName )
goto end;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
} else {
return ERROR_INVALID_PARAMETER;
}
if( szValueBuf )
{
szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
if( !szwValueBuf )
goto end;
}
hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
if( ERROR_SUCCESS == hr )
{
WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
}
end:
if( szwName )
HeapFree( GetProcessHeap(), 0, szwName );
if( szwValueBuf )
HeapFree( GetProcessHeap(), 0, szwValueBuf );
return hr;
}
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, LPWSTR szValueBuf, DWORD* pchValueBuf)
{
FIXME("%lu %s %lu\n", hInstall, debugstr_w(szName), *pchValueBuf);
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
{
......@@ -715,6 +683,13 @@ INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
return dwUILevel;
}
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
DWORD dwMessageFilter, LPVOID pvContext)
{
FIXME("STUB\n");
return NULL;
}
UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
{
/*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
......@@ -1220,3 +1195,148 @@ BOOL WINAPI MSI_DllCanUnloadNow(void)
{
return S_FALSE;
}
/* property code */
UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
{
FIXME("STUB until write access is done: (%s %s)\n", szName,
szValue);
if (!hInstall)
return ERROR_INVALID_HANDLE;
return ERROR_SUCCESS;
}
UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
{
FIXME("STUB until write access is done: (%s %s)\n",debugstr_w(szName),
debugstr_w(szValue));
if (!hInstall)
return ERROR_INVALID_HANDLE;
return ERROR_SUCCESS;
}
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
{
LPWSTR szwName = NULL, szwValueBuf = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
FIXME("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
if (NULL != szValueBuf && NULL == pchValueBuf) {
return ERROR_INVALID_PARAMETER;
}
if( szName )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwName )
goto end;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
} else {
return ERROR_INVALID_PARAMETER;
}
if( szValueBuf )
{
szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
if( !szwValueBuf )
goto end;
}
hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
if( ERROR_SUCCESS == hr )
{
WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
}
end:
if( szwName )
HeapFree( GetProcessHeap(), 0, szwName );
if( szwValueBuf )
HeapFree( GetProcessHeap(), 0, szwValueBuf );
return hr;
}
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
LPWSTR szValueBuf, DWORD* pchValueBuf)
{
MSIHANDLE view,row;
UINT rc;
WCHAR Query[1024]=
{'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' '
,'P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' ','`'
,'P','r','o','p','e','r','t','y','`','=','`',0};
static const WCHAR szEnd[]={'`',0};
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
strcatW(Query,szName);
strcatW(Query,szEnd);
rc = MsiDatabaseOpenViewW(hInstall, Query, &view);
if (rc == ERROR_SUCCESS)
{
DWORD sz;
WCHAR value[0x100];
rc = MsiViewExecute(view, 0);
if (rc != ERROR_SUCCESS)
{
MsiViewClose(view);
MsiCloseHandle(view);
return rc;
}
rc = MsiViewFetch(view,&row);
if (rc == ERROR_SUCCESS)
{
sz=0x100;
rc = MsiRecordGetStringW(row,2,value,&sz);
strncpyW(szValueBuf,value,min(sz+1,*pchValueBuf));
*pchValueBuf = sz+1;
MsiCloseHandle(row);
}
MsiViewClose(view);
MsiCloseHandle(view);
}
if (rc == ERROR_SUCCESS)
TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
debugstr_w(szName));
return rc;
}
INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
MSIHANDLE hRecord)
{
FIXME("STUB: \n");
return ERROR_SUCCESS;
}
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
{
FIXME("Is this correct?\n");
msihandle_addref(hInstall);
return hInstall;
}
......@@ -46,7 +46,7 @@
46 stdcall MsiEvaluateConditionA(long str)
47 stdcall MsiEvaluateConditionW(long wstr)
48 stub MsiGetLastErrorRecord
49 stub MsiGetActiveDatabase
49 stdcall MsiGetActiveDatabase(long)
50 stdcall MsiGetComponentStateA(long str ptr ptr)
51 stdcall MsiGetComponentStateW(long wstr ptr ptr)
52 stub MsiGetDatabaseState
......@@ -100,7 +100,7 @@
100 stub MsiPreviewDialogW
101 stub MsiProcessAdvertiseScriptA
102 stub MsiProcessAdvertiseScriptW
103 stub MsiProcessMessage
103 stdcall MsiProcessMessage(long long long)
104 stub MsiProvideComponentA
105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
......@@ -133,7 +133,7 @@
133 stub MsiSequenceW
134 stub MsiSetComponentStateA
135 stub MsiSetComponentStateW
136 stub MsiSetExternalUIA
136 stdcall MsiSetExternalUIA(ptr long ptr)
137 stub MsiSetExternalUIW
138 stub MsiSetFeatureStateA
139 stub MsiSetFeatureStateW
......@@ -141,8 +141,8 @@
141 stdcall MsiSetInternalUI(long ptr)
142 stub MsiVerifyDiskSpace
143 stub MsiSetMode
144 stub MsiSetPropertyA
145 stub MsiSetPropertyW
144 stdcall MsiSetPropertyA(long str str)
145 stdcall MsiSetPropertyW(long wstr wstr)
146 stub MsiSetTargetPathA
147 stub MsiSetTargetPathW
148 stdcall MsiSummaryInfoGetPropertyA(long long ptr ptr ptr ptr ptr)
......
......@@ -132,6 +132,7 @@ typedef struct tagMSIHANDLEINFO
{
UINT magic;
UINT type;
UINT refcount;
msihandledestructor destructor;
struct tagMSIHANDLEINFO *next;
struct tagMSIHANDLEINFO *prev;
......@@ -164,6 +165,7 @@ DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x0
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy, void **out);
void msihandle_addref(MSIHANDLE handle);
/* add this table to the list of cached tables in the database */
extern void add_table(MSIDATABASE *db, MSITABLE *table);
......@@ -199,4 +201,9 @@ UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n );
extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
USHORT **pdata, UINT *psz );
UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
LPCWSTR szCommandLine);
#endif /* __WINE_MSI_PRIVATE__ */
......@@ -571,7 +571,8 @@ LPWSTR SQL_getstring( struct sql_str *strdata)
LPWSTR str;
/* if there's quotes, remove them */
if( (p[0]=='`') && (p[len-1]=='`') )
if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
( (p[0]=='\'') && (p[len-1]=='\'') ) )
{
p++;
len -= 2;
......
......@@ -1254,3 +1254,76 @@ UINT MSI_CommitTables( MSIDATABASE *db )
return ERROR_SUCCESS;
}
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
USHORT **pdata, UINT *psz )
{
HRESULT r;
UINT ret = ERROR_FUNCTION_FAILED;
VOID *data;
ULONG sz, count;
IStream *stm = NULL;
IStorage *stg = NULL;
STATSTG stat;
WCHAR encname[0x20];
MSIDATABASE *db;
db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE );
if ( !db )
return ERROR_INVALID_HANDLE;
stg = db->storage;
encode_streamname(FALSE, stname, encname);
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
r = IStorage_OpenStream(stg, encname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
if( FAILED( r ) )
{
WARN("open stream failed r = %08lx - empty table?\n",r);
return ret;
}
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
{
ERR("open stream failed r = %08lx!\n",r);
goto end;
}
if( stat.cbSize.QuadPart >> 32 )
{
ERR("Too big!\n");
goto end;
}
sz = stat.cbSize.QuadPart;
data = HeapAlloc( GetProcessHeap(), 0, sz );
if( !data )
{
ERR("couldn't allocate memory r=%08lx!\n",r);
ret = ERROR_NOT_ENOUGH_MEMORY;
goto end;
}
r = IStream_Read(stm, data, sz, &count );
if( FAILED( r ) || ( count != sz ) )
{
HeapFree( GetProcessHeap(), 0, data );
ERR("read stream failed r = %08lx!\n",r);
goto end;
}
*pdata = data;
*psz = sz;
ret = ERROR_SUCCESS;
end:
IStream_Release( stm );
return ret;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment