Commit a7a6f5f3 authored by Alexandre Julliard's avatar Alexandre Julliard

Authors: Mike McCormack <mike@codeweavers.com>, Aric Stewart <aric@codeweavers.com>

Refcount all objects, and use pointers internally.
parent 95dc4726
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "msi.h" #include "msi.h"
#include "msiquery.h" #include "msiquery.h"
#include "msipriv.h"
#define YYLEX_PARAM info #define YYLEX_PARAM info
#define YYPARSE_PARAM info #define YYPARSE_PARAM info
...@@ -43,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); ...@@ -43,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
typedef struct tag_yyinput typedef struct tag_yyinput
{ {
MSIHANDLE hInstall; MSIPACKAGE *package;
LPCWSTR str; LPCWSTR str;
INT n; INT n;
MSICONDITION result; MSICONDITION result;
...@@ -408,7 +409,7 @@ symbol_i: ...@@ -408,7 +409,7 @@ symbol_i:
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetComponentStateW(cond->hInstall, $2, &install, &action ); MSI_GetComponentStateW(cond->package, $2, &install, &action );
$$ = action; $$ = action;
HeapFree( GetProcessHeap(), 0, $2 ); HeapFree( GetProcessHeap(), 0, $2 );
} }
...@@ -417,7 +418,7 @@ symbol_i: ...@@ -417,7 +418,7 @@ symbol_i:
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetComponentStateW(cond->hInstall, $2, &install, &action ); MSI_GetComponentStateW(cond->package, $2, &install, &action );
$$ = install; $$ = install;
HeapFree( GetProcessHeap(), 0, $2 ); HeapFree( GetProcessHeap(), 0, $2 );
} }
...@@ -426,7 +427,7 @@ symbol_i: ...@@ -426,7 +427,7 @@ symbol_i:
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetFeatureStateW(cond->hInstall, $2, &install, &action ); MSI_GetFeatureStateW(cond->package, $2, &install, &action );
$$ = action; $$ = action;
HeapFree( GetProcessHeap(), 0, $2 ); HeapFree( GetProcessHeap(), 0, $2 );
} }
...@@ -435,7 +436,7 @@ symbol_i: ...@@ -435,7 +436,7 @@ symbol_i:
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetFeatureStateW(cond->hInstall, $2, &install, &action ); MSI_GetFeatureStateW(cond->package, $2, &install, &action );
$$ = install; $$ = install;
HeapFree( GetProcessHeap(), 0, $2 ); HeapFree( GetProcessHeap(), 0, $2 );
} }
...@@ -451,7 +452,7 @@ symbol_s: ...@@ -451,7 +452,7 @@ symbol_s:
/* Lookup the identifier */ /* Lookup the identifier */
sz=0x100; sz=0x100;
if (MsiGetPropertyW(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS) if (MSI_GetPropertyW(cond->package,$1,$$,&sz) != ERROR_SUCCESS)
{ {
$$[0]=0; $$[0]=0;
} }
...@@ -687,12 +688,12 @@ static int COND_error(char *str) ...@@ -687,12 +688,12 @@ static int COND_error(char *str)
return 0; return 0;
} }
MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
{ {
COND_input cond; COND_input cond;
MSICONDITION r; MSICONDITION r;
cond.hInstall = hInstall; cond.package = package;
cond.str = szCondition; cond.str = szCondition;
cond.n = 0; cond.n = 0;
cond.result = -1; cond.result = -1;
...@@ -708,6 +709,19 @@ MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szConditi ...@@ -708,6 +709,19 @@ MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szConditi
return r; return r;
} }
MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
{
MSIPACKAGE *package;
UINT ret;
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
if( !package)
return ERROR_INVALID_HANDLE;
ret = MSI_EvaluateConditionW( package, szCondition );
msiobj_release( &package->hdr );
return ret;
}
MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
{ {
LPWSTR szwCond = NULL; LPWSTR szwCond = NULL;
......
...@@ -56,7 +56,7 @@ static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT ...@@ -56,7 +56,7 @@ static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSICREATEVIEW *cv = (MSICREATEVIEW*)view; MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
create_col_info *col; create_col_info *col;
...@@ -214,6 +214,7 @@ static UINT CREATE_delete( struct tagMSIVIEW *view ) ...@@ -214,6 +214,7 @@ static UINT CREATE_delete( struct tagMSIVIEW *view )
} }
HeapFree( GetProcessHeap(), 0, cv->name ); HeapFree( GetProcessHeap(), 0, cv->name );
HeapFree( GetProcessHeap(), 0, cv ); HeapFree( GetProcessHeap(), 0, cv );
msiobj_release( &cv->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -246,6 +247,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, ...@@ -246,6 +247,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */ /* fill the structure */
cv->view.ops = &create_ops; cv->view.ops = &create_ops;
msiobj_addref( &db->hdr );
cv->db = db; cv->db = db;
cv->name = table; /* FIXME: strdupW it? */ cv->name = table; /* FIXME: strdupW it? */
cv->col_info = col_info; cv->col_info = col_info;
......
...@@ -107,13 +107,13 @@ static UINT DISTINCT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UIN ...@@ -107,13 +107,13 @@ static UINT DISTINCT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UIN
return dv->table->ops->fetch_int( dv->table, row, col, val ); return dv->table->ops->fetch_int( dv->table, row, col, val );
} }
static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view; MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
UINT r, i, j, r_count, c_count; UINT r, i, j, r_count, c_count;
DISTINCTSET *rowset = NULL; DISTINCTSET *rowset = NULL;
TRACE("%p %ld\n", dv, record); TRACE("%p %p\n", dv, record);
if( !dv->table ) if( !dv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -242,6 +242,7 @@ static UINT DISTINCT_delete( struct tagMSIVIEW *view ) ...@@ -242,6 +242,7 @@ static UINT DISTINCT_delete( struct tagMSIVIEW *view )
if( dv->translation ) if( dv->translation )
HeapFree( GetProcessHeap(), 0, dv->translation ); HeapFree( GetProcessHeap(), 0, dv->translation );
HeapFree( GetProcessHeap(), 0, dv ); HeapFree( GetProcessHeap(), 0, dv );
msiobj_release( &dv->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -281,6 +282,7 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) ...@@ -281,6 +282,7 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
/* fill the structure */ /* fill the structure */
dv->view.ops = &distinct_ops; dv->view.ops = &distinct_ops;
msiobj_addref( &db->hdr );
dv->db = db; dv->db = db;
dv->table = table; dv->table = table;
dv->translation = NULL; dv->translation = NULL;
......
/* /*
* Implementation of the Microsoft Installer (msi.dll) * Implementation of the Microsoft Installer (msi.dll)
* *
* Copyright 2002 Mike McCormack for CodeWeavers * Copyright 2002-2004 Mike McCormack for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -31,66 +31,109 @@ ...@@ -31,66 +31,109 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
MSIHANDLEINFO *msihandletable[MSIMAXHANDLES]; static CRITICAL_SECTION MSI_handle_cs;
static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
{
0, 0, &MSI_handle_cs,
{ &MSI_handle_cs_debug.ProcessLocksList,
&MSI_handle_cs_debug.ProcessLocksList },
0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
};
static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
MSIOBJECTHDR *msihandletable[MSIMAXHANDLES];
MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy, void **out) MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
{ {
MSIHANDLEINFO *info; MSIHANDLE ret = 0;
UINT i; UINT i;
*out = NULL; EnterCriticalSection( &MSI_handle_cs );
/* find a slot */ /* find a slot */
for(i=0; i<MSIMAXHANDLES; i++) for(i=0; i<MSIMAXHANDLES; i++)
if( !msihandletable[i] ) if( !msihandletable[i] )
break; break;
if( (i>=MSIMAXHANDLES) || msihandletable[i] ) if( (i>=MSIMAXHANDLES) || msihandletable[i] )
return 0; goto out;
size += sizeof (MSIHANDLEINFO);
info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
if( !info )
return 0;
info->magic = MSIHANDLE_MAGIC;
info->type = type;
info->refcount = 1;
info->destructor = destroy;
msihandletable[i] = info; msiobj_addref( obj );
*out = (void*) &info[1]; msihandletable[i] = obj;
ret = (MSIHANDLE) (i+1);
out:
TRACE("%p -> %ld\n", obj, ret );
return (MSIHANDLE) (i+1); LeaveCriticalSection( &MSI_handle_cs );
return ret;
} }
void *msihandle2msiinfo(MSIHANDLE handle, UINT type) void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
{ {
MSIOBJECTHDR *ret = NULL;
EnterCriticalSection( &MSI_handle_cs );
handle--; handle--;
if( handle<0 ) if( handle<0 )
return NULL; goto out;
if( handle>=MSIMAXHANDLES ) if( handle>=MSIMAXHANDLES )
return NULL; goto out;
if( !msihandletable[handle] ) if( !msihandletable[handle] )
return NULL; goto out;
if( msihandletable[handle]->magic != MSIHANDLE_MAGIC ) if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
return NULL; goto out;
if( type && (msihandletable[handle]->type != type) ) if( type && (msihandletable[handle]->type != type) )
return NULL; goto out;
ret = msihandletable[handle];
msiobj_addref( ret );
out:
LeaveCriticalSection( &MSI_handle_cs );
return (void*) ret;
}
MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
{
MSIHANDLE ret = 0;
UINT i;
TRACE("%p\n", hdr);
return &msihandletable[handle][1]; EnterCriticalSection( &MSI_handle_cs );
for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
if( msihandletable[i] == hdr )
ret = i+1;
LeaveCriticalSection( &MSI_handle_cs );
TRACE("%p -> %ld\n", hdr, ret);
msiobj_addref( hdr );
return ret;
} }
void msihandle_addref(MSIHANDLE handle) void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
{ {
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0); MSIOBJECTHDR *info;
TRACE("%lx\n",handle); info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
if( info )
{
info->magic = MSIHANDLE_MAGIC;
info->type = type;
info->refcount = 1;
info->destructor = destroy;
}
return info;
}
void msiobj_addref( MSIOBJECTHDR *info )
{
TRACE("%p\n", info);
if( !info ) if( !info )
return; return;
info--;
if( info->magic != MSIHANDLE_MAGIC ) if( info->magic != MSIHANDLE_MAGIC )
{ {
ERR("Invalid handle!\n"); ERR("Invalid handle!\n");
...@@ -100,36 +143,63 @@ void msihandle_addref(MSIHANDLE handle) ...@@ -100,36 +143,63 @@ void msihandle_addref(MSIHANDLE handle)
info->refcount++; info->refcount++;
} }
UINT WINAPI MsiCloseHandle(MSIHANDLE handle) int msiobj_release( MSIOBJECTHDR *info )
{ {
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0); int ret;
TRACE("%lx\n",handle); TRACE("%p\n",info);
if( !info ) if( !info )
return ERROR_INVALID_HANDLE; return -1;
info--;
if( info->magic != MSIHANDLE_MAGIC ) if( info->magic != MSIHANDLE_MAGIC )
{ {
ERR("Invalid handle!\n"); ERR("Invalid handle!\n");
return ERROR_INVALID_HANDLE; return -1;
} }
info->refcount--; ret = info->refcount--;
if (info->refcount > 0) if (info->refcount == 0)
return ERROR_SUCCESS; {
if( info->destructor ) if( info->destructor )
info->destructor( &info[1] ); info->destructor( info );
HeapFree( GetProcessHeap(), 0, info ); HeapFree( GetProcessHeap(), 0, info );
TRACE("object %p destroyed\n", info);
}
return ret;
}
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
{
MSIOBJECTHDR *info;
UINT ret = ERROR_INVALID_HANDLE;
TRACE("%lx\n",handle);
EnterCriticalSection( &MSI_handle_cs );
info = msihandle2msiinfo(handle, 0);
if( !info )
goto out;
if( info->magic != MSIHANDLE_MAGIC )
{
ERR("Invalid handle!\n");
goto out;
}
msiobj_release( info );
msihandletable[handle-1] = NULL; msihandletable[handle-1] = NULL;
ret = ERROR_SUCCESS;
TRACE("Destroyed\n"); TRACE("handle %lx Destroyed\n", handle);
out:
LeaveCriticalSection( &MSI_handle_cs );
if( info )
msiobj_release( info );
return 0; return ret;
} }
UINT WINAPI MsiCloseAllHandles(void) UINT WINAPI MsiCloseAllHandles(void)
......
...@@ -56,13 +56,13 @@ static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT ...@@ -56,13 +56,13 @@ static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view; MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
UINT n, type, val, r, row, col_count = 0; UINT n, type, val, r, row, col_count = 0;
MSIVIEW *sv; MSIVIEW *sv;
TRACE("%p %ld\n", iv, record ); TRACE("%p %p\n", iv, record );
sv = iv->sv; sv = iv->sv;
if( !sv ) if( !sv )
...@@ -77,7 +77,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record ) ...@@ -77,7 +77,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
if( r ) if( r )
goto err; goto err;
n = MsiRecordGetFieldCount( record ); n = MSI_RecordGetFieldCount( record );
if( n != col_count ) if( n != col_count )
{ {
ERR("Number of fields do not match\n"); ERR("Number of fields do not match\n");
...@@ -103,7 +103,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record ) ...@@ -103,7 +103,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
} }
else else
{ {
val = MsiRecordGetInteger( record, n ); val = MSI_RecordGetInteger( record, n );
val |= 0x8000; val |= 0x8000;
} }
r = sv->ops->set_int( sv, row, n, val ); r = sv->ops->set_int( sv, row, n, val );
...@@ -180,6 +180,7 @@ static UINT INSERT_delete( struct tagMSIVIEW *view ) ...@@ -180,6 +180,7 @@ static UINT INSERT_delete( struct tagMSIVIEW *view )
sv->ops->delete( sv ); sv->ops->delete( sv );
delete_value_list( iv->vals ); delete_value_list( iv->vals );
HeapFree( GetProcessHeap(), 0, iv ); HeapFree( GetProcessHeap(), 0, iv );
msiobj_release( &iv->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -226,6 +227,7 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, ...@@ -226,6 +227,7 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */ /* fill the structure */
iv->view.ops = &insert_ops; iv->view.ops = &insert_ops;
msiobj_addref( &db->hdr );
iv->db = db; iv->db = db;
iv->vals = values; iv->vals = values;
iv->bIsTemp = temp; iv->bIsTemp = temp;
......
/* /*
* Implementation of the Microsoft Installer (msi.dll) * Implementation of the Microsoft Installer (msi.dll)
* *
* Copyright 2002,2003 Mike McCormack for CodeWeavers * Copyright 2002,2003,2004 Mike McCormack for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -222,7 +222,7 @@ BOOL encode_base85_guid( GUID *guid, LPWSTR str ) ...@@ -222,7 +222,7 @@ BOOL encode_base85_guid( GUID *guid, LPWSTR str )
} }
VOID MSI_CloseDatabase( VOID *arg ) VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{ {
MSIDATABASE *db = (MSIDATABASE *) arg; MSIDATABASE *db = (MSIDATABASE *) arg;
...@@ -230,58 +230,18 @@ VOID MSI_CloseDatabase( VOID *arg ) ...@@ -230,58 +230,18 @@ VOID MSI_CloseDatabase( VOID *arg )
IStorage_Release( db->storage ); IStorage_Release( db->storage );
} }
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB) UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
HRESULT r = ERROR_FUNCTION_FAILED;
LPWSTR szwDBPath = NULL, szwPersist = NULL;
UINT len;
TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
if( szDBPath )
{
len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwDBPath )
goto end;
MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
}
if( HIWORD(szPersist) )
{
len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwPersist )
goto end;
MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
}
else
szwPersist = (LPWSTR) szPersist;
r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
end:
if( szwPersist )
HeapFree( GetProcessHeap(), 0, szwPersist );
if( szwDBPath )
HeapFree( GetProcessHeap(), 0, szwDBPath );
return r;
}
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
{ {
IStorage *stg = NULL; IStorage *stg = NULL;
HRESULT r; HRESULT r;
MSIHANDLE handle; MSIDATABASE *db = NULL;
MSIDATABASE *db; UINT ret = ERROR_FUNCTION_FAILED;
UINT ret;
LPWSTR szMode; LPWSTR szMode;
STATSTG stat; STATSTG stat;
TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB); TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
if( !phDB ) if( !pdb )
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
szMode = (LPWSTR) szPersist; szMode = (LPWSTR) szPersist;
...@@ -328,7 +288,6 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD ...@@ -328,7 +288,6 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
if( FAILED( r ) ) if( FAILED( r ) )
{ {
FIXME("Failed to stat storage\n"); FIXME("Failed to stat storage\n");
ret = ERROR_FUNCTION_FAILED;
goto end; goto end;
} }
...@@ -336,17 +295,15 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD ...@@ -336,17 +295,15 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
{ {
ERR("storage GUID is not a MSI database GUID %s\n", ERR("storage GUID is not a MSI database GUID %s\n",
debugstr_guid(&stat.clsid) ); debugstr_guid(&stat.clsid) );
ret = ERROR_FUNCTION_FAILED;
goto end; goto end;
} }
handle = alloc_msihandle( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE), db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase, (void**) &db ); MSI_CloseDatabase );
if( !handle ) if( !db )
{ {
FIXME("Failed to allocate a handle\n"); FIXME("Failed to allocate a handle\n");
ret = ERROR_FUNCTION_FAILED;
goto end; goto end;
} }
...@@ -355,24 +312,80 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD ...@@ -355,24 +312,80 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
db->storage = stg; db->storage = stg;
db->mode = szMode; db->mode = szMode;
/* db->strings = NULL;
db->first_table = NULL;
db->last_table = NULL; */
ret = load_string_table( db ); ret = load_string_table( db );
if( ret != ERROR_SUCCESS ) if( ret != ERROR_SUCCESS )
goto end; goto end;
*phDB = handle; msiobj_addref( &db->hdr );
IStorage_AddRef( stg ); IStorage_AddRef( stg );
*pdb = db;
end: end:
if( db )
msiobj_release( &db->hdr );
if( stg ) if( stg )
IStorage_Release( stg ); IStorage_Release( stg );
return ret; return ret;
} }
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
{
MSIDATABASE *db;
UINT ret;
TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
if( ret == ERROR_SUCCESS )
{
*phDB = alloc_msihandle( &db->hdr );
msiobj_release( &db->hdr );
}
return ret;
}
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
{
HRESULT r = ERROR_FUNCTION_FAILED;
LPWSTR szwDBPath = NULL, szwPersist = NULL;
UINT len;
TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
if( szDBPath )
{
len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwDBPath )
goto end;
MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
}
if( HIWORD(szPersist) )
{
len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwPersist )
goto end;
MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
}
else
szwPersist = (LPWSTR) szPersist;
r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
end:
if( szwPersist )
HeapFree( GetProcessHeap(), 0, szwPersist );
if( szwDBPath )
HeapFree( GetProcessHeap(), 0, szwDBPath );
return r;
}
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct) UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{ {
UINT len, ret; UINT len, ret;
...@@ -525,8 +538,9 @@ end: ...@@ -525,8 +538,9 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine) UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{ {
MSIHANDLE packagehandle; MSIPACKAGE *package = NULL;
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
MSIHANDLE handle;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine)); FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
...@@ -534,13 +548,16 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine) ...@@ -534,13 +548,16 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
rc = MsiOpenPackageW(szPackagePath,&packagehandle); rc = MSI_OpenPackageW(szPackagePath,&package);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
ACTION_DoTopLevelINSTALL(packagehandle, szPackagePath, szCommandLine); handle = alloc_msihandle( &package->hdr );
rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
MsiCloseHandle(packagehandle); MsiCloseHandle(handle);
msiobj_release( &package->hdr );
return rc; return rc;
} }
......
...@@ -43,15 +43,58 @@ typedef struct tagMSITABLE MSITABLE; ...@@ -43,15 +43,58 @@ typedef struct tagMSITABLE MSITABLE;
struct string_table; struct string_table;
typedef struct string_table string_table; typedef struct string_table string_table;
struct tagMSIOBJECTHDR;
typedef struct tagMSIOBJECTHDR MSIOBJECTHDR;
typedef VOID (*msihandledestructor)( MSIOBJECTHDR * );
struct tagMSIOBJECTHDR
{
UINT magic;
UINT type;
UINT refcount;
msihandledestructor destructor;
struct tagMSIOBJECTHDR *next;
struct tagMSIOBJECTHDR *prev;
};
typedef struct tagMSIDATABASE typedef struct tagMSIDATABASE
{ {
MSIOBJECTHDR hdr;
IStorage *storage; IStorage *storage;
string_table *strings; string_table *strings;
LPWSTR mode; LPWSTR mode;
MSITABLE *first_table, *last_table; MSITABLE *first_table, *last_table;
} MSIDATABASE; } MSIDATABASE;
struct tagMSIVIEW; typedef struct tagMSIVIEW MSIVIEW;
typedef struct tagMSIQUERY
{
MSIOBJECTHDR hdr;
MSIVIEW *view;
UINT row;
MSIDATABASE *db;
} MSIQUERY;
/* maybe we can use a Variant instead of doing it ourselves? */
typedef struct tagMSIFIELD
{
UINT type;
union
{
INT iVal;
LPWSTR szwVal;
IStream *stream;
} u;
} MSIFIELD;
typedef struct tagMSIRECORD
{
MSIOBJECTHDR hdr;
UINT count; /* as passed to MsiCreateRecord */
MSIFIELD fields[1]; /* nb. array size is count+1 */
} MSIRECORD;
typedef struct tagMSIVIEWOPS typedef struct tagMSIVIEWOPS
{ {
...@@ -90,7 +133,7 @@ typedef struct tagMSIVIEWOPS ...@@ -90,7 +133,7 @@ typedef struct tagMSIVIEWOPS
/* /*
* execute - loads the underlying data into memory so it can be read * execute - loads the underlying data into memory so it can be read
*/ */
UINT (*execute)( struct tagMSIVIEW *, MSIHANDLE ); UINT (*execute)( struct tagMSIVIEW *, MSIRECORD * );
/* /*
* close - clears the data read by execute from memory * close - clears the data read by execute from memory
...@@ -126,31 +169,22 @@ typedef struct tagMSIVIEWOPS ...@@ -126,31 +169,22 @@ typedef struct tagMSIVIEWOPS
} MSIVIEWOPS; } MSIVIEWOPS;
typedef struct tagMSIVIEW
{
MSIVIEWOPS *ops;
} MSIVIEW;
typedef struct tagMSISUMMARYINFO typedef struct tagMSISUMMARYINFO
{ {
MSIOBJECTHDR hdr;
IPropertyStorage *propstg; IPropertyStorage *propstg;
} MSISUMMARYINFO; } MSISUMMARYINFO;
typedef VOID (*msihandledestructor)( VOID * ); struct tagMSIVIEW
typedef struct tagMSIHANDLEINFO
{ {
UINT magic; MSIOBJECTHDR hdr;
UINT type; MSIVIEWOPS *ops;
UINT refcount; };
msihandledestructor destructor;
struct tagMSIHANDLEINFO *next;
struct tagMSIHANDLEINFO *prev;
} MSIHANDLEINFO;
typedef struct tagMSIPACKAGE typedef struct tagMSIPACKAGE
{ {
MSIHANDLE db; MSIOBJECTHDR hdr;
MSIDATABASE *db;
struct tagMSIFEATURE *features; struct tagMSIFEATURE *features;
UINT loaded_features; UINT loaded_features;
struct tagMSIFOLDER *folders; struct tagMSIFOLDER *folders;
...@@ -186,10 +220,14 @@ DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0 ...@@ -186,10 +220,14 @@ DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0
DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy, void **out); /* handle functions */
void msihandle_addref(MSIHANDLE handle); extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
extern void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy );
extern void msiobj_addref(MSIOBJECTHDR *);
extern int msiobj_release(MSIOBJECTHDR *);
extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
/* add this table to the list of cached tables in the database */ /* add this table to the list of cached tables in the database */
extern void add_table(MSIDATABASE *db, MSITABLE *table); extern void add_table(MSIDATABASE *db, MSITABLE *table);
...@@ -222,27 +260,53 @@ extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id ); ...@@ -222,27 +260,53 @@ extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id );
extern UINT msi_string_get_codepage( string_table *st ); extern UINT msi_string_get_codepage( string_table *st );
UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n ); extern UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n );
extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname, extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
USHORT **pdata, UINT *psz ); USHORT **pdata, UINT *psz );
UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath, extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
LPCWSTR szCommandLine); extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
void ACTION_remove_tracked_tempfiles(MSIPACKAGE* hPackage);
/* record internals */ /* record internals */
extern UINT WINAPI MSI_RecordSetIStream( MSIHANDLE handle, extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
unsigned int iField, IStream *stm ); extern const WCHAR *MSI_RecordGetString( MSIRECORD *, unsigned int );
extern const WCHAR *MSI_RecordGetString( MSIHANDLE handle, unsigned int iField ); extern MSIRECORD *MSI_CreateRecord( unsigned int );
extern UINT MSI_RecordSetInteger( MSIRECORD *, unsigned int, int );
extern UINT MSI_RecordSetStringW( MSIRECORD *, unsigned int, LPCWSTR );
extern BOOL MSI_RecordIsNull( MSIRECORD *, unsigned int );
extern UINT MSI_RecordGetStringW( MSIRECORD * , unsigned int, LPWSTR, DWORD *);
extern int MSI_RecordGetInteger( MSIRECORD *, unsigned int );
extern UINT MSI_RecordReadStream( MSIRECORD *, unsigned int, char *, DWORD *);
extern unsigned int MSI_RecordGetFieldCount( MSIRECORD *rec );
/* stream internals */ /* stream internals */
extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm ); extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ); extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
extern void enum_stream_names( IStorage *stg ); extern void enum_stream_names( IStorage *stg );
/* database internals */
extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** );
extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
/* view internals */
extern UINT MSI_ViewExecute( MSIQUERY*, MSIRECORD * );
extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
extern UINT MSI_ViewClose( MSIQUERY* );
/* package internals */
extern UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE ** );
extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR);
extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD* );
extern UINT MSI_GetPropertyW( MSIPACKAGE *, LPCWSTR, LPWSTR, DWORD*);
extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR );
extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern UINT MSI_GetComponentStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
extern UINT MSI_GetFeatureStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
/* registry data encoding/decoding functions */
BOOL unsquash_guid(LPCWSTR in, LPWSTR out); BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
BOOL squash_guid(LPCWSTR in, LPWSTR out); BOOL squash_guid(LPCWSTR in, LPWSTR out);
BOOL encode_base85_guid(GUID *,LPWSTR); BOOL encode_base85_guid(GUID *,LPWSTR);
......
/* /*
* Implementation of the Microsoft Installer (msi.dll) * Implementation of the Microsoft Installer (msi.dll)
* *
* Copyright 2002 Mike McCormack for CodeWeavers * Copyright 2002-2004 Mike McCormack for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -36,12 +36,15 @@ ...@@ -36,12 +36,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
#if 0
typedef struct tagMSIQUERY typedef struct tagMSIQUERY
{ {
MSIOBJECTHDR hdr;
MSIVIEW *view; MSIVIEW *view;
UINT row; UINT row;
MSIDATABASE *db; MSIDATABASE *db;
} MSIQUERY; } MSIQUERY;
#endif
UINT WINAPI MsiDatabaseIsTablePersistentA( UINT WINAPI MsiDatabaseIsTablePersistentA(
MSIHANDLE hDatabase, LPSTR szTableName) MSIHANDLE hDatabase, LPSTR szTableName)
...@@ -57,12 +60,13 @@ UINT WINAPI MsiDatabaseIsTablePersistentW( ...@@ -57,12 +60,13 @@ UINT WINAPI MsiDatabaseIsTablePersistentW(
return ERROR_CALL_NOT_IMPLEMENTED; return ERROR_CALL_NOT_IMPLEMENTED;
} }
void MSI_CloseView( VOID *arg ) void MSI_CloseView( MSIOBJECTHDR *arg )
{ {
MSIQUERY *query = arg; MSIQUERY *query = (MSIQUERY*) arg;
if( query->view && query->view->ops->delete ) if( query->view && query->view->ops->delete )
query->view->ops->delete( query->view ); query->view->ops->delete( query->view );
msiobj_release( &query->db->hdr );
} }
UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n ) UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
...@@ -118,57 +122,71 @@ UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, ...@@ -118,57 +122,71 @@ UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
return r; return r;
} }
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
LPCWSTR szQuery, MSIHANDLE *phView) LPCWSTR szQuery, MSIQUERY **pView)
{ {
MSIDATABASE *db;
MSIHANDLE handle;
MSIQUERY *query; MSIQUERY *query;
UINT r; UINT r;
TRACE("%s %p\n", debugstr_w(szQuery), phView); TRACE("%s %p\n", debugstr_w(szQuery), pView);
if( !szQuery) if( !szQuery)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
/* pre allocate a handle to hold a pointer to the view */ /* pre allocate a handle to hold a pointer to the view */
handle = alloc_msihandle( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY), query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
MSI_CloseView, (void**) &query ); MSI_CloseView );
if( !handle ) if( !query )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
msiobj_addref( &db->hdr );
query->row = 0; query->row = 0;
query->db = db; query->db = db;
query->view = NULL; query->view = NULL;
r = MSI_ParseSQL( db, szQuery, &query->view ); r = MSI_ParseSQL( db, szQuery, &query->view );
if( r != ERROR_SUCCESS ) if( r == ERROR_SUCCESS )
{ {
MsiCloseHandle( handle ); msiobj_addref( &query->hdr );
return r; *pView = query;
} }
*phView = handle; msiobj_release( &query->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
LPCWSTR szQuery, MSIHANDLE *phView)
{
MSIDATABASE *db;
MSIQUERY *query = NULL;
UINT ret;
TRACE("%s %p\n", debugstr_w(szQuery), phView);
db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
if( ret == ERROR_SUCCESS )
{
*phView = alloc_msihandle( &query->hdr );
msiobj_release( &query->hdr );
}
msiobj_release( &db->hdr );
return ret;
}
UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
{ {
MSIQUERY *query;
MSIVIEW *view; MSIVIEW *view;
MSIHANDLE handle; MSIRECORD *rec;
UINT row_count = 0, col_count = 0, i, ival, ret, type; UINT row_count = 0, col_count = 0, i, ival, ret, type;
TRACE("%ld %p\n", hView, record); TRACE("%p %p\n", query, prec );
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query )
return ERROR_INVALID_HANDLE;
view = query->view; view = query->view;
if( !view ) if( !view )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -182,8 +200,8 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) ...@@ -182,8 +200,8 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
if( query->row >= row_count ) if( query->row >= row_count )
return ERROR_NO_MORE_ITEMS; return ERROR_NO_MORE_ITEMS;
handle = MsiCreateRecord( col_count ); rec = MSI_CreateRecord( col_count );
if( !handle ) if( !rec )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
for( i=1; i<=col_count; i++ ) for( i=1; i<=col_count; i++ )
...@@ -215,25 +233,25 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) ...@@ -215,25 +233,25 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
LPWSTR sval; LPWSTR sval;
sval = MSI_makestring( query->db, ival ); sval = MSI_makestring( query->db, ival );
MsiRecordSetStringW( handle, i, sval ); MSI_RecordSetStringW( rec, i, sval );
HeapFree( GetProcessHeap(), 0, sval ); HeapFree( GetProcessHeap(), 0, sval );
} }
else else
{ {
if( (type & MSI_DATASIZEMASK) == 2 ) if( (type & MSI_DATASIZEMASK) == 2 )
MsiRecordSetInteger( handle, i, ival - (1<<15) ); MSI_RecordSetInteger( rec, i, ival - (1<<15) );
else else
MsiRecordSetInteger( handle, i, ival - (1<<31) ); MSI_RecordSetInteger( rec, i, ival - (1<<31) );
} }
} }
else else
{ {
IStream *stm; IStream *stm = NULL;
ret = view->ops->fetch_stream( view, query->row, i, &stm ); ret = view->ops->fetch_stream( view, query->row, i, &stm );
if( ( ret == ERROR_SUCCESS ) && stm ) if( ( ret == ERROR_SUCCESS ) && stm )
{ {
MSI_RecordSetIStream( handle, i, stm ); MSI_RecordSetIStream( rec, i, stm );
IStream_Release( stm ); IStream_Release( stm );
} }
else else
...@@ -242,21 +260,37 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) ...@@ -242,21 +260,37 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
} }
query->row ++; query->row ++;
*record = handle; *prec = rec;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
UINT WINAPI MsiViewClose(MSIHANDLE hView) UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
{ {
MSIQUERY *query; MSIQUERY *query;
MSIVIEW *view; MSIRECORD *rec = NULL;
UINT ret;
TRACE("%ld\n", hView ); TRACE("%ld %p\n", hView, record);
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW ); query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query ) if( !query )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
ret = MSI_ViewFetch( query, &rec );
if( ret == ERROR_SUCCESS )
{
*record = alloc_msihandle( &rec->hdr );
msiobj_release( &rec->hdr );
}
msiobj_release( &query->hdr );
return ret;
}
UINT MSI_ViewClose(MSIQUERY *query)
{
MSIVIEW *view;
TRACE("%p\n", query );
view = query->view; view = query->view;
if( !view ) if( !view )
...@@ -267,17 +301,28 @@ UINT WINAPI MsiViewClose(MSIHANDLE hView) ...@@ -267,17 +301,28 @@ UINT WINAPI MsiViewClose(MSIHANDLE hView)
return view->ops->close( view ); return view->ops->close( view );
} }
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec) UINT WINAPI MsiViewClose(MSIHANDLE hView)
{ {
MSIQUERY *query; MSIQUERY *query;
MSIVIEW *view; UINT ret;
TRACE("%ld %ld\n", hView, hRec); TRACE("%ld\n", hView );
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW ); query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query ) if( !query )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
ret = MSI_ViewClose( query );
msiobj_release( &query->hdr );
return ret;
}
UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec )
{
MSIVIEW *view;
TRACE("%p %p\n", query, rec);
view = query->view; view = query->view;
if( !view ) if( !view )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -285,7 +330,39 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec) ...@@ -285,7 +330,39 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
query->row = 0; query->row = 0;
return view->ops->execute( view, hRec ); return view->ops->execute( view, rec );
}
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
{
MSIQUERY *query;
MSIRECORD *rec = NULL;
UINT ret;
TRACE("%ld %ld\n", hView, hRec);
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query )
return ERROR_INVALID_HANDLE;
if( hRec )
{
rec = msihandle2msiinfo( hRec, MSIHANDLETYPE_RECORD );
if( !rec )
{
ret = ERROR_INVALID_HANDLE;
goto out;
}
}
ret = MSI_ViewExecute( query, rec );
out:
if( query )
msiobj_release( &query->hdr );
if( rec )
msiobj_release( &rec->hdr );
return ret;
} }
UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec) UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
......
...@@ -142,12 +142,12 @@ static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * ...@@ -142,12 +142,12 @@ static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return ov->table->ops->fetch_int( ov->table, row, col, val ); return ov->table->ops->fetch_int( ov->table, row, col, val );
} }
static UINT ORDER_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIORDERVIEW *ov = (MSIORDERVIEW*)view; MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
UINT r, num_rows = 0, i; UINT r, num_rows = 0, i;
TRACE("%p %ld\n", ov, record); TRACE("%p %p\n", ov, record);
if( !ov->table ) if( !ov->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -245,6 +245,7 @@ static UINT ORDER_delete( struct tagMSIVIEW *view ) ...@@ -245,6 +245,7 @@ static UINT ORDER_delete( struct tagMSIVIEW *view )
ov->reorder = NULL; ov->reorder = NULL;
HeapFree( GetProcessHeap(), 0, ov ); HeapFree( GetProcessHeap(), 0, ov );
msiobj_release( &ov->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -285,6 +286,7 @@ UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) ...@@ -285,6 +286,7 @@ UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
/* fill the structure */ /* fill the structure */
ov->view.ops = &order_ops; ov->view.ops = &order_ops;
msiobj_addref( &db->hdr );
ov->db = db; ov->db = db;
ov->table = table; ov->table = table;
ov->reorder = NULL; ov->reorder = NULL;
......
...@@ -111,11 +111,11 @@ static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *num ) ...@@ -111,11 +111,11 @@ static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *num )
return sv->table->ops->insert_row( sv->table, num ); return sv->table->ops->insert_row( sv->table, num );
} }
static UINT SELECT_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
TRACE("%p %ld\n", sv, record); TRACE("%p %p\n", sv, record);
if( !sv->table ) if( !sv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
......
...@@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); ...@@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y', static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
'I','n','f','o','r','m','a','t','i','o','n',0 }; 'I','n','f','o','r','m','a','t','i','o','n',0 };
static void MSI_CloseSummaryInfo( VOID *arg ) static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
{ {
MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg; MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg;
IPropertyStorage_Release( suminfo->propstg ); IPropertyStorage_Release( suminfo->propstg );
...@@ -74,7 +74,7 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, ...@@ -74,7 +74,7 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo) LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
{ {
HRESULT r; HRESULT r;
MSIHANDLE handle, hdb = hDatabase; MSIHANDLE handle;
MSISUMMARYINFO *suminfo; MSISUMMARYINFO *suminfo;
MSIDATABASE *db; MSIDATABASE *db;
UINT ret = ERROR_SUCCESS; UINT ret = ERROR_SUCCESS;
...@@ -92,20 +92,24 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, ...@@ -92,20 +92,24 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
{ {
UINT res; UINT res;
res = MsiOpenDatabaseW(szDatabase, NULL, &hdb); res = MSI_OpenDatabaseW(szDatabase, NULL, &db);
if( res != ERROR_SUCCESS ) if( res != ERROR_SUCCESS )
return res; return res;
} }
else
db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE); {
if( !db ) db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
return ERROR_INVALID_PARAMETER; if( !db )
return ERROR_INVALID_PARAMETER;
}
r = IStorage_QueryInterface( db->storage, r = IStorage_QueryInterface( db->storage,
&IID_IPropertySetStorage, (LPVOID)&psstg); &IID_IPropertySetStorage, (LPVOID)&psstg);
if( FAILED( r ) ) if( FAILED( r ) )
{ {
ERR("IStorage -> IPropertySetStorage failed\n"); ERR("IStorage -> IPropertySetStorage failed\n");
if (db)
msiobj_release(&db->hdr);
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg); ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
...@@ -119,10 +123,9 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, ...@@ -119,10 +123,9 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
goto end; goto end;
} }
handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO, suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo, sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
(void**) &suminfo ); if( !suminfo )
if( !handle )
{ {
ret = ERROR_FUNCTION_FAILED; ret = ERROR_FUNCTION_FAILED;
goto end; goto end;
...@@ -130,15 +133,20 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, ...@@ -130,15 +133,20 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
IPropertyStorage_AddRef(ps); IPropertyStorage_AddRef(ps);
suminfo->propstg = ps; suminfo->propstg = ps;
handle = alloc_msihandle( &suminfo->hdr );
if( handle )
*phSummaryInfo = handle; *phSummaryInfo = handle;
else
ret = ERROR_FUNCTION_FAILED;
msiobj_release( &suminfo->hdr );
end: end:
if( ps ) if( ps )
IPropertyStorage_Release(ps); IPropertyStorage_Release(ps);
if( psstg ) if( psstg )
IPropertySetStorage_Release(psstg); IPropertySetStorage_Release(psstg);
if( !hDatabase ) if (db)
MsiCloseHandle( hdb ); msiobj_release(&db->hdr);
return ret; return ret;
} }
......
...@@ -288,18 +288,7 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) ...@@ -288,18 +288,7 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/* FIXME: we should be passing around pointers to db structures internally */ UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm )
{
MSIDATABASE *db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE );
if ( !db )
return ERROR_INVALID_HANDLE;
return db_get_raw_stream( db, stname, stm );
}
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
USHORT **pdata, UINT *psz ) USHORT **pdata, UINT *psz )
{ {
HRESULT r; HRESULT r;
...@@ -309,10 +298,9 @@ UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname, ...@@ -309,10 +298,9 @@ UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
IStream *stm = NULL; IStream *stm = NULL;
STATSTG stat; STATSTG stat;
r = get_raw_stream( hdb, stname, &stm ); r = db_get_raw_stream( db, stname, &stm );
if( r != ERROR_SUCCESS) if( r != ERROR_SUCCESS)
goto end; return ret;
ret = ERROR_FUNCTION_FAILED;
r = IStream_Stat(stm, &stat, STATFLAG_NONAME ); r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) ) if( FAILED( r ) )
{ {
...@@ -1114,6 +1102,9 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt ...@@ -1114,6 +1102,9 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT ival = 0, refcol = 0, r; UINT ival = 0, refcol = 0, r;
LPWSTR sval; LPWSTR sval;
LPWSTR full_name;
DWORD len;
static const WCHAR szDot[] = { '.', 0 };
if( !view->ops->fetch_int ) if( !view->ops->fetch_int )
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
...@@ -1138,22 +1129,16 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt ...@@ -1138,22 +1129,16 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
if( !sval ) if( !sval )
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
{ len = strlenW( tv->name ) + 2 + strlenW( sval );
LPWSTR full_name; full_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
DWORD len; strcpyW( full_name, tv->name );
static const WCHAR szDot[] = { '.', 0 }; strcatW( full_name, szDot );
strcatW( full_name, sval );
len = strlenW( tv->name ) + 2 + strlenW( sval );
full_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); r = db_get_raw_stream( tv->db, full_name, stm );
strcpyW( full_name, tv->name ); if( r )
strcatW( full_name, szDot ); ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
strcatW( full_name, sval ); HeapFree( GetProcessHeap(), 0, full_name );
r = db_get_raw_stream( tv->db, full_name, stm );
if( r )
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
HeapFree( GetProcessHeap(), 0, full_name );
}
HeapFree( GetProcessHeap(), 0, sval ); HeapFree( GetProcessHeap(), 0, sval );
return r; return r;
...@@ -1228,12 +1213,12 @@ UINT TABLE_insert_row( struct tagMSIVIEW *view, UINT *num ) ...@@ -1228,12 +1213,12 @@ UINT TABLE_insert_row( struct tagMSIVIEW *view, UINT *num )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT TABLE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT TABLE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT r; UINT r;
TRACE("%p %ld\n", tv, record); TRACE("%p %p\n", tv, record);
if( tv->table ) if( tv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
......
...@@ -55,13 +55,13 @@ static UINT UPDATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT ...@@ -55,13 +55,13 @@ static UINT UPDATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view; MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
UINT n, type, val, r, row, col_count = 0, row_count = 0; UINT n, type, val, r, row, col_count = 0, row_count = 0;
MSIVIEW *wv; MSIVIEW *wv;
TRACE("%p %ld\n", uv, record ); TRACE("%p %p\n", uv, record );
if( !record ) if( !record )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -94,7 +94,7 @@ static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) ...@@ -94,7 +94,7 @@ static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIHANDLE record )
} }
else else
{ {
val = MsiRecordGetInteger( record, n ); val = MSI_RecordGetInteger( record, n );
val |= 0x8000; val |= 0x8000;
} }
r = wv->ops->set_int( wv, row, n, val ); r = wv->ops->set_int( wv, row, n, val );
...@@ -172,6 +172,7 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view ) ...@@ -172,6 +172,7 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view )
wv->ops->delete( wv ); wv->ops->delete( wv );
delete_value_list( uv->vals ); delete_value_list( uv->vals );
HeapFree( GetProcessHeap(), 0, uv ); HeapFree( GetProcessHeap(), 0, uv );
msiobj_release( &uv->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -228,6 +229,7 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, ...@@ -228,6 +229,7 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */ /* fill the structure */
uv->view.ops = &update_ops; uv->view.ops = &update_ops;
msiobj_addref( &db->hdr );
uv->db = db; uv->db = db;
uv->vals = list->val_list; uv->vals = list->val_list;
uv->wv = sv; uv->wv = sv;
......
...@@ -131,7 +131,7 @@ static UINT INT_evaluate( UINT lval, UINT op, UINT rval ) ...@@ -131,7 +131,7 @@ static UINT INT_evaluate( UINT lval, UINT op, UINT rval )
} }
static const WCHAR *STRING_evaluate( string_table *st, static const WCHAR *STRING_evaluate( string_table *st,
MSIVIEW *table, UINT row, struct expr *expr, MSIHANDLE record ) MSIVIEW *table, UINT row, struct expr *expr, MSIRECORD *record )
{ {
UINT val = 0, r; UINT val = 0, r;
...@@ -157,7 +157,7 @@ static const WCHAR *STRING_evaluate( string_table *st, ...@@ -157,7 +157,7 @@ static const WCHAR *STRING_evaluate( string_table *st,
} }
static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row, static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row,
struct expr *cond, UINT *val, MSIHANDLE record ) struct expr *cond, UINT *val, MSIRECORD *record )
{ {
int sr; int sr;
const WCHAR *l_str, *r_str; const WCHAR *l_str, *r_str;
...@@ -181,7 +181,7 @@ static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row, ...@@ -181,7 +181,7 @@ static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row,
} }
static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row, static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
struct expr *cond, UINT *val, MSIHANDLE record ) struct expr *cond, UINT *val, MSIRECORD *record )
{ {
UINT r, lval, rval; UINT r, lval, rval;
...@@ -211,7 +211,7 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row, ...@@ -211,7 +211,7 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
return STRCMP_Evaluate( db->strings, table, row, cond, val, record ); return STRCMP_Evaluate( db->strings, table, row, cond, val, record );
case EXPR_WILDCARD: case EXPR_WILDCARD:
*val = MsiRecordGetInteger( record, 1 ); *val = MSI_RecordGetInteger( record, 1 );
return ERROR_SUCCESS; return ERROR_SUCCESS;
default: default:
...@@ -223,13 +223,13 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row, ...@@ -223,13 +223,13 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
} }
static UINT WHERE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
UINT count = 0, r, val, i; UINT count = 0, r, val, i;
MSIVIEW *table = wv->table; MSIVIEW *table = wv->table;
TRACE("%p %ld\n", wv, record); TRACE("%p %p\n", wv, record);
if( !table ) if( !table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
...@@ -337,6 +337,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view ) ...@@ -337,6 +337,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view )
delete_expr( wv->cond ); delete_expr( wv->cond );
HeapFree( GetProcessHeap(), 0, wv ); HeapFree( GetProcessHeap(), 0, wv );
msiobj_release( &wv->db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -458,6 +459,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, ...@@ -458,6 +459,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
/* fill the structure */ /* fill the structure */
wv->view.ops = &where_ops; wv->view.ops = &where_ops;
msiobj_addref( &db->hdr );
wv->db = db; wv->db = db;
wv->table = table; wv->table = table;
wv->row_count = 0; wv->row_count = 0;
......
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