xref: /reactos/dll/win32/msi/create.c (revision f4be6dc3)
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2002-2004 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 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "wine/debug.h"
27 #include "msi.h"
28 #include "msiquery.h"
29 #include "objbase.h"
30 #include "objidl.h"
31 #include "msipriv.h"
32 #include "winnls.h"
33 
34 #include "query.h"
35 
36 WINE_DEFAULT_DEBUG_CHANNEL(msidb);
37 
38 
39 /* below is the query interface to a table */
40 
41 struct create_view
42 {
43     MSIVIEW          view;
44     MSIDATABASE     *db;
45     LPCWSTR          name;
46     BOOL             bIsTemp;
47     BOOL             hold;
48     column_info     *col_info;
49 };
50 
CREATE_fetch_int(struct tagMSIVIEW * view,UINT row,UINT col,UINT * val)51 static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
52 {
53     struct create_view *cv = (struct create_view *)view;
54 
55     TRACE("%p %d %d %p\n", cv, row, col, val );
56 
57     return ERROR_FUNCTION_FAILED;
58 }
59 
CREATE_execute(struct tagMSIVIEW * view,MSIRECORD * record)60 static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
61 {
62     struct create_view *cv = (struct create_view *)view;
63     BOOL persist = (cv->bIsTemp) ? MSICONDITION_FALSE : MSICONDITION_TRUE;
64 
65     TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name),
66           cv->bIsTemp?"temporary":"permanent");
67 
68     if (cv->bIsTemp && !cv->hold)
69         return ERROR_SUCCESS;
70 
71     return msi_create_table( cv->db, cv->name, cv->col_info, persist, cv->hold );
72 }
73 
CREATE_close(struct tagMSIVIEW * view)74 static UINT CREATE_close( struct tagMSIVIEW *view )
75 {
76     struct create_view *cv = (struct create_view *)view;
77 
78     TRACE("%p\n", cv);
79 
80     return ERROR_SUCCESS;
81 }
82 
CREATE_get_dimensions(struct tagMSIVIEW * view,UINT * rows,UINT * cols)83 static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
84 {
85     struct create_view *cv = (struct create_view *)view;
86 
87     TRACE("%p %p %p\n", cv, rows, cols );
88 
89     return ERROR_FUNCTION_FAILED;
90 }
91 
CREATE_get_column_info(struct tagMSIVIEW * view,UINT n,LPCWSTR * name,UINT * type,BOOL * temporary,LPCWSTR * table_name)92 static UINT CREATE_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *name,
93                                     UINT *type, BOOL *temporary, LPCWSTR *table_name )
94 {
95     struct create_view *cv = (struct create_view *)view;
96 
97     TRACE("%p %d %p %p %p %p\n", cv, n, name, type, temporary, table_name );
98 
99     return ERROR_FUNCTION_FAILED;
100 }
101 
CREATE_modify(struct tagMSIVIEW * view,MSIMODIFY eModifyMode,MSIRECORD * rec,UINT row)102 static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
103                            MSIRECORD *rec, UINT row)
104 {
105     struct create_view *cv = (struct create_view *)view;
106 
107     TRACE("%p %d %p\n", cv, eModifyMode, rec );
108 
109     return ERROR_FUNCTION_FAILED;
110 }
111 
CREATE_delete(struct tagMSIVIEW * view)112 static UINT CREATE_delete( struct tagMSIVIEW *view )
113 {
114     struct create_view *cv = (struct create_view *)view;
115 
116     TRACE("%p\n", cv );
117 
118     msiobj_release( &cv->db->hdr );
119     free( cv );
120 
121     return ERROR_SUCCESS;
122 }
123 
124 static const MSIVIEWOPS create_ops =
125 {
126     CREATE_fetch_int,
127     NULL,
128     NULL,
129     NULL,
130     NULL,
131     NULL,
132     NULL,
133     NULL,
134     CREATE_execute,
135     CREATE_close,
136     CREATE_get_dimensions,
137     CREATE_get_column_info,
138     CREATE_modify,
139     CREATE_delete,
140     NULL,
141     NULL,
142     NULL,
143     NULL,
144     NULL,
145 };
146 
check_columns(const column_info * col_info)147 static UINT check_columns( const column_info *col_info )
148 {
149     const column_info *c1, *c2;
150 
151     /* check for two columns with the same name */
152     for( c1 = col_info; c1; c1 = c1->next )
153         for( c2 = c1->next; c2; c2 = c2->next )
154             if (!wcscmp( c1->column, c2->column ))
155                 return ERROR_BAD_QUERY_SYNTAX;
156 
157     return ERROR_SUCCESS;
158 }
159 
CREATE_CreateView(MSIDATABASE * db,MSIVIEW ** view,LPCWSTR table,column_info * col_info,BOOL hold)160 UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,
161                         column_info *col_info, BOOL hold )
162 {
163     struct create_view *cv = NULL;
164     UINT r;
165     column_info *col;
166     BOOL temp = TRUE;
167     BOOL tempprim = FALSE;
168 
169     TRACE("%p\n", cv );
170 
171     r = check_columns( col_info );
172     if( r != ERROR_SUCCESS )
173         return r;
174 
175     cv = calloc( 1, sizeof *cv );
176     if( !cv )
177         return ERROR_FUNCTION_FAILED;
178 
179     for( col = col_info; col; col = col->next )
180     {
181         if (!col->table)
182             col->table = table;
183 
184         if( !(col->type & MSITYPE_TEMPORARY) )
185             temp = FALSE;
186         else if ( col->type & MSITYPE_KEY )
187             tempprim = TRUE;
188     }
189 
190     if ( !temp && tempprim )
191     {
192         free( cv );
193         return ERROR_FUNCTION_FAILED;
194     }
195 
196     /* fill the structure */
197     cv->view.ops = &create_ops;
198     msiobj_addref( &db->hdr );
199     cv->db = db;
200     cv->name = table;
201     cv->col_info = col_info;
202     cv->bIsTemp = temp;
203     cv->hold = hold;
204     *view = (MSIVIEW*) cv;
205 
206     return ERROR_SUCCESS;
207 }
208