[CRT] Remove useless #undef abort from process.h
[reactos.git] / modules / 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 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;
40 handle = CreateFileA(name, GENERIC_READ|GENERIC_WRITE,
41 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
42 if(handle==INVALID_HANDLE_VALUE)
43 return FALSE;
44 for(i=0; i<26; i++)
45 buffer[i]=i+'a';
46 r = WriteFile(handle,buffer,sizeof buffer,&sz,NULL);
47 CloseHandle(handle);
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 */
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 = 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");
168 r = MsiRecordSetInteger(h, 0, MSI_NULL_INTEGER);
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 */
236 r = MsiRecordClearData(h);
237 ok(r == ERROR_SUCCESS, "Failed to clear record\n");
238 r = MsiRecordClearData(h);
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 */
339 r = create_temp_file(filename);
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");
346 r = MsiRecordSetStreamA(h, 0, filename);
347 ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n");
348 r = MsiRecordSetStreamA(h, 1, filename);
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
563 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
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);
628 DeleteFileA(msifile);
629 }
630
631 START_TEST(record)
632 {
633 test_msirecord();
634 test_MsiRecordGetString();
635 test_MsiRecordGetInteger();
636 test_fieldzero();
637 }