369c855bb4bab603f94b06ffbf0c8fec0a4bab82
[reactos.git] / rostests / winetests / msi / record.c
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
29 static BOOL create_temp_file(char *name)
30 {
31 UINT r;
32 unsigned char buffer[26], i;
33 DWORD sz;
34 HANDLE handle;
35
36 r = GetTempFileName(".", "msitest",0,name);
37 if(!r)
38 return r;
39 handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
40 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
41 if(handle==INVALID_HANDLE_VALUE)
42 return 0;
43 for(i=0; i<26; i++)
44 buffer[i]=i+'a';
45 r = WriteFile(handle,buffer,sizeof buffer,&sz,NULL);
46 CloseHandle(handle);
47 return r;
48 }
49
50 static void test_msirecord(void)
51 {
52 DWORD r, sz;
53 INT i;
54 MSIHANDLE h;
55 char buf[10];
56 WCHAR bufW[10];
57 const char str[] = "hello";
58 const WCHAR strW[] = { 'h','e','l','l','o',0};
59 char filename[MAX_PATH];
60
61 /* check behaviour with an invalid record */
62 r = MsiRecordGetFieldCount(0);
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");
90 r = MsiRecordGetFieldCount(h);
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 = MsiRecordGetString(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 = MsiRecordSetString(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 = sizeof bufW / sizeof bufW[0];
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 = MsiRecordSetString(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 = sizeof bufW / sizeof bufW[0];
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 string to it */
164 r = MsiRecordSetString(h,0,str);
165 ok(r == ERROR_SUCCESS, "Failed to set string at 0\n");
166 r = MsiRecordGetInteger(h, 0);
167 ok(r == MSI_NULL_INTEGER, "should get invalid integer\n");
168 r = MsiRecordDataSize(h,0);
169 ok(r==sizeof str-1, "size of string record is strlen\n");
170 buf[0]=0;
171 sz = sizeof buf;
172 r = MsiRecordGetString(h,0,buf,&sz);
173 ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
174 ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n");
175 ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
176 buf[0]=0;
177 sz = sizeof str - 2;
178 r = MsiRecordGetString(h,0,buf,&sz);
179 ok(r == ERROR_MORE_DATA, "small buffer should yield ERROR_MORE_DATA\n");
180 ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
181 ok(0==strncmp(buf,str,sizeof str-3), "MsiRecordGetString returned the wrong string\n");
182 ok(buf[sizeof str - 3]==0, "string wasn't nul terminated\n");
183
184 buf[0]=0;
185 sz = sizeof str;
186 r = MsiRecordGetString(h,0,buf,&sz);
187 ok(r == ERROR_SUCCESS, "wrong error\n");
188 ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
189 ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n");
190
191
192 memset(bufW, 0, sizeof bufW);
193 sz = 5;
194 r = MsiRecordGetStringW(h,0,bufW,&sz);
195 ok(r == ERROR_MORE_DATA, "wrong error\n");
196 ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
197 ok(0==memcmp(bufW,strW,8), "MsiRecordGetString returned the wrong string\n");
198
199 sz = 0;
200 bufW[0] = 'x';
201 r = MsiRecordGetStringW(h,0,bufW,&sz);
202 ok(r == ERROR_MORE_DATA, "wrong error\n");
203 ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
204 ok('x'==bufW[0], "MsiRecordGetString returned the wrong string\n");
205
206 memset(buf, 0, sizeof buf);
207 sz = 5;
208 r = MsiRecordGetStringA(h,0,buf,&sz);
209 ok(r == ERROR_MORE_DATA, "wrong error\n");
210 ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
211 ok(0==memcmp(buf,str,4), "MsiRecordGetString returned the wrong string\n");
212
213 sz = 0;
214 buf[0] = 'x';
215 r = MsiRecordGetStringA(h,0,buf,&sz);
216 ok(r == ERROR_MORE_DATA, "wrong error\n");
217 ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
218 ok('x'==buf[0], "MsiRecordGetString returned the wrong string\n");
219
220 /* same record, check we can wipe all the data */
221 r = MsiRecordClearData(h);
222 ok(r == ERROR_SUCCESS, "Failed to clear record\n");
223 r = MsiRecordClearData(h);
224 ok(r == ERROR_SUCCESS, "Failed to clear record again\n");
225 r = MsiRecordIsNull(h,0);
226 ok(r, "cleared record wasn't null\n");
227
228 /* same record, try converting strings to integers */
229 i = MsiRecordSetString(h,0,"42");
230 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
231 i = MsiRecordGetInteger(h, 0);
232 ok(i == 42, "should get invalid integer\n");
233 i = MsiRecordSetString(h,0,"-42");
234 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
235 i = MsiRecordGetInteger(h, 0);
236 ok(i == -42, "should get invalid integer\n");
237 i = MsiRecordSetString(h,0," 42");
238 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
239 i = MsiRecordGetInteger(h, 0);
240 ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
241 i = MsiRecordSetString(h,0,"42 ");
242 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
243 i = MsiRecordGetInteger(h, 0);
244 ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
245 i = MsiRecordSetString(h,0,"42.0");
246 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
247 i = MsiRecordGetInteger(h, 0);
248 ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
249 i = MsiRecordSetString(h,0,"0x42");
250 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
251 i = MsiRecordGetInteger(h, 0);
252 ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
253 i = MsiRecordSetString(h,0,"1000000000000000");
254 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
255 i = MsiRecordGetInteger(h, 0);
256 ok(i == -1530494976, "should get truncated integer\n");
257 i = MsiRecordSetString(h,0,"2147483647");
258 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
259 i = MsiRecordGetInteger(h, 0);
260 ok(i == 2147483647, "should get maxint\n");
261 i = MsiRecordSetString(h,0,"-2147483647");
262 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
263 i = MsiRecordGetInteger(h, 0);
264 ok(i == -2147483647, "should get -maxint-1\n");
265 i = MsiRecordSetString(h,0,"4294967297");
266 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
267 i = MsiRecordGetInteger(h, 0);
268 ok(i == 1, "should get one\n");
269 i = MsiRecordSetString(h,0,"foo");
270 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
271 i = MsiRecordGetInteger(h, 0);
272 ok(i == MSI_NULL_INTEGER, "should get zero\n");
273 i = MsiRecordSetString(h,0,"");
274 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
275 i = MsiRecordGetInteger(h, 0);
276 ok(i == MSI_NULL_INTEGER, "should get zero\n");
277 i = MsiRecordSetString(h,0,"+1");
278 ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
279 i = MsiRecordGetInteger(h, 0);
280 ok(i == MSI_NULL_INTEGER, "should get zero\n");
281
282 /* same record, try converting integers to strings */
283 r = MsiRecordSetInteger(h, 0, 32);
284 ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
285 sz = 1;
286 r = MsiRecordGetString(h, 0, NULL, &sz);
287 ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
288 ok(sz == 2, "length wrong\n");
289 buf[0]=0;
290 sz = sizeof buf;
291 r = MsiRecordGetString(h, 0, buf, &sz);
292 ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
293 ok(0==strcmp(buf,"32"), "failed to get string from integer\n");
294 r = MsiRecordSetInteger(h, 0, -32);
295 ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
296 buf[0]=0;
297 sz = 1;
298 r = MsiRecordGetString(h, 0, NULL, &sz);
299 ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
300 ok(sz == 3, "length wrong\n");
301 sz = sizeof buf;
302 r = MsiRecordGetString(h, 0, buf, &sz);
303 ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
304 ok(0==strcmp(buf,"-32"), "failed to get string from integer\n");
305 buf[0]=0;
306
307 /* same record, now try streams */
308 r = MsiRecordSetStream(h, 0, NULL);
309 ok(r == ERROR_INVALID_PARAMETER, "set NULL stream\n");
310 sz = sizeof buf;
311 r = MsiRecordReadStream(h, 0, buf, &sz);
312 ok(r == ERROR_INVALID_DATATYPE, "read non-stream type\n");
313 ok(sz == sizeof buf, "set sz\n");
314 r = MsiRecordDataSize( h, -1);
315 ok(r == 0,"MsiRecordDataSize returned wrong size\n");
316 r = MsiRecordDataSize( h, 0);
317 ok(r == 4,"MsiRecordDataSize returned wrong size\n");
318
319 /* same record, now close it */
320 r = MsiCloseHandle(h);
321 ok(r == ERROR_SUCCESS, "Failed to close handle\n");
322
323 /* now try streams in a new record - need to create a file to play with */
324 r = create_temp_file(filename);
325 if(!r)
326 return;
327
328 /* streams can't be inserted in field 0 for some reason */
329 h = MsiCreateRecord(2);
330 ok(h, "couldn't create a two field record\n");
331 r = MsiRecordSetStream(h, 0, filename);
332 ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n");
333 r = MsiRecordSetStream(h, 1, filename);
334 ok(r == ERROR_SUCCESS, "failed to add stream to record\n");
335 r = MsiRecordReadStream(h, 1, buf, NULL);
336 ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
337 /* http://test.winehq.org/data/200503181000/98_jmelgarejo98casa/msi:record.txt */
338 DeleteFile(filename); /* Windows 98 doesn't like this at all, so don't check return. */
339 r = MsiRecordReadStream(h, 1, NULL, NULL);
340 ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
341 sz = sizeof buf;
342 r = MsiRecordReadStream(h, 1, NULL, &sz);
343 ok(r == ERROR_SUCCESS, "failed to read stream\n");
344 ok(sz==26,"couldn't get size of stream\n");
345 sz = 0;
346 r = MsiRecordReadStream(h, 1, buf, &sz);
347 ok(r == ERROR_SUCCESS, "failed to read stream\n");
348 ok(sz==0,"short read\n");
349 sz = sizeof buf;
350 r = MsiRecordReadStream(h, 1, buf, &sz);
351 ok(r == ERROR_SUCCESS, "failed to read stream\n");
352 ok(sz==sizeof buf,"short read\n");
353 ok(!strncmp(buf,"abcdefghij",10), "read the wrong thing\n");
354 sz = sizeof buf;
355 r = MsiRecordReadStream(h, 1, buf, &sz);
356 ok(r == ERROR_SUCCESS, "failed to read stream\n");
357 ok(sz==sizeof buf,"short read\n");
358 ok(!strncmp(buf,"klmnopqrst",10), "read the wrong thing\n");
359 memset(buf,0,sizeof buf);
360 sz = sizeof buf;
361 r = MsiRecordReadStream(h, 1, buf, &sz);
362 ok(r == ERROR_SUCCESS, "failed to read stream\n");
363 ok(sz==6,"short read\n");
364 ok(!strcmp(buf,"uvwxyz"), "read the wrong thing\n");
365 memset(buf,0,sizeof buf);
366 sz = sizeof buf;
367 r = MsiRecordReadStream(h, 1, buf, &sz);
368 ok(r == ERROR_SUCCESS, "failed to read stream\n");
369 ok(sz==0,"size non-zero at end of stream\n");
370 ok(buf[0]==0, "read something at end of the stream\n");
371 r = MsiRecordSetStream(h, 1, NULL);
372 ok(r == ERROR_SUCCESS, "failed to reset stream\n");
373 sz = 0;
374 r = MsiRecordReadStream(h, 1, NULL, &sz);
375 ok(r == ERROR_SUCCESS, "bytes left wrong after reset\n");
376 ok(sz==26,"couldn't get size of stream\n");
377 r = MsiRecordDataSize(h,1);
378 ok(r == 26,"MsiRecordDataSize returned wrong size\n");
379
380 /* now close the stream record */
381 r = MsiCloseHandle(h);
382 ok(r == ERROR_SUCCESS, "Failed to close handle\n");
383 DeleteFile(filename); /* Delete it for sure, when everything else is closed. */
384 }
385
386 static void test_MsiRecordGetString(void)
387 {
388 MSIHANDLE rec;
389 CHAR buf[MAX_PATH];
390 DWORD sz;
391 UINT r;
392
393 rec = MsiCreateRecord(2);
394 ok(rec != 0, "Expected a valid handle\n");
395
396 sz = MAX_PATH;
397 r = MsiRecordGetString(rec, 1, NULL, &sz);
398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",r);
399 ok(sz == 0, "Expected 0, got %d\n",sz);
400
401 sz = MAX_PATH;
402 lstrcpyA(buf, "apple");
403 r = MsiRecordGetString(rec, 1, buf, &sz);
404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
405 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
406 ok(sz == 0, "Expected 0, got %d\n", sz);
407
408 sz = MAX_PATH;
409 lstrcpyA(buf, "apple");
410 r = MsiRecordGetString(rec, 10, buf, &sz);
411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
412 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
413 ok(sz == 0, "Expected 0, got %d\n", sz);
414
415 MsiCloseHandle(rec);
416
417 rec = MsiCreateRecord(1);
418 ok(rec != 0, "Expected a valid handle\n");
419
420 r = MsiRecordSetInteger(rec, 1, 5);
421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
422
423 sz = MAX_PATH;
424 r = MsiRecordGetString(rec, 1, NULL, &sz);
425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",r);
426 ok(sz == 1, "Expected 1, got %d\n",sz);
427
428 sz = MAX_PATH;
429 lstrcpyA(buf, "apple");
430 r = MsiRecordGetString(rec, 1, buf, &sz);
431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
432 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
433 ok(sz == 1, "Expectd 1, got %d\n", sz);
434
435 r = MsiRecordSetInteger(rec, 1, -5);
436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
437
438 sz = MAX_PATH;
439 lstrcpyA(buf, "apple");
440 r = MsiRecordGetString(rec, 1, buf, &sz);
441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
442 ok(!lstrcmpA(buf, "-5"), "Expected \"-5\", got \"%s\"\n", buf);
443 ok(sz == 2, "Expectd 2, got %d\n", sz);
444
445 MsiCloseHandle(rec);
446 }
447
448 static void test_MsiRecordGetInteger(void)
449 {
450 MSIHANDLE rec;
451 INT val;
452 UINT r;
453
454 rec = MsiCreateRecord(1);
455 ok(rec != 0, "Expected a valid handle\n");
456
457 r = MsiRecordSetString(rec, 1, "5");
458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
459
460 val = MsiRecordGetInteger(rec, 1);
461 ok(val == 5, "Expected 5, got %d\n", val);
462
463 r = MsiRecordSetString(rec, 1, "-5");
464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
465
466 val = MsiRecordGetInteger(rec, 1);
467 ok(val == -5, "Expected -5, got %d\n", val);
468
469 r = MsiRecordSetString(rec, 1, "5apple");
470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
471
472 val = MsiRecordGetInteger(rec, 1);
473 ok(val == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", val);
474
475 MsiCloseHandle(rec);
476 }
477
478 static void test_fieldzero(void)
479 {
480 MSIHANDLE hdb, hview, rec;
481 CHAR buf[MAX_PATH];
482 LPCSTR query;
483 DWORD sz;
484 UINT r;
485
486 rec = MsiCreateRecord(1);
487 ok(rec != 0, "Expected a valid handle\n");
488
489 r = MsiRecordGetInteger(rec, 0);
490 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
491
492 sz = MAX_PATH;
493 lstrcpyA(buf, "apple");
494 r = MsiRecordGetString(rec, 0, buf, &sz);
495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
496 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
497 ok(sz == 0, "Expectd 0, got %d\n", sz);
498
499 r = MsiRecordIsNull(rec, 0);
500 ok(r == TRUE, "Expected TRUE, got %d\n", r);
501
502 r = MsiRecordGetInteger(rec, 1);
503 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
504
505 r = MsiRecordSetInteger(rec, 1, 42);
506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
507
508 r = MsiRecordGetInteger(rec, 0);
509 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
510
511 sz = MAX_PATH;
512 lstrcpyA(buf, "apple");
513 r = MsiRecordGetString(rec, 0, buf, &sz);
514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
515 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
516 ok(sz == 0, "Expectd 0, got %d\n", sz);
517
518 r = MsiRecordIsNull(rec, 0);
519 ok(r == TRUE, "Expected TRUE, got %d\n", r);
520
521 r = MsiRecordGetInteger(rec, 1);
522 ok(r == 42, "Expected 42, got %d\n", r);
523
524 r = MsiRecordSetString(rec, 1, "bologna");
525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
526
527 r = MsiRecordGetInteger(rec, 0);
528 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
529
530 sz = MAX_PATH;
531 lstrcpyA(buf, "apple");
532 r = MsiRecordGetString(rec, 0, buf, &sz);
533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
534 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
535 ok(sz == 0, "Expectd 0, got %d\n", sz);
536
537 r = MsiRecordIsNull(rec, 0);
538 ok(r == TRUE, "Expected TRUE, got %d\n", r);
539
540 sz = MAX_PATH;
541 lstrcpyA(buf, "apple");
542 r = MsiRecordGetString(rec, 1, buf, &sz);
543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
544 ok(!lstrcmpA(buf, "bologna"), "Expected \"bologna\", got \"%s\"\n", buf);
545 ok(sz == 7, "Expectd 7, got %d\n", sz);
546
547 MsiCloseHandle(rec);
548
549 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
550 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
551
552 query = "CREATE TABLE `drone` ( "
553 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
554 "PRIMARY KEY `id`)";
555 r = MsiDatabaseOpenView(hdb, query, &hview);
556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
557 r = MsiViewExecute(hview, 0);
558 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
559 r = MsiViewClose(hview);
560 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
561 r = MsiCloseHandle(hview);
562 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
563
564 query = "INSERT INTO `drone` ( `id`, `name`, `number` )"
565 "VALUES('1', 'Abe', '8675309')";
566 r = MsiDatabaseOpenView(hdb, query, &hview);
567 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
568 r = MsiViewExecute(hview, 0);
569 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
570 r = MsiViewClose(hview);
571 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
572 r = MsiCloseHandle(hview);
573 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
574
575 r = MsiDatabaseGetPrimaryKeysA(hdb, "drone", &rec);
576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
577
578 r = MsiRecordGetInteger(rec, 0);
579 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
580
581 sz = MAX_PATH;
582 lstrcpyA(buf, "apple");
583 r = MsiRecordGetString(rec, 0, buf, &sz);
584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
585 ok(!lstrcmpA(buf, "drone"), "Expected \"drone\", got \"%s\"\n", buf);
586 ok(sz == 5, "Expectd 5, got %d\n", sz);
587
588 r = MsiRecordIsNull(rec, 0);
589 ok(r == FALSE, "Expected FALSE, got %d\n", r);
590
591 MsiCloseHandle(rec);
592
593 query = "SELECT * FROM `drone` WHERE `id` = 1";
594 r = MsiDatabaseOpenView(hdb, query, &hview);
595 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
596 r = MsiViewExecute(hview, 0);
597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
598 r = MsiViewFetch(hview, &rec);
599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
600
601 r = MsiRecordGetInteger(rec, 0);
602 ok(r != MSI_NULL_INTEGER && r != 0, "Expected non-NULL value, got %d\n", r);
603
604 r = MsiRecordIsNull(rec, 0);
605 ok(r == FALSE, "Expected FALSE, got %d\n", r);
606
607 r = MsiCloseHandle(hview);
608 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
609 MsiCloseHandle(rec);
610 MsiCloseHandle(hdb);
611 DeleteFileA(msifile);
612 }
613
614 START_TEST(record)
615 {
616 test_msirecord();
617 test_MsiRecordGetString();
618 test_MsiRecordGetInteger();
619 test_fieldzero();
620 }