Make rsabase.dll self-register.
[wine.git] / dlls / msi / msiquery.c
blobee53639b0f3ec6abc3d13f0914ce451f7b6471e7
1 /*
2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002 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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "wine/debug.h"
27 #include "msi.h"
28 #include "msiquery.h"
29 #include "objbase.h"
30 #include "objidl.h"
31 #include "msipriv.h"
32 #include "winnls.h"
34 #include "query.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msi);
38 typedef struct tagMSIQUERY
40 MSIVIEW *view;
41 UINT row;
42 MSIDATABASE *db;
43 } MSIQUERY;
45 UINT WINAPI MsiDatabaseIsTablePersistentA(
46 MSIHANDLE hDatabase, LPSTR szTableName)
48 FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
49 return ERROR_CALL_NOT_IMPLEMENTED;
52 UINT WINAPI MsiDatabaseIsTablePersistentW(
53 MSIHANDLE hDatabase, LPWSTR szTableName)
55 FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
56 return ERROR_CALL_NOT_IMPLEMENTED;
59 void MSI_CloseView( VOID *arg )
61 MSIQUERY *query = arg;
63 if( query->view && query->view->ops->delete )
64 query->view->ops->delete( query->view );
67 UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
69 LPWSTR col_name;
70 UINT i, count, r;
72 r = table->ops->get_dimensions( table, NULL, &count );
73 if( r != ERROR_SUCCESS )
74 return r;
76 for( i=1; i<=count; i++ )
78 INT x;
80 col_name = NULL;
81 r = table->ops->get_column_info( table, i, &col_name, NULL );
82 if( r != ERROR_SUCCESS )
83 return r;
84 x = lstrcmpW( name, col_name );
85 HeapFree( GetProcessHeap(), 0, col_name );
86 if( !x )
88 *n = i;
89 return ERROR_SUCCESS;
93 return ERROR_INVALID_PARAMETER;
96 UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
97 LPCSTR szQuery, MSIHANDLE *phView)
99 UINT r;
100 LPWSTR szwQuery;
102 TRACE("%ld %s %p\n", hdb, debugstr_a(szQuery), phView);
104 if( szQuery )
106 UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
107 szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
108 if( !szwQuery )
109 return ERROR_FUNCTION_FAILED;
110 MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
112 else
113 szwQuery = NULL;
115 r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
117 return r;
120 UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
121 LPCWSTR szQuery, MSIHANDLE *phView)
123 MSIDATABASE *db;
124 MSIHANDLE handle;
125 MSIQUERY *query;
126 UINT r;
128 TRACE("%s %p\n", debugstr_w(szQuery), phView);
130 if( !szQuery)
131 return ERROR_INVALID_PARAMETER;
133 db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
134 if( !db )
135 return ERROR_INVALID_HANDLE;
137 /* pre allocate a handle to hold a pointer to the view */
138 handle = alloc_msihandle( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY), MSI_CloseView );
139 if( !handle )
140 return ERROR_FUNCTION_FAILED;
141 query = msihandle2msiinfo( handle, MSIHANDLETYPE_VIEW );
142 if( !query )
143 return ERROR_FUNCTION_FAILED;
145 query->row = 0;
146 query->db = db;
147 query->view = NULL;
149 r = MSI_ParseSQL( db, szQuery, &query->view );
150 if( r != ERROR_SUCCESS )
152 MsiCloseHandle( handle );
153 return r;
156 *phView = handle;
158 return ERROR_SUCCESS;
161 UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
163 MSIQUERY *query;
164 MSIVIEW *view;
165 MSIHANDLE handle;
166 UINT row_count = 0, col_count = 0, i, ival, ret, type;
168 TRACE("%ld %p\n", hView, record);
170 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
171 if( !query )
172 return ERROR_INVALID_HANDLE;
173 view = query->view;
174 if( !view )
175 return ERROR_FUNCTION_FAILED;
177 ret = view->ops->get_dimensions( view, &row_count, &col_count );
178 if( ret )
179 return ret;
180 if( !col_count )
181 return ERROR_INVALID_PARAMETER;
183 if( query->row >= row_count )
184 return ERROR_NO_MORE_ITEMS;
186 handle = MsiCreateRecord( col_count );
187 if( !handle )
188 return ERROR_FUNCTION_FAILED;
190 for( i=1; i<=col_count; i++ )
192 ret = view->ops->get_column_info( view, i, NULL, &type );
193 if( ret )
195 ERR("Error getting column type for %d\n", i );
196 continue;
198 ret = view->ops->fetch_int( view, query->row, i, &ival );
199 if( ret )
201 ERR("Error fetching data for %d\n", i );
202 continue;
204 if( ! (type & MSITYPE_VALID ) )
205 ERR("Invalid type!\n");
207 /* check if it's nul (0) - if so, don't set anything */
208 if( !ival )
209 continue;
211 if( type & MSITYPE_STRING )
213 LPWSTR sval = MSI_makestring( query->db, ival );
214 MsiRecordSetStringW( handle, i, sval );
215 HeapFree( GetProcessHeap(), 0, sval );
217 else
219 if( (type & MSI_DATASIZEMASK) == 2 )
220 MsiRecordSetInteger( handle, i, ival - (1<<15) );
221 else
222 MsiRecordSetInteger( handle, i, ival - (1<<31) );
225 query->row ++;
227 *record = handle;
229 return ERROR_SUCCESS;
232 UINT WINAPI MsiViewClose(MSIHANDLE hView)
234 MSIQUERY *query;
235 MSIVIEW *view;
237 TRACE("%ld\n", hView );
239 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
240 if( !query )
241 return ERROR_INVALID_HANDLE;
243 view = query->view;
244 if( !view )
245 return ERROR_FUNCTION_FAILED;
246 if( !view->ops->close )
247 return ERROR_FUNCTION_FAILED;
249 return view->ops->close( view );
252 UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
254 MSIQUERY *query;
255 MSIVIEW *view;
257 TRACE("%ld %ld\n", hView, hRec);
259 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
260 if( !query )
261 return ERROR_INVALID_HANDLE;
263 view = query->view;
264 if( !view )
265 return ERROR_FUNCTION_FAILED;
266 if( !view->ops->execute )
267 return ERROR_FUNCTION_FAILED;
268 query->row = 0;
270 return view->ops->execute( view, hRec );
273 UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
275 MSIVIEW *view;
276 MSIQUERY *query;
277 MSIHANDLE handle;
278 UINT ret, i, count = 0, type;
279 LPWSTR name;
281 TRACE("%ld %d %p\n", hView, info, hRec);
283 query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
284 if( !query )
285 return ERROR_INVALID_HANDLE;
287 view = query->view;
288 if( !view )
289 return ERROR_FUNCTION_FAILED;
291 if( !view->ops->get_dimensions )
292 return ERROR_FUNCTION_FAILED;
294 ret = view->ops->get_dimensions( view, NULL, &count );
295 if( ret )
296 return ret;
297 if( !count )
298 return ERROR_INVALID_PARAMETER;
300 handle = MsiCreateRecord( count );
301 if( !handle )
302 return ERROR_FUNCTION_FAILED;
304 for( i=0; i<count; i++ )
306 name = NULL;
307 ret = view->ops->get_column_info( view, i+1, &name, &type );
308 if( ret != ERROR_SUCCESS )
309 continue;
310 MsiRecordSetStringW( handle, i+1, name );
311 HeapFree( GetProcessHeap(), 0, name );
314 *hRec = handle;
316 return ERROR_SUCCESS;
320 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
322 FIXME("%ld %s\n", hInstall, debugstr_a(szAction) );
323 return ERROR_CALL_NOT_IMPLEMENTED;
326 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
328 FIXME("%ld %s\n", hInstall, debugstr_w(szAction) );
329 return ERROR_CALL_NOT_IMPLEMENTED;
332 UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
333 LPCSTR szTransformFile, int iErrorCond)
335 FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
336 return ERROR_CALL_NOT_IMPLEMENTED;
339 UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
340 LPCWSTR szTransformFile, int iErrorCond)
342 FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
343 return ERROR_CALL_NOT_IMPLEMENTED;
346 UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
347 LPCSTR szTransformFile, int iReserved1, int iReserved2 )
349 FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
350 debugstr_a(szTransformFile), iReserved1, iReserved2);
351 return ERROR_CALL_NOT_IMPLEMENTED;
354 UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
355 LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
357 FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
358 debugstr_w(szTransformFile), iReserved1, iReserved2);
359 return ERROR_CALL_NOT_IMPLEMENTED;
362 UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
364 FIXME("%ld\n", hdb);
365 return ERROR_SUCCESS;
368 UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb,
369 LPCSTR table, MSIHANDLE* rec)
371 FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
372 return ERROR_CALL_NOT_IMPLEMENTED;
375 UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,
376 LPCWSTR table, MSIHANDLE* rec)
378 FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
379 return ERROR_CALL_NOT_IMPLEMENTED;
382 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
383 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
385 FIXME("%ld %s %p %p\n", hInstall, debugstr_a(szFeature), piInstalled, piAction);
386 return ERROR_CALL_NOT_IMPLEMENTED;
389 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPWSTR szFeature,
390 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
392 FIXME("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
393 return ERROR_CALL_NOT_IMPLEMENTED;
396 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szFeature,
397 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
399 FIXME("%ld %s %p %p\n", hInstall, debugstr_a(szFeature), piInstalled, piAction);
400 return ERROR_CALL_NOT_IMPLEMENTED;
403 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szFeature,
404 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
406 FIXME("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
407 return ERROR_CALL_NOT_IMPLEMENTED;