ReactOS 0.4.17-dev-966-gf06eace
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/exception.h"
30#include "msi.h"
31#include "msiquery.h"
32#include "objbase.h"
33#include "objidl.h"
34#include "winnls.h"
35
36#include "msipriv.h"
37#include "query.h"
38#include "winemsi.h"
39
40#include "initguid.h"
41
43
45{
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 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 = wcscmp( name, col_name );
77 if( table_name )
78 x |= wcscmp( table_name, haystack_table_name );
79 if( !x )
80 {
81 *n = i;
82 return ERROR_SUCCESS;
83 }
84 }
86}
87
88UINT WINAPI MsiDatabaseOpenViewA( MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView )
89{
90 UINT r;
91 WCHAR *szwQuery;
92
93 TRACE( "%lu, %s, %p\n", hdb, debugstr_a(szQuery), phView );
94
95 if( szQuery )
96 {
97 szwQuery = strdupAtoW( szQuery );
98 if( !szwQuery )
100 }
101 else
102 szwQuery = NULL;
103
104 r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
105
106 free( szwQuery );
107 return r;
108}
109
110UINT MSI_DatabaseOpenViewW( MSIDATABASE *db, const WCHAR *szQuery, MSIQUERY **pView )
111{
113 UINT r;
114
115 TRACE( "%s, %p\n", debugstr_w(szQuery), pView );
116
117 /* pre allocate a handle to hold a pointer to the view */
120 if( !query )
122
123 msiobj_addref( &db->hdr );
124 query->db = db;
125 list_init( &query->mem );
126
127 r = MSI_ParseSQL( db, szQuery, &query->view, &query->mem );
128 if( r == ERROR_SUCCESS )
129 {
130 msiobj_addref( &query->hdr );
131 *pView = query;
132 }
133
134 msiobj_release( &query->hdr );
135 return r;
136}
137
139{
140 UINT r;
141 int size = 100, res;
143
144 /* construct the string */
145 for (;;)
146 {
147 va_list va;
148 query = malloc(size * sizeof(WCHAR));
149 va_start(va, fmt);
150 res = vswprintf(query, size, fmt, va);
151 va_end(va);
152 if (res == -1) size *= 2;
153 else if (res >= size) size = res + 1;
154 else break;
155 free(query);
156 }
157 /* perform the query */
159 free(query);
160 return r;
161}
162
165{
166 MSIRECORD *rec = NULL;
167 UINT r, n = 0, max = 0;
168
170 if( r != ERROR_SUCCESS )
171 return r;
172
173 if( count )
174 max = *count;
175
176 /* iterate a query */
177 for( n = 0; (max == 0) || (n < max); n++ )
178 {
179 r = MSI_ViewFetch( view, &rec );
180 if( r != ERROR_SUCCESS )
181 break;
182 if (func)
183 r = func( rec, param );
184 msiobj_release( &rec->hdr );
185 if( r != ERROR_SUCCESS )
186 break;
187 }
188
190
191 if( count )
192 *count = n;
193
194 if( r == ERROR_NO_MORE_ITEMS )
196
197 return r;
198}
199
200/* return a single record from a query */
202{
203 MSIRECORD *rec = NULL;
204 MSIQUERY *view = NULL;
205 UINT r;
206 int size = 100, res;
208
209 /* construct the string */
210 for (;;)
211 {
212 va_list va;
213 query = malloc(size * sizeof(WCHAR));
214 va_start(va, fmt);
215 res = vswprintf(query, size, fmt, va);
216 va_end(va);
217 if (res == -1) size *= 2;
218 else if (res >= size) size = res + 1;
219 else break;
220 free(query);
221 }
222 /* perform the query */
224 free(query);
225
226 if( r == ERROR_SUCCESS )
227 {
229 MSI_ViewFetch( view, &rec );
231 msiobj_release( &view->hdr );
232 }
233 return rec;
234}
235
237 LPCWSTR szQuery, MSIHANDLE *phView)
238{
239 MSIDATABASE *db;
241 UINT ret;
242
243 TRACE("%s %p\n", debugstr_w(szQuery), phView);
244
245 if (!phView)
247
248 if (!szQuery)
250
252 if( !db )
253 {
254 MSIHANDLE remote, remote_view;
255
256 if (!(remote = msi_get_remote(hdb)))
258
259 __TRY
260 {
261 ret = remote_DatabaseOpenView(remote, szQuery, &remote_view);
262 }
264 {
266 }
268
269 if (!ret)
270 *phView = alloc_msi_remote_handle(remote_view);
271 return ret;
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 ret = view->ops->get_dimensions(view, &row_count, &col_count);
292 if (ret)
293 return ret;
294
295 if (!col_count)
297
298 for (i = 1; i <= col_count; i++)
299 {
300 ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL);
301 if (ret)
302 {
303 ERR("Error getting column type for %d\n", i);
304 continue;
305 }
306
308 {
309 IStream *stm = NULL;
310
311 ret = view->ops->fetch_stream(view, row, i, &stm);
312 if ((ret == ERROR_SUCCESS) && stm)
313 {
314 MSI_RecordSetIStream(rec, i, stm);
315 IStream_Release(stm);
316 }
317 else
318 WARN("failed to get stream\n");
319
320 continue;
321 }
322
323 ret = view->ops->fetch_int(view, row, i, &ival);
324 if (ret)
325 {
326 ERR("Error fetching data for %d\n", i);
327 continue;
328 }
329
330 if (! (type & MSITYPE_VALID))
331 ERR("Invalid type!\n");
332
333 if (type & MSITYPE_STRING)
334 {
335 int len;
336 const WCHAR *sval = msi_string_lookup(db->strings, ival, &len);
337 msi_record_set_string(rec, i, sval, len);
338 }
339 else
340 {
341 if ((type & MSI_DATASIZEMASK) == 2)
342 MSI_RecordSetInteger(rec, i, ival ? ival - (1<<15) : MSI_NULL_INTEGER);
343 else
344 MSI_RecordSetInteger(rec, i, ival - (1u<<31));
345 }
346 }
347
348 return ERROR_SUCCESS;
349}
350
352{
353 UINT row_count = 0, col_count = 0, r;
355
356 if ((r = view->ops->get_dimensions(view, &row_count, &col_count)))
357 return r;
358
359 if (row >= row_count)
360 return ERROR_NO_MORE_ITEMS;
361
362 if (!(object = MSI_CreateRecord( col_count )))
363 return ERROR_OUTOFMEMORY;
364
365 if ((r = msi_view_refresh_row(db, view, row, object)))
366 msiobj_release( &object->hdr );
367 else
368 *rec = object;
369
370 return r;
371}
372
374{
375 MSIVIEW *view;
376 UINT r;
377
378 TRACE("%p %p\n", query, prec );
379
380 view = query->view;
381 if( !view )
383
384 r = msi_view_get_row(query->db, view, query->row, prec);
385 if (r == ERROR_SUCCESS)
386 {
387 query->row ++;
388 (*prec)->cookie = (UINT64)(ULONG_PTR)query;
389 MSI_RecordSetInteger(*prec, 0, 1);
390 }
391 else if (r == ERROR_NO_MORE_ITEMS)
392 {
393 /* end of view; reset cursor to first row */
394 query->row = 0;
395 }
396
397 return r;
398}
399
401{
403 MSIRECORD *rec = NULL;
404 UINT ret;
405
406 TRACE( "%lu, %p\n", hView, record );
407
408 if( !record )
410 *record = 0;
411
413 if (!query)
414 {
415 struct wire_record *wire_rec = NULL;
416 MSIHANDLE remote;
417
418 if (!(remote = msi_get_remote(hView)))
420
421 __TRY
422 {
423 ret = remote_ViewFetch(remote, &wire_rec);
424 }
426 {
428 }
430
431 if (!ret)
432 {
433 ret = unmarshal_record(wire_rec, record);
434 free_remote_record(wire_rec);
435 }
436 return ret;
437 }
438 ret = MSI_ViewFetch( query, &rec );
439 if( ret == ERROR_SUCCESS )
440 {
441 *record = alloc_msihandle( &rec->hdr );
442 if (! *record)
444 msiobj_release( &rec->hdr );
445 }
446 msiobj_release( &query->hdr );
447 return ret;
448}
449
451{
452 MSIVIEW *view;
453
454 TRACE("%p\n", query );
455
456 view = query->view;
457 if( !view )
459 if( !view->ops->close )
461
462 return view->ops->close( view );
463}
464
466{
468 UINT ret;
469
470 TRACE( "%lu\n", hView );
471
473 if (!query)
474 {
475 MSIHANDLE remote;
476
477 if (!(remote = msi_get_remote(hView)))
479
480 __TRY
481 {
482 ret = remote_ViewClose(remote);
483 }
485 {
487 }
489
490 return ret;
491 }
492
494 msiobj_release( &query->hdr );
495 return ret;
496}
497
499{
500 MSIVIEW *view;
501
502 TRACE("%p %p\n", query, rec);
503
504 view = query->view;
505 if( !view )
507 if( !view->ops->execute )
509 query->row = 0;
510
511 return view->ops->execute( view, rec );
512}
513
515{
517 MSIRECORD *rec = NULL;
518 UINT ret;
519
520 TRACE( "%lu, %lu\n", hView, hRec );
521
522 if( hRec )
523 {
525 if( !rec )
527 }
528
530 if( !query )
531 {
532 MSIHANDLE remote;
533
534 if (!(remote = msi_get_remote(hView)))
536
537 __TRY
538 {
539 ret = remote_ViewExecute(remote, rec ? (struct wire_record *)&rec->count : NULL);
540 }
542 {
544 }
546
547 if (rec)
548 msiobj_release(&rec->hdr);
549 return ret;
550 }
551
552 msiobj_lock( &rec->hdr );
553 ret = MSI_ViewExecute( query, rec );
554 msiobj_unlock( &rec->hdr );
555
556 msiobj_release( &query->hdr );
557 if( rec )
558 msiobj_release( &rec->hdr );
559
560 return ret;
561}
562
564{
565 WCHAR szType[0x10];
566
568 szType[0] = 'v';
569 else if (type & MSITYPE_LOCALIZABLE)
570 szType[0] = 'l';
571 else if (type & MSITYPE_UNKNOWN)
572 szType[0] = 'f';
573 else if (type & MSITYPE_STRING)
574 {
575 if (temporary)
576 szType[0] = 'g';
577 else
578 szType[0] = 's';
579 }
580 else
581 {
582 if (temporary)
583 szType[0] = 'j';
584 else
585 szType[0] = 'i';
586 }
587
589 szType[0] &= ~0x20;
590
591 swprintf( &szType[1], ARRAY_SIZE(szType) - 1, L"%d", (type&0xff) );
592
593 TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
594
595 return MSI_RecordSetStringW( rec, field, szType );
596}
597
599{
601 MSIRECORD *rec;
604 BOOL temporary;
605
606 if( !view )
608
609 if( !view->ops->get_dimensions )
611
612 r = view->ops->get_dimensions( view, NULL, &count );
613 if( r != ERROR_SUCCESS )
614 return r;
615 if( !count )
617
618 rec = MSI_CreateRecord( count );
619 if( !rec )
621
622 for( i=0; i<count; i++ )
623 {
624 name = NULL;
625 r = view->ops->get_column_info( view, i+1, &name, &type, &temporary, NULL );
626 if( r != ERROR_SUCCESS )
627 continue;
628 if (info == MSICOLINFO_NAMES)
629 MSI_RecordSetStringW( rec, i+1, name );
630 else
631 set_record_type_string( rec, i+1, type, temporary );
632 }
633 *prec = rec;
634 return ERROR_SUCCESS;
635}
636
638{
640 MSIRECORD *rec = NULL;
641 UINT r;
642
643 TRACE( "%lu, %d, %p\n", hView, info, hRec );
644
645 if( !hRec )
647
650
652 if (!query)
653 {
654 struct wire_record *wire_rec = NULL;
655 MSIHANDLE remote;
656
657 if (!(remote = msi_get_remote(hView)))
659
660 __TRY
661 {
662 r = remote_ViewGetColumnInfo(remote, info, &wire_rec);
663 }
665 {
667 }
669
670 if (!r)
671 {
672 r = unmarshal_record(wire_rec, hRec);
673 free_remote_record(wire_rec);
674 }
675
676 return r;
677 }
678
679 r = MSI_ViewGetColumnInfo( query, info, &rec );
680 if ( r == ERROR_SUCCESS )
681 {
682 *hRec = alloc_msihandle( &rec->hdr );
683 if ( !*hRec )
685 msiobj_release( &rec->hdr );
686 }
687
688 msiobj_release( &query->hdr );
689
690 return r;
691}
692
694{
695 MSIVIEW *view = NULL;
696 UINT r;
697
698 if ( !query || !rec )
700
701 view = query->view;
702 if ( !view || !view->ops->modify)
704
705 if ( mode == MSIMODIFY_UPDATE && rec->cookie != (UINT64)(ULONG_PTR)query )
707
708 r = view->ops->modify( view, mode, rec, query->row - 1 );
710 query->row--;
711
712 return r;
713}
714
715UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord )
716{
718 MSIRECORD *rec = NULL;
720
721 TRACE( "%lu, %#x, %lu\n", hView, eModifyMode, hRecord );
722
723 rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
724
725 if (!rec)
727
729 if (!query)
730 {
731 struct wire_record *wire_refreshed = NULL;
732 MSIHANDLE remote;
733
734 if (!(remote = msi_get_remote(hView)))
736
737 __TRY
738 {
739 r = remote_ViewModify(remote, eModifyMode,
740 (struct wire_record *)&rec->count, &wire_refreshed);
741 }
743 {
745 }
747
748 if (!r && (eModifyMode == MSIMODIFY_REFRESH || eModifyMode == MSIMODIFY_SEEK))
749 {
750 r = copy_remote_record(wire_refreshed, hRecord);
751 free_remote_record(wire_refreshed);
752 }
753
754 msiobj_release(&rec->hdr);
755 return r;
756 }
757
758 r = MSI_ViewModify( query, eModifyMode, rec );
759
760 msiobj_release( &query->hdr );
761 msiobj_release(&rec->hdr);
762 return r;
763}
764
766{
768 const WCHAR *column;
770
771 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
772
773 if (!buflen)
775
777 {
778 WCHAR *remote_column = NULL;
779 MSIHANDLE remote;
780
781 if (!(remote = msi_get_remote(handle)))
783
784 if (!*buflen)
786
787 __TRY
788 {
789 r = remote_ViewGetError(remote, &remote_column);
790 }
792 {
794 }
795 __ENDTRY;
796
797 if (msi_strncpyW(remote_column ? remote_column : L"", -1, buffer, buflen) == ERROR_MORE_DATA)
799
800 if (remote_column)
801 midl_user_free(remote_column);
802
803 return r;
804 }
805
806 if ((r = query->view->error)) column = query->view->error_column;
807 else column = L"";
808
809 if (msi_strncpyW(column, -1, buffer, buflen) == ERROR_MORE_DATA)
811
812 msiobj_release( &query->hdr );
813 return r;
814}
815
817{
819 const WCHAR *column;
821
822 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
823
824 if (!buflen)
826
828 {
829 WCHAR *remote_column = NULL;
830 MSIHANDLE remote;
831
832 if (!(remote = msi_get_remote(handle)))
834
835 if (!*buflen)
837
838 __TRY
839 {
840 r = remote_ViewGetError(remote, &remote_column);
841 }
843 {
845 }
846 __ENDTRY;
847
848 if (msi_strncpyWtoA(remote_column ? remote_column : L"", -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
850
851 if (remote_column)
852 midl_user_free(remote_column);
853
854 return r;
855 }
856
857 if ((r = query->view->error)) column = query->view->error_column;
858 else column = L"";
859
860 if (msi_strncpyWtoA(column, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
862
863 msiobj_release( &query->hdr );
864 return r;
865}
866
868{
869 FIXME("\n");
870 return 0;
871}
872
874{
875 HRESULT hr;
877 IStorage *stg;
878 STATSTG stat;
879
880 TRACE( "%p %s %08x\n", db, debugstr_w(transform), error_cond );
881
882 if (*transform == ':')
883 {
884 hr = IStorage_OpenStorage( db->storage, transform + 1, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
885 if (FAILED( hr ))
886 {
887 WARN( "failed to open substorage transform %#lx\n", hr );
889 }
890 }
891 else
892 {
894 if (FAILED( hr ))
895 {
896 WARN( "failed to open file transform %#lx\n", hr );
898 }
899 }
900
901 hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
902 if (FAILED( hr )) goto end;
903 if (!IsEqualGUID( &stat.clsid, &CLSID_MsiTransform )) goto end;
904 if (TRACE_ON( msi )) enum_stream_names( stg );
905
906 ret = msi_table_apply_transform( db, stg, error_cond );
907
908end:
909 IStorage_Release( stg );
910 return ret;
911}
912
914{
915 MSIDATABASE *db;
916 UINT r;
917
918 if (error_cond & ~MSITRANSFORM_ERROR_VIEWTRANSFORM) FIXME( "ignoring error conditions\n" );
919
922
923 r = MSI_DatabaseApplyTransformW( db, transform, error_cond );
924 msiobj_release( &db->hdr );
925 return r;
926}
927
928UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb, const char *transform, int error_cond )
929{
930 WCHAR *wstr;
931 UINT ret;
932
933 TRACE( "%lu, %s, %#x\n", hdb, debugstr_a(transform), error_cond );
934
935 wstr = strdupAtoW( transform );
936 if (transform && !wstr)
938
939 ret = MsiDatabaseApplyTransformW( hdb, wstr, error_cond );
940 free( wstr );
941 return ret;
942}
943
944UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile,
945 int iReserved1, int iReserved2 )
946{
947 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_a(szTransformFile), iReserved1, iReserved2 );
949}
950
952 int iReserved1, int iReserved2 )
953{
954 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_w(szTransformFile), iReserved1, iReserved2 );
956}
957
959{
960 MSIDATABASE *db;
961 UINT r;
962
963 TRACE( "%lu\n", hdb );
964
966 if( !db )
967 {
968 MSIHANDLE remote;
969
970 if (!(remote = msi_get_remote(hdb)))
972
973 WARN("not allowed during a custom action!\n");
974
975 return ERROR_SUCCESS;
976 }
977
978 if (db->mode == MSI_OPEN_READONLY)
979 {
980 msiobj_release( &db->hdr );
981 return ERROR_SUCCESS;
982 }
983
984 /* FIXME: lock the database */
985
986 r = msi_commit_streams( db );
987 if (r != ERROR_SUCCESS) ERR("Failed to commit streams!\n");
988 else
989 {
990 r = MSI_CommitTables( db );
991 if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
992 }
993
994 /* FIXME: unlock the database */
995
996 msiobj_release( &db->hdr );
997
998 if (r == ERROR_SUCCESS)
999 {
1000 free( db->deletefile );
1001 db->deletefile = NULL;
1002 }
1003
1004 return r;
1005}
1006
1008{
1011};
1012
1014{
1017 DWORD type;
1018
1020 if( type & MSITYPE_KEY )
1021 {
1022 info->n++;
1023 if( info->rec )
1024 {
1025 if ( info->n == 1 )
1026 {
1028 MSI_RecordSetStringW( info->rec, 0, table);
1029 }
1030
1032 MSI_RecordSetStringW( info->rec, info->n, name );
1033 }
1034 }
1035
1036 return ERROR_SUCCESS;
1037}
1038
1040{
1042 MSIQUERY *query = NULL;
1043 UINT r;
1044
1045 if (!TABLE_Exists( db, table ))
1046 return ERROR_INVALID_TABLE;
1047
1048 r = MSI_OpenQuery( db, &query, L"SELECT * FROM `_Columns` WHERE `Table` = '%s'", table );
1049 if( r != ERROR_SUCCESS )
1050 return r;
1051
1052 /* count the number of primary key records */
1053 info.n = 0;
1054 info.rec = 0;
1056 if( r == ERROR_SUCCESS )
1057 {
1058 TRACE( "found %lu primary keys\n", info.n );
1059
1060 /* allocate a record and fill in the names of the tables */
1061 info.rec = MSI_CreateRecord( info.n );
1062 info.n = 0;
1064 if( r == ERROR_SUCCESS )
1065 *prec = info.rec;
1066 else
1067 msiobj_release( &info.rec->hdr );
1068 }
1069 msiobj_release( &query->hdr );
1070
1071 return r;
1072}
1073
1075{
1076 MSIRECORD *rec = NULL;
1077 MSIDATABASE *db;
1078 UINT r;
1079
1080 TRACE( "%lu, %s, %p\n", hdb, debugstr_w(table), phRec );
1081
1083 if( !db )
1084 {
1085 struct wire_record *wire_rec = NULL;
1086 MSIHANDLE remote;
1087
1088 if (!(remote = msi_get_remote(hdb)))
1089 return ERROR_INVALID_HANDLE;
1090
1091 __TRY
1092 {
1093 r = remote_DatabaseGetPrimaryKeys(remote, table, &wire_rec);
1094 }
1096 {
1097 r = GetExceptionCode();
1098 }
1099 __ENDTRY
1100
1101 if (!r)
1102 {
1103 r = unmarshal_record(wire_rec, phRec);
1104 free_remote_record(wire_rec);
1105 }
1106
1107 return r;
1108 }
1109
1110 r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
1111 if( r == ERROR_SUCCESS )
1112 {
1113 *phRec = alloc_msihandle( &rec->hdr );
1114 if (! *phRec)
1116 msiobj_release( &rec->hdr );
1117 }
1118 msiobj_release( &db->hdr );
1119
1120 return r;
1121}
1122
1124{
1125 WCHAR *szwTable = NULL;
1126 UINT r;
1127
1128 TRACE( "%lu, %s, %p\n", hdb, debugstr_a(table), phRec );
1129
1130 if( table )
1131 {
1132 szwTable = strdupAtoW( table );
1133 if( !szwTable )
1134 return ERROR_OUTOFMEMORY;
1135 }
1136 r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
1137 free( szwTable );
1138
1139 return r;
1140}
1141
1142MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( MSIHANDLE hDatabase, const char *szTableName )
1143{
1144 WCHAR *szwTableName = NULL;
1146
1147 TRACE( "%lu, %s\n", hDatabase, debugstr_a(szTableName) );
1148
1149 if( szTableName )
1150 {
1151 szwTableName = strdupAtoW( szTableName );
1152 if( !szwTableName )
1153 return MSICONDITION_ERROR;
1154 }
1155 r = MsiDatabaseIsTablePersistentW( hDatabase, szwTableName );
1156 free( szwTableName );
1157
1158 return r;
1159}
1160
1162{
1163 MSIDATABASE *db;
1165
1166 TRACE( "%lu, %s\n", hDatabase, debugstr_w(szTableName) );
1167
1168 db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
1169 if( !db )
1170 {
1171 MSIHANDLE remote;
1172
1173 if (!(remote = msi_get_remote(hDatabase)))
1174 return MSICONDITION_ERROR;
1175
1176 __TRY
1177 {
1178 r = remote_DatabaseIsTablePersistent(remote, szTableName);
1179 }
1181 {
1183 }
1184 __ENDTRY
1185
1186 return r;
1187 }
1188
1189 r = MSI_DatabaseIsTablePersistent( db, szTableName );
1190
1191 msiobj_release( &db->hdr );
1192
1193 return r;
1194}
1195
1197{
1198 return MsiViewClose(view);
1199}
1200
1202{
1203 MSIHANDLE rec = 0;
1204 UINT r;
1205
1206 if ((r = unmarshal_record(remote_rec, &rec)))
1207 return r;
1208
1209 r = MsiViewExecute(view, rec);
1210
1211 MsiCloseHandle(rec);
1212 return r;
1213}
1214
1216{
1219 *rec = NULL;
1220 if (!r)
1221 *rec = marshal_record(handle);
1223 return r;
1224}
1225
1227{
1230 *rec = NULL;
1231 if (!r)
1232 *rec = marshal_record(handle);
1234 return r;
1235}
1236
1238{
1239 WCHAR empty[1];
1240 DWORD size = 1;
1241 UINT r;
1242
1244 if (r == MSIDBERROR_MOREDATA)
1245 {
1246 if (!(*column = midl_user_allocate(++size * sizeof(WCHAR))))
1249 }
1250 return r;
1251}
1252
1254 struct wire_record *remote_rec, struct wire_record **remote_refreshed)
1255{
1256 MSIHANDLE handle = 0;
1257 UINT r;
1258
1259 if ((r = unmarshal_record(remote_rec, &handle)))
1260 return r;
1261
1263 *remote_refreshed = NULL;
1264 if (!r && (mode == MSIMODIFY_REFRESH || mode == MSIMODIFY_SEEK))
1265 *remote_refreshed = marshal_record(handle);
1266
1268 return r;
1269}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define stat
Definition: acwin.h:100
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: list.h:39
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr)
Definition: rpc.c:184
static const WCHAR empty[1]
Definition: string.c:47
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:61
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define __TRY
Definition: compat.h:80
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define TRACE_ON(x)
Definition: compat.h:75
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define __ENDTRY
Definition: compat.h:82
void msiobj_lock(MSIOBJECTHDR *info)
Definition: handle.c:231
void * alloc_msiobject(UINT type, UINT size, msihandledestructor destroy)
Definition: handle.c:201
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
Definition: handle.c:111
MSIHANDLE msi_get_remote(MSIHANDLE handle)
Definition: handle.c:183
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
MSIHANDLE alloc_msi_remote_handle(MSIHANDLE remote)
Definition: handle.c:135
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
Definition: handle.c:158
void msiobj_unlock(MSIOBJECTHDR *info)
Definition: handle.c:236
UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz)
Definition: install.c:213
UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remote)
Definition: install.c:190
#define __cdecl
Definition: corecrt.h:121
static int __cdecl vswprintf(wchar_t *buffer, size_t size, const wchar_t *format, va_list args)
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8701
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
#define swprintf
Definition: precomp.h:40
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum mode
Definition: glext.h:6217
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
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
unsigned int UINT
Definition: sysinfo.c:13
#define GetExceptionCode
Definition: excpt.h:83
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
#define MSIHANDLETYPE_DATABASE
Definition: msipriv.h:746
UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int)
Definition: record.c:573
UINT copy_remote_record(const struct wire_record *rec, MSIHANDLE handle)
Definition: record.c:1052
BOOL TABLE_Exists(MSIDATABASE *db, LPCWSTR name)
Definition: table.c:962
#define MSITYPE_VALID
Definition: msipriv.h:48
#define MSIHANDLETYPE_RECORD
Definition: msipriv.h:749
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int)
Definition: record.c:280
UINT MSI_RecordSetIStream(MSIRECORD *, UINT, IStream *)
Definition: record.c:836
#define MSITYPE_IS_BINARY(type)
Definition: msipriv.h:62
#define MSITYPE_STRING
Definition: msipriv.h:50
UINT msi_commit_streams(MSIDATABASE *db)
Definition: streams.c:607
UINT(* record_func)(MSIRECORD *, LPVOID)
Definition: msipriv.h:890
#define MSITYPE_UNKNOWN
Definition: msipriv.h:54
UINT msi_table_apply_transform(MSIDATABASE *db, IStorage *stg, int err_cond)
Definition: table.c:3385
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
#define MSITYPE_NULLABLE
Definition: msipriv.h:51
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len)
Definition: string.c:343
#define MSI_OPEN_READONLY
Definition: msipriv.h:99
void enum_stream_names(IStorage *stg)
Definition: table.c:206
MSICONDITION MSI_DatabaseIsTablePersistent(MSIDATABASE *db, LPCWSTR table)
Definition: table.c:2938
void free_remote_record(struct wire_record *rec)
Definition: record.c:1149
#define MSI_DATASIZEMASK
Definition: msipriv.h:47
#define MSITYPE_KEY
Definition: msipriv.h:52
#define MSIHANDLETYPE_VIEW
Definition: msipriv.h:748
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR)
Definition: record.c:597
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76
struct wire_record * marshal_record(MSIHANDLE handle)
Definition: record.c:1109
#define MSITYPE_LOCALIZABLE
Definition: msipriv.h:49
UINT MSI_CommitTables(MSIDATABASE *db)
Definition: table.c:2903
UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out)
Definition: record.c:1095
UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord)
Definition: msiquery.c:715
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:465
UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
Definition: msiquery.c:351
UINT msi_view_refresh_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD *rec)
Definition: msiquery.c:287
static void MSI_CloseView(MSIOBJECTHDR *arg)
Definition: msiquery.c:44
MSIDBERROR WINAPI MsiViewGetErrorW(MSIHANDLE handle, WCHAR *buffer, DWORD *buflen)
Definition: msiquery.c:765
UINT __cdecl s_remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct wire_record **rec)
Definition: msiquery.c:1226
UINT __cdecl s_remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
Definition: msiquery.c:1215
UINT WINAPI MsiDatabaseApplyTransformA(MSIHANDLE hdb, const char *transform, int error_cond)
Definition: msiquery.c:928
UINT MSI_IterateRecords(MSIQUERY *view, LPDWORD count, record_func func, LPVOID param)
Definition: msiquery.c:163
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:514
UINT WINAPI MsiDatabaseGenerateTransformA(MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:944
UINT __cdecl s_remote_ViewModify(MSIHANDLE view, MSIMODIFY mode, struct wire_record *remote_rec, struct wire_record **remote_refreshed)
Definition: msiquery.c:1253
UINT MSI_DatabaseApplyTransformW(MSIDATABASE *db, const WCHAR *transform, int error_cond)
Definition: msiquery.c:873
UINT MSI_ViewGetColumnInfo(MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec)
Definition: msiquery.c:598
UINT WINAPI MsiDatabaseApplyTransformW(MSIHANDLE hdb, const WCHAR *transform, int error_cond)
Definition: msiquery.c:913
static UINT set_record_type_string(MSIRECORD *rec, UINT field, UINT type, BOOL temporary)
Definition: msiquery.c:563
UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec)
Definition: msiquery.c:498
UINT WINAPI MsiDatabaseGenerateTransformW(MSIHANDLE hdb, MSIHANDLE hdbref, const WCHAR *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:951
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, const char *table, MSIHANDLE *phRec)
Definition: msiquery.c:1123
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:236
UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb, const WCHAR *table, MSIHANDLE *phRec)
Definition: msiquery.c:1074
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:958
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *db, const WCHAR *table, MSIRECORD **prec)
Definition: msiquery.c:1039
UINT MSI_ViewClose(MSIQUERY *query)
Definition: msiquery.c:450
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR fmt,...)
Definition: msiquery.c:201
UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
Definition: msiquery.c:373
UINT __cdecl s_remote_ViewExecute(MSIHANDLE view, struct wire_record *remote_rec)
Definition: msiquery.c:1201
MSIDBERROR WINAPI MsiViewGetErrorA(MSIHANDLE handle, char *buffer, DWORD *buflen)
Definition: msiquery.c:816
MSIDBERROR __cdecl s_remote_ViewGetError(MSIHANDLE view, LPWSTR *column)
Definition: msiquery.c:1237
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, const WCHAR *szTableName)
Definition: msiquery.c:1161
UINT VIEW_find_column(MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n)
Definition: msiquery.c:59
UINT __cdecl s_remote_ViewClose(MSIHANDLE view)
Definition: msiquery.c:1196
UINT MSI_DatabaseOpenViewW(MSIDATABASE *db, const WCHAR *szQuery, MSIQUERY **pView)
Definition: msiquery.c:110
UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
Definition: msiquery.c:637
UINT WINAPIV MSI_OpenQuery(MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt,...)
Definition: msiquery.c:138
UINT MSI_ViewModify(MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec)
Definition: msiquery.c:693
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
static UINT primary_key_iterator(MSIRECORD *rec, void *param)
Definition: msiquery.c:1013
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:400
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1142
MSIHANDLE WINAPI MsiGetLastErrorRecord(void)
Definition: msiquery.c:867
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_UPDATE
Definition: msiquery.h:53
@ MSIMODIFY_SEEK
Definition: msiquery.h:50
@ MSIMODIFY_REFRESH
Definition: msiquery.h:51
@ MSITRANSFORM_ERROR_VIEWTRANSFORM
Definition: msiquery.h:156
@ MSIDBERROR_FUNCTIONERROR
Definition: msiquery.h:108
@ MSIDBERROR_INVALIDARG
Definition: msiquery.h:106
@ MSIDBERROR_MOREDATA
Definition: msiquery.h:107
@ MSICONDITION_ERROR
Definition: msiquery.h:29
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
@ MSICOLINFO_NAMES
Definition: msiquery.h:36
@ MSICOLINFO_TYPES
Definition: msiquery.h:37
#define STGM_DIRECT
Definition: objbase.h:933
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:942
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:941
#define STGM_READ
Definition: objbase.h:936
short WCHAR
Definition: pedump.c:58
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
UINT MSI_ParseSQL(MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, struct list *mem)
#define WINAPIV
Definition: sdbpapi.h:64
#define midl_user_free
Definition: rpc.h:41
#define midl_user_allocate
Definition: rpc.h:40
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:230
#define TRACE(s)
Definition: solgame.cpp:4
Definition: parser.c:44
Definition: dsound.c:943
Definition: name.c:39
struct list mem
struct view * view
Definition: stat.h:66
MSIOBJECTHDR hdr
Definition: msipriv.h:108
LPWSTR deletefile
Definition: msipriv.h:113
IStorage * storage
Definition: msipriv.h:109
string_table * strings
Definition: msipriv.h:110
MSIOBJECTHDR hdr
Definition: msipriv.h:151
UINT count
Definition: msipriv.h:152
UINT64 cookie
Definition: msipriv.h:153
#define max(a, b)
Definition: svc.c:63
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define WINAPI
Definition: msvc.h:6
#define __EXCEPT(func)
Definition: exception.h:62
int MSIDBERROR
Definition: winemsi.idl:35
int MSICONDITION
Definition: winemsi.idl:29
unsigned long MSIHANDLE
Definition: winemsi.idl:27
int MSIMODIFY
Definition: winemsi.idl:33
int MSICOLINFO
Definition: winemsi.idl:32
#define ERROR_INVALID_TABLE
Definition: winerror.h:1334
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:1321
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333