ReactOS  0.4.13-dev-92-gf251225
msiquery.c
Go to the documentation of this file.
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2002-2005 Mike McCormack for CodeWeavers
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdarg.h>
22 
23 #define COBJMACROS
24 
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
30 #include "msi.h"
31 #include "msiquery.h"
32 #include "objbase.h"
33 #include "objidl.h"
34 #include "msipriv.h"
35 #include "winnls.h"
36 
37 #include "query.h"
38 #include "msiserver.h"
39 
40 #include "initguid.h"
41 
43 
45 {
46  MSIQUERY *query = (MSIQUERY*) arg;
47  struct list *ptr, *t;
48 
49  if( query->view && query->view->ops->delete )
50  query->view->ops->delete( query->view );
51  msiobj_release( &query->db->hdr );
52 
54  {
55  msi_free( ptr );
56  }
57 }
58 
60 {
61  LPCWSTR col_name, haystack_table_name;
62  UINT i, count, r;
63 
64  r = table->ops->get_dimensions( table, NULL, &count );
65  if( r != ERROR_SUCCESS )
66  return r;
67 
68  for( i=1; i<=count; i++ )
69  {
70  INT x;
71 
72  r = table->ops->get_column_info( table, i, &col_name, NULL,
73  NULL, &haystack_table_name );
74  if( r != ERROR_SUCCESS )
75  return r;
76  x = strcmpW( name, col_name );
77  if( table_name )
78  x |= strcmpW( table_name, haystack_table_name );
79  if( !x )
80  {
81  *n = i;
82  return ERROR_SUCCESS;
83  }
84  }
86 }
87 
89  LPCSTR szQuery, MSIHANDLE *phView)
90 {
91  UINT r;
92  LPWSTR szwQuery;
93 
94  TRACE("%d %s %p\n", hdb, debugstr_a(szQuery), phView);
95 
96  if( szQuery )
97  {
98  szwQuery = strdupAtoW( szQuery );
99  if( !szwQuery )
100  return ERROR_FUNCTION_FAILED;
101  }
102  else
103  szwQuery = NULL;
104 
105  r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
106 
107  msi_free( szwQuery );
108  return r;
109 }
110 
112  LPCWSTR szQuery, MSIQUERY **pView)
113 {
114  MSIQUERY *query;
115  UINT r;
116 
117  TRACE("%s %p\n", debugstr_w(szQuery), pView);
118 
119  if( !szQuery)
121 
122  /* pre allocate a handle to hold a pointer to the view */
124  MSI_CloseView );
125  if( !query )
126  return ERROR_FUNCTION_FAILED;
127 
128  msiobj_addref( &db->hdr );
129  query->db = db;
130  list_init( &query->mem );
131 
132  r = MSI_ParseSQL( db, szQuery, &query->view, &query->mem );
133  if( r == ERROR_SUCCESS )
134  {
135  msiobj_addref( &query->hdr );
136  *pView = query;
137  }
138 
139  msiobj_release( &query->hdr );
140  return r;
141 }
142 
144 {
145  UINT r;
146  int size = 100, res;
147  LPWSTR query;
148 
149  /* construct the string */
150  for (;;)
151  {
152  va_list va;
153  query = msi_alloc( size*sizeof(WCHAR) );
154  va_start(va, fmt);
155  res = vsnprintfW(query, size, fmt, va);
156  va_end(va);
157  if (res == -1) size *= 2;
158  else if (res >= size) size = res + 1;
159  else break;
160  msi_free( query );
161  }
162  /* perform the query */
164  msi_free(query);
165  return r;
166 }
167 
170 {
171  MSIRECORD *rec = NULL;
172  UINT r, n = 0, max = 0;
173 
174  r = MSI_ViewExecute( view, NULL );
175  if( r != ERROR_SUCCESS )
176  return r;
177 
178  if( count )
179  max = *count;
180 
181  /* iterate a query */
182  for( n = 0; (max == 0) || (n < max); n++ )
183  {
184  r = MSI_ViewFetch( view, &rec );
185  if( r != ERROR_SUCCESS )
186  break;
187  if (func)
188  r = func( rec, param );
189  msiobj_release( &rec->hdr );
190  if( r != ERROR_SUCCESS )
191  break;
192  }
193 
194  MSI_ViewClose( view );
195 
196  if( count )
197  *count = n;
198 
199  if( r == ERROR_NO_MORE_ITEMS )
200  r = ERROR_SUCCESS;
201 
202  return r;
203 }
204 
205 /* return a single record from a query */
207 {
208  MSIRECORD *rec = NULL;
209  MSIQUERY *view = NULL;
210  UINT r;
211  int size = 100, res;
212  LPWSTR query;
213 
214  /* construct the string */
215  for (;;)
216  {
217  va_list va;
218  query = msi_alloc( size*sizeof(WCHAR) );
219  va_start(va, fmt);
220  res = vsnprintfW(query, size, fmt, va);
221  va_end(va);
222  if (res == -1) size *= 2;
223  else if (res >= size) size = res + 1;
224  else break;
225  msi_free( query );
226  }
227  /* perform the query */
229  msi_free(query);
230 
231  if( r == ERROR_SUCCESS )
232  {
234  MSI_ViewFetch( view, &rec );
235  MSI_ViewClose( view );
236  msiobj_release( &view->hdr );
237  }
238  return rec;
239 }
240 
242  LPCWSTR szQuery, MSIHANDLE *phView)
243 {
244  MSIDATABASE *db;
245  MSIQUERY *query = NULL;
246  UINT ret;
247 
248  TRACE("%s %p\n", debugstr_w(szQuery), phView);
249 
251  if( !db )
252  {
253  HRESULT hr;
254  IWineMsiRemoteDatabase *remote_database;
255 
256  remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
257  if ( !remote_database )
258  return ERROR_INVALID_HANDLE;
259 
260  hr = IWineMsiRemoteDatabase_OpenView( remote_database, szQuery, phView );
261  IWineMsiRemoteDatabase_Release( remote_database );
262 
263  if (FAILED(hr))
264  {
266  return HRESULT_CODE(hr);
267 
268  return ERROR_FUNCTION_FAILED;
269  }
270 
271  return ERROR_SUCCESS;
272  }
273 
274  ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
275  if( ret == ERROR_SUCCESS )
276  {
277  *phView = alloc_msihandle( &query->hdr );
278  if (! *phView)
280  msiobj_release( &query->hdr );
281  }
282  msiobj_release( &db->hdr );
283 
284  return ret;
285 }
286 
288 {
289  UINT row_count = 0, col_count = 0, i, ival, ret, type;
290 
291  TRACE("%p %p %d %p\n", db, view, row, rec);
292 
293  ret = view->ops->get_dimensions(view, &row_count, &col_count);
294  if (ret)
295  return ret;
296 
297  if (!col_count)
299 
300  if (row >= row_count)
301  return ERROR_NO_MORE_ITEMS;
302 
303  *rec = MSI_CreateRecord(col_count);
304  if (!*rec)
305  return ERROR_FUNCTION_FAILED;
306 
307  for (i = 1; i <= col_count; i++)
308  {
309  ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL);
310  if (ret)
311  {
312  ERR("Error getting column type for %d\n", i);
313  continue;
314  }
315 
316  if (MSITYPE_IS_BINARY(type))
317  {
318  IStream *stm = NULL;
319 
320  ret = view->ops->fetch_stream(view, row, i, &stm);
321  if ((ret == ERROR_SUCCESS) && stm)
322  {
323  MSI_RecordSetIStream(*rec, i, stm);
324  IStream_Release(stm);
325  }
326  else
327  WARN("failed to get stream\n");
328 
329  continue;
330  }
331 
332  ret = view->ops->fetch_int(view, row, i, &ival);
333  if (ret)
334  {
335  ERR("Error fetching data for %d\n", i);
336  continue;
337  }
338 
339  if (! (type & MSITYPE_VALID))
340  ERR("Invalid type!\n");
341 
342  /* check if it's nul (0) - if so, don't set anything */
343  if (!ival)
344  continue;
345 
346  if (type & MSITYPE_STRING)
347  {
348  int len;
349  const WCHAR *sval = msi_string_lookup( db->strings, ival, &len );
350  msi_record_set_string( *rec, i, sval, len );
351  }
352  else
353  {
354  if ((type & MSI_DATASIZEMASK) == 2)
355  MSI_RecordSetInteger(*rec, i, ival - (1<<15));
356  else
357  MSI_RecordSetInteger(*rec, i, ival - (1u<<31));
358  }
359  }
360 
361  return ERROR_SUCCESS;
362 }
363 
365 {
366  MSIVIEW *view;
367  UINT r;
368 
369  TRACE("%p %p\n", query, prec );
370 
371  view = query->view;
372  if( !view )
373  return ERROR_FUNCTION_FAILED;
374 
375  r = msi_view_get_row(query->db, view, query->row, prec);
376  if (r == ERROR_SUCCESS)
377  {
378  query->row ++;
379  MSI_RecordSetIntPtr(*prec, 0, (INT_PTR)query);
380  }
381 
382  return r;
383 }
384 
386 {
387  MSIQUERY *query;
388  MSIRECORD *rec = NULL;
389  UINT ret;
390 
391  TRACE("%d %p\n", hView, record);
392 
393  if( !record )
395  *record = 0;
396 
398  if( !query )
399  return ERROR_INVALID_HANDLE;
400  ret = MSI_ViewFetch( query, &rec );
401  if( ret == ERROR_SUCCESS )
402  {
403  *record = alloc_msihandle( &rec->hdr );
404  if (! *record)
406  msiobj_release( &rec->hdr );
407  }
408  msiobj_release( &query->hdr );
409  return ret;
410 }
411 
413 {
414  MSIVIEW *view;
415 
416  TRACE("%p\n", query );
417 
418  view = query->view;
419  if( !view )
420  return ERROR_FUNCTION_FAILED;
421  if( !view->ops->close )
422  return ERROR_FUNCTION_FAILED;
423 
424  return view->ops->close( view );
425 }
426 
428 {
429  MSIQUERY *query;
430  UINT ret;
431 
432  TRACE("%d\n", hView );
433 
435  if( !query )
436  return ERROR_INVALID_HANDLE;
437 
438  ret = MSI_ViewClose( query );
439  msiobj_release( &query->hdr );
440  return ret;
441 }
442 
444 {
445  MSIVIEW *view;
446 
447  TRACE("%p %p\n", query, rec);
448 
449  view = query->view;
450  if( !view )
451  return ERROR_FUNCTION_FAILED;
452  if( !view->ops->execute )
453  return ERROR_FUNCTION_FAILED;
454  query->row = 0;
455 
456  return view->ops->execute( view, rec );
457 }
458 
460 {
461  MSIQUERY *query;
462  MSIRECORD *rec = NULL;
463  UINT ret;
464 
465  TRACE("%d %d\n", hView, hRec);
466 
468  if( !query )
469  return ERROR_INVALID_HANDLE;
470 
471  if( hRec )
472  {
474  if( !rec )
475  {
477  goto out;
478  }
479  }
480 
481  msiobj_lock( &rec->hdr );
482  ret = MSI_ViewExecute( query, rec );
483  msiobj_unlock( &rec->hdr );
484 
485 out:
486  msiobj_release( &query->hdr );
487  if( rec )
488  msiobj_release( &rec->hdr );
489 
490  return ret;
491 }
492 
494  UINT type, BOOL temporary )
495 {
496  static const WCHAR fmt[] = { '%','d',0 };
497  WCHAR szType[0x10];
498 
499  if (MSITYPE_IS_BINARY(type))
500  szType[0] = 'v';
501  else if (type & MSITYPE_LOCALIZABLE)
502  szType[0] = 'l';
503  else if (type & MSITYPE_UNKNOWN)
504  szType[0] = 'f';
505  else if (type & MSITYPE_STRING)
506  {
507  if (temporary)
508  szType[0] = 'g';
509  else
510  szType[0] = 's';
511  }
512  else
513  {
514  if (temporary)
515  szType[0] = 'j';
516  else
517  szType[0] = 'i';
518  }
519 
520  if (type & MSITYPE_NULLABLE)
521  szType[0] &= ~0x20;
522 
523  sprintfW( &szType[1], fmt, (type&0xff) );
524 
525  TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
526 
527  return MSI_RecordSetStringW( rec, field, szType );
528 }
529 
531 {
533  MSIRECORD *rec;
534  MSIVIEW *view = query->view;
535  LPCWSTR name;
536  BOOL temporary;
537 
538  if( !view )
539  return ERROR_FUNCTION_FAILED;
540 
541  if( !view->ops->get_dimensions )
542  return ERROR_FUNCTION_FAILED;
543 
544  r = view->ops->get_dimensions( view, NULL, &count );
545  if( r != ERROR_SUCCESS )
546  return r;
547  if( !count )
549 
550  rec = MSI_CreateRecord( count );
551  if( !rec )
552  return ERROR_FUNCTION_FAILED;
553 
554  for( i=0; i<count; i++ )
555  {
556  name = NULL;
557  r = view->ops->get_column_info( view, i+1, &name, &type, &temporary, NULL );
558  if( r != ERROR_SUCCESS )
559  continue;
560  if (info == MSICOLINFO_NAMES)
561  MSI_RecordSetStringW( rec, i+1, name );
562  else
563  msi_set_record_type_string( rec, i+1, type, temporary );
564  }
565  *prec = rec;
566  return ERROR_SUCCESS;
567 }
568 
570 {
571  MSIQUERY *query = NULL;
572  MSIRECORD *rec = NULL;
573  UINT r;
574 
575  TRACE("%d %d %p\n", hView, info, hRec);
576 
577  if( !hRec )
579 
582 
584  if( !query )
585  return ERROR_INVALID_HANDLE;
586 
587  r = MSI_ViewGetColumnInfo( query, info, &rec );
588  if ( r == ERROR_SUCCESS )
589  {
590  *hRec = alloc_msihandle( &rec->hdr );
591  if ( !*hRec )
593  msiobj_release( &rec->hdr );
594  }
595 
596  msiobj_release( &query->hdr );
597 
598  return r;
599 }
600 
602 {
603  MSIVIEW *view = NULL;
604  UINT r;
605 
606  if ( !query || !rec )
607  return ERROR_INVALID_HANDLE;
608 
609  view = query->view;
610  if ( !view || !view->ops->modify)
611  return ERROR_FUNCTION_FAILED;
612 
613  if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetIntPtr( rec, 0 ) != (INT_PTR)query )
614  return ERROR_FUNCTION_FAILED;
615 
616  r = view->ops->modify( view, mode, rec, query->row );
617  if (mode == MSIMODIFY_DELETE && r == ERROR_SUCCESS)
618  query->row--;
619 
620  return r;
621 }
622 
624  MSIHANDLE hRecord)
625 {
626  MSIQUERY *query = NULL;
627  MSIRECORD *rec = NULL;
629 
630  TRACE("%d %x %d\n", hView, eModifyMode, hRecord);
631 
633  if( !query )
634  return ERROR_INVALID_HANDLE;
635 
636  rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
637  r = MSI_ViewModify( query, eModifyMode, rec );
638 
639  msiobj_release( &query->hdr );
640  if( rec )
641  msiobj_release( &rec->hdr );
642 
643  return r;
644 }
645 
647 {
648  MSIQUERY *query;
649  const WCHAR *column;
650  MSIDBERROR r;
651  DWORD len;
652 
653  TRACE("%u %p %p\n", handle, buffer, buflen);
654 
655  if (!buflen)
656  return MSIDBERROR_INVALIDARG;
657 
659  if( !query )
660  return MSIDBERROR_INVALIDARG;
661 
662  if ((r = query->view->error)) column = query->view->error_column;
663  else column = szEmpty;
664 
665  len = strlenW( column );
666  if (buffer)
667  {
668  if (*buflen > len)
669  strcpyW( buffer, column );
670  else
672  }
673  *buflen = len;
674  msiobj_release( &query->hdr );
675  return r;
676 }
677 
679 {
680  MSIQUERY *query;
681  const WCHAR *column;
682  MSIDBERROR r;
683  DWORD len;
684 
685  TRACE("%u %p %p\n", handle, buffer, buflen);
686 
687  if (!buflen)
688  return MSIDBERROR_INVALIDARG;
689 
691  if (!query)
692  return MSIDBERROR_INVALIDARG;
693 
694  if ((r = query->view->error)) column = query->view->error_column;
695  else column = szEmpty;
696 
697  len = WideCharToMultiByte( CP_ACP, 0, column, -1, NULL, 0, NULL, NULL );
698  if (buffer)
699  {
700  if (*buflen >= len)
701  WideCharToMultiByte( CP_ACP, 0, column, -1, buffer, *buflen, NULL, NULL );
702  else
704  }
705  *buflen = len - 1;
706  msiobj_release( &query->hdr );
707  return r;
708 }
709 
711 {
712  FIXME("\n");
713  return 0;
714 }
715 
717  LPCWSTR szTransformFile, int iErrorCond )
718 {
719  HRESULT r;
721  IStorage *stg = NULL;
722  STATSTG stat;
723 
724  TRACE("%p %s %d\n", db, debugstr_w(szTransformFile), iErrorCond);
725 
726  r = StgOpenStorage( szTransformFile, NULL,
728  if ( FAILED(r) )
729  {
730  WARN("failed to open transform 0x%08x\n", r);
731  return ret;
732  }
733 
734  r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
735  if ( FAILED( r ) )
736  goto end;
737 
738  if ( !IsEqualGUID( &stat.clsid, &CLSID_MsiTransform ) )
739  goto end;
740 
741  if( TRACE_ON( msi ) )
742  enum_stream_names( stg );
743 
744  ret = msi_table_apply_transform( db, stg );
745 
746 end:
747  IStorage_Release( stg );
748 
749  return ret;
750 }
751 
753  LPCWSTR szTransformFile, int iErrorCond)
754 {
755  MSIDATABASE *db;
756  UINT r;
757 
759  if( !db )
760  {
761  IWineMsiRemoteDatabase *remote_database;
762 
763  remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
764  if ( !remote_database )
765  return ERROR_INVALID_HANDLE;
766 
767  IWineMsiRemoteDatabase_Release( remote_database );
768  WARN("MsiDatabaseApplyTransform not allowed during a custom action!\n");
769 
770  return ERROR_SUCCESS;
771  }
772 
773  r = MSI_DatabaseApplyTransformW( db, szTransformFile, iErrorCond );
774  msiobj_release( &db->hdr );
775  return r;
776 }
777 
779  LPCSTR szTransformFile, int iErrorCond)
780 {
781  LPWSTR wstr;
782  UINT ret;
783 
784  TRACE("%d %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
785 
786  wstr = strdupAtoW( szTransformFile );
787  if( szTransformFile && !wstr )
789 
790  ret = MsiDatabaseApplyTransformW( hdb, wstr, iErrorCond);
791 
792  msi_free( wstr );
793 
794  return ret;
795 }
796 
798  LPCSTR szTransformFile, int iReserved1, int iReserved2 )
799 {
800  FIXME("%d %d %s %d %d\n", hdb, hdbref,
801  debugstr_a(szTransformFile), iReserved1, iReserved2);
803 }
804 
806  LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
807 {
808  FIXME("%d %d %s %d %d\n", hdb, hdbref,
809  debugstr_w(szTransformFile), iReserved1, iReserved2);
811 }
812 
814 {
815  MSIDATABASE *db;
816  UINT r;
817 
818  TRACE("%d\n", hdb);
819 
821  if( !db )
822  {
823  IWineMsiRemoteDatabase *remote_database;
824 
825  remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
826  if ( !remote_database )
827  return ERROR_INVALID_HANDLE;
828 
829  IWineMsiRemoteDatabase_Release( remote_database );
830  WARN("not allowed during a custom action!\n");
831 
832  return ERROR_SUCCESS;
833  }
834 
835  if (db->mode == MSIDBOPEN_READONLY)
836  {
837  msiobj_release( &db->hdr );
838  return ERROR_SUCCESS;
839  }
840 
841  /* FIXME: lock the database */
842 
843  r = msi_commit_streams( db );
844  if (r != ERROR_SUCCESS) ERR("Failed to commit streams!\n");
845  else
846  {
847  r = MSI_CommitTables( db );
848  if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
849  }
850 
851  /* FIXME: unlock the database */
852 
853  msiobj_release( &db->hdr );
854 
855  if (r == ERROR_SUCCESS)
856  {
857  msi_free( db->deletefile );
858  db->deletefile = NULL;
859  }
860 
861  return r;
862 }
863 
865 {
868 };
869 
871 {
873  LPCWSTR name, table;
874  DWORD type;
875 
876  type = MSI_RecordGetInteger( rec, 4 );
877  if( type & MSITYPE_KEY )
878  {
879  info->n++;
880  if( info->rec )
881  {
882  if ( info->n == 1 )
883  {
884  table = MSI_RecordGetString( rec, 1 );
885  MSI_RecordSetStringW( info->rec, 0, table);
886  }
887 
888  name = MSI_RecordGetString( rec, 3 );
889  MSI_RecordSetStringW( info->rec, info->n, name );
890  }
891  }
892 
893  return ERROR_SUCCESS;
894 }
895 
897  LPCWSTR table, MSIRECORD **prec )
898 {
899  static const WCHAR sql[] = {
900  's','e','l','e','c','t',' ','*',' ',
901  'f','r','o','m',' ','`','_','C','o','l','u','m','n','s','`',' ',
902  'w','h','e','r','e',' ',
903  '`','T','a','b','l','e','`',' ','=',' ','\'','%','s','\'',0 };
905  MSIQUERY *query = NULL;
906  UINT r;
907 
908  if (!TABLE_Exists( db, table ))
909  return ERROR_INVALID_TABLE;
910 
911  r = MSI_OpenQuery( db, &query, sql, table );
912  if( r != ERROR_SUCCESS )
913  return r;
914 
915  /* count the number of primary key records */
916  info.n = 0;
917  info.rec = 0;
919  if( r == ERROR_SUCCESS )
920  {
921  TRACE("Found %d primary keys\n", info.n );
922 
923  /* allocate a record and fill in the names of the tables */
924  info.rec = MSI_CreateRecord( info.n );
925  info.n = 0;
927  if( r == ERROR_SUCCESS )
928  *prec = info.rec;
929  else
930  msiobj_release( &info.rec->hdr );
931  }
932  msiobj_release( &query->hdr );
933 
934  return r;
935 }
936 
938  LPCWSTR table, MSIHANDLE* phRec )
939 {
940  MSIRECORD *rec = NULL;
941  MSIDATABASE *db;
942  UINT r;
943 
944  TRACE("%d %s %p\n", hdb, debugstr_w(table), phRec);
945 
947  if( !db )
948  {
949  HRESULT hr;
950  IWineMsiRemoteDatabase *remote_database;
951 
952  remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
953  if ( !remote_database )
954  return ERROR_INVALID_HANDLE;
955 
956  hr = IWineMsiRemoteDatabase_GetPrimaryKeys( remote_database, table, phRec );
957  IWineMsiRemoteDatabase_Release( remote_database );
958 
959  if (FAILED(hr))
960  {
962  return HRESULT_CODE(hr);
963 
964  return ERROR_FUNCTION_FAILED;
965  }
966 
967  return ERROR_SUCCESS;
968  }
969 
971  if( r == ERROR_SUCCESS )
972  {
973  *phRec = alloc_msihandle( &rec->hdr );
974  if (! *phRec)
976  msiobj_release( &rec->hdr );
977  }
978  msiobj_release( &db->hdr );
979 
980  return r;
981 }
982 
984  LPCSTR table, MSIHANDLE* phRec)
985 {
986  LPWSTR szwTable = NULL;
987  UINT r;
988 
989  TRACE("%d %s %p\n", hdb, debugstr_a(table), phRec);
990 
991  if( table )
992  {
993  szwTable = strdupAtoW( table );
994  if( !szwTable )
995  return ERROR_OUTOFMEMORY;
996  }
997  r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
998  msi_free( szwTable );
999 
1000  return r;
1001 }
1002 
1004  MSIHANDLE hDatabase, LPCSTR szTableName)
1005 {
1006  LPWSTR szwTableName = NULL;
1007  MSICONDITION r;
1008 
1009  TRACE("%x %s\n", hDatabase, debugstr_a(szTableName));
1010 
1011  if( szTableName )
1012  {
1013  szwTableName = strdupAtoW( szTableName );
1014  if( !szwTableName )
1015  return MSICONDITION_ERROR;
1016  }
1017  r = MsiDatabaseIsTablePersistentW( hDatabase, szwTableName );
1018  msi_free( szwTableName );
1019 
1020  return r;
1021 }
1022 
1024  MSIHANDLE hDatabase, LPCWSTR szTableName)
1025 {
1026  MSIDATABASE *db;
1027  MSICONDITION r;
1028 
1029  TRACE("%x %s\n", hDatabase, debugstr_w(szTableName));
1030 
1031  db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
1032  if( !db )
1033  {
1034  HRESULT hr;
1036  IWineMsiRemoteDatabase *remote_database;
1037 
1038  remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hDatabase );
1039  if ( !remote_database )
1040  return MSICONDITION_ERROR;
1041 
1042  hr = IWineMsiRemoteDatabase_IsTablePersistent( remote_database,
1043  szTableName, &condition );
1044  IWineMsiRemoteDatabase_Release( remote_database );
1045 
1046  if (FAILED(hr))
1047  return MSICONDITION_ERROR;
1048 
1049  return condition;
1050  }
1051 
1052  r = MSI_DatabaseIsTablePersistent( db, szTableName );
1053 
1054  msiobj_release( &db->hdr );
1055 
1056  return r;
1057 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:218
UINT msi_table_apply_transform(MSIDATABASE *db, IStorage *stg) DECLSPEC_HIDDEN
Definition: table.c:2714
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len) DECLSPEC_HIDDEN
Definition: string.c:347
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
GLenum func
Definition: glext.h:6028
#define MSIDBOPEN_READONLY
Definition: msiquery.h:66
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:459
#define max(a, b)
Definition: svc.c:63
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:649
void msiobj_lock(MSIOBJECTHDR *info)
Definition: handle.c:232
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
MSIOBJECTHDR hdr
Definition: msipriv.h:141
UINT MSI_ViewGetColumnInfo(MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec)
Definition: msiquery.c:530
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define CP_ACP
Definition: compat.h:99
UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec)
Definition: msiquery.c:443
static void MSI_CloseView(MSIOBJECTHDR *arg)
Definition: msiquery.c:44
GLuint GLuint GLsizei count
Definition: gl.h:1545
UINT MSI_ViewModify(MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec)
Definition: msiquery.c:601
#define WARN(fmt,...)
Definition: debug.h:111
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
UINT MSI_IterateRecords(MSIQUERY *view, LPDWORD count, record_func func, LPVOID param)
Definition: msiquery.c:168
LPCWSTR mode
Definition: msipriv.h:104
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble t
Definition: gl.h:2047
UINT WINAPI MsiDatabaseApplyTransformW(MSIHANDLE hdb, LPCWSTR szTransformFile, int iErrorCond)
Definition: msiquery.c:752
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
void enum_stream_names(IStorage *stg) DECLSPEC_HIDDEN
Definition: table.c:213
#define MSITYPE_IS_BINARY(type)
Definition: msipriv.h:59
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
MSIDBERROR WINAPI MsiViewGetErrorW(MSIHANDLE handle, LPWSTR buffer, LPDWORD buflen)
Definition: msiquery.c:646
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
Definition: msiquery.c:287
#define MSITYPE_STRING
Definition: msipriv.h:47
#define MSIHANDLETYPE_DATABASE
Definition: msipriv.h:699
int32_t INT_PTR
Definition: typedefs.h:62
char * LPSTR
Definition: xmlstorage.h:182
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, LPCSTR table, MSIHANDLE *phRec)
Definition: msiquery.c:983
UINT WINAPI MsiDatabaseGenerateTransformW(MSIHANDLE hdb, MSIHANDLE hdbref, LPCWSTR szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:805
int32_t INT
Definition: typedefs.h:56
MSIHANDLE WINAPI MsiGetLastErrorRecord(void)
Definition: msiquery.c:710
MSIDBERROR WINAPI MsiViewGetErrorA(MSIHANDLE handle, LPSTR buffer, LPDWORD buflen)
Definition: msiquery.c:678
UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord)
Definition: msiquery.c:623
unsigned long MSIHANDLE
Definition: msiserver.idl:25
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, LPCSTR szTableName)
Definition: msiquery.c:1003
#define MSITYPE_UNKNOWN
Definition: msipriv.h:51
void msiobj_unlock(MSIOBJECTHDR *info)
Definition: handle.c:237
BOOL TABLE_Exists(MSIDATABASE *db, LPCWSTR name) DECLSPEC_HIDDEN
Definition: table.c:971
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:427
void * alloc_msiobject(UINT type, UINT size, msihandledestructor destroy)
Definition: handle.c:202
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *db, LPCWSTR table, MSIRECORD **prec)
Definition: msiquery.c:896
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
Definition: record.c:328
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define va_end(ap)
Definition: acmsvcex.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
string_table * strings
Definition: msipriv.h:99
#define HRESULT_FACILITY(hr)
Definition: winerror.h:79
#define debugstr_w
Definition: kernel32.h:32
UINT MSI_DatabaseOpenViewW(MSIDATABASE *db, LPCWSTR szQuery, MSIQUERY **pView)
Definition: msiquery.c:111
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
GLenum condition
Definition: glext.h:9255
#define MSIHANDLETYPE_RECORD
Definition: msipriv.h:702
smooth NULL
Definition: ftsmooth.c:416
UINT WINAPI MsiDatabaseGenerateTransformA(MSIHANDLE hdb, MSIHANDLE hdbref, LPCSTR szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:797
char * va_list
Definition: acmsvcex.h:78
#define MSITYPE_NULLABLE
Definition: msipriv.h:48
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:482
const char * LPCSTR
Definition: xmlstorage.h:183
#define STGM_READ
Definition: objbase.h:916
static const WCHAR szEmpty[]
Definition: provider.c:47
static UINT msi_primary_key_iterator(MSIRECORD *rec, LPVOID param)
Definition: msiquery.c:870
UINT WINAPI MsiDatabaseApplyTransformA(MSIHANDLE hdb, LPCSTR szTransformFile, int iErrorCond)
Definition: msiquery.c:778
enum tagMSIDBERROR MSIDBERROR
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, LPCWSTR szTableName)
Definition: msiquery.c:1023
MSICONDITION MSI_DatabaseIsTablePersistent(MSIDATABASE *db, LPCWSTR table) DECLSPEC_HIDDEN
Definition: table.c:2239
#define MSITYPE_LOCALIZABLE
Definition: msipriv.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180
Definition: parser.c:43
#define debugstr_a
Definition: kernel32.h:31
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:385
LONG HRESULT
Definition: typedefs.h:77
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8756
UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb, LPCWSTR table, MSIHANDLE *phRec)
Definition: msiquery.c:937
#define STGM_DIRECT
Definition: objbase.h:913
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:8
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MSITYPE_KEY
Definition: msipriv.h:49
UINT msi_commit_streams(MSIDATABASE *db) DECLSPEC_HIDDEN
Definition: streams.c:625
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:242
#define MSIHANDLETYPE_VIEW
Definition: msipriv.h:701
int ret
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:79
Definition: stat.h:55
GLenum GLsizei len
Definition: glext.h:6722
int MSICONDITION
Definition: msiserver.idl:33
Definition: _list.h:228
UINT MSI_RecordSetIntPtr(MSIRECORD *, UINT, INT_PTR) DECLSPEC_HIDDEN
Definition: record.c:314
GLenum mode
Definition: glext.h:6217
enum tagMSICOLINFO MSICOLINFO
UINT MSI_CommitTables(MSIDATABASE *db) DECLSPEC_HIDDEN
Definition: table.c:2204
static UINT msi_set_record_type_string(MSIRECORD *rec, UINT field, UINT type, BOOL temporary)
Definition: msiquery.c:493
UINT MSI_RecordSetIStream(MSIRECORD *, UINT, IStream *) DECLSPEC_HIDDEN
Definition: record.c:889
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:245
#define ERR(fmt,...)
Definition: debug.h:109
#define ERROR_INVALID_TABLE
Definition: winerror.h:986
#define FACILITY_WIN32
Definition: winerror.h:27
struct list mem
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
UINT VIEW_find_column(MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n)
Definition: msiquery.c:59
INT_PTR MSI_RecordGetIntPtr(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:219
UINT MSI_ParseSQL(MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, struct list *mem) DECLSPEC_HIDDEN
Definition: sql.tab.c:2714
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:813
LPWSTR deletefile
Definition: msipriv.h:102
#define sprintfW
Definition: unicode.h:58
struct view * view
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
Definition: handle.c:109
#define vsnprintfW
Definition: unicode.h:61
#define va_start(ap, A)
Definition: acmsvcex.h:91
WINE_DEFAULT_DEBUG_CHANNEL(msi)
enum tagMSIMODIFY MSIMODIFY
unsigned int UINT
Definition: ndis.h:50
UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPEC_HIDDEN
Definition: record.c:625
UINT(* record_func)(MSIRECORD *, LPVOID)
Definition: msipriv.h:847
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
#define MSITYPE_VALID
Definition: msipriv.h:45
UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
Definition: msiquery.c:569
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
#define HRESULT_CODE(hr)
Definition: winerror.h:76
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:241
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
GLuint res
Definition: glext.h:9613
UINT MSI_DatabaseApplyTransformW(MSIDATABASE *db, LPCWSTR szTransformFile, int iErrorCond)
Definition: msiquery.c:716
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
uint32_t * LPDWORD
Definition: typedefs.h:57
MSIRECORD * MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR fmt,...)
Definition: msiquery.c:206
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
static IOleDocumentView * view
Definition: activex.c:1749
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
Definition: msiquery.c:364
IUnknown * msi_get_remote(MSIHANDLE handle)
Definition: handle.c:182
GLenum GLenum GLvoid GLvoid * column
Definition: glext.h:5664
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:921
WCHAR * LPWSTR
Definition: xmlstorage.h:184
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
Definition: handle.c:157
#define TRACE_ON(x)
Definition: compat.h:65
GLenum query
Definition: glext.h:7781
Definition: dsound.c:943
UINT MSI_OpenQuery(MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt,...)
Definition: msiquery.c:143
MSIOBJECTHDR hdr
Definition: msipriv.h:97
static const WCHAR szType[]
Definition: table.c:81
#define MSI_DATASIZEMASK
Definition: msipriv.h:44
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:67
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
GLuint const GLchar * name
Definition: glext.h:6031
UINT MSI_ViewClose(MSIQUERY *query)
Definition: msiquery.c:412