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 @@
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#define YYLEX_PARAM info
#define YYPARSE_PARAM info
......@@ -43,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
typedef struct tag_yyinput
{
MSIHANDLE hInstall;
MSIPACKAGE *package;
LPCWSTR str;
INT n;
MSICONDITION result;
......@@ -408,7 +409,7 @@ symbol_i:
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
MSI_GetComponentStateW(cond->package, $2, &install, &action );
$$ = action;
HeapFree( GetProcessHeap(), 0, $2 );
}
......@@ -417,7 +418,7 @@ symbol_i:
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
MSI_GetComponentStateW(cond->package, $2, &install, &action );
$$ = install;
HeapFree( GetProcessHeap(), 0, $2 );
}
......@@ -426,7 +427,7 @@ symbol_i:
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
MSI_GetFeatureStateW(cond->package, $2, &install, &action );
$$ = action;
HeapFree( GetProcessHeap(), 0, $2 );
}
......@@ -435,7 +436,7 @@ symbol_i:
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
MSI_GetFeatureStateW(cond->package, $2, &install, &action );
$$ = install;
HeapFree( GetProcessHeap(), 0, $2 );
}
......@@ -451,7 +452,7 @@ symbol_s:
/* Lookup the identifier */
sz=0x100;
if (MsiGetPropertyW(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
if (MSI_GetPropertyW(cond->package,$1,$$,&sz) != ERROR_SUCCESS)
{
$$[0]=0;
}
......@@ -687,12 +688,12 @@ static int COND_error(char *str)
return 0;
}
MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
{
COND_input cond;
MSICONDITION r;
cond.hInstall = hInstall;
cond.package = package;
cond.str = szCondition;
cond.n = 0;
cond.result = -1;
......@@ -708,6 +709,19 @@ MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szConditi
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 )
{
LPWSTR szwCond = NULL;
......
......@@ -56,7 +56,7 @@ static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
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;
create_col_info *col;
......@@ -214,6 +214,7 @@ static UINT CREATE_delete( struct tagMSIVIEW *view )
}
HeapFree( GetProcessHeap(), 0, cv->name );
HeapFree( GetProcessHeap(), 0, cv );
msiobj_release( &cv->db->hdr );
return ERROR_SUCCESS;
}
......@@ -246,6 +247,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */
cv->view.ops = &create_ops;
msiobj_addref( &db->hdr );
cv->db = db;
cv->name = table; /* FIXME: strdupW it? */
cv->col_info = col_info;
......
......@@ -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 );
}
static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
UINT r, i, j, r_count, c_count;
DISTINCTSET *rowset = NULL;
TRACE("%p %ld\n", dv, record);
TRACE("%p %p\n", dv, record);
if( !dv->table )
return ERROR_FUNCTION_FAILED;
......@@ -242,6 +242,7 @@ static UINT DISTINCT_delete( struct tagMSIVIEW *view )
if( dv->translation )
HeapFree( GetProcessHeap(), 0, dv->translation );
HeapFree( GetProcessHeap(), 0, dv );
msiobj_release( &dv->db->hdr );
return ERROR_SUCCESS;
}
......@@ -281,6 +282,7 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
/* fill the structure */
dv->view.ops = &distinct_ops;
msiobj_addref( &db->hdr );
dv->db = db;
dv->table = table;
dv->translation = NULL;
......
/*
* 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
* modify it under the terms of the GNU Lesser General Public
......@@ -31,66 +31,109 @@
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;
*out = NULL;
EnterCriticalSection( &MSI_handle_cs );
/* find a slot */
for(i=0; i<MSIMAXHANDLES; i++)
if( !msihandletable[i] )
break;
if( (i>=MSIMAXHANDLES) || msihandletable[i] )
return 0;
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;
goto out;
msihandletable[i] = info;
*out = (void*) &info[1];
msiobj_addref( obj );
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)
{
MSIOBJECTHDR *ret = NULL;
EnterCriticalSection( &MSI_handle_cs );
handle--;
if( handle<0 )
return NULL;
goto out;
if( handle>=MSIMAXHANDLES )
return NULL;
goto out;
if( !msihandletable[handle] )
return NULL;
goto out;
if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
return NULL;
goto out;
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 )
return;
info--;
if( info->magic != MSIHANDLE_MAGIC )
{
ERR("Invalid handle!\n");
......@@ -100,36 +143,63 @@ void msihandle_addref(MSIHANDLE handle)
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 )
return ERROR_INVALID_HANDLE;
info--;
return -1;
if( info->magic != MSIHANDLE_MAGIC )
{
ERR("Invalid handle!\n");
return ERROR_INVALID_HANDLE;
return -1;
}
info->refcount--;
if (info->refcount > 0)
return ERROR_SUCCESS;
ret = info->refcount--;
if (info->refcount == 0)
{
if( info->destructor )
info->destructor( &info[1] );
info->destructor( 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;
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)
......
......@@ -56,13 +56,13 @@ static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
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;
UINT n, type, val, r, row, col_count = 0;
MSIVIEW *sv;
TRACE("%p %ld\n", iv, record );
TRACE("%p %p\n", iv, record );
sv = iv->sv;
if( !sv )
......@@ -77,7 +77,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
if( r )
goto err;
n = MsiRecordGetFieldCount( record );
n = MSI_RecordGetFieldCount( record );
if( n != col_count )
{
ERR("Number of fields do not match\n");
......@@ -103,7 +103,7 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
}
else
{
val = MsiRecordGetInteger( record, n );
val = MSI_RecordGetInteger( record, n );
val |= 0x8000;
}
r = sv->ops->set_int( sv, row, n, val );
......@@ -180,6 +180,7 @@ static UINT INSERT_delete( struct tagMSIVIEW *view )
sv->ops->delete( sv );
delete_value_list( iv->vals );
HeapFree( GetProcessHeap(), 0, iv );
msiobj_release( &iv->db->hdr );
return ERROR_SUCCESS;
}
......@@ -226,6 +227,7 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */
iv->view.ops = &insert_ops;
msiobj_addref( &db->hdr );
iv->db = db;
iv->vals = values;
iv->bIsTemp = temp;
......
/*
* 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
* modify it under the terms of the GNU Lesser General Public
......@@ -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;
......@@ -230,58 +230,18 @@ VOID MSI_CloseDatabase( VOID *arg )
IStorage_Release( db->storage );
}
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 MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
IStorage *stg = NULL;
HRESULT r;
MSIHANDLE handle;
MSIDATABASE *db;
UINT ret;
MSIDATABASE *db = NULL;
UINT ret = ERROR_FUNCTION_FAILED;
LPWSTR szMode;
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;
szMode = (LPWSTR) szPersist;
......@@ -328,7 +288,6 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
if( FAILED( r ) )
{
FIXME("Failed to stat storage\n");
ret = ERROR_FUNCTION_FAILED;
goto end;
}
......@@ -336,17 +295,15 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
{
ERR("storage GUID is not a MSI database GUID %s\n",
debugstr_guid(&stat.clsid) );
ret = ERROR_FUNCTION_FAILED;
goto end;
}
handle = alloc_msihandle( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase, (void**) &db );
if( !handle )
db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase );
if( !db )
{
FIXME("Failed to allocate a handle\n");
ret = ERROR_FUNCTION_FAILED;
goto end;
}
......@@ -355,24 +312,80 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phD
db->storage = stg;
db->mode = szMode;
/* db->strings = NULL;
db->first_table = NULL;
db->last_table = NULL; */
ret = load_string_table( db );
if( ret != ERROR_SUCCESS )
goto end;
*phDB = handle;
msiobj_addref( &db->hdr );
IStorage_AddRef( stg );
*pdb = db;
end:
if( db )
msiobj_release( &db->hdr );
if( stg )
IStorage_Release( stg );
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 len, ret;
......@@ -525,8 +538,9 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIHANDLE packagehandle;
MSIPACKAGE *package = NULL;
UINT rc = ERROR_SUCCESS;
MSIHANDLE handle;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
......@@ -534,13 +548,16 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
if (rc != ERROR_SUCCESS)
return rc;
rc = MsiOpenPackageW(szPackagePath,&packagehandle);
rc = MSI_OpenPackageW(szPackagePath,&package);
if (rc != ERROR_SUCCESS)
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;
}
......
......@@ -43,15 +43,58 @@ typedef struct tagMSITABLE MSITABLE;
struct 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
{
MSIOBJECTHDR hdr;
IStorage *storage;
string_table *strings;
LPWSTR mode;
MSITABLE *first_table, *last_table;
} 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
{
......@@ -90,7 +133,7 @@ typedef struct tagMSIVIEWOPS
/*
* 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
......@@ -126,31 +169,22 @@ typedef struct tagMSIVIEWOPS
} MSIVIEWOPS;
typedef struct tagMSIVIEW
{
MSIVIEWOPS *ops;
} MSIVIEW;
typedef struct tagMSISUMMARYINFO
{
MSIOBJECTHDR hdr;
IPropertyStorage *propstg;
} MSISUMMARYINFO;
typedef VOID (*msihandledestructor)( VOID * );
typedef struct tagMSIHANDLEINFO
struct tagMSIVIEW
{
UINT magic;
UINT type;
UINT refcount;
msihandledestructor destructor;
struct tagMSIHANDLEINFO *next;
struct tagMSIHANDLEINFO *prev;
} MSIHANDLEINFO;
MSIOBJECTHDR hdr;
MSIVIEWOPS *ops;
};
typedef struct tagMSIPACKAGE
{
MSIHANDLE db;
MSIOBJECTHDR hdr;
MSIDATABASE *db;
struct tagMSIFEATURE *features;
UINT loaded_features;
struct tagMSIFOLDER *folders;
......@@ -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);
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy, void **out);
void msihandle_addref(MSIHANDLE handle);
/* handle functions */
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 */
extern void add_table(MSIDATABASE *db, MSITABLE *table);
......@@ -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 );
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 );
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
USHORT **pdata, UINT *psz );
UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
LPCWSTR szCommandLine);
void ACTION_remove_tracked_tempfiles(MSIPACKAGE* hPackage);
extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
/* record internals */
extern UINT WINAPI MSI_RecordSetIStream( MSIHANDLE handle,
unsigned int iField, IStream *stm );
extern const WCHAR *MSI_RecordGetString( MSIHANDLE handle, unsigned int iField );
extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
extern const WCHAR *MSI_RecordGetString( MSIRECORD *, unsigned int );
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 */
extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
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 squash_guid(LPCWSTR in, LPWSTR out);
BOOL encode_base85_guid(GUID *,LPWSTR);
......
/*
* 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
* modify it under the terms of the GNU Lesser General Public
......@@ -36,12 +36,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
#if 0
typedef struct tagMSIQUERY
{
MSIOBJECTHDR hdr;
MSIVIEW *view;
UINT row;
MSIDATABASE *db;
} MSIQUERY;
#endif
UINT WINAPI MsiDatabaseIsTablePersistentA(
MSIHANDLE hDatabase, LPSTR szTableName)
......@@ -57,12 +60,13 @@ UINT WINAPI MsiDatabaseIsTablePersistentW(
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 )
query->view->ops->delete( query->view );
msiobj_release( &query->db->hdr );
}
UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
......@@ -118,57 +122,71 @@ UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
return r;
}
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
LPCWSTR szQuery, MSIHANDLE *phView)
UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
LPCWSTR szQuery, MSIQUERY **pView)
{
MSIDATABASE *db;
MSIHANDLE handle;
MSIQUERY *query;
UINT r;
TRACE("%s %p\n", debugstr_w(szQuery), phView);
TRACE("%s %p\n", debugstr_w(szQuery), pView);
if( !szQuery)
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 */
handle = alloc_msihandle( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
MSI_CloseView, (void**) &query );
if( !handle )
query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
MSI_CloseView );
if( !query )
return ERROR_FUNCTION_FAILED;
msiobj_addref( &db->hdr );
query->row = 0;
query->db = db;
query->view = NULL;
r = MSI_ParseSQL( db, szQuery, &query->view );
if( r != ERROR_SUCCESS )
if( r == ERROR_SUCCESS )
{
MsiCloseHandle( handle );
return r;
msiobj_addref( &query->hdr );
*pView = query;
}
*phView = handle;
msiobj_release( &query->hdr );
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;
MSIHANDLE handle;
MSIRECORD *rec;
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;
if( !view )
return ERROR_FUNCTION_FAILED;
......@@ -182,8 +200,8 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
if( query->row >= row_count )
return ERROR_NO_MORE_ITEMS;
handle = MsiCreateRecord( col_count );
if( !handle )
rec = MSI_CreateRecord( col_count );
if( !rec )
return ERROR_FUNCTION_FAILED;
for( i=1; i<=col_count; i++ )
......@@ -215,25 +233,25 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
LPWSTR sval;
sval = MSI_makestring( query->db, ival );
MsiRecordSetStringW( handle, i, sval );
MSI_RecordSetStringW( rec, i, sval );
HeapFree( GetProcessHeap(), 0, sval );
}
else
{
if( (type & MSI_DATASIZEMASK) == 2 )
MsiRecordSetInteger( handle, i, ival - (1<<15) );
MSI_RecordSetInteger( rec, i, ival - (1<<15) );
else
MsiRecordSetInteger( handle, i, ival - (1<<31) );
MSI_RecordSetInteger( rec, i, ival - (1<<31) );
}
}
else
{
IStream *stm;
IStream *stm = NULL;
ret = view->ops->fetch_stream( view, query->row, i, &stm );
if( ( ret == ERROR_SUCCESS ) && stm )
{
MSI_RecordSetIStream( handle, i, stm );
MSI_RecordSetIStream( rec, i, stm );
IStream_Release( stm );
}
else
......@@ -242,21 +260,37 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
}
query->row ++;
*record = handle;
*prec = rec;
return ERROR_SUCCESS;
}
UINT WINAPI MsiViewClose(MSIHANDLE hView)
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
{
MSIQUERY *query;
MSIVIEW *view;
MSIRECORD *rec = NULL;
UINT ret;
TRACE("%ld\n", hView );
TRACE("%ld %p\n", hView, record);
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query )
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;
if( !view )
......@@ -267,17 +301,28 @@ UINT WINAPI MsiViewClose(MSIHANDLE hView)
return view->ops->close( view );
}
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
UINT WINAPI MsiViewClose(MSIHANDLE hView)
{
MSIQUERY *query;
MSIVIEW *view;
UINT ret;
TRACE("%ld %ld\n", hView, hRec);
TRACE("%ld\n", hView );
query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
if( !query )
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;
if( !view )
return ERROR_FUNCTION_FAILED;
......@@ -285,7 +330,39 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
return ERROR_FUNCTION_FAILED;
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)
......
......@@ -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 );
}
static UINT ORDER_execute( struct tagMSIVIEW *view, MSIHANDLE record )
static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
UINT r, num_rows = 0, i;
TRACE("%p %ld\n", ov, record);
TRACE("%p %p\n", ov, record);
if( !ov->table )
return ERROR_FUNCTION_FAILED;
......@@ -245,6 +245,7 @@ static UINT ORDER_delete( struct tagMSIVIEW *view )
ov->reorder = NULL;
HeapFree( GetProcessHeap(), 0, ov );
msiobj_release( &ov->db->hdr );
return ERROR_SUCCESS;
}
......@@ -285,6 +286,7 @@ UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
/* fill the structure */
ov->view.ops = &order_ops;
msiobj_addref( &db->hdr );
ov->db = db;
ov->table = table;
ov->reorder = NULL;
......
......@@ -111,11 +111,11 @@ static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *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;
TRACE("%p %ld\n", sv, record);
TRACE("%p %p\n", sv, record);
if( !sv->table )
return ERROR_FUNCTION_FAILED;
......
......@@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
'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;
IPropertyStorage_Release( suminfo->propstg );
......@@ -74,7 +74,7 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
{
HRESULT r;
MSIHANDLE handle, hdb = hDatabase;
MSIHANDLE handle;
MSISUMMARYINFO *suminfo;
MSIDATABASE *db;
UINT ret = ERROR_SUCCESS;
......@@ -92,20 +92,24 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
{
UINT res;
res = MsiOpenDatabaseW(szDatabase, NULL, &hdb);
res = MSI_OpenDatabaseW(szDatabase, NULL, &db);
if( res != ERROR_SUCCESS )
return res;
}
db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE);
if( !db )
return ERROR_INVALID_PARAMETER;
else
{
db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
if( !db )
return ERROR_INVALID_PARAMETER;
}
r = IStorage_QueryInterface( db->storage,
&IID_IPropertySetStorage, (LPVOID)&psstg);
if( FAILED( r ) )
{
ERR("IStorage -> IPropertySetStorage failed\n");
if (db)
msiobj_release(&db->hdr);
return ERROR_FUNCTION_FAILED;
}
ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
......@@ -119,10 +123,9 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
goto end;
}
handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo,
(void**) &suminfo );
if( !handle )
suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
if( !suminfo )
{
ret = ERROR_FUNCTION_FAILED;
goto end;
......@@ -130,15 +133,20 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
IPropertyStorage_AddRef(ps);
suminfo->propstg = ps;
handle = alloc_msihandle( &suminfo->hdr );
if( handle )
*phSummaryInfo = handle;
else
ret = ERROR_FUNCTION_FAILED;
msiobj_release( &suminfo->hdr );
end:
if( ps )
IPropertyStorage_Release(ps);
if( psstg )
IPropertySetStorage_Release(psstg);
if( !hDatabase )
MsiCloseHandle( hdb );
if (db)
msiobj_release(&db->hdr);
return ret;
}
......
......@@ -288,18 +288,7 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
return ERROR_SUCCESS;
}
/* FIXME: we should be passing around pointers to db structures internally */
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,
UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
USHORT **pdata, UINT *psz )
{
HRESULT r;
......@@ -309,10 +298,9 @@ UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
IStream *stm = NULL;
STATSTG stat;
r = get_raw_stream( hdb, stname, &stm );
r = db_get_raw_stream( db, stname, &stm );
if( r != ERROR_SUCCESS)
goto end;
ret = ERROR_FUNCTION_FAILED;
return ret;
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
{
......@@ -1114,6 +1102,9 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT ival = 0, refcol = 0, r;
LPWSTR sval;
LPWSTR full_name;
DWORD len;
static const WCHAR szDot[] = { '.', 0 };
if( !view->ops->fetch_int )
return ERROR_INVALID_PARAMETER;
......@@ -1138,22 +1129,16 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
if( !sval )
return ERROR_INVALID_PARAMETER;
{
LPWSTR full_name;
DWORD len;
static const WCHAR szDot[] = { '.', 0 };
len = strlenW( tv->name ) + 2 + strlenW( sval );
full_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
strcpyW( full_name, tv->name );
strcatW( full_name, szDot );
strcatW( full_name, sval );
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 );
}
len = strlenW( tv->name ) + 2 + strlenW( sval );
full_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
strcpyW( full_name, tv->name );
strcatW( full_name, szDot );
strcatW( full_name, sval );
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 );
return r;
......@@ -1228,12 +1213,12 @@ UINT TABLE_insert_row( struct tagMSIVIEW *view, UINT *num )
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;
UINT r;
TRACE("%p %ld\n", tv, record);
TRACE("%p %p\n", tv, record);
if( tv->table )
return ERROR_FUNCTION_FAILED;
......
......@@ -55,13 +55,13 @@ static UINT UPDATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
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;
UINT n, type, val, r, row, col_count = 0, row_count = 0;
MSIVIEW *wv;
TRACE("%p %ld\n", uv, record );
TRACE("%p %p\n", uv, record );
if( !record )
return ERROR_FUNCTION_FAILED;
......@@ -94,7 +94,7 @@ static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIHANDLE record )
}
else
{
val = MsiRecordGetInteger( record, n );
val = MSI_RecordGetInteger( record, n );
val |= 0x8000;
}
r = wv->ops->set_int( wv, row, n, val );
......@@ -172,6 +172,7 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view )
wv->ops->delete( wv );
delete_value_list( uv->vals );
HeapFree( GetProcessHeap(), 0, uv );
msiobj_release( &uv->db->hdr );
return ERROR_SUCCESS;
}
......@@ -228,6 +229,7 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
/* fill the structure */
uv->view.ops = &update_ops;
msiobj_addref( &db->hdr );
uv->db = db;
uv->vals = list->val_list;
uv->wv = sv;
......
......@@ -131,7 +131,7 @@ static UINT INT_evaluate( UINT lval, UINT op, UINT rval )
}
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;
......@@ -157,7 +157,7 @@ static const WCHAR *STRING_evaluate( string_table *st,
}
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;
const WCHAR *l_str, *r_str;
......@@ -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,
struct expr *cond, UINT *val, MSIHANDLE record )
struct expr *cond, UINT *val, MSIRECORD *record )
{
UINT r, lval, rval;
......@@ -211,7 +211,7 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
return STRCMP_Evaluate( db->strings, table, row, cond, val, record );
case EXPR_WILDCARD:
*val = MsiRecordGetInteger( record, 1 );
*val = MSI_RecordGetInteger( record, 1 );
return ERROR_SUCCESS;
default:
......@@ -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;
UINT count = 0, r, val, i;
MSIVIEW *table = wv->table;
TRACE("%p %ld\n", wv, record);
TRACE("%p %p\n", wv, record);
if( !table )
return ERROR_FUNCTION_FAILED;
......@@ -337,6 +337,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view )
delete_expr( wv->cond );
HeapFree( GetProcessHeap(), 0, wv );
msiobj_release( &wv->db->hdr );
return ERROR_SUCCESS;
}
......@@ -458,6 +459,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
/* fill the structure */
wv->view.ops = &where_ops;
msiobj_addref( &db->hdr );
wv->db = db;
wv->table = table;
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