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