ReactOS 0.4.15-dev-7842-g558ab78
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 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 = 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 msi_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 = msi_alloc( 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 msi_free( query );
156 }
157 /* perform the 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 = msi_alloc( 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 msi_free( query );
221 }
222 /* perform the 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 UINT type, BOOL temporary )
569{
570 WCHAR szType[0x10];
571
573 szType[0] = 'v';
574 else if (type & MSITYPE_LOCALIZABLE)
575 szType[0] = 'l';
576 else if (type & MSITYPE_UNKNOWN)
577 szType[0] = 'f';
578 else if (type & MSITYPE_STRING)
579 {
580 if (temporary)
581 szType[0] = 'g';
582 else
583 szType[0] = 's';
584 }
585 else
586 {
587 if (temporary)
588 szType[0] = 'j';
589 else
590 szType[0] = 'i';
591 }
592
594 szType[0] &= ~0x20;
595
596 swprintf( &szType[1], ARRAY_SIZE(szType) - 1, L"%d", (type&0xff) );
597
598 TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
599
600 return MSI_RecordSetStringW( rec, field, szType );
601}
602
604{
606 MSIRECORD *rec;
609 BOOL temporary;
610
611 if( !view )
613
614 if( !view->ops->get_dimensions )
616
617 r = view->ops->get_dimensions( view, NULL, &count );
618 if( r != ERROR_SUCCESS )
619 return r;
620 if( !count )
622
623 rec = MSI_CreateRecord( count );
624 if( !rec )
626
627 for( i=0; i<count; i++ )
628 {
629 name = NULL;
630 r = view->ops->get_column_info( view, i+1, &name, &type, &temporary, NULL );
631 if( r != ERROR_SUCCESS )
632 continue;
633 if (info == MSICOLINFO_NAMES)
634 MSI_RecordSetStringW( rec, i+1, name );
635 else
636 msi_set_record_type_string( rec, i+1, type, temporary );
637 }
638 *prec = rec;
639 return ERROR_SUCCESS;
640}
641
643{
645 MSIRECORD *rec = NULL;
646 UINT r;
647
648 TRACE( "%lu, %d, %p\n", hView, info, hRec );
649
650 if( !hRec )
652
655
657 if (!query)
658 {
659 struct wire_record *wire_rec = NULL;
660 MSIHANDLE remote;
661
662 if (!(remote = msi_get_remote(hView)))
664
665 __TRY
666 {
667 r = remote_ViewGetColumnInfo(remote, info, &wire_rec);
668 }
670 {
672 }
674
675 if (!r)
676 {
677 r = unmarshal_record(wire_rec, hRec);
678 free_remote_record(wire_rec);
679 }
680
681 return r;
682 }
683
684 r = MSI_ViewGetColumnInfo( query, info, &rec );
685 if ( r == ERROR_SUCCESS )
686 {
687 *hRec = alloc_msihandle( &rec->hdr );
688 if ( !*hRec )
690 msiobj_release( &rec->hdr );
691 }
692
693 msiobj_release( &query->hdr );
694
695 return r;
696}
697
699{
700 MSIVIEW *view = NULL;
701 UINT r;
702
703 if ( !query || !rec )
705
706 view = query->view;
707 if ( !view || !view->ops->modify)
709
710 if ( mode == MSIMODIFY_UPDATE && rec->cookie != (UINT64)(ULONG_PTR)query )
712
713 r = view->ops->modify( view, mode, rec, query->row - 1 );
715 query->row--;
716
717 return r;
718}
719
720UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord )
721{
723 MSIRECORD *rec = NULL;
725
726 TRACE( "%lu, %#x, %lu\n", hView, eModifyMode, hRecord );
727
728 rec = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
729
730 if (!rec)
732
734 if (!query)
735 {
736 struct wire_record *wire_refreshed = NULL;
737 MSIHANDLE remote;
738
739 if (!(remote = msi_get_remote(hView)))
741
742 __TRY
743 {
744 r = remote_ViewModify(remote, eModifyMode,
745 (struct wire_record *)&rec->count, &wire_refreshed);
746 }
748 {
750 }
752
753 if (!r && (eModifyMode == MSIMODIFY_REFRESH || eModifyMode == MSIMODIFY_SEEK))
754 {
755 r = copy_remote_record(wire_refreshed, hRecord);
756 free_remote_record(wire_refreshed);
757 }
758
759 msiobj_release(&rec->hdr);
760 return r;
761 }
762
763 r = MSI_ViewModify( query, eModifyMode, rec );
764
765 msiobj_release( &query->hdr );
766 msiobj_release(&rec->hdr);
767 return r;
768}
769
771{
773 const WCHAR *column;
775
776 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
777
778 if (!buflen)
780
782 {
783 WCHAR *remote_column = NULL;
784 MSIHANDLE remote;
785
786 if (!(remote = msi_get_remote(handle)))
788
789 if (!*buflen)
791
792 __TRY
793 {
794 r = remote_ViewGetError(remote, &remote_column);
795 }
797 {
799 }
800 __ENDTRY;
801
802 if (msi_strncpyW(remote_column ? remote_column : L"", -1, buffer, buflen) == ERROR_MORE_DATA)
804
805 if (remote_column)
806 midl_user_free(remote_column);
807
808 return r;
809 }
810
811 if ((r = query->view->error)) column = query->view->error_column;
812 else column = L"";
813
814 if (msi_strncpyW(column, -1, buffer, buflen) == ERROR_MORE_DATA)
816
817 msiobj_release( &query->hdr );
818 return r;
819}
820
822{
824 const WCHAR *column;
826
827 TRACE( "%lu, %p, %p\n", handle, buffer, buflen );
828
829 if (!buflen)
831
833 {
834 WCHAR *remote_column = NULL;
835 MSIHANDLE remote;
836
837 if (!(remote = msi_get_remote(handle)))
839
840 if (!*buflen)
842
843 __TRY
844 {
845 r = remote_ViewGetError(remote, &remote_column);
846 }
848 {
850 }
851 __ENDTRY;
852
853 if (msi_strncpyWtoA(remote_column ? remote_column : L"", -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
855
856 if (remote_column)
857 midl_user_free(remote_column);
858
859 return r;
860 }
861
862 if ((r = query->view->error)) column = query->view->error_column;
863 else column = L"";
864
865 if (msi_strncpyWtoA(column, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
867
868 msiobj_release( &query->hdr );
869 return r;
870}
871
873{
874 FIXME("\n");
875 return 0;
876}
877
879{
880 HRESULT hr;
882 IStorage *stg;
883 STATSTG stat;
884
885 TRACE( "%p %s %08x\n", db, debugstr_w(transform), error_cond );
886
887 if (*transform == ':')
888 {
889 hr = IStorage_OpenStorage( db->storage, transform + 1, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
890 if (FAILED( hr ))
891 {
892 WARN( "failed to open substorage transform %#lx\n", hr );
894 }
895 }
896 else
897 {
899 if (FAILED( hr ))
900 {
901 WARN( "failed to open file transform %#lx\n", hr );
903 }
904 }
905
906 hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
907 if (FAILED( hr )) goto end;
908 if (!IsEqualGUID( &stat.clsid, &CLSID_MsiTransform )) goto end;
909 if (TRACE_ON( msi )) enum_stream_names( stg );
910
911 ret = msi_table_apply_transform( db, stg, error_cond );
912
913end:
914 IStorage_Release( stg );
915 return ret;
916}
917
919{
920 MSIDATABASE *db;
921 UINT r;
922
923 if (error_cond & ~MSITRANSFORM_ERROR_VIEWTRANSFORM) FIXME( "ignoring error conditions\n" );
924
927
928 r = MSI_DatabaseApplyTransformW( db, transform, error_cond );
929 msiobj_release( &db->hdr );
930 return r;
931}
932
933UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb, const char *transform, int error_cond )
934{
935 WCHAR *wstr;
936 UINT ret;
937
938 TRACE( "%lu, %s, %#x\n", hdb, debugstr_a(transform), error_cond );
939
940 wstr = strdupAtoW( transform );
941 if (transform && !wstr)
943
944 ret = MsiDatabaseApplyTransformW( hdb, wstr, error_cond );
945 msi_free( wstr );
946 return ret;
947}
948
949UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile,
950 int iReserved1, int iReserved2 )
951{
952 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_a(szTransformFile), iReserved1, iReserved2 );
954}
955
957 int iReserved1, int iReserved2 )
958{
959 FIXME( "%lu, %lu, %s, %d, %d\n", hdb, hdbref, debugstr_w(szTransformFile), iReserved1, iReserved2 );
961}
962
964{
965 MSIDATABASE *db;
966 UINT r;
967
968 TRACE( "%lu\n", hdb );
969
971 if( !db )
972 {
973 MSIHANDLE remote;
974
975 if (!(remote = msi_get_remote(hdb)))
977
978 WARN("not allowed during a custom action!\n");
979
980 return ERROR_SUCCESS;
981 }
982
983 if (db->mode == MSI_OPEN_READONLY)
984 {
985 msiobj_release( &db->hdr );
986 return ERROR_SUCCESS;
987 }
988
989 /* FIXME: lock the database */
990
991 r = msi_commit_streams( db );
992 if (r != ERROR_SUCCESS) ERR("Failed to commit streams!\n");
993 else
994 {
995 r = MSI_CommitTables( db );
996 if (r != ERROR_SUCCESS) ERR("Failed to commit tables!\n");
997 }
998
999 /* FIXME: unlock the database */
1000
1001 msiobj_release( &db->hdr );
1002
1003 if (r == ERROR_SUCCESS)
1004 {
1005 msi_free( db->deletefile );
1006 db->deletefile = NULL;
1007 }
1008
1009 return r;
1010}
1011
1013{
1016};
1017
1019{
1022 DWORD type;
1023
1025 if( type & MSITYPE_KEY )
1026 {
1027 info->n++;
1028 if( info->rec )
1029 {
1030 if ( info->n == 1 )
1031 {
1033 MSI_RecordSetStringW( info->rec, 0, table);
1034 }
1035
1037 MSI_RecordSetStringW( info->rec, info->n, name );
1038 }
1039 }
1040
1041 return ERROR_SUCCESS;
1042}
1043
1045 LPCWSTR table, MSIRECORD **prec )
1046{
1048 MSIQUERY *query = NULL;
1049 UINT r;
1050
1051 if (!TABLE_Exists( db, table ))
1052 return ERROR_INVALID_TABLE;
1053
1054 r = MSI_OpenQuery( db, &query, L"SELECT * FROM `_Columns` WHERE `Table` = '%s'", table );
1055 if( r != ERROR_SUCCESS )
1056 return r;
1057
1058 /* count the number of primary key records */
1059 info.n = 0;
1060 info.rec = 0;
1062 if( r == ERROR_SUCCESS )
1063 {
1064 TRACE( "found %lu primary keys\n", info.n );
1065
1066 /* allocate a record and fill in the names of the tables */
1067 info.rec = MSI_CreateRecord( info.n );
1068 info.n = 0;
1070 if( r == ERROR_SUCCESS )
1071 *prec = info.rec;
1072 else
1073 msiobj_release( &info.rec->hdr );
1074 }
1075 msiobj_release( &query->hdr );
1076
1077 return r;
1078}
1079
1081{
1082 MSIRECORD *rec = NULL;
1083 MSIDATABASE *db;
1084 UINT r;
1085
1086 TRACE( "%lu, %s, %p\n", hdb, debugstr_w(table), phRec );
1087
1089 if( !db )
1090 {
1091 struct wire_record *wire_rec = NULL;
1092 MSIHANDLE remote;
1093
1094 if (!(remote = msi_get_remote(hdb)))
1095 return ERROR_INVALID_HANDLE;
1096
1097 __TRY
1098 {
1099 r = remote_DatabaseGetPrimaryKeys(remote, table, &wire_rec);
1100 }
1102 {
1103 r = GetExceptionCode();
1104 }
1105 __ENDTRY
1106
1107 if (!r)
1108 {
1109 r = unmarshal_record(wire_rec, phRec);
1110 free_remote_record(wire_rec);
1111 }
1112
1113 return r;
1114 }
1115
1116 r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
1117 if( r == ERROR_SUCCESS )
1118 {
1119 *phRec = alloc_msihandle( &rec->hdr );
1120 if (! *phRec)
1122 msiobj_release( &rec->hdr );
1123 }
1124 msiobj_release( &db->hdr );
1125
1126 return r;
1127}
1128
1130{
1131 WCHAR *szwTable = NULL;
1132 UINT r;
1133
1134 TRACE( "%lu, %s, %p\n", hdb, debugstr_a(table), phRec );
1135
1136 if( table )
1137 {
1138 szwTable = strdupAtoW( table );
1139 if( !szwTable )
1140 return ERROR_OUTOFMEMORY;
1141 }
1142 r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
1143 msi_free( szwTable );
1144
1145 return r;
1146}
1147
1148MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( MSIHANDLE hDatabase, const char *szTableName )
1149{
1150 WCHAR *szwTableName = NULL;
1152
1153 TRACE( "%lu, %s\n", hDatabase, debugstr_a(szTableName) );
1154
1155 if( szTableName )
1156 {
1157 szwTableName = strdupAtoW( szTableName );
1158 if( !szwTableName )
1159 return MSICONDITION_ERROR;
1160 }
1161 r = MsiDatabaseIsTablePersistentW( hDatabase, szwTableName );
1162 msi_free( szwTableName );
1163
1164 return r;
1165}
1166
1168{
1169 MSIDATABASE *db;
1171
1172 TRACE( "%lu, %s\n", hDatabase, debugstr_w(szTableName) );
1173
1174 db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE );
1175 if( !db )
1176 {
1177 MSIHANDLE remote;
1178
1179 if (!(remote = msi_get_remote(hDatabase)))
1180 return MSICONDITION_ERROR;
1181
1182 __TRY
1183 {
1184 r = remote_DatabaseIsTablePersistent(remote, szTableName);
1185 }
1187 {
1189 }
1190 __ENDTRY
1191
1192 return r;
1193 }
1194
1195 r = MSI_DatabaseIsTablePersistent( db, szTableName );
1196
1197 msiobj_release( &db->hdr );
1198
1199 return r;
1200}
1201
1203{
1204 return MsiViewClose(view);
1205}
1206
1208{
1209 MSIHANDLE rec = 0;
1210 UINT r;
1211
1212 if ((r = unmarshal_record(remote_rec, &rec)))
1213 return r;
1214
1215 r = MsiViewExecute(view, rec);
1216
1217 MsiCloseHandle(rec);
1218 return r;
1219}
1220
1222{
1225 *rec = NULL;
1226 if (!r)
1227 *rec = marshal_record(handle);
1229 return r;
1230}
1231
1233{
1236 *rec = NULL;
1237 if (!r)
1238 *rec = marshal_record(handle);
1240 return r;
1241}
1242
1244{
1245 WCHAR empty[1];
1246 DWORD size = 1;
1247 UINT r;
1248
1250 if (r == MSIDBERROR_MOREDATA)
1251 {
1252 if (!(*column = midl_user_allocate(++size * sizeof(WCHAR))))
1255 }
1256 return r;
1257}
1258
1260 struct wire_record *remote_rec, struct wire_record **remote_refreshed)
1261{
1262 MSIHANDLE handle = 0;
1263 UINT r;
1264
1265 if ((r = unmarshal_record(remote_rec, &handle)))
1266 return r;
1267
1269 *remote_refreshed = NULL;
1270 if (!r && (mode == MSIMODIFY_REFRESH || mode == MSIMODIFY_SEEK))
1271 *remote_refreshed = marshal_record(handle);
1272
1274 return r;
1275}
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:33
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#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
UINT MSI_CommitTables(MSIDATABASE *db) DECLSPEC_HIDDEN
Definition: table.c:2887
#define MSIHANDLETYPE_DATABASE
Definition: msipriv.h:722
UINT MSI_RecordSetIStream(MSIRECORD *, UINT, IStream *) DECLSPEC_HIDDEN
Definition: record.c:836
UINT unmarshal_record(const struct wire_record *in, MSIHANDLE *out) DECLSPEC_HIDDEN
Definition: record.c:1095
#define MSITYPE_VALID
Definition: msipriv.h:48
#define MSIHANDLETYPE_RECORD
Definition: msipriv.h:725
static void msi_free(void *mem)
Definition: msipriv.h:1159
void free_remote_record(struct wire_record *rec) DECLSPEC_HIDDEN
Definition: record.c:1149
#define MSITYPE_IS_BINARY(type)
Definition: msipriv.h:62
MSICONDITION MSI_DatabaseIsTablePersistent(MSIDATABASE *db, LPCWSTR table) DECLSPEC_HIDDEN
Definition: table.c:2922
#define MSITYPE_STRING
Definition: msipriv.h:50
UINT msi_table_apply_transform(MSIDATABASE *db, IStorage *stg, int err_cond) DECLSPEC_HIDDEN
Definition: table.c:3371
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:213
UINT(* record_func)(MSIRECORD *, LPVOID)
Definition: msipriv.h:865
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len) DECLSPEC_HIDDEN
Definition: string.c:343
#define MSITYPE_UNKNOWN
Definition: msipriv.h:54
UINT copy_remote_record(const struct wire_record *rec, MSIHANDLE handle) DECLSPEC_HIDDEN
Definition: record.c:1052
BOOL TABLE_Exists(MSIDATABASE *db, LPCWSTR name) DECLSPEC_HIDDEN
Definition: table.c:960
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
Definition: record.c:280
#define MSITYPE_NULLABLE
Definition: msipriv.h:51
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
struct wire_record * marshal_record(MSIHANDLE handle) DECLSPEC_HIDDEN
Definition: record.c:1109
UINT msi_commit_streams(MSIDATABASE *db) DECLSPEC_HIDDEN
Definition: streams.c:607
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
#define MSI_OPEN_READONLY
Definition: msipriv.h:99
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
#define MSI_DATASIZEMASK
Definition: msipriv.h:47
#define MSITYPE_KEY
Definition: msipriv.h:52
#define MSIHANDLETYPE_VIEW
Definition: msipriv.h:724
#define MSITYPE_LOCALIZABLE
Definition: msipriv.h:49
void enum_stream_names(IStorage *stg) DECLSPEC_HIDDEN
Definition: table.c:204
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPEC_HIDDEN
Definition: record.c:573
UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord)
Definition: msiquery.c:720
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:770
UINT __cdecl s_remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct wire_record **rec)
Definition: msiquery.c:1232
UINT __cdecl s_remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
Definition: msiquery.c:1221
UINT WINAPI MsiDatabaseApplyTransformA(MSIHANDLE hdb, const char *transform, int error_cond)
Definition: msiquery.c:933
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
static UINT msi_set_record_type_string(MSIRECORD *rec, UINT field, UINT type, BOOL temporary)
Definition: msiquery.c:567
UINT WINAPI MsiDatabaseGenerateTransformA(MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:949
UINT __cdecl s_remote_ViewModify(MSIHANDLE view, MSIMODIFY mode, struct wire_record *remote_rec, struct wire_record **remote_refreshed)
Definition: msiquery.c:1259
UINT MSI_DatabaseApplyTransformW(MSIDATABASE *db, const WCHAR *transform, int error_cond)
Definition: msiquery.c:878
static UINT msi_primary_key_iterator(MSIRECORD *rec, LPVOID param)
Definition: msiquery.c:1018
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *db, LPCWSTR table, MSIRECORD **prec)
Definition: msiquery.c:1044
UINT MSI_ViewGetColumnInfo(MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec)
Definition: msiquery.c:603
UINT WINAPI MsiDatabaseApplyTransformW(MSIHANDLE hdb, const WCHAR *transform, int error_cond)
Definition: msiquery.c:918
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:956
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, const char *table, MSIHANDLE *phRec)
Definition: msiquery.c:1129
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:1080
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
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:1207
MSIDBERROR WINAPI MsiViewGetErrorA(MSIHANDLE handle, char *buffer, DWORD *buflen)
Definition: msiquery.c:821
MSIDBERROR __cdecl s_remote_ViewGetError(MSIHANDLE view, LPWSTR *column)
Definition: msiquery.c:1243
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, const WCHAR *szTableName)
Definition: msiquery.c:1167
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:1202
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:642
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:698
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1148
MSIHANDLE WINAPI MsiGetLastErrorRecord(void)
Definition: msiquery.c:872
@ 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) DECLSPEC_HIDDEN
#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