2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002-2004 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(msi);
42 typedef struct tagMSIQUERY
51 UINT WINAPI MsiDatabaseIsTablePersistentA(
52 MSIHANDLE hDatabase, LPSTR szTableName)
54 FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
55 return ERROR_CALL_NOT_IMPLEMENTED;
58 UINT WINAPI MsiDatabaseIsTablePersistentW(
59 MSIHANDLE hDatabase, LPWSTR szTableName)
61 FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
62 return ERROR_CALL_NOT_IMPLEMENTED;
65 void MSI_CloseView( MSIOBJECTHDR *arg )
67 MSIQUERY *query = (MSIQUERY*) arg;
69 if( query->view && query->view->ops->delete )
70 query->view->ops->delete( query->view );
71 msiobj_release( &query->db->hdr );
74 UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
79 r = table->ops->get_dimensions( table, NULL, &count );
80 if( r != ERROR_SUCCESS )
83 for( i=1; i<=count; i++ )
88 r = table->ops->get_column_info( table, i, &col_name, NULL );
89 if( r != ERROR_SUCCESS )
91 x = lstrcmpW( name, col_name );
92 HeapFree( GetProcessHeap(), 0, col_name );
100 return ERROR_INVALID_PARAMETER;
103 UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
104 LPCSTR szQuery, MSIHANDLE *phView)
109 TRACE("%ld %s %p\n", hdb, debugstr_a(szQuery), phView);
113 UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
114 szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
116 return ERROR_FUNCTION_FAILED;
117 MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
122 r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
124 HeapFree( GetProcessHeap(), 0, szwQuery );
128 UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
129 LPCWSTR szQuery, MSIQUERY **pView)
134 TRACE("%s %p\n", debugstr_w(szQuery), pView);
137 return ERROR_INVALID_PARAMETER;
139 /* pre allocate a handle to hold a pointer to the view */
140 query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
143 return ERROR_FUNCTION_FAILED;
145 msiobj_addref( &db->hdr );
150 r = MSI_ParseSQL( db, szQuery, &query->view );
151 if( r == ERROR_SUCCESS )
153 msiobj_addref( &query->hdr );
157 msiobj_release( &query->hdr );
161 UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
162 LPCWSTR szQuery, MSIHANDLE *phView)
165 MSIQUERY *query = NULL;
168 TRACE("%s %p\n", debugstr_w(szQuery), phView);
170 db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
172 return ERROR_INVALID_HANDLE;
174 ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
175 if( ret == ERROR_SUCCESS )
177 *phView = alloc_msihandle( &query->hdr );
178 msiobj_release( &query->hdr );
180 msiobj_release( &db->hdr );
185 UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
189 UINT row_count = 0, col_count = 0, i, ival, ret, type;
191 TRACE("%p %p\n", query, prec );
195 return ERROR_FUNCTION_FAILED;
197 ret = view->ops->get_dimensions( view, &row_count, &col_count );
201 return ERROR_INVALID_PARAMETER;
203 if( query->row >= row_count )
204 return ERROR_NO_MORE_ITEMS;
206 rec = MSI_CreateRecord( col_count );
208 return ERROR_FUNCTION_FAILED;
210 for( i=1; i<=col_count; i++ )
212 ret = view->ops->get_column_info( view, i, NULL, &type );
215 ERR("Error getting column type for %d\n", i );
218 if (( type != MSITYPE_BINARY) && (type != (MSITYPE_BINARY |
221 ret = view->ops->fetch_int( view, query->row, i, &ival );
224 ERR("Error fetching data for %d\n", i );
227 if( ! (type & MSITYPE_VALID ) )
228 ERR("Invalid type!\n");
230 /* check if it's nul (0) - if so, don't set anything */
234 if( type & MSITYPE_STRING )
238 sval = MSI_makestring( query->db, ival );
239 MSI_RecordSetStringW( rec, i, sval );
240 HeapFree( GetProcessHeap(), 0, sval );
244 if( (type & MSI_DATASIZEMASK) == 2 )
245 MSI_RecordSetInteger( rec, i, ival - (1<<15) );
247 MSI_RecordSetInteger( rec, i, ival - (1<<31) );
254 ret = view->ops->fetch_stream( view, query->row, i, &stm );
255 if( ( ret == ERROR_SUCCESS ) && stm )
257 MSI_RecordSetIStream( rec, i, stm );
258 IStream_Release( stm );
261 ERR("failed to get stream\n");
268 return ERROR_SUCCESS;
271 UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
274 MSIRECORD *rec = NULL;
277 TRACE("%ld %p\n", hView, record);
279 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
281 return ERROR_INVALID_HANDLE;
282 ret = MSI_ViewFetch( query, &rec );
283 if( ret == ERROR_SUCCESS )
285 *record = alloc_msihandle( &rec->hdr );
286 msiobj_release( &rec->hdr );
288 msiobj_release( &query->hdr );
292 UINT MSI_ViewClose(MSIQUERY *query)
296 TRACE("%p\n", query );
300 return ERROR_FUNCTION_FAILED;
301 if( !view->ops->close )
302 return ERROR_FUNCTION_FAILED;
304 return view->ops->close( view );
307 UINT WINAPI MsiViewClose(MSIHANDLE hView)
312 TRACE("%ld\n", hView );
314 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
316 return ERROR_INVALID_HANDLE;
318 ret = MSI_ViewClose( query );
319 msiobj_release( &query->hdr );
323 UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec )
327 TRACE("%p %p\n", query, rec);
331 return ERROR_FUNCTION_FAILED;
332 if( !view->ops->execute )
333 return ERROR_FUNCTION_FAILED;
336 return view->ops->execute( view, rec );
339 UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
342 MSIRECORD *rec = NULL;
345 TRACE("%ld %ld\n", hView, hRec);
347 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
349 return ERROR_INVALID_HANDLE;
353 rec = msihandle2msiinfo( hRec, MSIHANDLETYPE_RECORD );
356 ret = ERROR_INVALID_HANDLE;
361 ret = MSI_ViewExecute( query, rec );
364 msiobj_release( &query->hdr );
366 msiobj_release( &rec->hdr );
371 UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
376 UINT ret, i, count = 0, type;
379 TRACE("%ld %d %p\n", hView, info, hRec);
381 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
383 return ERROR_INVALID_HANDLE;
387 return ERROR_FUNCTION_FAILED;
389 if( !view->ops->get_dimensions )
390 return ERROR_FUNCTION_FAILED;
392 ret = view->ops->get_dimensions( view, NULL, &count );
396 return ERROR_INVALID_PARAMETER;
398 handle = MsiCreateRecord( count );
400 return ERROR_FUNCTION_FAILED;
402 for( i=0; i<count; i++ )
405 ret = view->ops->get_column_info( view, i+1, &name, &type );
406 if( ret != ERROR_SUCCESS )
408 MsiRecordSetStringW( handle, i+1, name );
409 HeapFree( GetProcessHeap(), 0, name );
414 return ERROR_SUCCESS;
417 UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
418 LPCSTR szTransformFile, int iErrorCond)
420 FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
421 return ERROR_CALL_NOT_IMPLEMENTED;
424 UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
425 LPCWSTR szTransformFile, int iErrorCond)
427 FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
428 return ERROR_CALL_NOT_IMPLEMENTED;
431 UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
432 LPCSTR szTransformFile, int iReserved1, int iReserved2 )
434 FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
435 debugstr_a(szTransformFile), iReserved1, iReserved2);
436 return ERROR_CALL_NOT_IMPLEMENTED;
439 UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
440 LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
442 FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
443 debugstr_w(szTransformFile), iReserved1, iReserved2);
444 return ERROR_CALL_NOT_IMPLEMENTED;
447 UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
454 db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
456 return ERROR_INVALID_HANDLE;
458 /* FIXME: lock the database */
460 r = MSI_CommitTables( db );
462 /* FIXME: unlock the database */
467 UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb,
468 LPCSTR table, MSIHANDLE* rec)
470 FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
471 return ERROR_CALL_NOT_IMPLEMENTED;
474 UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,
475 LPCWSTR table, MSIHANDLE* rec)
477 FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
478 return ERROR_CALL_NOT_IMPLEMENTED;
481 UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE
484 FIXME("%ld %x %ld\n",hView, eModifyMode, hRecord);
485 return ERROR_CALL_NOT_IMPLEMENTED;