ReactOS 0.4.16-dev-178-g8ba6102
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_s.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 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 for (i = 1; i <= col_count; i++)
301 {
302 ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL);
303 if (ret)
304 {
305 ERR("Error getting column type for %d\n", i);
306 continue;
307 }
308
310 {
311 IStream *stm = NULL;
312
313 ret = view->ops->fetch_stream(view, row, i, &stm);
314 if ((ret == ERROR_SUCCESS) && stm)
315 {
316 MSI_RecordSetIStream(rec, i, stm);
317 IStream_Release(stm);
318 }
319 else
320 WARN("failed to get stream\n");
321
322 continue;
323 }
324
325 ret = view->ops->fetch_int(view, row, i, &ival);
326 if (ret)
327 {
328 ERR("Error fetching data for %d\n", i);
329 continue;
330 }
331
332 if (! (type & MSITYPE_VALID))
333 ERR("Invalid type!\n");
334
335 if (type & MSITYPE_STRING)
336 {
337 int len;
338 const WCHAR *sval = msi_string_lookup(db->strings, ival, &len);
339 msi_record_set_string(rec, i, sval, len);
340 }
341 else
342 {
343 if ((type & MSI_DATASIZEMASK) == 2)
344 MSI_RecordSetInteger(rec, i, ival ? ival - (1<<15) : MSI_NULL_INTEGER);
345 else
346 MSI_RecordSetInteger(rec, i, ival - (1u<<31));
347 }
348 }
349
350 return ERROR_SUCCESS;
351}
352
354{
355 UINT row_count = 0, col_count = 0, r;
357
358 TRACE("view %p, row %u, rec %p.\n", view, row, rec);
359
360 if ((r = view->ops->get_dimensions(view, &row_count, &col_count)))
361 return r;
362
363 if (row >= row_count)
364 return ERROR_NO_MORE_ITEMS;
365
366 if (!(object = MSI_CreateRecord( col_count )))
367 return ERROR_OUTOFMEMORY;
368
369 if ((r = msi_view_refresh_row(db, view, row, object)))
370 msiobj_release( &object->hdr );
371 else
372 *rec = object;
373
374 return r;
375}
376
378{
379 MSIVIEW *view;
380 UINT r;
381
382 TRACE("%p %p\n", query, prec );
383
384 view = query->view;
385 if( !view )
387
388 r = msi_view_get_row(query->db, view, query->row, prec);
389 if (r == ERROR_SUCCESS)
390 {
391 query->row ++;
392 (*prec)->cookie = (UINT64)(ULONG_PTR)query;
393 MSI_RecordSetInteger(*prec, 0, 1);
394 }
395 else if (r == ERROR_NO_MORE_ITEMS)
396 {
397 /* end of view; reset cursor to first row */
398 query->row = 0;
399 }
400
401 return r;
402}
403
405{
407 MSIRECORD *rec = NULL;
408 UINT ret;
409
410 TRACE( "%lu, %p\n", hView, record );
411
412 if( !record )
414 *record = 0;
415
417 if (!query)
418 {
419 struct wire_record *wire_rec = NULL;
420 MSIHANDLE remote;
421
422 if (!(remote = msi_get_remote(hView)))
424
425 __TRY
426 {
427 ret = remote_ViewFetch(remote, &wire_rec);
428 }
430 {
432 }
434
435 if (!ret)
436 {
437 ret = unmarshal_record(wire_rec, record);
438 free_remote_record(wire_rec);
439 }
440 return ret;
441 }
442 ret = MSI_ViewFetch( query, &rec );
443 if( ret == ERROR_SUCCESS )
444 {
445 *record = alloc_msihandle( &rec->hdr );
446 if (! *record)
448 msiobj_release( &rec->hdr );
449 }
450 msiobj_release( &query->hdr );
451 return ret;
452}
453
455{
456 MSIVIEW *view;
457
458 TRACE("%p\n", query );
459
460 view = query->view;
461 if( !view )
463 if( !view->ops->close )
465
466 return view->ops->close( view );
467}
468
470{
472 UINT ret;
473
474 TRACE( "%lu\n", hView );
475
477 if (!query)
478 {
479 MSIHANDLE remote;
480
481 if (!(remote = msi_get_remote(hView)))
483
484 __TRY
485 {
486 ret = remote_ViewClose(remote);
487 }
489 {
491 }
493
494 return ret;
495 }
496
498 msiobj_release( &query->hdr );
499 return ret;
500}
501
503{
504 MSIVIEW *view;
505
506 TRACE("%p %p\n", query, rec);
507
508 view = query->view;
509 if( !view )
511 if( !view->ops->execute )
513 query->row = 0;
514
515 return view->ops->execute( view, rec );
516}
517
519{
521 MSIRECORD *rec = NULL;
522 UINT ret;
523
524 TRACE( "%lu, %lu\n", hView, hRec );
525
526 if( hRec )
527 {
529 if( !rec )
531 }
532
534 if( !query )
535 {
536 MSIHANDLE remote;
537
538 if (!(remote = msi_get_remote(hView)))
540
541 __TRY
542 {
543 ret = remote_ViewExecute(remote, rec ? (struct wire_record *)&rec->count : NULL);
544 }
546 {
548 }
550
551 if (rec)
552 msiobj_release(&rec->hdr);
553 return ret;
554 }
555
556 msiobj_lock( &rec->hdr );
557 ret = MSI_ViewExecute( query, rec );
558 msiobj_unlock( &rec->hdr );
559
560 msiobj_release( &query->hdr );
561 if( rec )
562 msiobj_release( &rec->hdr );
563
564 return ret;
565}
566
568{
569 WCHAR szType[0x10];
570
572 szType[0] = 'v';
573 else if (type & MSITYPE_LOCALIZABLE)
574 szType[0] = 'l';
575 else if (type & MSITYPE_UNKNOWN)
576 szType[0] = 'f';
577 else if (type & MSITYPE_STRING)
578 {
579 if (temporary)
580 szType[0] = 'g';
581 else
582 szType[0] = 's';
583 }
584 else
585 {
586 if (temporary)
587 szType[0] = 'j';
588 else
589 szType[0] = 'i';
590 }
591
593 szType[0] &= ~0x20;
594
595 swprintf( &szType[1], ARRAY_SIZE(szType) - 1, L"%d", (type&0xff) );
596
597 TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
598
599 return MSI_RecordSetStringW( rec, field, szType );
600}
601
603{
605 MSIRECORD *rec;
608 BOOL temporary;
609
610 if( !view )
612
613 if( !view->ops->get_dimensions )
615
616 r = view->ops->get_dimensions( view, NULL, &count );
617 if( r != ERROR_SUCCESS )
618 return r;
619 if( !count )
621
622 rec = MSI_CreateRecord( count );
623 if( !rec )
625
626 for( i=0; i<count; i++ )
627 {
628 name = NULL;
629 r = view->ops->get_column_info( view, i+1, &name, &type, &temporary, NULL );
630 if( r != ERROR_SUCCESS )
631 continue;
632 if (info == MSICOLINFO_NAMES)
633 MSI_RecordSetStringW( rec, i+1, name );
634 else
635 set_record_type_string( rec, i+1, type, temporary );
636 }
637 *prec = rec;
638 return ERROR_SUCCESS;
639}
640
642{
644 MSIRECORD *rec = NULL;
645 UINT r;
646
647 TRACE( "%lu, %d, %p\n", hView, info, hRec );
648
649 if( !hRec )
651
654
656 if (!query)
657 {
658 struct wire_record *wire_rec = NULL;
659 MSIHANDLE remote;
660
661 if (!(remote = msi_get_remote(hView)))
663
664 __TRY
665 {
666 r = remote_ViewGetColumnInfo(remote, info, &wire_rec);
667 }
669 {
671 }
673
674 if (!r)
675 {
676 r = unmarshal_record(wire_rec, hRec);
677 free_remote_record(wire_rec);
678 }
679
680 return r;
681 }
682
683 r = MSI_ViewGetColumnInfo( query, info, &rec );
684 if ( r == ERROR_SUCCESS )
685 {
686 *hRec = alloc_msihandle( &rec->hdr );
687 if ( !*hRec )
689 msiobj_release( &rec->hdr );
690 }
691
692 msiobj_release( &query->hdr );
693
694 return r;
695}
696
698{
699 MSIVIEW *view = NULL;
700 UINT r;
701
702 if ( !query || !rec )
704
705 view = query->view;
706 if ( !view || !view->ops->modify)
708
709 if ( mode == MSIMODIFY_UPDATE && rec->cookie != (UINT64)(ULONG_PTR)query )
711
712 r = view->ops->modify( view, mode, rec, query->row - 1 );
714 query->row--;
715
716 return r;
717}
718
719UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord )
720{
722 MSIRECORD *rec = NULL;
724
725 TRACE( "%lu, %#x, %lu\n", hView, eModifyMode, hRecord );
726
727 rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
728
729 if (!rec)
731
733 if (!query)
734 {
735 struct wire_record *wire_refreshed = NULL;
736 MSIHANDLE remote;
737
738 if (!(remote = msi_get_remote(hView)))
740
741 __TRY
742 {
743 r = remote_ViewModify(remote, eModifyMode,
744 (struct wire_record *)&rec->count, &wire_refreshed);
745 }
747 {
749 }
751
752 if (!r && (eModifyMode == MSIMODIFY_REFRESH || eModifyMode == MSIMODIFY_SEEK))
753 {
754 r = copy_remote_record(wire_refreshed, hRecord);
755 free_remote_record(wire_refreshed);
756 }
757
758 msiobj_release(&rec->hdr);
759 return r;
760 }
761
762 r = MSI_ViewModify( query, eModifyMode, rec );
763
764 msiobj_release( &query->hdr );
765 msiobj_release(&rec->hdr);
766 return r;
767}
768
770{
772 const WCHAR *column;
774
775 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
776
777 if (!buflen)
779
781 {
782 WCHAR *remote_column = NULL;
783 MSIHANDLE remote;
784
785 if (!(remote = msi_get_remote(handle)))
787
788 if (!*buflen)
790
791 __TRY
792 {
793 r = remote_ViewGetError(remote, &remote_column);
794 }
796 {
798 }
799 __ENDTRY;
800
801 if (msi_strncpyW(remote_column ? remote_column : L"", -1, buffer, buflen) == ERROR_MORE_DATA)
803
804 if (remote_column)
805 midl_user_free(remote_column);
806
807 return r;
808 }
809
810 if ((r = query->view->error)) column = query->view->error_column;
811 else column = L"";
812
813 if (msi_strncpyW(column, -1, buffer, buflen) == ERROR_MORE_DATA)
815
816 msiobj_release( &query->hdr );
817 return r;
818}
819
821{
823 const WCHAR *column;
825
826 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
827
828 if (!buflen)
830
832 {
833 WCHAR *remote_column = NULL;
834 MSIHANDLE remote;
835
836 if (!(remote = msi_get_remote(handle)))
838
839 if (!*buflen)
841
842 __TRY
843 {
844 r = remote_ViewGetError(remote, &remote_column);
845 }
847 {
849 }
850 __ENDTRY;
851
852 if (msi_strncpyWtoA(remote_column ? remote_column : L"", -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
854
855 if (remote_column)
856 midl_user_free(remote_column);
857
858 return r;
859 }
860
861 if ((r = query->view->error)) column = query->view->error_column;
862 else column = L"";
863
864 if (msi_strncpyWtoA(column, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
866
867 msiobj_release( &query->hdr );
868 return r;
869}
870
872{
873 FIXME("\n");
874 return 0;
875}
876
878{
879 HRESULT hr;
881 IStorage *stg;
882 STATSTG stat;
883
884 TRACE( "%p %s %08x\n", db, debugstr_w(transform), error_cond );
885
886 if (*transform == ':')
887 {
888 hr = IStorage_OpenStorage( db->storage, transform + 1, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
889 if (FAILED( hr ))
890 {
891 WARN( "failed to open substorage transform %#lx\n", hr );
893 }
894 }
895 else
896 {
898 if (FAILED( hr ))
899 {
900 WARN( "failed to open file transform %#lx\n", hr );
902 }
903 }
904
905 hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
906 if (FAILED( hr )) goto end;
907 if (!IsEqualGUID( &stat.clsid, &CLSID_MsiTransform )) goto end;
908 if (TRACE_ON( msi )) enum_stream_names( stg );
909
910 ret = msi_table_apply_transform( db, stg, error_cond );
911
912end:
913 IStorage_Release( stg );
914 return ret;
915}
916
918{
919 MSIDATABASE *db;
920 UINT r;
921
922 if (error_cond & ~MSITRANSFORM_ERROR_VIEWTRANSFORM) FIXME( "ignoring error conditions\n" );
923
926
927 r = MSI_DatabaseApplyTransformW( db, transform, error_cond );
928 msiobj_release( &db->hdr );
929 return r;
930}
931
932UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb, const char *transform, int error_cond )
933{
934 WCHAR *wstr;
935 UINT ret;
936
937 TRACE( "%lu, %s, %#x\n", hdb, debugstr_a(transform), error_cond );
938
939 wstr = strdupAtoW( transform );
940 if (transform && !wstr)
942
943 ret = MsiDatabaseApplyTransformW( hdb, wstr, error_cond );
944 free( wstr );
945 return ret;
946}
947
948UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile,
949 int iReserved1, int iReserved2 )
950{
951 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_a(szTransformFile), iReserved1, iReserved2 );
953}
954
956 int iReserved1, int iReserved2 )
957{
958 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_w(szTransformFile), iReserved1, iReserved2 );
960}
961
963{
964 MSIDATABASE *db;
965 UINT r;
966
967 TRACE( "%lu\n", hdb );
968
970 if( !db )
971 {
972 MSIHANDLE remote;
973
974 if (!(remote = msi_get_remote(hdb)))
976
977 WARN("not allowed during a custom action!\n");
978
979 return ERROR_SUCCESS;
980 }
981
982 if (db->mode == MSI_OPEN_READONLY)
983 {
984 msiobj_release( &db->hdr );
985 return ERROR_SUCCESS;
986 }
987
988 /* FIXME: lock the database */
989
990 r = msi_commit_streams( db );
991 if (r != ERROR_SUCCESS) ERR("Failed to commit streams!\n");
992 else
993 {
994 r = MSI_CommitTables( db );
995 if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
996 }
997
998 /* FIXME: unlock the database */
999
1000 msiobj_release( &db->hdr );
1001
1002 if (r == ERROR_SUCCESS)
1003 {
1004 free( db->deletefile );
1005 db->deletefile = NULL;
1006 }
1007
1008 return r;
1009}
1010
1012{
1015};
1016
1018{
1021 DWORD type;
1022
1024 if( type & MSITYPE_KEY )
1025 {
1026 info->n++;
1027 if( info->rec )
1028 {
1029 if ( info->n == 1 )
1030 {
1032 MSI_RecordSetStringW( info->rec, 0, table);
1033 }
1034
1036 MSI_RecordSetStringW( info->rec, info->n, name );
1037 }
1038 }
1039
1040 return ERROR_SUCCESS;
1041}
1042
1044{
1046 MSIQUERY *query = NULL;
1047 UINT r;
1048
1049 if (!TABLE_Exists( db, table ))
1050 return ERROR_INVALID_TABLE;
1051
1052 r = MSI_OpenQuery( db, &query, L"SELECT * FROM `_Columns` WHERE `Table` = '%s'", table );
1053 if( r != ERROR_SUCCESS )
1054 return r;
1055
1056 /* count the number of primary key records */
1057 info.n = 0;
1058 info.rec = 0;
1060 if( r == ERROR_SUCCESS )
1061 {
1062 TRACE( "found %lu primary keys\n", info.n );
1063
1064 /* allocate a record and fill in the names of the tables */
1065 info.rec = MSI_CreateRecord( info.n );
1066 info.n = 0;
1068 if( r == ERROR_SUCCESS )
1069 *prec = info.rec;
1070 else
1071 msiobj_release( &info.rec->hdr );
1072 }
1073 msiobj_release( &query->hdr );
1074
1075 return r;
1076}
1077
1079{
1080 MSIRECORD *rec = NULL;
1081 MSIDATABASE *db;
1082 UINT r;
1083
1084 TRACE( "%lu, %s, %p\n", hdb, debugstr_w(table), phRec );
1085
1087 if( !db )
1088 {
1089 struct wire_record *wire_rec = NULL;
1090 MSIHANDLE remote;
1091
1092 if (!(remote = msi_get_remote(hdb)))
1093 return ERROR_INVALID_HANDLE;
1094
1095 __TRY
1096 {
1097 r = remote_DatabaseGetPrimaryKeys(remote, table, &wire_rec);
1098 }
1100 {
1101 r = GetExceptionCode();
1102 }
1103 __ENDTRY
1104
1105 if (!r)
1106 {
1107 r = unmarshal_record(wire_rec, phRec);
1108 free_remote_record(wire_rec);
1109 }
1110
1111 return r;
1112 }
1113
1114 r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
1115 if( r == ERROR_SUCCESS )
1116 {
1117 *phRec = alloc_msihandle( &rec->hdr );
1118 if (! *phRec)
1120 msiobj_release( &rec->hdr );
1121 }
1122 msiobj_release( &db->hdr );
1123
1124 return r;
1125}
1126
1128{
1129 WCHAR *szwTable = NULL;
1130 UINT r;
1131
1132 TRACE( "%lu, %s, %p\n", hdb, debugstr_a(table), phRec );
1133
1134 if( table )
1135 {
1136 szwTable = strdupAtoW( table );
1137 if( !szwTable )
1138 return ERROR_OUTOFMEMORY;
1139 }
1140 r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
1141 free( szwTable );
1142
1143 return r;
1144}
1145
1146MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( MSIHANDLE hDatabase, const char *szTableName )
1147{
1148 WCHAR *szwTableName = NULL;
1150
1151 TRACE( "%lu, %s\n", hDatabase, debugstr_a(szTableName) );
1152
1153 if( szTableName )
1154 {
1155 szwTableName = strdupAtoW( szTableName );
1156 if( !szwTableName )
1157 return MSICONDITION_ERROR;
1158 }
1159 r = MsiDatabaseIsTablePersistentW( hDatabase, szwTableName );
1160 free( szwTableName );
1161
1162 return r;
1163}
1164
1166{
1167 MSIDATABASE *db;
1169
1170 TRACE( "%lu, %s\n", hDatabase, debugstr_w(szTableName) );
1171
1172 db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
1173 if( !db )
1174 {
1175 MSIHANDLE remote;
1176
1177 if (!(remote = msi_get_remote(hDatabase)))
1178 return MSICONDITION_ERROR;
1179
1180 __TRY
1181 {
1182 r = remote_DatabaseIsTablePersistent(remote, szTableName);
1183 }
1185 {
1187 }
1188 __ENDTRY
1189
1190 return r;
1191 }
1192
1193 r = MSI_DatabaseIsTablePersistent( db, szTableName );
1194
1195 msiobj_release( &db->hdr );
1196
1197 return r;
1198}
1199
1201{
1202 return MsiViewClose(view);
1203}
1204
1206{
1207 MSIHANDLE rec = 0;
1208 UINT r;
1209
1210 if ((r = unmarshal_record(remote_rec, &rec)))
1211 return r;
1212
1213 r = MsiViewExecute(view, rec);
1214
1215 MsiCloseHandle(rec);
1216 return r;
1217}
1218
1220{
1223 *rec = NULL;
1224 if (!r)
1225 *rec = marshal_record(handle);
1227 return r;
1228}
1229
1231{
1234 *rec = NULL;
1235 if (!r)
1236 *rec = marshal_record(handle);
1238 return r;
1239}
1240
1242{
1243 WCHAR empty[1];
1244 DWORD size = 1;
1245 UINT r;
1246
1248 if (r == MSIDBERROR_MOREDATA)
1249 {
1250 if (!(*column = midl_user_allocate(++size * sizeof(WCHAR))))
1253 }
1254 return r;
1255}
1256
1258 struct wire_record *remote_rec, struct wire_record **remote_refreshed)
1259{
1260 MSIHANDLE handle = 0;
1261 UINT r;
1262
1263 if ((r = unmarshal_record(remote_rec, &handle)))
1264 return r;
1265
1267 *remote_refreshed = NULL;
1268 if (!r && (mode == MSIMODIFY_REFRESH || mode == MSIMODIFY_SEEK))
1269 *remote_refreshed = marshal_record(handle);
1270
1272 return r;
1273}
unsigned long long UINT64
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define stat
Definition: acwin.h:99
#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:37
#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
#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 const WCHAR empty[]
Definition: main.c:47
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
#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
LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr)
Definition: custom.c:85
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
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
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
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 GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
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
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
static _Check_return_opt_ int __cdecl vswprintf(_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, _In_ size_t _SizeInWords, _In_z_ _Printf_format_string_ const wchar_t *_Format, va_list _ArgList)
Definition: stdio.h:977
#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:722
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:725
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:866
#define MSITYPE_UNKNOWN
Definition: msipriv.h:54
UINT msi_table_apply_transform(MSIDATABASE *db, IStorage *stg, int err_cond)
Definition: table.c:3368
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:2921
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:724
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:2886
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:719
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:469
UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
Definition: msiquery.c:353
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:769
UINT __cdecl s_remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct wire_record **rec)
Definition: msiquery.c:1230
UINT __cdecl s_remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
Definition: msiquery.c:1219
UINT WINAPI MsiDatabaseApplyTransformA(MSIHANDLE hdb, const char *transform, int error_cond)
Definition: msiquery.c:932
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:518
UINT WINAPI MsiDatabaseGenerateTransformA(MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:948
UINT __cdecl s_remote_ViewModify(MSIHANDLE view, MSIMODIFY mode, struct wire_record *remote_rec, struct wire_record **remote_refreshed)
Definition: msiquery.c:1257
UINT MSI_DatabaseApplyTransformW(MSIDATABASE *db, const WCHAR *transform, int error_cond)
Definition: msiquery.c:877
UINT MSI_ViewGetColumnInfo(MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec)
Definition: msiquery.c:602
UINT WINAPI MsiDatabaseApplyTransformW(MSIHANDLE hdb, const WCHAR *transform, int error_cond)
Definition: msiquery.c:917
static UINT set_record_type_string(MSIRECORD *rec, UINT field, UINT type, BOOL temporary)
Definition: msiquery.c:567
UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec)
Definition: msiquery.c:502
UINT WINAPI MsiDatabaseGenerateTransformW(MSIHANDLE hdb, MSIHANDLE hdbref, const WCHAR *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:955
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, const char *table, MSIHANDLE *phRec)
Definition: msiquery.c:1127
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:1078
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:962
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *db, const WCHAR *table, MSIRECORD **prec)
Definition: msiquery.c:1043
UINT MSI_ViewClose(MSIQUERY *query)
Definition: msiquery.c:454
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR fmt,...)
Definition: msiquery.c:201
UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
Definition: msiquery.c:377
UINT __cdecl s_remote_ViewExecute(MSIHANDLE view, struct wire_record *remote_rec)
Definition: msiquery.c:1205
MSIDBERROR WINAPI MsiViewGetErrorA(MSIHANDLE handle, char *buffer, DWORD *buflen)
Definition: msiquery.c:820
MSIDBERROR __cdecl s_remote_ViewGetError(MSIHANDLE view, LPWSTR *column)
Definition: msiquery.c:1241
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, const WCHAR *szTableName)
Definition: msiquery.c:1165
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:1200
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:641
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:697
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:1017
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1146
MSIHANDLE WINAPI MsiGetLastErrorRecord(void)
Definition: msiquery.c:871
@ 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
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_READ
Definition: objbase.h:917
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
UINT MSI_ParseSQL(MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, struct list *mem)
#define __EXCEPT(func)
Definition: exception.h:84
#define WINAPIV
Definition: sdbpapi.h:64
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define midl_user_free
Definition: rpc.h:45
#define midl_user_allocate
Definition: rpc.h:44
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define GetExceptionCode()
Definition: seh.h:27
HRESULT hr
Definition: shlfolder.c:183
#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:55
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
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
int ret
#define WINAPI
Definition: msvc.h:6
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:986
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:973
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185