ReactOS  0.4.15-dev-5109-g2469ce2
record.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005 Mike McCormack for CodeWeavers
3  *
4  * A test program for MSI records
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 <windows.h>
22 #include <msi.h>
23 #include <msiquery.h>
24 
25 #include "wine/test.h"
26 
27 static const char *msifile = "winetest-record.msi";
28 static const WCHAR msifileW[] = L"winetest-record.msi";
29 
30 static BOOL create_temp_file(char *name)
31 {
32  UINT r;
33  unsigned char buffer[26], i;
34  DWORD sz;
35  HANDLE handle;
36 
37  r = GetTempFileNameA(".", "msitest",0,name);
38  if(!r)
39  return r;
43  return FALSE;
44  for(i=0; i<26; i++)
45  buffer[i]=i+'a';
46  r = WriteFile(handle,buffer,sizeof buffer,&sz,NULL);
48  return r;
49 }
50 
51 static void test_msirecord(void)
52 {
53  DWORD r, sz;
54  INT i;
55  MSIHANDLE h;
56  char buf[10];
57  WCHAR bufW[10];
58  const char str[] = "hello";
59  char filename[MAX_PATH];
60 
61  /* check behaviour with an invalid record */
63  ok(r==-1, "field count for invalid record not -1\n");
64  SetLastError(0);
65  r = MsiRecordIsNull(0, 0);
66  ok(r==0, "invalid handle not considered to be non-null...\n");
67  ok(GetLastError()==0, "MsiRecordIsNull set LastError\n");
68  r = MsiRecordGetInteger(0,0);
69  ok(r == MSI_NULL_INTEGER, "got integer from invalid record\n");
70  r = MsiRecordSetInteger(0,0,0);
71  ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n");
72  r = MsiRecordSetInteger(0,-1,0);
73  ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n");
74  SetLastError(0);
75  h = MsiCreateRecord(-1);
76  ok(h==0, "created record with -1 elements\n");
77  h = MsiCreateRecord(0x10000);
78  ok(h==0, "created record with 0x10000 elements\n");
79  /* doesn't set LastError */
80  ok(GetLastError()==0, "MsiCreateRecord set last error\n");
81  r = MsiRecordClearData(0);
82  ok(r == ERROR_INVALID_HANDLE, "MsiRecordClearData returned wrong error\n");
83  r = MsiRecordDataSize(0,0);
84  ok(r == 0, "MsiRecordDataSize returned wrong error\n");
85 
86 
87  /* check behaviour of a record with 0 elements */
88  h = MsiCreateRecord(0);
89  ok(h!=0, "couldn't create record with zero elements\n");
91  ok(r==0, "field count should be zero\n");
92  r = MsiRecordIsNull(h,0);
93  ok(r, "new record wasn't null\n");
94  r = MsiRecordIsNull(h,1);
95  ok(r, "out of range record wasn't null\n");
96  r = MsiRecordIsNull(h,-1);
97  ok(r, "out of range record wasn't null\n");
98  r = MsiRecordDataSize(h,0);
99  ok(r==0, "size of null record is 0\n");
100  sz = sizeof buf;
101  strcpy(buf,"x");
102  r = MsiRecordGetStringA(h, 0, buf, &sz);
103  ok(r==ERROR_SUCCESS, "failed to get null string\n");
104  ok(sz==0, "null string too long\n");
105  ok(buf[0]==0, "null string not set\n");
106 
107  /* same record, but add an integer to it */
108  r = MsiRecordSetInteger(h, 0, 0);
109  ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 0\n");
110  r = MsiRecordIsNull(h,0);
111  ok(r==0, "new record is null after setting an integer\n");
112  r = MsiRecordDataSize(h,0);
113  ok(r==sizeof(DWORD), "size of integer record is 4\n");
114  r = MsiRecordSetInteger(h, 0, 1);
115  ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 1\n");
116  r = MsiRecordSetInteger(h, 1, 1);
117  ok(r == ERROR_INVALID_PARAMETER, "set integer at 1\n");
118  r = MsiRecordSetInteger(h, -1, 0);
119  ok(r == ERROR_INVALID_PARAMETER, "set integer at -1\n");
120  r = MsiRecordIsNull(h,0);
121  ok(r==0, "new record is null after setting an integer\n");
122  r = MsiRecordGetInteger(h, 0);
123  ok(r == 1, "failed to get integer\n");
124 
125  /* same record, but add a null or empty string to it */
126  r = MsiRecordSetStringA(h, 0, NULL);
127  ok(r == ERROR_SUCCESS, "Failed to set null string at 0\n");
128  r = MsiRecordIsNull(h, 0);
129  ok(r == TRUE, "null string not null field\n");
130  r = MsiRecordDataSize(h, 0);
131  ok(r == 0, "size of string record is strlen\n");
132  buf[0] = 0;
133  sz = sizeof buf;
134  r = MsiRecordGetStringA(h, 0, buf, &sz);
135  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
136  ok(buf[0] == 0, "MsiRecordGetStringA returned the wrong string\n");
137  ok(sz == 0, "MsiRecordGetStringA returned the wrong length\n");
138  bufW[0] = 0;
139  sz = ARRAY_SIZE(bufW);
140  r = MsiRecordGetStringW(h, 0, bufW, &sz);
141  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
142  ok(bufW[0] == 0, "MsiRecordGetStringW returned the wrong string\n");
143  ok(sz == 0, "MsiRecordGetStringW returned the wrong length\n");
144  r = MsiRecordSetStringA(h, 0, "");
145  ok(r == ERROR_SUCCESS, "Failed to set empty string at 0\n");
146  r = MsiRecordIsNull(h, 0);
147  ok(r == TRUE, "null string not null field\n");
148  r = MsiRecordDataSize(h, 0);
149  ok(r == 0, "size of string record is strlen\n");
150  buf[0] = 0;
151  sz = sizeof buf;
152  r = MsiRecordGetStringA(h, 0, buf, &sz);
153  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
154  ok(buf[0] == 0, "MsiRecordGetStringA returned the wrong string\n");
155  ok(sz == 0, "MsiRecordGetStringA returned the wrong length\n");
156  bufW[0] = 0;
157  sz = ARRAY_SIZE(bufW);
158  r = MsiRecordGetStringW(h, 0, bufW, &sz);
159  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
160  ok(bufW[0] == 0, "MsiRecordGetStringW returned the wrong string\n");
161  ok(sz == 0, "MsiRecordGetStringW returned the wrong length\n");
162 
163  /* same record, but add a null integer to it */
164  r = MsiRecordSetInteger(h, 0, 1);
165  ok(r == ERROR_SUCCESS, "Failed to set integer at 0\n");
166  r = MsiRecordIsNull(h, 0);
167  ok(r == FALSE, "expected field to be non-null\n");
169  ok(r == ERROR_SUCCESS, "Failed to set integer at 0\n");
170  r = MsiRecordIsNull(h, 0);
171  ok(r == TRUE, "expected field to be null\n");
172  sz = sizeof buf;
173  r = MsiRecordGetStringA(h, 0, buf, &sz);
174  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
175  ok(buf[0] == 0, "MsiRecordGetStringA returned the wrong string\n");
176  ok(sz == 0, "MsiRecordGetStringA returned the wrong length\n");
177 
178  /* same record, but add a string to it */
179  r = MsiRecordSetStringA(h,0,str);
180  ok(r == ERROR_SUCCESS, "Failed to set string at 0\n");
181  r = MsiRecordGetInteger(h, 0);
182  ok(r == MSI_NULL_INTEGER, "should get invalid integer\n");
183  r = MsiRecordDataSize(h,0);
184  ok(r==sizeof str-1, "size of string record is strlen\n");
185  buf[0]=0;
186  sz = sizeof buf;
187  r = MsiRecordGetStringA(h,0,buf,&sz);
188  ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
189  ok(0==strcmp(buf,str), "MsiRecordGetStringA returned the wrong string\n");
190  ok(sz == sizeof str-1, "MsiRecordGetStringA returned the wrong length\n");
191  buf[0]=0;
192  sz = sizeof str - 2;
193  r = MsiRecordGetStringA(h,0,buf,&sz);
194  ok(r == ERROR_MORE_DATA, "small buffer should yield ERROR_MORE_DATA\n");
195  ok(sz == sizeof str-1, "MsiRecordGetStringA returned the wrong length\n");
196  ok(0==strncmp(buf,str,sizeof str-3), "MsiRecordGetStringA returned the wrong string\n");
197  ok(buf[sizeof str - 3]==0, "string wasn't nul terminated\n");
198 
199  buf[0]=0;
200  sz = sizeof str;
201  r = MsiRecordGetStringA(h,0,buf,&sz);
202  ok(r == ERROR_SUCCESS, "wrong error\n");
203  ok(sz == sizeof str-1, "MsiRecordGetStringA returned the wrong length\n");
204  ok(0==strcmp(buf,str), "MsiRecordGetStringA returned the wrong string\n");
205 
206 
207  memset(bufW, 0, sizeof bufW);
208  sz = 5;
209  r = MsiRecordGetStringW(h,0,bufW,&sz);
210  ok(r == ERROR_MORE_DATA, "wrong error\n");
211  ok(sz == 5, "MsiRecordGetStringA returned the wrong length\n");
212  ok(!memcmp(bufW, L"hello", 8), "MsiRecordGetStringA returned the wrong string\n");
213 
214  sz = 0;
215  bufW[0] = 'x';
216  r = MsiRecordGetStringW(h,0,bufW,&sz);
217  ok(r == ERROR_MORE_DATA, "wrong error\n");
218  ok(sz == 5, "MsiRecordGetStringA returned the wrong length\n");
219  ok('x'==bufW[0], "MsiRecordGetStringA returned the wrong string\n");
220 
221  memset(buf, 0, sizeof buf);
222  sz = 5;
223  r = MsiRecordGetStringA(h,0,buf,&sz);
224  ok(r == ERROR_MORE_DATA, "wrong error\n");
225  ok(sz == 5, "MsiRecordGetStringA returned the wrong length\n");
226  ok(0==memcmp(buf,str,4), "MsiRecordGetStringA returned the wrong string\n");
227 
228  sz = 0;
229  buf[0] = 'x';
230  r = MsiRecordGetStringA(h,0,buf,&sz);
231  ok(r == ERROR_MORE_DATA, "wrong error\n");
232  ok(sz == 5, "MsiRecordGetStringA returned the wrong length\n");
233  ok('x'==buf[0], "MsiRecordGetStringA returned the wrong string\n");
234 
235  /* same record, check we can wipe all the data */
237  ok(r == ERROR_SUCCESS, "Failed to clear record\n");
239  ok(r == ERROR_SUCCESS, "Failed to clear record again\n");
240  r = MsiRecordIsNull(h,0);
241  ok(r, "cleared record wasn't null\n");
242 
243  /* same record, try converting strings to integers */
244  i = MsiRecordSetStringA(h,0,"42");
245  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
246  i = MsiRecordGetInteger(h, 0);
247  ok(i == 42, "should get invalid integer\n");
248  i = MsiRecordSetStringA(h,0,"-42");
249  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
250  i = MsiRecordGetInteger(h, 0);
251  ok(i == -42, "should get invalid integer\n");
252  i = MsiRecordSetStringA(h,0," 42");
253  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
254  i = MsiRecordGetInteger(h, 0);
255  ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
256  i = MsiRecordSetStringA(h,0,"42 ");
257  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
258  i = MsiRecordGetInteger(h, 0);
259  ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
260  i = MsiRecordSetStringA(h,0,"42.0");
261  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
262  i = MsiRecordGetInteger(h, 0);
263  ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
264  i = MsiRecordSetStringA(h,0,"0x42");
265  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
266  i = MsiRecordGetInteger(h, 0);
267  ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
268  i = MsiRecordSetStringA(h,0,"1000000000000000");
269  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
270  i = MsiRecordGetInteger(h, 0);
271  ok(i == -1530494976, "should get truncated integer\n");
272  i = MsiRecordSetStringA(h,0,"2147483647");
273  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
274  i = MsiRecordGetInteger(h, 0);
275  ok(i == 2147483647, "should get maxint\n");
276  i = MsiRecordSetStringA(h,0,"-2147483647");
277  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
278  i = MsiRecordGetInteger(h, 0);
279  ok(i == -2147483647, "should get -maxint-1\n");
280  i = MsiRecordSetStringA(h,0,"4294967297");
281  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
282  i = MsiRecordGetInteger(h, 0);
283  ok(i == 1, "should get one\n");
284  i = MsiRecordSetStringA(h,0,"foo");
285  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
286  i = MsiRecordGetInteger(h, 0);
287  ok(i == MSI_NULL_INTEGER, "should get zero\n");
288  i = MsiRecordSetStringA(h,0,"");
289  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
290  i = MsiRecordGetInteger(h, 0);
291  ok(i == MSI_NULL_INTEGER, "should get zero\n");
292  i = MsiRecordSetStringA(h,0,"+1");
293  ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
294  i = MsiRecordGetInteger(h, 0);
295  ok(i == MSI_NULL_INTEGER, "should get zero\n");
296 
297  /* same record, try converting integers to strings */
298  r = MsiRecordSetInteger(h, 0, 32);
299  ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
300  sz = 1;
301  r = MsiRecordGetStringA(h, 0, NULL, &sz);
302  ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
303  ok(sz == 2, "length wrong\n");
304  buf[0]=0;
305  sz = sizeof buf;
306  r = MsiRecordGetStringA(h, 0, buf, &sz);
307  ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
308  ok(0==strcmp(buf,"32"), "failed to get string from integer\n");
309  r = MsiRecordSetInteger(h, 0, -32);
310  ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
311  buf[0]=0;
312  sz = 1;
313  r = MsiRecordGetStringA(h, 0, NULL, &sz);
314  ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
315  ok(sz == 3, "length wrong\n");
316  sz = sizeof buf;
317  r = MsiRecordGetStringA(h, 0, buf, &sz);
318  ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
319  ok(0==strcmp(buf,"-32"), "failed to get string from integer\n");
320  buf[0]=0;
321 
322  /* same record, now try streams */
323  r = MsiRecordSetStreamA(h, 0, NULL);
324  ok(r == ERROR_INVALID_PARAMETER, "set NULL stream\n");
325  sz = sizeof buf;
326  r = MsiRecordReadStream(h, 0, buf, &sz);
327  ok(r == ERROR_INVALID_DATATYPE, "read non-stream type\n");
328  ok(sz == sizeof buf, "set sz\n");
329  r = MsiRecordDataSize( h, -1);
330  ok(r == 0,"MsiRecordDataSize returned wrong size\n");
331  r = MsiRecordDataSize( h, 0);
332  ok(r == 4,"MsiRecordDataSize returned wrong size\n");
333 
334  /* same record, now close it */
335  r = MsiCloseHandle(h);
336  ok(r == ERROR_SUCCESS, "Failed to close handle\n");
337 
338  /* now try streams in a new record - need to create a file to play with */
340  if(!r)
341  return;
342 
343  /* streams can't be inserted in field 0 for some reason */
344  h = MsiCreateRecord(2);
345  ok(h, "couldn't create a two field record\n");
347  ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n");
349  ok(r == ERROR_SUCCESS, "failed to add stream to record\n");
350  r = MsiRecordReadStream(h, 1, buf, NULL);
351  ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
352  DeleteFileA(filename); /* Windows 98 doesn't like this at all, so don't check return. */
353  r = MsiRecordReadStream(h, 1, NULL, NULL);
354  ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
355  sz = sizeof buf;
356  r = MsiRecordReadStream(h, 1, NULL, &sz);
357  ok(r == ERROR_SUCCESS, "failed to read stream\n");
358  ok(sz==26,"couldn't get size of stream\n");
359  sz = 0;
360  r = MsiRecordReadStream(h, 1, buf, &sz);
361  ok(r == ERROR_SUCCESS, "failed to read stream\n");
362  ok(sz==0,"short read\n");
363  sz = sizeof buf;
364  r = MsiRecordReadStream(h, 1, buf, &sz);
365  ok(r == ERROR_SUCCESS, "failed to read stream\n");
366  ok(sz==sizeof buf,"short read\n");
367  ok(!strncmp(buf,"abcdefghij",10), "read the wrong thing\n");
368  sz = sizeof buf;
369  r = MsiRecordReadStream(h, 1, buf, &sz);
370  ok(r == ERROR_SUCCESS, "failed to read stream\n");
371  ok(sz==sizeof buf,"short read\n");
372  ok(!strncmp(buf,"klmnopqrst",10), "read the wrong thing\n");
373  memset(buf,0,sizeof buf);
374  sz = sizeof buf;
375  r = MsiRecordReadStream(h, 1, buf, &sz);
376  ok(r == ERROR_SUCCESS, "failed to read stream\n");
377  ok(sz==6,"short read\n");
378  ok(!strcmp(buf,"uvwxyz"), "read the wrong thing\n");
379  memset(buf,0,sizeof buf);
380  sz = sizeof buf;
381  r = MsiRecordReadStream(h, 1, buf, &sz);
382  ok(r == ERROR_SUCCESS, "failed to read stream\n");
383  ok(sz==0,"size non-zero at end of stream\n");
384  ok(buf[0]==0, "read something at end of the stream\n");
385  r = MsiRecordSetStreamA(h, 1, NULL);
386  ok(r == ERROR_SUCCESS, "failed to reset stream\n");
387  sz = 0;
388  r = MsiRecordReadStream(h, 1, NULL, &sz);
389  ok(r == ERROR_SUCCESS, "bytes left wrong after reset\n");
390  ok(sz==26,"couldn't get size of stream\n");
391  r = MsiRecordDataSize(h,1);
392  ok(r == 26,"MsiRecordDataSize returned wrong size\n");
393 
394  /* now close the stream record */
395  r = MsiCloseHandle(h);
396  ok(r == ERROR_SUCCESS, "Failed to close handle\n");
397  DeleteFileA(filename); /* Delete it for sure, when everything else is closed. */
398 }
399 
400 static void test_MsiRecordGetString(void)
401 {
402  MSIHANDLE rec;
403  CHAR buf[MAX_PATH];
404  DWORD sz;
405  UINT r;
406 
407  rec = MsiCreateRecord(2);
408  ok(rec != 0, "Expected a valid handle\n");
409 
410  sz = MAX_PATH;
411  r = MsiRecordGetStringA(rec, 1, NULL, &sz);
412  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",r);
413  ok(sz == 0, "Expected 0, got %lu\n", sz);
414 
415  sz = MAX_PATH;
416  lstrcpyA(buf, "apple");
417  r = MsiRecordGetStringA(rec, 1, buf, &sz);
418  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
419  ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
420  ok(sz == 0, "Expected 0, got %lu\n", sz);
421 
422  sz = MAX_PATH;
423  lstrcpyA(buf, "apple");
424  r = MsiRecordGetStringA(rec, 10, buf, &sz);
425  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
426  ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
427  ok(sz == 0, "Expected 0, got %lu\n", sz);
428 
429  MsiCloseHandle(rec);
430 
431  rec = MsiCreateRecord(1);
432  ok(rec != 0, "Expected a valid handle\n");
433 
434  r = MsiRecordSetInteger(rec, 1, 5);
435  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
436 
437  sz = MAX_PATH;
438  r = MsiRecordGetStringA(rec, 1, NULL, &sz);
439  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",r);
440  ok(sz == 1, "Expected 1, got %lu\n",sz);
441 
442  sz = MAX_PATH;
443  lstrcpyA(buf, "apple");
444  r = MsiRecordGetStringA(rec, 1, buf, &sz);
445  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
446  ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
447  ok(sz == 1, "Expected 1, got %lu\n", sz);
448 
449  r = MsiRecordSetInteger(rec, 1, -5);
450  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
451 
452  sz = MAX_PATH;
453  lstrcpyA(buf, "apple");
454  r = MsiRecordGetStringA(rec, 1, buf, &sz);
455  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
456  ok(!lstrcmpA(buf, "-5"), "Expected \"-5\", got \"%s\"\n", buf);
457  ok(sz == 2, "Expected 2, got %lu\n", sz);
458 
459  MsiCloseHandle(rec);
460 }
461 
462 static void test_MsiRecordGetInteger(void)
463 {
464  MSIHANDLE rec;
465  INT val;
466  UINT r;
467 
468  rec = MsiCreateRecord(1);
469  ok(rec != 0, "Expected a valid handle\n");
470 
471  r = MsiRecordSetStringA(rec, 1, "5");
472  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
473 
474  val = MsiRecordGetInteger(rec, 1);
475  ok(val == 5, "Expected 5, got %d\n", val);
476 
477  r = MsiRecordSetStringA(rec, 1, "-5");
478  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
479 
480  val = MsiRecordGetInteger(rec, 1);
481  ok(val == -5, "Expected -5, got %d\n", val);
482 
483  r = MsiRecordSetStringA(rec, 1, "5apple");
484  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
485 
486  val = MsiRecordGetInteger(rec, 1);
487  ok(val == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", val);
488 
489  MsiCloseHandle(rec);
490 }
491 
492 static void test_fieldzero(void)
493 {
494  MSIHANDLE hdb, hview, rec;
495  CHAR buf[MAX_PATH];
496  LPCSTR query;
497  DWORD sz;
498  UINT r;
499 
500  rec = MsiCreateRecord(1);
501  ok(rec != 0, "Expected a valid handle\n");
502 
503  r = MsiRecordGetInteger(rec, 0);
504  ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
505 
506  sz = MAX_PATH;
507  lstrcpyA(buf, "apple");
508  r = MsiRecordGetStringA(rec, 0, buf, &sz);
509  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
510  ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
511  ok(sz == 0, "Expected 0, got %lu\n", sz);
512 
513  r = MsiRecordIsNull(rec, 0);
514  ok(r == TRUE, "Expected TRUE, got %d\n", r);
515 
516  r = MsiRecordGetInteger(rec, 1);
517  ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
518 
519  r = MsiRecordSetInteger(rec, 1, 42);
520  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
521 
522  r = MsiRecordGetInteger(rec, 0);
523  ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
524 
525  sz = MAX_PATH;
526  lstrcpyA(buf, "apple");
527  r = MsiRecordGetStringA(rec, 0, buf, &sz);
528  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
529  ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
530  ok(sz == 0, "Expected 0, got %lu\n", sz);
531 
532  r = MsiRecordIsNull(rec, 0);
533  ok(r == TRUE, "Expected TRUE, got %d\n", r);
534 
535  r = MsiRecordGetInteger(rec, 1);
536  ok(r == 42, "Expected 42, got %d\n", r);
537 
538  r = MsiRecordSetStringA(rec, 1, "bologna");
539  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
540 
541  r = MsiRecordGetInteger(rec, 0);
542  ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
543 
544  sz = MAX_PATH;
545  lstrcpyA(buf, "apple");
546  r = MsiRecordGetStringA(rec, 0, buf, &sz);
547  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
548  ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
549  ok(sz == 0, "Expected 0, got %lu\n", sz);
550 
551  r = MsiRecordIsNull(rec, 0);
552  ok(r == TRUE, "Expected TRUE, got %d\n", r);
553 
554  sz = MAX_PATH;
555  lstrcpyA(buf, "apple");
556  r = MsiRecordGetStringA(rec, 1, buf, &sz);
557  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
558  ok(!lstrcmpA(buf, "bologna"), "Expected \"bologna\", got \"%s\"\n", buf);
559  ok(sz == 7, "Expected 7, got %lu\n", sz);
560 
561  MsiCloseHandle(rec);
562 
564  ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
565 
566  query = "CREATE TABLE `drone` ( "
567  "`id` INT, `name` CHAR(32), `number` CHAR(32) "
568  "PRIMARY KEY `id`)";
569  r = MsiDatabaseOpenViewA(hdb, query, &hview);
570  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
571  r = MsiViewExecute(hview, 0);
572  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
573  r = MsiViewClose(hview);
574  ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
575  r = MsiCloseHandle(hview);
576  ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
577 
578  query = "INSERT INTO `drone` ( `id`, `name`, `number` )"
579  "VALUES('1', 'Abe', '8675309')";
580  r = MsiDatabaseOpenViewA(hdb, query, &hview);
581  ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
582  r = MsiViewExecute(hview, 0);
583  ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
584  r = MsiViewClose(hview);
585  ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
586  r = MsiCloseHandle(hview);
587  ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
588 
589  r = MsiDatabaseGetPrimaryKeysA(hdb, "drone", &rec);
590  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
591 
592  r = MsiRecordGetInteger(rec, 0);
593  ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
594 
595  sz = MAX_PATH;
596  lstrcpyA(buf, "apple");
597  r = MsiRecordGetStringA(rec, 0, buf, &sz);
598  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
599  ok(!lstrcmpA(buf, "drone"), "Expected \"drone\", got \"%s\"\n", buf);
600  ok(sz == 5, "Expected 5, got %lu\n", sz);
601 
602  r = MsiRecordIsNull(rec, 0);
603  ok(r == FALSE, "Expected FALSE, got %d\n", r);
604 
605  MsiCloseHandle(rec);
606 
607  r = MsiDatabaseGetPrimaryKeysA(hdb, "nosuchtable", &rec);
608  ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r);
609 
610  query = "SELECT * FROM `drone` WHERE `id` = 1";
611  r = MsiDatabaseOpenViewA(hdb, query, &hview);
612  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
613  r = MsiViewExecute(hview, 0);
614  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
615  r = MsiViewFetch(hview, &rec);
616  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
617 
618  r = MsiRecordGetInteger(rec, 0);
619  ok(r != MSI_NULL_INTEGER && r != 0, "Expected non-NULL value, got %d\n", r);
620 
621  r = MsiRecordIsNull(rec, 0);
622  ok(r == FALSE, "Expected FALSE, got %d\n", r);
623 
624  r = MsiCloseHandle(hview);
625  ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
626  MsiCloseHandle(rec);
627  MsiCloseHandle(hdb);
629 }
630 
632 {
633  test_msirecord();
636  test_fieldzero();
637 }
#define ERROR_INVALID_DATATYPE
Definition: winerror.h:1111
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:518
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static void test_fieldzero(void)
Definition: record.c:492
MSIHANDLE WINAPI MsiCreateRecord(UINT cParams)
Definition: record.c:92
#define CloseHandle
Definition: compat.h:598
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
UINT WINAPI MsiRecordSetInteger(MSIHANDLE handle, UINT iField, int iVal)
Definition: record.c:303
#define ERROR_SUCCESS
Definition: deptool.c:10
UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField, char *szValue, DWORD *pcchValue)
Definition: record.c:403
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
int WINAPI MsiRecordGetInteger(MSIHANDLE handle, UINT iField)
Definition: record.c:237
char CHAR
Definition: xmlstorage.h:175
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
static void test_MsiRecordGetInteger(void)
Definition: record.c:462
BOOL WINAPI MsiRecordIsNull(MSIHANDLE handle, UINT iField)
Definition: record.c:333
UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, UINT iField, const char *szFilename)
Definition: record.c:724
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
GLuint buffer
Definition: glext.h:5915
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
const char * filename
Definition: ioapi.h:135
int32_t INT
Definition: typedefs.h:58
UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, UINT iField, WCHAR *szValue, DWORD *pcchValue)
Definition: record.c:482
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:469
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void test_msirecord(void)
Definition: record.c:51
#define L(x)
Definition: ntvdm.h:50
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, UINT iField, char *buf, DWORD *sz)
Definition: record.c:819
#define FALSE
Definition: types.h:117
UINT WINAPI MsiRecordClearData(MSIHANDLE handle)
Definition: record.c:256
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
unsigned long MSIHANDLE
Definition: winemsi.idl:24
const WCHAR * str
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
const char * LPCSTR
Definition: xmlstorage.h:183
static BOOL create_temp_file(char *name)
Definition: record.c:30
GLuint GLfloat * val
Definition: glext.h:7180
static const WCHAR msifileW[]
Definition: record.c:28
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
#define MAX_PATH
Definition: compat.h:34
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_MORE_DATA
Definition: dderror.h:13
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
#define ERROR_INVALID_TABLE
Definition: winerror.h:986
#define CREATE_ALWAYS
Definition: disk.h:72
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
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
static const char * msifile
Definition: record.c:27
Definition: name.c:38
static void test_MsiRecordGetString(void)
Definition: record.c:400
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, const char *table, MSIHANDLE *phRec)
Definition: msiquery.c:1129
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:599
#define memset(x, y, z)
Definition: compat.h:39
UINT WINAPI MsiRecordGetFieldCount(MSIHANDLE handle)
Definition: record.c:113
START_TEST(record)
Definition: record.c:144
GLenum query
Definition: glext.h:7781
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
UINT WINAPI MsiRecordDataSize(MSIHANDLE handle, UINT iField)
Definition: record.c:532
UINT WINAPI MsiRecordSetStringA(MSIHANDLE handle, UINT iField, const char *szValue)
Definition: record.c:549