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
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
40 typedef struct tagMSIQUERY
49 UINT WINAPI
MsiDatabaseIsTablePersistentA(
50 MSIHANDLE hDatabase
, LPSTR szTableName
)
52 FIXME("%lx %s\n", hDatabase
, debugstr_a(szTableName
));
53 return ERROR_CALL_NOT_IMPLEMENTED
;
56 UINT WINAPI
MsiDatabaseIsTablePersistentW(
57 MSIHANDLE hDatabase
, LPWSTR szTableName
)
59 FIXME("%lx %s\n", hDatabase
, debugstr_w(szTableName
));
60 return ERROR_CALL_NOT_IMPLEMENTED
;
63 void MSI_CloseView( MSIOBJECTHDR
*arg
)
65 MSIQUERY
*query
= (MSIQUERY
*) arg
;
67 if( query
->view
&& query
->view
->ops
->delete )
68 query
->view
->ops
->delete( query
->view
);
69 msiobj_release( &query
->db
->hdr
);
72 UINT
VIEW_find_column( MSIVIEW
*table
, LPWSTR name
, UINT
*n
)
77 r
= table
->ops
->get_dimensions( table
, NULL
, &count
);
78 if( r
!= ERROR_SUCCESS
)
81 for( i
=1; i
<=count
; i
++ )
86 r
= table
->ops
->get_column_info( table
, i
, &col_name
, NULL
);
87 if( r
!= ERROR_SUCCESS
)
89 x
= lstrcmpW( name
, col_name
);
90 HeapFree( GetProcessHeap(), 0, col_name
);
98 return ERROR_INVALID_PARAMETER
;
101 UINT WINAPI
MsiDatabaseOpenViewA(MSIHANDLE hdb
,
102 LPCSTR szQuery
, MSIHANDLE
*phView
)
107 TRACE("%ld %s %p\n", hdb
, debugstr_a(szQuery
), phView
);
111 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szQuery
, -1, NULL
, 0 );
112 szwQuery
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
114 return ERROR_FUNCTION_FAILED
;
115 MultiByteToWideChar( CP_ACP
, 0, szQuery
, -1, szwQuery
, len
);
120 r
= MsiDatabaseOpenViewW( hdb
, szwQuery
, phView
);
125 UINT
MSI_DatabaseOpenViewW(MSIDATABASE
*db
,
126 LPCWSTR szQuery
, MSIQUERY
**pView
)
131 TRACE("%s %p\n", debugstr_w(szQuery
), pView
);
134 return ERROR_INVALID_PARAMETER
;
136 /* pre allocate a handle to hold a pointer to the view */
137 query
= alloc_msiobject( MSIHANDLETYPE_VIEW
, sizeof (MSIQUERY
),
140 return ERROR_FUNCTION_FAILED
;
142 msiobj_addref( &db
->hdr
);
147 r
= MSI_ParseSQL( db
, szQuery
, &query
->view
);
148 if( r
== ERROR_SUCCESS
)
150 msiobj_addref( &query
->hdr
);
154 msiobj_release( &query
->hdr
);
155 return ERROR_SUCCESS
;
158 UINT WINAPI
MsiDatabaseOpenViewW(MSIHANDLE hdb
,
159 LPCWSTR szQuery
, MSIHANDLE
*phView
)
162 MSIQUERY
*query
= NULL
;
165 TRACE("%s %p\n", debugstr_w(szQuery
), phView
);
167 db
= msihandle2msiinfo( hdb
, MSIHANDLETYPE_DATABASE
);
169 return ERROR_INVALID_HANDLE
;
171 ret
= MSI_DatabaseOpenViewW( db
, szQuery
, &query
);
172 if( ret
== ERROR_SUCCESS
)
174 *phView
= alloc_msihandle( &query
->hdr
);
175 msiobj_release( &query
->hdr
);
177 msiobj_release( &db
->hdr
);
182 UINT
MSI_ViewFetch(MSIQUERY
*query
, MSIRECORD
**prec
)
186 UINT row_count
= 0, col_count
= 0, i
, ival
, ret
, type
;
188 TRACE("%p %p\n", query
, prec
);
192 return ERROR_FUNCTION_FAILED
;
194 ret
= view
->ops
->get_dimensions( view
, &row_count
, &col_count
);
198 return ERROR_INVALID_PARAMETER
;
200 if( query
->row
>= row_count
)
201 return ERROR_NO_MORE_ITEMS
;
203 rec
= MSI_CreateRecord( col_count
);
205 return ERROR_FUNCTION_FAILED
;
207 for( i
=1; i
<=col_count
; i
++ )
209 ret
= view
->ops
->get_column_info( view
, i
, NULL
, &type
);
212 ERR("Error getting column type for %d\n", i
);
215 if (( type
!= MSITYPE_BINARY
) && (type
!= (MSITYPE_BINARY
|
218 ret
= view
->ops
->fetch_int( view
, query
->row
, i
, &ival
);
221 ERR("Error fetching data for %d\n", i
);
224 if( ! (type
& MSITYPE_VALID
) )
225 ERR("Invalid type!\n");
227 /* check if it's nul (0) - if so, don't set anything */
231 if( type
& MSITYPE_STRING
)
235 sval
= MSI_makestring( query
->db
, ival
);
236 MSI_RecordSetStringW( rec
, i
, sval
);
237 HeapFree( GetProcessHeap(), 0, sval
);
241 if( (type
& MSI_DATASIZEMASK
) == 2 )
242 MSI_RecordSetInteger( rec
, i
, ival
- (1<<15) );
244 MSI_RecordSetInteger( rec
, i
, ival
- (1<<31) );
251 ret
= view
->ops
->fetch_stream( view
, query
->row
, i
, &stm
);
252 if( ( ret
== ERROR_SUCCESS
) && stm
)
254 MSI_RecordSetIStream( rec
, i
, stm
);
255 IStream_Release( stm
);
258 ERR("failed to get stream\n");
265 return ERROR_SUCCESS
;
268 UINT WINAPI
MsiViewFetch(MSIHANDLE hView
, MSIHANDLE
*record
)
271 MSIRECORD
*rec
= NULL
;
274 TRACE("%ld %p\n", hView
, record
);
276 query
= msihandle2msiinfo( hView
, MSIHANDLETYPE_VIEW
);
278 return ERROR_INVALID_HANDLE
;
279 ret
= MSI_ViewFetch( query
, &rec
);
280 if( ret
== ERROR_SUCCESS
)
282 *record
= alloc_msihandle( &rec
->hdr
);
283 msiobj_release( &rec
->hdr
);
285 msiobj_release( &query
->hdr
);
289 UINT
MSI_ViewClose(MSIQUERY
*query
)
293 TRACE("%p\n", query
);
297 return ERROR_FUNCTION_FAILED
;
298 if( !view
->ops
->close
)
299 return ERROR_FUNCTION_FAILED
;
301 return view
->ops
->close( view
);
304 UINT WINAPI
MsiViewClose(MSIHANDLE hView
)
309 TRACE("%ld\n", hView
);
311 query
= msihandle2msiinfo( hView
, MSIHANDLETYPE_VIEW
);
313 return ERROR_INVALID_HANDLE
;
315 ret
= MSI_ViewClose( query
);
316 msiobj_release( &query
->hdr
);
320 UINT
MSI_ViewExecute(MSIQUERY
*query
, MSIRECORD
*rec
)
324 TRACE("%p %p\n", query
, rec
);
328 return ERROR_FUNCTION_FAILED
;
329 if( !view
->ops
->execute
)
330 return ERROR_FUNCTION_FAILED
;
333 return view
->ops
->execute( view
, rec
);
336 UINT WINAPI
MsiViewExecute(MSIHANDLE hView
, MSIHANDLE hRec
)
339 MSIRECORD
*rec
= NULL
;
342 TRACE("%ld %ld\n", hView
, hRec
);
344 query
= msihandle2msiinfo( hView
, MSIHANDLETYPE_VIEW
);
346 return ERROR_INVALID_HANDLE
;
350 rec
= msihandle2msiinfo( hRec
, MSIHANDLETYPE_RECORD
);
353 ret
= ERROR_INVALID_HANDLE
;
358 ret
= MSI_ViewExecute( query
, rec
);
361 msiobj_release( &query
->hdr
);
363 msiobj_release( &rec
->hdr
);
368 UINT WINAPI
MsiViewGetColumnInfo(MSIHANDLE hView
, MSICOLINFO info
, MSIHANDLE
*hRec
)
373 UINT ret
, i
, count
= 0, type
;
376 TRACE("%ld %d %p\n", hView
, info
, hRec
);
378 query
= msihandle2msiinfo( hView
, MSIHANDLETYPE_VIEW
);
380 return ERROR_INVALID_HANDLE
;
384 return ERROR_FUNCTION_FAILED
;
386 if( !view
->ops
->get_dimensions
)
387 return ERROR_FUNCTION_FAILED
;
389 ret
= view
->ops
->get_dimensions( view
, NULL
, &count
);
393 return ERROR_INVALID_PARAMETER
;
395 handle
= MsiCreateRecord( count
);
397 return ERROR_FUNCTION_FAILED
;
399 for( i
=0; i
<count
; i
++ )
402 ret
= view
->ops
->get_column_info( view
, i
+1, &name
, &type
);
403 if( ret
!= ERROR_SUCCESS
)
405 MsiRecordSetStringW( handle
, i
+1, name
);
406 HeapFree( GetProcessHeap(), 0, name
);
411 return ERROR_SUCCESS
;
414 UINT WINAPI
MsiDatabaseApplyTransformA( MSIHANDLE hdb
,
415 LPCSTR szTransformFile
, int iErrorCond
)
417 FIXME("%ld %s %d\n", hdb
, debugstr_a(szTransformFile
), iErrorCond
);
418 return ERROR_CALL_NOT_IMPLEMENTED
;
421 UINT WINAPI
MsiDatabaseApplyTransformW( MSIHANDLE hdb
,
422 LPCWSTR szTransformFile
, int iErrorCond
)
424 FIXME("%ld %s %d\n", hdb
, debugstr_w(szTransformFile
), iErrorCond
);
425 return ERROR_CALL_NOT_IMPLEMENTED
;
428 UINT WINAPI
MsiDatabaseGenerateTransformA( MSIHANDLE hdb
, MSIHANDLE hdbref
,
429 LPCSTR szTransformFile
, int iReserved1
, int iReserved2
)
431 FIXME("%ld %ld %s %d %d\n", hdb
, hdbref
,
432 debugstr_a(szTransformFile
), iReserved1
, iReserved2
);
433 return ERROR_CALL_NOT_IMPLEMENTED
;
436 UINT WINAPI
MsiDatabaseGenerateTransformW( MSIHANDLE hdb
, MSIHANDLE hdbref
,
437 LPCWSTR szTransformFile
, int iReserved1
, int iReserved2
)
439 FIXME("%ld %ld %s %d %d\n", hdb
, hdbref
,
440 debugstr_w(szTransformFile
), iReserved1
, iReserved2
);
441 return ERROR_CALL_NOT_IMPLEMENTED
;
444 UINT WINAPI
MsiDatabaseCommit( MSIHANDLE hdb
)
451 db
= msihandle2msiinfo( hdb
, MSIHANDLETYPE_DATABASE
);
453 return ERROR_INVALID_HANDLE
;
455 /* FIXME: lock the database */
457 r
= MSI_CommitTables( db
);
459 /* FIXME: unlock the database */
464 UINT WINAPI
MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb
,
465 LPCSTR table
, MSIHANDLE
* rec
)
467 FIXME("%ld %s %p\n", hdb
, debugstr_a(table
), rec
);
468 return ERROR_CALL_NOT_IMPLEMENTED
;
471 UINT WINAPI
MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb
,
472 LPCWSTR table
, MSIHANDLE
* rec
)
474 FIXME("%ld %s %p\n", hdb
, debugstr_w(table
), rec
);
475 return ERROR_CALL_NOT_IMPLEMENTED
;
478 UINT WINAPI
MsiViewModify(MSIHANDLE hView
, MSIMODIFY eModifyMode
, MSIHANDLE
481 FIXME("%ld %x %ld\n",hView
, eModifyMode
, hRecord
);
482 return ERROR_CALL_NOT_IMPLEMENTED
;