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; 41 handle = CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 42 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 43 if(handle==INVALID_HANDLE_VALUE) 44 return FALSE; 45 for(i=0; i<26; i++) 46 buffer[i]=i+'a'; 47 r = WriteFile(handle,buffer,sizeof buffer,&sz,NULL); 48 CloseHandle(handle); 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 */ 64 r = MsiRecordGetFieldCount(0); 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"); 92 r = MsiRecordGetFieldCount(h); 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"); 170 r = MsiRecordSetInteger(h, 0, MSI_NULL_INTEGER); 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 */ 238 r = MsiRecordClearData(h); 239 ok(r == ERROR_SUCCESS, "Failed to clear record\n"); 240 r = MsiRecordClearData(h); 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 */ 341 r = create_temp_file(filename); 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"); 348 r = MsiRecordSetStreamA(h, 0, filename); 349 ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n"); 350 r = MsiRecordSetStreamA(h, 1, filename); 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 565 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 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); 630 DeleteFileA(msifile); 631 } 632 633 START_TEST(record) 634 { 635 test_msirecord(); 636 test_MsiRecordGetString(); 637 test_MsiRecordGetInteger(); 638 test_fieldzero(); 639 } 640