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