1 /* 2 * Copyright (C) 2005 Mike McCormack for CodeWeavers 3 * 4 * A test program for MSI database files. 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 #define COBJMACROS 22 23 #include <stdio.h> 24 25 #include <windows.h> 26 #include <objidl.h> 27 #include <msi.h> 28 #include <msidefs.h> 29 #include <msiquery.h> 30 31 #include "wine/test.h" 32 33 static const char *msifile = "winetest-db.msi"; 34 static const char *msifile2 = "winetst2-db.msi"; 35 static const char *mstfile = "winetst-db.mst"; 36 static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','-','d','b','.','m','s','i',0}; 37 static const WCHAR msifile2W[] = {'w','i','n','e','t','s','t','2','-','d','b','.','m','s','i',0}; 38 39 static void test_msidatabase(void) 40 { 41 MSIHANDLE hdb = 0, hdb2 = 0; 42 UINT res; 43 44 DeleteFileW(msifileW); 45 46 res = MsiOpenDatabaseW( msifileW, msifile2W, &hdb ); 47 ok( res == ERROR_OPEN_FAILED, "expected failure\n"); 48 49 res = MsiOpenDatabaseW( msifileW, (LPWSTR)0xff, &hdb ); 50 ok( res == ERROR_INVALID_PARAMETER, "expected failure\n"); 51 52 res = MsiCloseHandle( hdb ); 53 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 54 55 /* create an empty database */ 56 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 57 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 58 59 res = MsiDatabaseCommit( hdb ); 60 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 61 62 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n"); 63 64 res = MsiCloseHandle( hdb ); 65 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 66 res = MsiOpenDatabaseW( msifileW, msifile2W, &hdb2 ); 67 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 68 69 ok( GetFileAttributesA( msifile2 ) != INVALID_FILE_ATTRIBUTES, "database should exist\n"); 70 71 res = MsiDatabaseCommit( hdb2 ); 72 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 73 74 res = MsiCloseHandle( hdb2 ); 75 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 76 77 res = MsiOpenDatabaseW( msifileW, msifile2W, &hdb2 ); 78 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 79 80 res = MsiCloseHandle( hdb2 ); 81 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 82 83 ok( GetFileAttributesA( msifile2 ) == INVALID_FILE_ATTRIBUTES, "uncommitted database should not exist\n"); 84 85 res = MsiOpenDatabaseW( msifileW, msifile2W, &hdb2 ); 86 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 87 88 res = MsiDatabaseCommit( hdb2 ); 89 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 90 91 res = MsiCloseHandle( hdb2 ); 92 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 93 94 ok( GetFileAttributesA( msifile2 ) != INVALID_FILE_ATTRIBUTES, "committed database should exist\n"); 95 96 res = MsiOpenDatabaseW( msifileW, MSIDBOPEN_READONLY, &hdb ); 97 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 98 99 res = MsiDatabaseCommit( hdb ); 100 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 101 102 res = MsiCloseHandle( hdb ); 103 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 104 105 res = MsiOpenDatabaseW( msifileW, MSIDBOPEN_DIRECT, &hdb ); 106 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 107 108 res = MsiCloseHandle( hdb ); 109 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 110 111 res = MsiOpenDatabaseW( msifileW, MSIDBOPEN_TRANSACT, &hdb ); 112 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 113 114 res = MsiCloseHandle( hdb ); 115 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 116 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n"); 117 118 /* MSIDBOPEN_CREATE deletes the database if MsiCommitDatabase isn't called */ 119 res = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 120 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 121 122 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n"); 123 124 res = MsiCloseHandle( hdb ); 125 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 126 127 ok( GetFileAttributesA( msifile ) == INVALID_FILE_ATTRIBUTES, "database should exist\n"); 128 129 res = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 130 ok( res == ERROR_SUCCESS , "Failed to open database\n" ); 131 132 res = MsiDatabaseCommit( hdb ); 133 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 134 135 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n"); 136 137 res = MsiCloseHandle( hdb ); 138 ok( res == ERROR_SUCCESS , "Failed to close database\n" ); 139 140 res = DeleteFileA( msifile2 ); 141 ok( res == TRUE, "Failed to delete database\n" ); 142 143 res = DeleteFileA( msifile ); 144 ok( res == TRUE, "Failed to delete database\n" ); 145 } 146 147 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec) 148 { 149 MSIHANDLE hview = 0; 150 UINT r, ret; 151 152 if (phrec) 153 *phrec = 0; 154 155 /* open a select query */ 156 r = MsiDatabaseOpenViewA(hdb, query, &hview); 157 if (r != ERROR_SUCCESS) 158 return r; 159 r = MsiViewExecute(hview, 0); 160 if (r != ERROR_SUCCESS) 161 return r; 162 ret = MsiViewFetch(hview, phrec); 163 r = MsiViewClose(hview); 164 if (r != ERROR_SUCCESS) 165 return r; 166 r = MsiCloseHandle(hview); 167 if (r != ERROR_SUCCESS) 168 return r; 169 return ret; 170 } 171 172 static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query ) 173 { 174 MSIHANDLE hview = 0; 175 UINT r; 176 177 r = MsiDatabaseOpenViewA(hdb, query, &hview); 178 if( r != ERROR_SUCCESS ) 179 return r; 180 181 r = MsiViewExecute(hview, hrec); 182 if( r == ERROR_SUCCESS ) 183 r = MsiViewClose(hview); 184 MsiCloseHandle(hview); 185 return r; 186 } 187 188 static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query ) 189 { 190 MSIHANDLE hview = 0; 191 UINT r; 192 193 r = MsiDatabaseOpenViewW(hdb, query, &hview); 194 if( r != ERROR_SUCCESS ) 195 return r; 196 197 r = MsiViewExecute(hview, hrec); 198 if( r == ERROR_SUCCESS ) 199 r = MsiViewClose(hview); 200 MsiCloseHandle(hview); 201 return r; 202 } 203 204 static UINT create_component_table( MSIHANDLE hdb ) 205 { 206 return run_query( hdb, 0, 207 "CREATE TABLE `Component` ( " 208 "`Component` CHAR(72) NOT NULL, " 209 "`ComponentId` CHAR(38), " 210 "`Directory_` CHAR(72) NOT NULL, " 211 "`Attributes` SHORT NOT NULL, " 212 "`Condition` CHAR(255), " 213 "`KeyPath` CHAR(72) " 214 "PRIMARY KEY `Component`)" ); 215 } 216 217 static UINT create_custom_action_table( MSIHANDLE hdb ) 218 { 219 return run_query( hdb, 0, 220 "CREATE TABLE `CustomAction` ( " 221 "`Action` CHAR(72) NOT NULL, " 222 "`Type` SHORT NOT NULL, " 223 "`Source` CHAR(72), " 224 "`Target` CHAR(255) " 225 "PRIMARY KEY `Action`)" ); 226 } 227 228 static UINT create_directory_table( MSIHANDLE hdb ) 229 { 230 return run_query( hdb, 0, 231 "CREATE TABLE `Directory` ( " 232 "`Directory` CHAR(255) NOT NULL, " 233 "`Directory_Parent` CHAR(255), " 234 "`DefaultDir` CHAR(255) NOT NULL " 235 "PRIMARY KEY `Directory`)" ); 236 } 237 238 static UINT create_feature_components_table( MSIHANDLE hdb ) 239 { 240 return run_query( hdb, 0, 241 "CREATE TABLE `FeatureComponents` ( " 242 "`Feature_` CHAR(38) NOT NULL, " 243 "`Component_` CHAR(72) NOT NULL " 244 "PRIMARY KEY `Feature_`, `Component_` )" ); 245 } 246 247 static UINT create_std_dlls_table( MSIHANDLE hdb ) 248 { 249 return run_query( hdb, 0, 250 "CREATE TABLE `StdDlls` ( " 251 "`File` CHAR(255) NOT NULL, " 252 "`Binary_` CHAR(72) NOT NULL " 253 "PRIMARY KEY `File` )" ); 254 } 255 256 static UINT create_binary_table( MSIHANDLE hdb ) 257 { 258 return run_query( hdb, 0, 259 "CREATE TABLE `Binary` ( " 260 "`Name` CHAR(72) NOT NULL, " 261 "`Data` CHAR(72) NOT NULL " 262 "PRIMARY KEY `Name` )" ); 263 } 264 265 #define make_add_entry(type, qtext) \ 266 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \ 267 { \ 268 char insert[] = qtext; \ 269 char *query; \ 270 UINT sz, r; \ 271 sz = strlen(values) + sizeof insert; \ 272 query = HeapAlloc(GetProcessHeap(),0,sz); \ 273 sprintf(query,insert,values); \ 274 r = run_query( hdb, 0, query ); \ 275 HeapFree(GetProcessHeap(), 0, query); \ 276 return r; \ 277 } 278 279 make_add_entry(component, 280 "INSERT INTO `Component` " 281 "(`Component`, `ComponentId`, `Directory_`, " 282 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") 283 284 make_add_entry(custom_action, 285 "INSERT INTO `CustomAction` " 286 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") 287 288 make_add_entry(feature_components, 289 "INSERT INTO `FeatureComponents` " 290 "(`Feature_`, `Component_`) VALUES( %s )") 291 292 make_add_entry(std_dlls, 293 "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )") 294 295 make_add_entry(binary, 296 "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )") 297 298 static void test_msiinsert(void) 299 { 300 MSIHANDLE hdb = 0, hview = 0, hview2 = 0, hrec = 0; 301 UINT r; 302 const char *query; 303 char buf[80]; 304 DWORD sz; 305 306 DeleteFileA(msifile); 307 308 /* just MsiOpenDatabase should not create a file */ 309 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 310 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 311 312 /* create a table */ 313 query = "CREATE TABLE `phone` ( " 314 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 315 "PRIMARY KEY `id`)"; 316 r = MsiDatabaseOpenViewA(hdb, query, &hview); 317 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 318 r = MsiViewExecute(hview, 0); 319 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 320 r = MsiViewClose(hview); 321 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 322 r = MsiCloseHandle(hview); 323 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 324 325 query = "SELECT * FROM phone WHERE number = '8675309'"; 326 r = MsiDatabaseOpenViewA(hdb, query, &hview2); 327 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 328 r = MsiViewExecute(hview2, 0); 329 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 330 r = MsiViewFetch(hview2, &hrec); 331 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); 332 333 /* insert a value into it */ 334 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 335 "VALUES('1', 'Abe', '8675309')"; 336 r = MsiDatabaseOpenViewA(hdb, query, &hview); 337 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 338 r = MsiViewExecute(hview, 0); 339 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 340 r = MsiViewClose(hview); 341 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 342 r = MsiCloseHandle(hview); 343 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 344 345 r = MsiViewFetch(hview2, &hrec); 346 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); 347 r = MsiViewExecute(hview2, 0); 348 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 349 r = MsiViewFetch(hview2, &hrec); 350 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %u\n", r); 351 352 r = MsiCloseHandle(hrec); 353 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 354 r = MsiViewClose(hview2); 355 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 356 r = MsiCloseHandle(hview2); 357 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 358 359 query = "SELECT * FROM `phone` WHERE `id` = 1"; 360 r = do_query(hdb, query, &hrec); 361 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 362 363 /* check the record contains what we put in it */ 364 r = MsiRecordGetFieldCount(hrec); 365 ok(r == 3, "record count wrong\n"); 366 367 r = MsiRecordIsNull(hrec, 0); 368 ok(r == FALSE, "field 0 not null\n"); 369 370 r = MsiRecordGetInteger(hrec, 1); 371 ok(r == 1, "field 1 contents wrong\n"); 372 sz = sizeof buf; 373 r = MsiRecordGetStringA(hrec, 2, buf, &sz); 374 ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n"); 375 ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n"); 376 sz = sizeof buf; 377 r = MsiRecordGetStringA(hrec, 3, buf, &sz); 378 ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n"); 379 ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n"); 380 381 r = MsiCloseHandle(hrec); 382 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 383 384 /* open a select query */ 385 hrec = 100; 386 query = "SELECT * FROM `phone` WHERE `id` >= 10"; 387 r = do_query(hdb, query, &hrec); 388 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 389 ok(hrec == 0, "hrec should be null\n"); 390 391 r = MsiCloseHandle(hrec); 392 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 393 394 query = "SELECT * FROM `phone` WHERE `id` < 0"; 395 r = do_query(hdb, query, &hrec); 396 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 397 398 query = "SELECT * FROM `phone` WHERE `id` <= 0"; 399 r = do_query(hdb, query, &hrec); 400 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 401 402 query = "SELECT * FROM `phone` WHERE `id` <> 1"; 403 r = do_query(hdb, query, &hrec); 404 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 405 406 query = "SELECT * FROM `phone` WHERE `id` > 10"; 407 r = do_query(hdb, query, &hrec); 408 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 409 410 /* now try a few bad INSERT xqueries */ 411 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 412 "VALUES(?, ?)"; 413 r = MsiDatabaseOpenViewA(hdb, query, &hview); 414 ok(r == ERROR_BAD_QUERY_SYNTAX, "MsiDatabaseOpenView failed\n"); 415 416 /* construct a record to insert */ 417 hrec = MsiCreateRecord(4); 418 r = MsiRecordSetInteger(hrec, 1, 2); 419 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n"); 420 r = MsiRecordSetStringA(hrec, 2, "Adam"); 421 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 422 r = MsiRecordSetStringA(hrec, 3, "96905305"); 423 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 424 425 /* insert another value, using a record and wildcards */ 426 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 427 "VALUES(?, ?, ?)"; 428 r = MsiDatabaseOpenViewA(hdb, query, &hview); 429 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 430 431 if (r == ERROR_SUCCESS) 432 { 433 r = MsiViewExecute(hview, hrec); 434 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 435 r = MsiViewClose(hview); 436 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 437 r = MsiCloseHandle(hview); 438 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 439 } 440 r = MsiCloseHandle(hrec); 441 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 442 443 r = MsiViewFetch(0, NULL); 444 ok(r == ERROR_INVALID_PARAMETER, "MsiViewFetch failed\n"); 445 446 r = MsiDatabaseCommit(hdb); 447 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 448 449 r = MsiCloseHandle(hdb); 450 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 451 452 r = DeleteFileA(msifile); 453 ok(r == TRUE, "file didn't exist after commit\n"); 454 } 455 456 static void test_msidecomposedesc(void) 457 { 458 UINT (WINAPI *pMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *); 459 char prod[MAX_FEATURE_CHARS+1], comp[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1]; 460 const char *desc; 461 UINT r; 462 DWORD len; 463 HMODULE hmod; 464 465 hmod = GetModuleHandleA("msi.dll"); 466 pMsiDecomposeDescriptorA = (void*)GetProcAddress(hmod, "MsiDecomposeDescriptorA"); 467 if (!pMsiDecomposeDescriptorA) 468 return; 469 470 /* test a valid feature descriptor */ 471 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk."; 472 len = 0; 473 prod[0] = feature[0] = comp[0] = 0; 474 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 475 ok(r == ERROR_SUCCESS, "returned an error\n"); 476 ok(len == strlen(desc), "length was wrong\n"); 477 ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n"); 478 ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n"); 479 ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n"); 480 481 /* test an invalid feature descriptor with too many characters */ 482 desc = "']gAVn-}f(ZXfeAR6.ji" 483 "ThisWillFailIfTheresMoreThanAGuidsChars>" 484 "3w2x^IGfe?CxI5heAvk."; 485 len = 0; 486 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 487 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); 488 489 /* test a feature descriptor with < instead of > */ 490 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit<3w2x^IGfe?CxI5heAvk."; 491 len = 0; 492 prod[0] = feature[0] = 0; 493 comp[0] = 0x55; 494 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 495 ok(r == ERROR_SUCCESS, "returned an error\n"); 496 ok(len == 41, "got %u\n", len); 497 ok(!strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}"), "got '%s'\n", prod); 498 ok(!strcmp(feature,"FollowTheWhiteRabbit"), "got '%s'\n", feature); 499 ok(!comp[0], "got '%s'\n", comp); 500 501 len = 0; 502 prod[0] = feature[0] = 0; 503 comp[0] = 0x55; 504 r = pMsiDecomposeDescriptorA("yh1BVN)8A$!!!!!MKKSkAlwaysInstalledIntl_1033<", prod, feature, comp, &len); 505 ok(r == ERROR_SUCCESS, "got %u\n", r); 506 ok(len == 45, "got %u\n", len); 507 ok(!strcmp(prod, "{90150000-006E-0409-0000-0000000FF1CE}"), "got '%s'\n", prod); 508 ok(!strcmp(feature, "AlwaysInstalledIntl_1033"), "got '%s'\n", feature); 509 ok(!comp[0], "got '%s'\n", comp); 510 511 /* 512 * Test a valid feature descriptor with the 513 * maximum number of characters and some trailing characters. 514 */ 515 desc = "']gAVn-}f(ZXfeAR6.ji" 516 "ThisWillWorkIfTheresLTEThanAGuidsChars>" 517 "3w2x^IGfe?CxI5heAvk." 518 "extra"; 519 len = 0; 520 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 521 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 522 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 523 524 len = 0; 525 r = pMsiDecomposeDescriptorA(desc, prod, feature, NULL, &len); 526 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 527 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 528 529 len = 0; 530 r = pMsiDecomposeDescriptorA(desc, prod, NULL, NULL, &len); 531 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 532 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 533 534 len = 0; 535 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, &len); 536 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 537 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 538 539 len = 0; 540 r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len); 541 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); 542 ok(len == 0, "length wrong\n"); 543 544 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL); 545 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 546 } 547 548 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec ) 549 { 550 MSIHANDLE htab = 0; 551 UINT res; 552 553 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab ); 554 if(res == ERROR_SUCCESS ) 555 { 556 UINT r; 557 558 r = MsiViewExecute( htab, hrec ); 559 if(r != ERROR_SUCCESS ) 560 res = r; 561 562 r = MsiViewClose( htab ); 563 if(r != ERROR_SUCCESS ) 564 res = r; 565 566 r = MsiCloseHandle( htab ); 567 if(r != ERROR_SUCCESS ) 568 res = r; 569 } 570 return res; 571 } 572 573 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery ) 574 { 575 return try_query_param( hdb, szQuery, 0 ); 576 } 577 578 static UINT try_insert_query( MSIHANDLE hdb, LPCSTR szQuery ) 579 { 580 MSIHANDLE hrec = 0; 581 UINT r; 582 583 hrec = MsiCreateRecord( 1 ); 584 MsiRecordSetStringA( hrec, 1, "Hello"); 585 586 r = try_query_param( hdb, szQuery, hrec ); 587 588 MsiCloseHandle( hrec ); 589 return r; 590 } 591 592 static void test_msibadqueries(void) 593 { 594 MSIHANDLE hdb = 0; 595 UINT r; 596 597 DeleteFileA(msifile); 598 599 /* just MsiOpenDatabase should not create a file */ 600 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 601 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 602 603 r = MsiDatabaseCommit( hdb ); 604 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 605 606 r = MsiCloseHandle( hdb ); 607 ok(r == ERROR_SUCCESS , "Failed to close database\n"); 608 609 /* open it readonly */ 610 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb ); 611 ok(r == ERROR_SUCCESS , "Failed to open database r/o\n"); 612 613 /* add a table to it */ 614 r = try_query( hdb, "select * from _Tables"); 615 ok(r == ERROR_SUCCESS , "query 1 failed\n"); 616 617 r = MsiCloseHandle( hdb ); 618 ok(r == ERROR_SUCCESS , "Failed to close database r/o\n"); 619 620 /* open it read/write */ 621 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 622 ok(r == ERROR_SUCCESS , "Failed to open database r/w\n"); 623 624 /* a bunch of test queries that fail with the native MSI */ 625 626 r = try_query( hdb, "CREATE TABLE"); 627 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2a return code\n"); 628 629 r = try_query( hdb, "CREATE TABLE `a`"); 630 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2b return code\n"); 631 632 r = try_query( hdb, "CREATE TABLE `a` ()"); 633 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2c return code\n"); 634 635 r = try_query( hdb, "CREATE TABLE `a` (`b`)"); 636 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2d return code\n"); 637 638 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) )"); 639 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2e return code\n"); 640 641 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL)"); 642 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2f return code\n"); 643 644 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY)"); 645 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2g return code\n"); 646 647 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)"); 648 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2h return code\n"); 649 650 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)"); 651 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2i return code\n"); 652 653 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY 'b')"); 654 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2j return code\n"); 655 656 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')"); 657 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2k return code\n"); 658 659 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')"); 660 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2l return code\n"); 661 662 r = try_query( hdb, "CREATE TABLE `a` (`b` CHA(72) NOT NULL PRIMARY KEY `b`)"); 663 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2m return code\n"); 664 665 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(-1) NOT NULL PRIMARY KEY `b`)"); 666 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2n return code\n"); 667 668 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(720) NOT NULL PRIMARY KEY `b`)"); 669 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2o return code\n"); 670 671 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL KEY `b`)"); 672 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n"); 673 674 r = try_query( hdb, "CREATE TABLE `a` (`` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 675 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n"); 676 677 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 678 ok(r == ERROR_SUCCESS , "valid query 2z failed\n"); 679 680 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 681 ok(r == ERROR_BAD_QUERY_SYNTAX , "created same table again\n"); 682 683 r = try_query( hdb, "CREATE TABLE `aa` (`b` CHAR(72) NOT NULL, `c` " 684 "CHAR(72), `d` CHAR(255) NOT NULL LOCALIZABLE PRIMARY KEY `b`)"); 685 ok(r == ERROR_SUCCESS , "query 4 failed\n"); 686 687 r = MsiDatabaseCommit( hdb ); 688 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n"); 689 690 r = try_query( hdb, "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL " 691 "PRIMARY KEY `foo`)"); 692 ok(r == ERROR_SUCCESS , "query 4 failed\n"); 693 694 r = try_insert_query( hdb, "insert into a ( `b` ) VALUES ( ? )"); 695 ok(r == ERROR_SUCCESS , "failed to insert record in db\n"); 696 697 r = MsiDatabaseCommit( hdb ); 698 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n"); 699 700 r = try_query( hdb, "CREATE TABLE `boo` (`foo` CHAR(72) NOT NULL " 701 "PRIMARY KEY `ba`)"); 702 ok(r != ERROR_SUCCESS , "query 5 succeeded\n"); 703 704 r = try_query( hdb,"CREATE TABLE `bee` (`foo` CHAR(72) NOT NULL )"); 705 ok(r != ERROR_SUCCESS , "query 6 succeeded\n"); 706 707 r = try_query( hdb, "CREATE TABLE `temp` (`t` CHAR(72) NOT NULL " 708 "PRIMARY KEY `t`)"); 709 ok(r == ERROR_SUCCESS , "query 7 failed\n"); 710 711 r = try_query( hdb, "CREATE TABLE `c` (`b` CHAR NOT NULL PRIMARY KEY `b`)"); 712 ok(r == ERROR_SUCCESS , "query 8 failed\n"); 713 714 r = try_query( hdb, "select * from c"); 715 ok(r == ERROR_SUCCESS , "query failed\n"); 716 717 r = try_query( hdb, "select * from c where b = 'x"); 718 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 719 720 r = try_query( hdb, "select * from c where b = 'x'"); 721 ok(r == ERROR_SUCCESS, "query failed\n"); 722 723 r = try_query( hdb, "select * from 'c'"); 724 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 725 726 r = try_query( hdb, "select * from ''"); 727 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 728 729 r = try_query( hdb, "select * from c where b = x"); 730 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 731 732 r = try_query( hdb, "select * from c where b = \"x\""); 733 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 734 735 r = try_query( hdb, "select * from c where b = 'x'"); 736 ok(r == ERROR_SUCCESS, "query failed\n"); 737 738 r = try_query( hdb, "select * from c where b = '\"x'"); 739 ok(r == ERROR_SUCCESS, "query failed\n"); 740 741 if (0) /* FIXME: this query causes trouble with other tests */ 742 { 743 r = try_query( hdb, "select * from c where b = '\\\'x'"); 744 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 745 } 746 747 r = try_query( hdb, "select * from 'c'"); 748 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 749 750 r = try_query( hdb, "select `c`.`b` from `c` order by `c`.`order`"); 751 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 752 753 r = try_query( hdb, "select `c`.b` from `c`"); 754 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 755 756 r = try_query( hdb, "select `c`.`b from `c`"); 757 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 758 759 r = try_query( hdb, "select `c`.b from `c`"); 760 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 761 762 r = try_query( hdb, "select `c.`b` from `c`"); 763 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 764 765 r = try_query( hdb, "select c`.`b` from `c`"); 766 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 767 768 r = try_query( hdb, "select c.`b` from `c`"); 769 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 770 771 r = try_query( hdb, "select `c`.`b` from c`"); 772 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 773 774 r = try_query( hdb, "select `c`.`b` from `c"); 775 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 776 777 r = try_query( hdb, "select `c`.`b` from c"); 778 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 779 780 r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 781 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 782 783 r = try_query( hdb, "SELECT * FROM \5a" ); 784 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 785 786 r = try_query( hdb, "CREATE TABLE `a\5` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 787 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 788 789 r = try_query( hdb, "SELECT * FROM a\5" ); 790 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 791 792 r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 793 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 794 795 r = try_query( hdb, "SELECT * FROM -a" ); 796 todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 797 798 r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 799 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 800 801 r = try_query( hdb, "SELECT * FROM a-" ); 802 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 803 804 r = MsiCloseHandle( hdb ); 805 ok(r == ERROR_SUCCESS , "Failed to close database transact\n"); 806 807 r = DeleteFileA( msifile ); 808 ok(r == TRUE, "file didn't exist after commit\n"); 809 } 810 811 static void test_viewmodify(void) 812 { 813 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 814 UINT r; 815 MSIDBERROR err; 816 const char *query; 817 char buffer[0x100]; 818 DWORD sz; 819 820 DeleteFileA(msifile); 821 822 /* just MsiOpenDatabase should not create a file */ 823 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 824 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 825 826 query = "CREATE TABLE `phone` ( " 827 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 828 "PRIMARY KEY `id`)"; 829 r = run_query( hdb, 0, query ); 830 ok(r == ERROR_SUCCESS, "query failed\n"); 831 832 query = "CREATE TABLE `_Validation` ( " 833 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, " 834 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, " 835 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), " 836 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)"; 837 r = run_query( hdb, 0, query ); 838 ok(r == ERROR_SUCCESS, "query failed\n"); 839 840 query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) " 841 "VALUES('phone', 'id', 'N')"; 842 r = run_query( hdb, 0, query ); 843 ok(r == ERROR_SUCCESS, "query failed\n"); 844 845 /* check what the error function reports without doing anything */ 846 sz = 0; 847 /* passing NULL as the 3rd param make function to crash on older platforms */ 848 err = MsiViewGetErrorA( 0, NULL, &sz ); 849 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n"); 850 851 /* open a view */ 852 query = "SELECT * FROM `phone`"; 853 r = MsiDatabaseOpenViewA(hdb, query, &hview); 854 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 855 856 /* see what happens with a good hview and bad args */ 857 err = MsiViewGetErrorA( hview, NULL, NULL ); 858 ok(err == MSIDBERROR_INVALIDARG || err == MSIDBERROR_NOERROR, 859 "MsiViewGetError returns %u (expected -3)\n", err); 860 err = MsiViewGetErrorA( hview, buffer, NULL ); 861 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n"); 862 863 /* see what happens with a zero length buffer */ 864 sz = 0; 865 buffer[0] = 'x'; 866 err = MsiViewGetErrorA( hview, buffer, &sz ); 867 ok(err == MSIDBERROR_MOREDATA, "MsiViewGetError return\n"); 868 ok(buffer[0] == 'x', "buffer cleared\n"); 869 ok(sz == 0, "size not zero\n"); 870 871 /* ok this one is strange */ 872 sz = 0; 873 err = MsiViewGetErrorA( hview, NULL, &sz ); 874 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 875 ok(sz == 0, "size not zero\n"); 876 877 /* see if it really has an error */ 878 sz = sizeof buffer; 879 buffer[0] = 'x'; 880 err = MsiViewGetErrorA( hview, buffer, &sz ); 881 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 882 ok(buffer[0] == 0, "buffer not cleared\n"); 883 ok(sz == 0, "size not zero\n"); 884 885 r = MsiViewExecute(hview, 0); 886 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 887 888 /* try some invalid records */ 889 r = MsiViewModify(hview, MSIMODIFY_INSERT, 0 ); 890 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n"); 891 r = MsiViewModify(hview, -1, 0 ); 892 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n"); 893 894 /* try an small record */ 895 hrec = MsiCreateRecord(1); 896 r = MsiViewModify(hview, -1, hrec ); 897 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n"); 898 899 sz = sizeof buffer; 900 buffer[0] = 'x'; 901 err = MsiViewGetErrorA( hview, buffer, &sz ); 902 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 903 ok(buffer[0] == 0, "buffer not cleared\n"); 904 ok(sz == 0, "size not zero\n"); 905 906 r = MsiCloseHandle(hrec); 907 ok(r == ERROR_SUCCESS, "failed to close record\n"); 908 909 /* insert a valid record */ 910 hrec = MsiCreateRecord(3); 911 912 r = MsiRecordSetInteger(hrec, 1, 1); 913 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 914 r = MsiRecordSetStringA(hrec, 2, "bob"); 915 ok(r == ERROR_SUCCESS, "failed to set string\n"); 916 r = MsiRecordSetStringA(hrec, 3, "7654321"); 917 ok(r == ERROR_SUCCESS, "failed to set string\n"); 918 919 r = MsiViewExecute(hview, 0); 920 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 921 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 922 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 923 924 /* validate it */ 925 r = MsiViewExecute(hview, 0); 926 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 927 928 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec ); 929 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r); 930 931 sz = sizeof buffer; 932 buffer[0] = 'x'; 933 err = MsiViewGetErrorA( hview, buffer, &sz ); 934 ok(err == MSIDBERROR_DUPLICATEKEY, "MsiViewGetError returned %u\n", err); 935 ok(!strcmp(buffer, "id"), "expected \"id\" c, got \"%s\"\n", buffer); 936 ok(sz == 2, "size not 2\n"); 937 938 /* insert the same thing again */ 939 r = MsiViewExecute(hview, 0); 940 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 941 942 /* should fail ... */ 943 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 944 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 945 946 /* try to merge the same record */ 947 r = MsiViewExecute(hview, 0); 948 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 949 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec ); 950 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 951 952 r = MsiCloseHandle(hrec); 953 ok(r == ERROR_SUCCESS, "failed to close record\n"); 954 955 /* try merging a new record */ 956 hrec = MsiCreateRecord(3); 957 958 r = MsiRecordSetInteger(hrec, 1, 10); 959 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 960 r = MsiRecordSetStringA(hrec, 2, "pepe"); 961 ok(r == ERROR_SUCCESS, "failed to set string\n"); 962 r = MsiRecordSetStringA(hrec, 3, "7654321"); 963 ok(r == ERROR_SUCCESS, "failed to set string\n"); 964 965 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec ); 966 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 967 r = MsiViewExecute(hview, 0); 968 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 969 970 r = MsiCloseHandle(hrec); 971 ok(r == ERROR_SUCCESS, "failed to close record\n"); 972 973 r = MsiViewClose(hview); 974 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 975 r = MsiCloseHandle(hview); 976 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 977 978 query = "SELECT * FROM `phone`"; 979 r = MsiDatabaseOpenViewA(hdb, query, &hview); 980 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 981 982 r = MsiViewExecute(hview, 0); 983 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 984 985 r = MsiViewFetch(hview, &hrec); 986 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 987 988 r = MsiRecordGetInteger(hrec, 1); 989 ok(r == 1, "Expected 1, got %d\n", r); 990 991 sz = sizeof(buffer); 992 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 993 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 994 ok(!lstrcmpA(buffer, "bob"), "Expected bob, got %s\n", buffer); 995 996 sz = sizeof(buffer); 997 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 998 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 999 ok(!lstrcmpA(buffer, "7654321"), "Expected 7654321, got %s\n", buffer); 1000 1001 /* update the view, non-primary key */ 1002 r = MsiRecordSetStringA(hrec, 3, "3141592"); 1003 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 1004 1005 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1006 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 1007 1008 /* do it again */ 1009 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1010 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 1011 1012 /* update the view, primary key */ 1013 r = MsiRecordSetInteger(hrec, 1, 5); 1014 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n"); 1015 1016 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1017 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1018 1019 r = MsiCloseHandle(hrec); 1020 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1021 1022 r = MsiViewClose(hview); 1023 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1024 r = MsiCloseHandle(hview); 1025 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1026 1027 query = "SELECT * FROM `phone`"; 1028 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1029 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1030 1031 r = MsiViewExecute(hview, 0); 1032 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1033 1034 r = MsiViewFetch(hview, &hrec); 1035 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1036 1037 r = MsiRecordGetInteger(hrec, 1); 1038 ok(r == 1, "Expected 1, got %d\n", r); 1039 1040 sz = sizeof(buffer); 1041 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 1042 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1043 ok(!lstrcmpA(buffer, "bob"), "Expected bob, got %s\n", buffer); 1044 1045 sz = sizeof(buffer); 1046 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 1047 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1048 ok(!lstrcmpA(buffer, "3141592"), "Expected 3141592, got %s\n", buffer); 1049 1050 r = MsiCloseHandle(hrec); 1051 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1052 1053 /* use a record that doesn't come from a view fetch */ 1054 hrec = MsiCreateRecord(3); 1055 ok(hrec != 0, "MsiCreateRecord failed\n"); 1056 1057 r = MsiRecordSetInteger(hrec, 1, 3); 1058 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1059 r = MsiRecordSetStringA(hrec, 2, "jane"); 1060 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1061 r = MsiRecordSetStringA(hrec, 3, "112358"); 1062 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1063 1064 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1065 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 1066 1067 r = MsiCloseHandle(hrec); 1068 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1069 1070 /* use a record that doesn't come from a view fetch, primary key matches */ 1071 hrec = MsiCreateRecord(3); 1072 ok(hrec != 0, "MsiCreateRecord failed\n"); 1073 1074 r = MsiRecordSetInteger(hrec, 1, 1); 1075 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1076 r = MsiRecordSetStringA(hrec, 2, "jane"); 1077 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1078 r = MsiRecordSetStringA(hrec, 3, "112358"); 1079 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1080 1081 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1082 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1083 1084 r = MsiCloseHandle(hrec); 1085 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1086 1087 hrec = MsiCreateRecord(3); 1088 1089 r = MsiRecordSetInteger(hrec, 1, 2); 1090 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1091 r = MsiRecordSetStringA(hrec, 2, "nick"); 1092 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1093 r = MsiRecordSetStringA(hrec, 3, "141421"); 1094 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1095 1096 r = MsiViewExecute(hview, 0); 1097 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1098 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 1099 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 1100 1101 r = MsiCloseHandle(hrec); 1102 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1103 r = MsiViewClose(hview); 1104 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1105 r = MsiCloseHandle(hview); 1106 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1107 1108 query = "SELECT * FROM `phone` WHERE `id` = 1"; 1109 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1110 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1111 r = MsiViewExecute(hview, 0); 1112 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1113 r = MsiViewFetch(hview, &hrec); 1114 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1115 1116 /* change the id to match the second row */ 1117 r = MsiRecordSetInteger(hrec, 1, 2); 1118 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1119 r = MsiRecordSetStringA(hrec, 2, "jerry"); 1120 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1121 1122 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1123 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1124 1125 r = MsiCloseHandle(hrec); 1126 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1127 r = MsiViewClose(hview); 1128 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1129 r = MsiCloseHandle(hview); 1130 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1131 1132 /* broader search */ 1133 query = "SELECT * FROM `phone` ORDER BY `id`"; 1134 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1135 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1136 r = MsiViewExecute(hview, 0); 1137 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1138 r = MsiViewFetch(hview, &hrec); 1139 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1140 1141 /* change the id to match the second row */ 1142 r = MsiRecordSetInteger(hrec, 1, 2); 1143 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1144 r = MsiRecordSetStringA(hrec, 2, "jerry"); 1145 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1146 1147 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1148 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1149 1150 r = MsiCloseHandle(hrec); 1151 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1152 r = MsiViewClose(hview); 1153 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1154 r = MsiCloseHandle(hview); 1155 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1156 1157 r = MsiCloseHandle( hdb ); 1158 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 1159 } 1160 1161 static MSIHANDLE create_db(void) 1162 { 1163 MSIHANDLE hdb = 0; 1164 UINT res; 1165 1166 DeleteFileW(msifileW); 1167 1168 /* create an empty database */ 1169 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1170 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 1171 if( res != ERROR_SUCCESS ) 1172 return hdb; 1173 1174 res = MsiDatabaseCommit( hdb ); 1175 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 1176 1177 return hdb; 1178 } 1179 1180 static void test_getcolinfo(void) 1181 { 1182 MSIHANDLE hdb, hview = 0, rec = 0; 1183 UINT r; 1184 DWORD sz; 1185 char buffer[0x20]; 1186 1187 /* create an empty db */ 1188 hdb = create_db(); 1189 ok( hdb, "failed to create db\n"); 1190 1191 /* tables should be present */ 1192 r = MsiDatabaseOpenViewA(hdb, "select * from _Tables", &hview); 1193 ok( r == ERROR_SUCCESS, "failed to open query\n"); 1194 1195 r = MsiViewExecute(hview, 0); 1196 ok( r == ERROR_SUCCESS, "failed to execute query\n"); 1197 1198 /* check that NAMES works */ 1199 rec = 0; 1200 r = MsiViewGetColumnInfo( hview, MSICOLINFO_NAMES, &rec ); 1201 ok( r == ERROR_SUCCESS, "failed to get names\n"); 1202 sz = sizeof buffer; 1203 r = MsiRecordGetStringA(rec, 1, buffer, &sz ); 1204 ok( r == ERROR_SUCCESS, "failed to get string\n"); 1205 ok( !strcmp(buffer,"Name"), "_Tables has wrong column name\n"); 1206 r = MsiCloseHandle( rec ); 1207 ok( r == ERROR_SUCCESS, "failed to close record handle\n"); 1208 1209 /* check that TYPES works */ 1210 rec = 0; 1211 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, &rec ); 1212 ok( r == ERROR_SUCCESS, "failed to get names\n"); 1213 sz = sizeof buffer; 1214 r = MsiRecordGetStringA(rec, 1, buffer, &sz ); 1215 ok( r == ERROR_SUCCESS, "failed to get string\n"); 1216 ok( !strcmp(buffer,"s64"), "_Tables has wrong column type\n"); 1217 r = MsiCloseHandle( rec ); 1218 ok( r == ERROR_SUCCESS, "failed to close record handle\n"); 1219 1220 /* check that invalid values fail */ 1221 rec = 0; 1222 r = MsiViewGetColumnInfo( hview, 100, &rec ); 1223 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n"); 1224 ok( rec == 0, "returned a record\n"); 1225 1226 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, NULL ); 1227 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n"); 1228 1229 r = MsiViewGetColumnInfo( 0, MSICOLINFO_TYPES, &rec ); 1230 ok( r == ERROR_INVALID_HANDLE, "wrong error code\n"); 1231 1232 r = MsiViewClose(hview); 1233 ok( r == ERROR_SUCCESS, "failed to close view\n"); 1234 r = MsiCloseHandle(hview); 1235 ok( r == ERROR_SUCCESS, "failed to close view handle\n"); 1236 r = MsiCloseHandle(hdb); 1237 ok( r == ERROR_SUCCESS, "failed to close database\n"); 1238 } 1239 1240 static MSIHANDLE get_column_info(MSIHANDLE hdb, const char *query, MSICOLINFO type) 1241 { 1242 MSIHANDLE hview = 0, rec = 0; 1243 UINT r; 1244 1245 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1246 if( r != ERROR_SUCCESS ) 1247 return r; 1248 1249 r = MsiViewExecute(hview, 0); 1250 if( r == ERROR_SUCCESS ) 1251 { 1252 MsiViewGetColumnInfo( hview, type, &rec ); 1253 } 1254 MsiViewClose(hview); 1255 MsiCloseHandle(hview); 1256 return rec; 1257 } 1258 1259 static UINT get_columns_table_type(MSIHANDLE hdb, const char *table, UINT field) 1260 { 1261 MSIHANDLE hview = 0, rec = 0; 1262 UINT r, type = 0; 1263 char query[0x100]; 1264 1265 sprintf(query, "select * from `_Columns` where `Table` = '%s'", table ); 1266 1267 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1268 if( r != ERROR_SUCCESS ) 1269 return r; 1270 1271 r = MsiViewExecute(hview, 0); 1272 if( r == ERROR_SUCCESS ) 1273 { 1274 while (1) 1275 { 1276 r = MsiViewFetch( hview, &rec ); 1277 if( r != ERROR_SUCCESS) 1278 break; 1279 r = MsiRecordGetInteger( rec, 2 ); 1280 if (r == field) 1281 type = MsiRecordGetInteger( rec, 4 ); 1282 MsiCloseHandle( rec ); 1283 } 1284 } 1285 MsiViewClose(hview); 1286 MsiCloseHandle(hview); 1287 return type; 1288 } 1289 1290 static BOOL check_record( MSIHANDLE rec, UINT field, LPCSTR val ) 1291 { 1292 CHAR buffer[0x20]; 1293 UINT r; 1294 DWORD sz; 1295 1296 sz = sizeof buffer; 1297 r = MsiRecordGetStringA( rec, field, buffer, &sz ); 1298 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer); 1299 } 1300 1301 static void test_viewgetcolumninfo(void) 1302 { 1303 MSIHANDLE hdb = 0, rec; 1304 UINT r; 1305 1306 hdb = create_db(); 1307 ok( hdb, "failed to create db\n"); 1308 1309 r = run_query( hdb, 0, 1310 "CREATE TABLE `Properties` " 1311 "( `Property` CHAR(255), " 1312 " `Value` CHAR(1), " 1313 " `Intvalue` INT, " 1314 " `Integervalue` INTEGER, " 1315 " `Shortvalue` SHORT, " 1316 " `Longvalue` LONG, " 1317 " `Longcharvalue` LONGCHAR, " 1318 " `Charvalue` CHAR, " 1319 " `Localizablevalue` CHAR LOCALIZABLE " 1320 " PRIMARY KEY `Property`)" ); 1321 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1322 1323 /* check the column types */ 1324 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES ); 1325 ok( rec, "failed to get column info record\n" ); 1326 1327 ok( check_record( rec, 1, "S255"), "wrong record type\n"); 1328 ok( check_record( rec, 2, "S1"), "wrong record type\n"); 1329 ok( check_record( rec, 3, "I2"), "wrong record type\n"); 1330 ok( check_record( rec, 4, "I2"), "wrong record type\n"); 1331 ok( check_record( rec, 5, "I2"), "wrong record type\n"); 1332 ok( check_record( rec, 6, "I4"), "wrong record type\n"); 1333 ok( check_record( rec, 7, "S0"), "wrong record type\n"); 1334 ok( check_record( rec, 8, "S0"), "wrong record type\n"); 1335 ok( check_record( rec, 9, "L0"), "wrong record type\n"); 1336 1337 MsiCloseHandle( rec ); 1338 1339 /* check the type in _Columns */ 1340 ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n"); 1341 ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n"); 1342 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n"); 1343 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n"); 1344 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n"); 1345 ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n"); 1346 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n"); 1347 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 8 ), "_columns table wrong\n"); 1348 ok( 0x1f00 == get_columns_table_type(hdb, "Properties", 9 ), "_columns table wrong\n"); 1349 1350 /* now try the names */ 1351 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES ); 1352 ok( rec, "failed to get column info record\n" ); 1353 1354 ok( check_record( rec, 1, "Property"), "wrong record type\n"); 1355 ok( check_record( rec, 2, "Value"), "wrong record type\n"); 1356 ok( check_record( rec, 3, "Intvalue"), "wrong record type\n"); 1357 ok( check_record( rec, 4, "Integervalue"), "wrong record type\n"); 1358 ok( check_record( rec, 5, "Shortvalue"), "wrong record type\n"); 1359 ok( check_record( rec, 6, "Longvalue"), "wrong record type\n"); 1360 ok( check_record( rec, 7, "Longcharvalue"), "wrong record type\n"); 1361 ok( check_record( rec, 8, "Charvalue"), "wrong record type\n"); 1362 ok( check_record( rec, 9, "Localizablevalue"), "wrong record type\n"); 1363 1364 MsiCloseHandle( rec ); 1365 1366 r = run_query( hdb, 0, 1367 "CREATE TABLE `Binary` " 1368 "( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" ); 1369 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1370 1371 /* check the column types */ 1372 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES ); 1373 ok( rec, "failed to get column info record\n" ); 1374 1375 ok( check_record( rec, 1, "S255"), "wrong record type\n"); 1376 ok( check_record( rec, 2, "V0"), "wrong record type\n"); 1377 1378 MsiCloseHandle( rec ); 1379 1380 /* check the type in _Columns */ 1381 ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n"); 1382 ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n"); 1383 1384 /* now try the names */ 1385 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES ); 1386 ok( rec, "failed to get column info record\n" ); 1387 1388 ok( check_record( rec, 1, "Name"), "wrong record type\n"); 1389 ok( check_record( rec, 2, "Data"), "wrong record type\n"); 1390 MsiCloseHandle( rec ); 1391 1392 r = run_query( hdb, 0, 1393 "CREATE TABLE `UIText` " 1394 "( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" ); 1395 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1396 1397 ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n"); 1398 ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n"); 1399 1400 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES ); 1401 ok( rec, "failed to get column info record\n" ); 1402 ok( check_record( rec, 1, "Key"), "wrong record type\n"); 1403 ok( check_record( rec, 2, "Text"), "wrong record type\n"); 1404 MsiCloseHandle( rec ); 1405 1406 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES ); 1407 ok( rec, "failed to get column info record\n" ); 1408 ok( check_record( rec, 1, "s72"), "wrong record type\n"); 1409 ok( check_record( rec, 2, "L255"), "wrong record type\n"); 1410 MsiCloseHandle( rec ); 1411 1412 MsiCloseHandle( hdb ); 1413 } 1414 1415 static void test_msiexport(void) 1416 { 1417 MSIHANDLE hdb = 0, hview = 0; 1418 UINT r; 1419 const char *query; 1420 char path[MAX_PATH]; 1421 const char file[] = "phone.txt"; 1422 HANDLE handle; 1423 char buffer[0x100]; 1424 DWORD length; 1425 const char expected[] = 1426 "id\tname\tnumber\r\n" 1427 "I2\tS32\tS32\r\n" 1428 "phone\tid\r\n" 1429 "1\tAbe\t8675309\r\n"; 1430 1431 DeleteFileW(msifileW); 1432 1433 /* just MsiOpenDatabase should not create a file */ 1434 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 1435 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1436 1437 /* create a table */ 1438 query = "CREATE TABLE `phone` ( " 1439 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 1440 "PRIMARY KEY `id`)"; 1441 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1442 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1443 r = MsiViewExecute(hview, 0); 1444 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1445 r = MsiViewClose(hview); 1446 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1447 r = MsiCloseHandle(hview); 1448 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1449 1450 /* insert a value into it */ 1451 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 1452 "VALUES('1', 'Abe', '8675309')"; 1453 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1454 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1455 r = MsiViewExecute(hview, 0); 1456 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1457 r = MsiViewClose(hview); 1458 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1459 r = MsiCloseHandle(hview); 1460 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1461 1462 GetCurrentDirectoryA(MAX_PATH, path); 1463 1464 r = MsiDatabaseExportA(hdb, "phone", path, file); 1465 ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n"); 1466 1467 MsiCloseHandle(hdb); 1468 1469 lstrcatA(path, "\\"); 1470 lstrcatA(path, file); 1471 1472 /* check the data that was written */ 1473 length = 0; 1474 memset(buffer, 0, sizeof buffer); 1475 handle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 1476 if (handle != INVALID_HANDLE_VALUE) 1477 { 1478 ReadFile(handle, buffer, sizeof buffer, &length, NULL); 1479 CloseHandle(handle); 1480 DeleteFileA(path); 1481 } 1482 else 1483 ok(0, "failed to open file %s\n", path); 1484 1485 ok( length == strlen(expected), "length of data wrong\n"); 1486 ok( !lstrcmpA(buffer, expected), "data doesn't match\n"); 1487 DeleteFileA(msifile); 1488 } 1489 1490 static void test_longstrings(void) 1491 { 1492 const char insert_query[] = 1493 "INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')"; 1494 char *str; 1495 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 1496 DWORD len; 1497 UINT r; 1498 const DWORD STRING_LENGTH = 0x10005; 1499 1500 DeleteFileW(msifileW); 1501 /* just MsiOpenDatabase should not create a file */ 1502 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 1503 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1504 1505 /* create a table */ 1506 r = try_query( hdb, 1507 "CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)"); 1508 ok(r == ERROR_SUCCESS, "query failed\n"); 1509 1510 /* try to insert a very long string */ 1511 str = HeapAlloc(GetProcessHeap(), 0, STRING_LENGTH+sizeof insert_query); 1512 len = strchr(insert_query, 'Z') - insert_query; 1513 strcpy(str, insert_query); 1514 memset(str+len, 'Z', STRING_LENGTH); 1515 strcpy(str+len+STRING_LENGTH, insert_query+len+1); 1516 r = try_query( hdb, str ); 1517 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1518 1519 HeapFree(GetProcessHeap(), 0, str); 1520 1521 r = MsiDatabaseCommit(hdb); 1522 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 1523 MsiCloseHandle(hdb); 1524 1525 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 1526 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1527 1528 r = MsiDatabaseOpenViewA(hdb, "select * from `strings` where `id` = 1", &hview); 1529 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1530 1531 r = MsiViewExecute(hview, 0); 1532 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1533 1534 r = MsiViewFetch(hview, &hrec); 1535 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1536 1537 MsiViewClose(hview); 1538 MsiCloseHandle(hview); 1539 1540 r = MsiRecordGetStringA(hrec, 2, NULL, &len); 1541 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1542 ok(len == STRING_LENGTH, "string length wrong\n"); 1543 1544 MsiCloseHandle(hrec); 1545 MsiCloseHandle(hdb); 1546 DeleteFileA(msifile); 1547 } 1548 1549 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size) 1550 { 1551 HANDLE file; 1552 DWORD written; 1553 1554 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 1555 if (file == INVALID_HANDLE_VALUE) 1556 return; 1557 1558 WriteFile(file, data, strlen(data), &written, NULL); 1559 WriteFile(file, "\n", strlen("\n"), &written, NULL); 1560 1561 if (size) 1562 { 1563 SetFilePointer(file, size, NULL, FILE_BEGIN); 1564 SetEndOfFile(file); 1565 } 1566 1567 CloseHandle(file); 1568 } 1569 1570 #define create_file(name) create_file_data(name, name, 0) 1571 1572 static void test_streamtable(void) 1573 { 1574 MSIHANDLE hdb = 0, rec, view, hsi; 1575 char file[MAX_PATH]; 1576 char buf[MAX_PATH]; 1577 DWORD size; 1578 UINT r; 1579 1580 hdb = create_db(); 1581 ok( hdb, "failed to create db\n"); 1582 1583 r = run_query( hdb, 0, 1584 "CREATE TABLE `Properties` " 1585 "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" ); 1586 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1587 1588 r = run_query( hdb, 0, 1589 "INSERT INTO `Properties` " 1590 "( `Value`, `Property` ) VALUES ( 'Prop', 'value' )" ); 1591 ok( r == ERROR_SUCCESS, "Failed to add to table\n" ); 1592 1593 r = MsiDatabaseCommit( hdb ); 1594 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 1595 1596 MsiCloseHandle( hdb ); 1597 1598 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 1599 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1600 1601 /* check the column types */ 1602 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES ); 1603 ok( rec, "failed to get column info record\n" ); 1604 1605 ok( check_record( rec, 1, "s62"), "wrong record type\n"); 1606 ok( check_record( rec, 2, "V0"), "wrong record type\n"); 1607 1608 MsiCloseHandle( rec ); 1609 1610 /* now try the names */ 1611 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES ); 1612 ok( rec, "failed to get column info record\n" ); 1613 1614 ok( check_record( rec, 1, "Name"), "wrong record type\n"); 1615 ok( check_record( rec, 2, "Data"), "wrong record type\n"); 1616 1617 MsiCloseHandle( rec ); 1618 1619 r = MsiDatabaseOpenViewA( hdb, 1620 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view ); 1621 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r ); 1622 1623 r = MsiViewExecute( view, 0 ); 1624 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r ); 1625 1626 r = MsiViewFetch( view, &rec ); 1627 ok( r == ERROR_NO_MORE_ITEMS, "Unexpected result: %u\n", r ); 1628 1629 MsiCloseHandle( rec ); 1630 MsiViewClose( view ); 1631 MsiCloseHandle( view ); 1632 1633 /* create a summary information stream */ 1634 r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi ); 1635 ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r ); 1636 1637 r = MsiSummaryInfoSetPropertyA( hsi, PID_SECURITY, VT_I4, 2, NULL, NULL ); 1638 ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r ); 1639 1640 r = MsiSummaryInfoPersist( hsi ); 1641 ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r ); 1642 1643 MsiCloseHandle( hsi ); 1644 1645 r = MsiDatabaseOpenViewA( hdb, 1646 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view ); 1647 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r ); 1648 1649 r = MsiViewExecute( view, 0 ); 1650 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r ); 1651 1652 r = MsiViewFetch( view, &rec ); 1653 ok( r == ERROR_SUCCESS, "Unexpected result: %u\n", r ); 1654 1655 MsiCloseHandle( rec ); 1656 MsiViewClose( view ); 1657 MsiCloseHandle( view ); 1658 1659 /* insert a file into the _Streams table */ 1660 create_file( "test.txt" ); 1661 1662 rec = MsiCreateRecord( 2 ); 1663 MsiRecordSetStringA( rec, 1, "data" ); 1664 1665 r = MsiRecordSetStreamA( rec, 2, "test.txt" ); 1666 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1667 1668 DeleteFileA("test.txt"); 1669 1670 r = MsiDatabaseOpenViewA( hdb, 1671 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1672 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1673 1674 r = MsiViewExecute( view, rec ); 1675 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1676 1677 MsiCloseHandle( rec ); 1678 MsiViewClose( view ); 1679 MsiCloseHandle( view ); 1680 1681 /* insert another one */ 1682 create_file( "test1.txt" ); 1683 1684 rec = MsiCreateRecord( 2 ); 1685 MsiRecordSetStringA( rec, 1, "data1" ); 1686 1687 r = MsiRecordSetStreamA( rec, 2, "test1.txt" ); 1688 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1689 1690 DeleteFileA("test1.txt"); 1691 1692 r = MsiDatabaseOpenViewA( hdb, 1693 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1694 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1695 1696 r = MsiViewExecute( view, rec ); 1697 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1698 1699 MsiCloseHandle( rec ); 1700 MsiViewClose( view ); 1701 MsiCloseHandle( view ); 1702 1703 /* try again */ 1704 create_file( "test1.txt" ); 1705 1706 rec = MsiCreateRecord( 2 ); 1707 MsiRecordSetStringA( rec, 1, "data1" ); 1708 1709 r = MsiRecordSetStreamA( rec, 2, "test1.txt" ); 1710 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r ); 1711 1712 DeleteFileA( "test1.txt" ); 1713 1714 r = MsiDatabaseOpenViewA( hdb, 1715 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1716 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r ); 1717 1718 r = MsiViewExecute( view, rec ); 1719 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r ); 1720 1721 MsiCloseHandle( rec ); 1722 MsiViewClose( view ); 1723 MsiCloseHandle( view ); 1724 1725 r = MsiDatabaseOpenViewA( hdb, 1726 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view ); 1727 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1728 1729 r = MsiViewExecute( view, 0 ); 1730 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1731 1732 r = MsiViewFetch( view, &rec ); 1733 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r); 1734 1735 size = MAX_PATH; 1736 r = MsiRecordGetStringA( rec, 1, file, &size ); 1737 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1738 ok( !lstrcmpA(file, "data"), "Expected 'data', got %s\n", file); 1739 1740 size = MAX_PATH; 1741 memset(buf, 0, MAX_PATH); 1742 r = MsiRecordReadStream( rec, 2, buf, &size ); 1743 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1744 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf); 1745 1746 MsiCloseHandle( rec ); 1747 MsiViewClose( view ); 1748 MsiCloseHandle( view ); 1749 1750 r = MsiDatabaseOpenViewA( hdb, 1751 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view ); 1752 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1753 1754 r = MsiViewExecute( view, 0 ); 1755 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1756 1757 r = MsiViewFetch( view, &rec ); 1758 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 1759 1760 size = MAX_PATH; 1761 r = MsiRecordGetStringA( rec, 1, file, &size ); 1762 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1763 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file); 1764 1765 size = MAX_PATH; 1766 memset(buf, 0, MAX_PATH); 1767 r = MsiRecordReadStream( rec, 2, buf, &size ); 1768 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1769 ok( !lstrcmpA(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf); 1770 1771 MsiCloseHandle( rec ); 1772 MsiViewClose( view ); 1773 MsiCloseHandle( view ); 1774 1775 /* perform an update */ 1776 create_file( "test2.txt" ); 1777 rec = MsiCreateRecord( 1 ); 1778 1779 r = MsiRecordSetStreamA( rec, 1, "test2.txt" ); 1780 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1781 1782 DeleteFileA("test2.txt"); 1783 1784 r = MsiDatabaseOpenViewA( hdb, 1785 "UPDATE `_Streams` SET `Data` = ? WHERE `Name` = 'data1'", &view ); 1786 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1787 1788 r = MsiViewExecute( view, rec ); 1789 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1790 1791 MsiCloseHandle( rec ); 1792 MsiViewClose( view ); 1793 MsiCloseHandle( view ); 1794 1795 r = MsiDatabaseOpenViewA( hdb, 1796 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view ); 1797 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1798 1799 r = MsiViewExecute( view, 0 ); 1800 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1801 1802 r = MsiViewFetch( view, &rec ); 1803 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r); 1804 1805 size = MAX_PATH; 1806 r = MsiRecordGetStringA( rec, 1, file, &size ); 1807 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1808 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file); 1809 1810 size = MAX_PATH; 1811 memset(buf, 0, MAX_PATH); 1812 r = MsiRecordReadStream( rec, 2, buf, &size ); 1813 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1814 ok( !lstrcmpA(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf); 1815 1816 MsiCloseHandle( rec ); 1817 MsiViewClose( view ); 1818 MsiCloseHandle( view ); 1819 MsiCloseHandle( hdb ); 1820 DeleteFileA(msifile); 1821 } 1822 1823 static void test_binary(void) 1824 { 1825 MSIHANDLE hdb = 0, rec; 1826 char file[MAX_PATH]; 1827 char buf[MAX_PATH]; 1828 DWORD size; 1829 LPCSTR query; 1830 UINT r; 1831 1832 /* insert a file into the Binary table */ 1833 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1834 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1835 1836 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)"; 1837 r = run_query( hdb, 0, query ); 1838 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r ); 1839 1840 create_file( "test.txt" ); 1841 rec = MsiCreateRecord( 1 ); 1842 r = MsiRecordSetStreamA( rec, 1, "test.txt" ); 1843 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1844 DeleteFileA( "test.txt" ); 1845 1846 /* try a name that exceeds maximum OLE stream name length */ 1847 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'encryption.dll.CB4E6205_F99A_4C51_ADD4_184506EFAB87', 10000, ? )"; 1848 r = run_query( hdb, rec, query ); 1849 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r ); 1850 1851 r = MsiCloseHandle( rec ); 1852 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1853 1854 r = MsiDatabaseCommit( hdb ); 1855 ok( r == ERROR_FUNCTION_FAILED , "got %u\n", r ); 1856 1857 r = MsiCloseHandle( hdb ); 1858 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1859 1860 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1861 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1862 1863 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)"; 1864 r = run_query( hdb, 0, query ); 1865 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r ); 1866 1867 create_file( "test.txt" ); 1868 rec = MsiCreateRecord( 1 ); 1869 r = MsiRecordSetStreamA( rec, 1, "test.txt" ); 1870 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r ); 1871 DeleteFileA( "test.txt" ); 1872 1873 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )"; 1874 r = run_query( hdb, rec, query ); 1875 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r ); 1876 1877 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )"; 1878 r = run_query( hdb, rec, query ); 1879 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r ); 1880 1881 r = MsiCloseHandle( rec ); 1882 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1883 1884 r = MsiDatabaseCommit( hdb ); 1885 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 1886 1887 r = MsiCloseHandle( hdb ); 1888 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1889 1890 /* read file from the Stream table */ 1891 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_READONLY, &hdb ); 1892 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1893 1894 query = "SELECT * FROM `_Streams`"; 1895 r = do_query( hdb, query, &rec ); 1896 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r ); 1897 1898 size = MAX_PATH; 1899 r = MsiRecordGetStringA( rec, 1, file, &size ); 1900 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r ); 1901 ok( !lstrcmpA(file, "Binary.filename1.1"), "Expected 'Binary.filename1.1', got %s\n", file ); 1902 1903 size = MAX_PATH; 1904 memset( buf, 0, MAX_PATH ); 1905 r = MsiRecordReadStream( rec, 2, buf, &size ); 1906 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r ); 1907 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf ); 1908 1909 r = MsiCloseHandle( rec ); 1910 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1911 1912 /* read file from the Binary table */ 1913 query = "SELECT * FROM `Binary`"; 1914 r = do_query( hdb, query, &rec ); 1915 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r ); 1916 1917 size = MAX_PATH; 1918 r = MsiRecordGetStringA( rec, 1, file, &size ); 1919 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r ); 1920 ok( !lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file ); 1921 1922 size = MAX_PATH; 1923 memset( buf, 0, MAX_PATH ); 1924 r = MsiRecordReadStream( rec, 3, buf, &size ); 1925 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r ); 1926 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf ); 1927 1928 r = MsiCloseHandle( rec ); 1929 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1930 1931 r = MsiCloseHandle( hdb ); 1932 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1933 1934 DeleteFileA( msifile ); 1935 } 1936 1937 static void test_where_not_in_selected(void) 1938 { 1939 MSIHANDLE hdb = 0, rec, view; 1940 LPCSTR query; 1941 UINT r; 1942 1943 hdb = create_db(); 1944 ok( hdb, "failed to create db\n"); 1945 1946 r = run_query(hdb, 0, 1947 "CREATE TABLE `IESTable` (" 1948 "`Action` CHAR(64), " 1949 "`Condition` CHAR(64), " 1950 "`Sequence` LONG PRIMARY KEY `Sequence`)"); 1951 ok( r == S_OK, "Cannot create IESTable table: %d\n", r); 1952 1953 r = run_query(hdb, 0, 1954 "CREATE TABLE `CATable` (" 1955 "`Action` CHAR(64), " 1956 "`Type` LONG PRIMARY KEY `Type`)"); 1957 ok( r == S_OK, "Cannot create CATable table: %d\n", r); 1958 1959 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1960 "( `Action`, `Condition`, `Sequence`) " 1961 "VALUES ( 'clean', 'cond4', 4)"); 1962 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1963 1964 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1965 "( `Action`, `Condition`, `Sequence`) " 1966 "VALUES ( 'depends', 'cond1', 1)"); 1967 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1968 1969 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1970 "( `Action`, `Condition`, `Sequence`) " 1971 "VALUES ( 'build', 'cond2', 2)"); 1972 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1973 1974 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1975 "( `Action`, `Condition`, `Sequence`) " 1976 "VALUES ( 'build2', 'cond6', 6)"); 1977 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1978 1979 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1980 "( `Action`, `Condition`, `Sequence`) " 1981 "VALUES ( 'build', 'cond3', 3)"); 1982 ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1983 1984 r = run_query(hdb, 0, "INSERT INTO `CATable` " 1985 "( `Action`, `Type` ) " 1986 "VALUES ( 'build', 32)"); 1987 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 1988 1989 r = run_query(hdb, 0, "INSERT INTO `CATable` " 1990 "( `Action`, `Type` ) " 1991 "VALUES ( 'depends', 64)"); 1992 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 1993 1994 r = run_query(hdb, 0, "INSERT INTO `CATable` " 1995 "( `Action`, `Type` ) " 1996 "VALUES ( 'clean', 63)"); 1997 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 1998 1999 r = run_query(hdb, 0, "INSERT INTO `CATable` " 2000 "( `Action`, `Type` ) " 2001 "VALUES ( 'build2', 34)"); 2002 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 2003 query = "Select IESTable.Condition from CATable, IESTable where " 2004 "CATable.Action = IESTable.Action and CATable.Type = 32"; 2005 r = MsiDatabaseOpenViewA(hdb, query, &view); 2006 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 2007 2008 r = MsiViewExecute(view, 0); 2009 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 2010 2011 r = MsiViewFetch(view, &rec); 2012 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2013 2014 ok( check_record( rec, 1, "cond2"), "wrong condition\n"); 2015 2016 MsiCloseHandle( rec ); 2017 r = MsiViewFetch(view, &rec); 2018 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2019 2020 ok( check_record( rec, 1, "cond3"), "wrong condition\n"); 2021 2022 MsiCloseHandle( rec ); 2023 MsiViewClose(view); 2024 MsiCloseHandle(view); 2025 2026 MsiCloseHandle( hdb ); 2027 DeleteFileA(msifile); 2028 } 2029 2030 2031 static void test_where(void) 2032 { 2033 MSIHANDLE hdb = 0, rec, view; 2034 LPCSTR query; 2035 UINT r; 2036 DWORD size; 2037 CHAR buf[MAX_PATH]; 2038 UINT count; 2039 2040 hdb = create_db(); 2041 ok( hdb, "failed to create db\n"); 2042 2043 r = run_query( hdb, 0, 2044 "CREATE TABLE `Media` (" 2045 "`DiskId` SHORT NOT NULL, " 2046 "`LastSequence` LONG, " 2047 "`DiskPrompt` CHAR(64) LOCALIZABLE, " 2048 "`Cabinet` CHAR(255), " 2049 "`VolumeLabel` CHAR(32), " 2050 "`Source` CHAR(72) " 2051 "PRIMARY KEY `DiskId`)" ); 2052 ok( r == S_OK, "cannot create Media table: %d\n", r ); 2053 2054 r = run_query( hdb, 0, "INSERT INTO `Media` " 2055 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2056 "VALUES ( 1, 0, '', 'zero.cab', '', '' )" ); 2057 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2058 2059 r = run_query( hdb, 0, "INSERT INTO `Media` " 2060 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2061 "VALUES ( 2, 1, '', 'one.cab', '', '' )" ); 2062 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2063 2064 r = run_query( hdb, 0, "INSERT INTO `Media` " 2065 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2066 "VALUES ( 3, 2, '', 'two.cab', '', '' )" ); 2067 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2068 2069 query = "SELECT * FROM `Media`"; 2070 r = do_query(hdb, query, &rec); 2071 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r); 2072 ok( check_record( rec, 4, "zero.cab"), "wrong cabinet\n"); 2073 MsiCloseHandle( rec ); 2074 2075 query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1"; 2076 r = do_query(hdb, query, &rec); 2077 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r); 2078 ok( check_record( rec, 4, "one.cab"), "wrong cabinet\n"); 2079 2080 r = MsiRecordGetInteger(rec, 1); 2081 ok( 2 == r, "field wrong\n"); 2082 r = MsiRecordGetInteger(rec, 2); 2083 ok( 1 == r, "field wrong\n"); 2084 MsiCloseHandle( rec ); 2085 2086 query = "SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= 1 AND DiskId >= 0"; 2087 r = MsiDatabaseOpenViewA(hdb, query, &view); 2088 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 2089 2090 r = MsiViewExecute(view, 0); 2091 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 2092 2093 r = MsiViewFetch(view, &rec); 2094 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2095 2096 count = MsiRecordGetFieldCount( rec ); 2097 ok( count == 1, "Expected 1 record fields, got %d\n", count ); 2098 2099 size = MAX_PATH; 2100 r = MsiRecordGetStringA( rec, 1, buf, &size ); 2101 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 2102 ok( !lstrcmpA( buf, "2" ), "For (row %d, column 1) expected '%d', got %s\n", 0, 2, buf ); 2103 MsiCloseHandle( rec ); 2104 2105 r = MsiViewFetch(view, &rec); 2106 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2107 2108 size = MAX_PATH; 2109 r = MsiRecordGetStringA( rec, 1, buf, &size ); 2110 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 2111 ok( !lstrcmpA( buf, "3" ), "For (row %d, column 1) expected '%d', got %s\n", 1, 3, buf ); 2112 MsiCloseHandle( rec ); 2113 2114 r = MsiViewFetch(view, &rec); 2115 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 2116 2117 MsiViewClose(view); 2118 MsiCloseHandle(view); 2119 2120 MsiCloseHandle( rec ); 2121 2122 rec = 0; 2123 query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL"; 2124 r = do_query(hdb, query, &rec); 2125 ok( r == ERROR_SUCCESS, "query failed: %d\n", r ); 2126 MsiCloseHandle( rec ); 2127 2128 rec = 0; 2129 query = "SELECT * FROM `Media` WHERE `DiskPrompt` < 'Cabinet'"; 2130 r = do_query(hdb, query, &rec); 2131 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r ); 2132 MsiCloseHandle( rec ); 2133 2134 rec = 0; 2135 query = "SELECT * FROM `Media` WHERE `DiskPrompt` > 'Cabinet'"; 2136 r = do_query(hdb, query, &rec); 2137 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r ); 2138 MsiCloseHandle( rec ); 2139 2140 rec = 0; 2141 query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'"; 2142 r = do_query(hdb, query, &rec); 2143 ok( r == ERROR_SUCCESS, "query failed: %d\n", r ); 2144 MsiCloseHandle( rec ); 2145 2146 rec = 0; 2147 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'"; 2148 r = do_query(hdb, query, &rec); 2149 ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r ); 2150 MsiCloseHandle( rec ); 2151 2152 rec = MsiCreateRecord(1); 2153 MsiRecordSetStringA(rec, 1, ""); 2154 2155 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = ?"; 2156 r = MsiDatabaseOpenViewA(hdb, query, &view); 2157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2158 r = MsiViewExecute(view, rec); 2159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2160 2161 MsiCloseHandle(rec); 2162 2163 r = MsiViewFetch(view, &rec); 2164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2165 2166 MsiCloseHandle(rec); 2167 MsiViewClose(view); 2168 MsiCloseHandle(view); 2169 2170 MsiCloseHandle( hdb ); 2171 DeleteFileA(msifile); 2172 } 2173 2174 static CHAR CURR_DIR[MAX_PATH]; 2175 2176 static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n" 2177 "s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n" 2178 "TestTable\tFirstPrimaryColumn\n" 2179 "stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n"; 2180 2181 static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n" 2182 "s255\ts255\n" 2183 "TwoPrimary\tPrimaryOne\tPrimaryTwo\n" 2184 "papaya\tleaf\n" 2185 "papaya\tflower\n"; 2186 2187 static const CHAR endlines1[] = "A\tB\tC\tD\tE\tF\r\n" 2188 "s72\ts72\ts72\ts72\ts72\ts72\n" 2189 "Table\tA\r\n" 2190 "a\tb\tc\td\te\tf\n" 2191 "g\th\ti\t\rj\tk\tl\r\n"; 2192 2193 static const CHAR endlines2[] = "A\tB\tC\tD\tE\tF\r" 2194 "s72\ts72\ts72\ts72\ts72\ts72\n" 2195 "Table2\tA\r\n" 2196 "a\tb\tc\td\te\tf\n" 2197 "g\th\ti\tj\tk\tl\r\n"; 2198 2199 static const CHAR suminfo[] = "PropertyId\tValue\n" 2200 "i2\tl255\n" 2201 "_SummaryInformation\tPropertyId\n" 2202 "1\t1252\n" 2203 "2\tInstaller Database\n" 2204 "3\tInstaller description\n" 2205 "4\tWineHQ\n" 2206 "5\tInstaller\n" 2207 "6\tInstaller comments\n" 2208 "7\tIntel;1033,2057\n" 2209 "9\t{12345678-1234-1234-1234-123456789012}\n" 2210 "12\t2009/04/12 15:46:11\n" 2211 "13\t2009/04/12 15:46:11\n" 2212 "14\t200\n" 2213 "15\t2\n" 2214 "18\tVim\n" 2215 "19\t2\n"; 2216 2217 static void write_file(const CHAR *filename, const char *data, int data_size) 2218 { 2219 DWORD size; 2220 2221 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL, 2222 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 2223 WriteFile(hf, data, data_size, &size, NULL); 2224 CloseHandle(hf); 2225 } 2226 2227 static UINT add_table_to_db(MSIHANDLE hdb, LPCSTR table_data) 2228 { 2229 UINT r; 2230 2231 write_file("temp_file", table_data, (lstrlenA(table_data) - 1) * sizeof(char)); 2232 r = MsiDatabaseImportA(hdb, CURR_DIR, "temp_file"); 2233 DeleteFileA("temp_file"); 2234 2235 return r; 2236 } 2237 2238 static void test_suminfo_import(void) 2239 { 2240 MSIHANDLE hdb, hsi, view = 0; 2241 LPCSTR query; 2242 UINT r, count, size, type; 2243 char str_value[50]; 2244 INT int_value; 2245 FILETIME ft_value; 2246 2247 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 2248 2249 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2251 2252 r = add_table_to_db(hdb, suminfo); 2253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2254 2255 /* _SummaryInformation is not imported as a regular table... */ 2256 2257 query = "SELECT * FROM `_SummaryInformation`"; 2258 r = MsiDatabaseOpenViewA(hdb, query, &view); 2259 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %u\n", r); 2260 MsiCloseHandle(view); 2261 2262 /* ...its data is added to the special summary information stream */ 2263 2264 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsi); 2265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2266 2267 r = MsiSummaryInfoGetPropertyCount(hsi, &count); 2268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2269 ok(count == 14, "Expected 14, got %u\n", count); 2270 2271 r = MsiSummaryInfoGetPropertyA(hsi, PID_CODEPAGE, &type, &int_value, NULL, NULL, NULL); 2272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2273 ok(type == VT_I2, "Expected VT_I2, got %u\n", type); 2274 ok(int_value == 1252, "Expected 1252, got %d\n", int_value); 2275 2276 size = sizeof(str_value); 2277 r = MsiSummaryInfoGetPropertyA(hsi, PID_TITLE, &type, NULL, NULL, str_value, &size); 2278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2279 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2280 ok(size == 18, "Expected 18, got %u\n", size); 2281 ok(!strcmp(str_value, "Installer Database"), 2282 "Expected \"Installer Database\", got %s\n", str_value); 2283 2284 size = sizeof(str_value); 2285 r = MsiSummaryInfoGetPropertyA(hsi, PID_SUBJECT, &type, NULL, NULL, str_value, &size); 2286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2287 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2288 ok(!strcmp(str_value, "Installer description"), 2289 "Expected \"Installer description\", got %s\n", str_value); 2290 2291 size = sizeof(str_value); 2292 r = MsiSummaryInfoGetPropertyA(hsi, PID_AUTHOR, &type, NULL, NULL, str_value, &size); 2293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2294 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2295 ok(!strcmp(str_value, "WineHQ"), 2296 "Expected \"WineHQ\", got %s\n", str_value); 2297 2298 size = sizeof(str_value); 2299 r = MsiSummaryInfoGetPropertyA(hsi, PID_KEYWORDS, &type, NULL, NULL, str_value, &size); 2300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2301 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2302 ok(!strcmp(str_value, "Installer"), 2303 "Expected \"Installer\", got %s\n", str_value); 2304 2305 size = sizeof(str_value); 2306 r = MsiSummaryInfoGetPropertyA(hsi, PID_COMMENTS, &type, NULL, NULL, str_value, &size); 2307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2308 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2309 ok(!strcmp(str_value, "Installer comments"), 2310 "Expected \"Installer comments\", got %s\n", str_value); 2311 2312 size = sizeof(str_value); 2313 r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size); 2314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2315 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2316 ok(!strcmp(str_value, "Intel;1033,2057"), 2317 "Expected \"Intel;1033,2057\", got %s\n", str_value); 2318 2319 size = sizeof(str_value); 2320 r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size); 2321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2322 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2323 ok(!strcmp(str_value, "{12345678-1234-1234-1234-123456789012}"), 2324 "Expected \"{12345678-1234-1234-1234-123456789012}\", got %s\n", str_value); 2325 2326 r = MsiSummaryInfoGetPropertyA(hsi, PID_CREATE_DTM, &type, NULL, &ft_value, NULL, NULL); 2327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2328 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type); 2329 2330 r = MsiSummaryInfoGetPropertyA(hsi, PID_LASTSAVE_DTM, &type, NULL, &ft_value, NULL, NULL); 2331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2332 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type); 2333 2334 r = MsiSummaryInfoGetPropertyA(hsi, PID_PAGECOUNT, &type, &int_value, NULL, NULL, NULL); 2335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2336 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2337 ok(int_value == 200, "Expected 200, got %d\n", int_value); 2338 2339 r = MsiSummaryInfoGetPropertyA(hsi, PID_WORDCOUNT, &type, &int_value, NULL, NULL, NULL); 2340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2341 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2342 ok(int_value == 2, "Expected 2, got %d\n", int_value); 2343 2344 r = MsiSummaryInfoGetPropertyA(hsi, PID_SECURITY, &type, &int_value, NULL, NULL, NULL); 2345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2346 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2347 ok(int_value == 2, "Expected 2, got %d\n", int_value); 2348 2349 size = sizeof(str_value); 2350 r = MsiSummaryInfoGetPropertyA(hsi, PID_APPNAME, &type, NULL, NULL, str_value, &size); 2351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2352 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2353 ok(!strcmp(str_value, "Vim"), "Expected \"Vim\", got %s\n", str_value); 2354 2355 MsiCloseHandle(hsi); 2356 MsiCloseHandle(hdb); 2357 DeleteFileA(msifile); 2358 } 2359 2360 static void test_msiimport(void) 2361 { 2362 MSIHANDLE hdb, view, rec; 2363 LPCSTR query; 2364 UINT r, count; 2365 signed int i; 2366 2367 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 2368 2369 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2371 2372 r = MsiDatabaseImportA(hdb, CURR_DIR, NULL); 2373 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2374 2375 r = MsiDatabaseImportA(hdb, CURR_DIR, "nonexistent"); 2376 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2377 2378 r = add_table_to_db(hdb, test_data); 2379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2380 2381 r = add_table_to_db(hdb, two_primary); 2382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2383 2384 r = add_table_to_db(hdb, endlines1); 2385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2386 2387 r = add_table_to_db(hdb, endlines2); 2388 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2389 2390 query = "SELECT * FROM `TestTable`"; 2391 r = MsiDatabaseOpenViewA(hdb, query, &view); 2392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2393 2394 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2396 count = MsiRecordGetFieldCount(rec); 2397 ok(count == 9, "Expected 9, got %d\n", count); 2398 ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n"); 2399 ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n"); 2400 ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n"); 2401 ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n"); 2402 ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n"); 2403 ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n"); 2404 ok(check_record(rec, 7, "String"), "Expected String\n"); 2405 ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n"); 2406 ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n"); 2407 MsiCloseHandle(rec); 2408 2409 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2411 count = MsiRecordGetFieldCount(rec); 2412 ok(count == 9, "Expected 9, got %d\n", count); 2413 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2414 ok(check_record(rec, 2, "i2"), "Expected i2\n"); 2415 ok(check_record(rec, 3, "i2"), "Expected i2\n"); 2416 ok(check_record(rec, 4, "I2"), "Expected I2\n"); 2417 ok(check_record(rec, 5, "i4"), "Expected i4\n"); 2418 ok(check_record(rec, 6, "I4"), "Expected I4\n"); 2419 ok(check_record(rec, 7, "S255"), "Expected S255\n"); 2420 ok(check_record(rec, 8, "S0"), "Expected S0\n"); 2421 ok(check_record(rec, 9, "s0"), "Expected s0\n"); 2422 MsiCloseHandle(rec); 2423 2424 query = "SELECT * FROM `TestTable`"; 2425 r = do_query(hdb, query, &rec); 2426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2427 ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n"); 2428 ok(check_record(rec, 7, "another string"), "Expected 'another string'\n"); 2429 ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n"); 2430 ok(check_record(rec, 9, "duh"), "Expected 'duh'\n"); 2431 2432 i = MsiRecordGetInteger(rec, 2); 2433 ok(i == 5, "Expected 5, got %d\n", i); 2434 2435 i = MsiRecordGetInteger(rec, 3); 2436 ok(i == 2, "Expected 2, got %d\n", i); 2437 2438 i = MsiRecordGetInteger(rec, 4); 2439 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 2440 2441 i = MsiRecordGetInteger(rec, 5); 2442 ok(i == 2147483640, "Expected 2147483640, got %d\n", i); 2443 2444 i = MsiRecordGetInteger(rec, 6); 2445 ok(i == -2147483640, "Expected -2147483640, got %d\n", i); 2446 2447 MsiCloseHandle(rec); 2448 MsiViewClose(view); 2449 MsiCloseHandle(view); 2450 2451 query = "SELECT * FROM `TwoPrimary`"; 2452 r = MsiDatabaseOpenViewA(hdb, query, &view); 2453 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2454 2455 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2456 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2457 count = MsiRecordGetFieldCount(rec); 2458 ok(count == 2, "Expected 2, got %d\n", count); 2459 ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n"); 2460 ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n"); 2461 2462 MsiCloseHandle(rec); 2463 2464 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2466 count = MsiRecordGetFieldCount(rec); 2467 ok(count == 2, "Expected 2, got %d\n", count); 2468 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2469 ok(check_record(rec, 2, "s255"), "Expected s255\n"); 2470 MsiCloseHandle(rec); 2471 2472 r = MsiViewExecute(view, 0); 2473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2474 2475 r = MsiViewFetch(view, &rec); 2476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2477 2478 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2479 ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n"); 2480 2481 MsiCloseHandle(rec); 2482 2483 r = MsiViewFetch(view, &rec); 2484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2485 2486 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2487 ok(check_record(rec, 2, "flower"), "Expected 'flower'\n"); 2488 2489 MsiCloseHandle(rec); 2490 2491 r = MsiViewFetch(view, &rec); 2492 ok(r == ERROR_NO_MORE_ITEMS, 2493 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2494 2495 r = MsiViewClose(view); 2496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2497 2498 MsiCloseHandle(view); 2499 2500 query = "SELECT * FROM `Table`"; 2501 r = MsiDatabaseOpenViewA(hdb, query, &view); 2502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2503 2504 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2506 count = MsiRecordGetFieldCount(rec); 2507 ok(count == 6, "Expected 6, got %d\n", count); 2508 ok(check_record(rec, 1, "A"), "Expected A\n"); 2509 ok(check_record(rec, 2, "B"), "Expected B\n"); 2510 ok(check_record(rec, 3, "C"), "Expected C\n"); 2511 ok(check_record(rec, 4, "D"), "Expected D\n"); 2512 ok(check_record(rec, 5, "E"), "Expected E\n"); 2513 ok(check_record(rec, 6, "F"), "Expected F\n"); 2514 MsiCloseHandle(rec); 2515 2516 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2518 count = MsiRecordGetFieldCount(rec); 2519 ok(count == 6, "Expected 6, got %d\n", count); 2520 ok(check_record(rec, 1, "s72"), "Expected s72\n"); 2521 ok(check_record(rec, 2, "s72"), "Expected s72\n"); 2522 ok(check_record(rec, 3, "s72"), "Expected s72\n"); 2523 ok(check_record(rec, 4, "s72"), "Expected s72\n"); 2524 ok(check_record(rec, 5, "s72"), "Expected s72\n"); 2525 ok(check_record(rec, 6, "s72"), "Expected s72\n"); 2526 MsiCloseHandle(rec); 2527 2528 MsiViewClose(view); 2529 MsiCloseHandle(view); 2530 2531 query = "SELECT * FROM `Table`"; 2532 r = MsiDatabaseOpenViewA(hdb, query, &view); 2533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2534 2535 r = MsiViewExecute(view, 0); 2536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2537 2538 r = MsiViewFetch(view, &rec); 2539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2540 ok(check_record(rec, 1, "a"), "Expected 'a'\n"); 2541 ok(check_record(rec, 2, "b"), "Expected 'b'\n"); 2542 ok(check_record(rec, 3, "c"), "Expected 'c'\n"); 2543 ok(check_record(rec, 4, "d"), "Expected 'd'\n"); 2544 ok(check_record(rec, 5, "e"), "Expected 'e'\n"); 2545 ok(check_record(rec, 6, "f"), "Expected 'f'\n"); 2546 2547 MsiCloseHandle(rec); 2548 2549 r = MsiViewFetch(view, &rec); 2550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2551 ok(check_record(rec, 1, "g"), "Expected 'g'\n"); 2552 ok(check_record(rec, 2, "h"), "Expected 'h'\n"); 2553 ok(check_record(rec, 3, "i"), "Expected 'i'\n"); 2554 ok(check_record(rec, 4, "j"), "Expected 'j'\n"); 2555 ok(check_record(rec, 5, "k"), "Expected 'k'\n"); 2556 ok(check_record(rec, 6, "l"), "Expected 'l'\n"); 2557 2558 MsiCloseHandle(rec); 2559 2560 r = MsiViewFetch(view, &rec); 2561 ok(r == ERROR_NO_MORE_ITEMS, 2562 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2563 2564 MsiViewClose(view); 2565 MsiCloseHandle(view); 2566 MsiCloseHandle(hdb); 2567 DeleteFileA(msifile); 2568 } 2569 2570 static const CHAR bin_import_dat[] = "Name\tData\r\n" 2571 "s72\tV0\r\n" 2572 "Binary\tName\r\n" 2573 "filename1\tfilename1.ibd\r\n"; 2574 2575 static void test_binary_import(void) 2576 { 2577 MSIHANDLE hdb = 0, rec; 2578 char file[MAX_PATH]; 2579 char buf[MAX_PATH]; 2580 char path[MAX_PATH]; 2581 DWORD size; 2582 LPCSTR query; 2583 UINT r; 2584 2585 /* create files to import */ 2586 write_file("bin_import.idt", bin_import_dat, 2587 (sizeof(bin_import_dat) - 1) * sizeof(char)); 2588 CreateDirectoryA("bin_import", NULL); 2589 create_file_data("bin_import/filename1.ibd", "just some words", 15); 2590 2591 /* import files into database */ 2592 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2593 ok( r == ERROR_SUCCESS , "Failed to open database\n"); 2594 2595 GetCurrentDirectoryA(MAX_PATH, path); 2596 r = MsiDatabaseImportA(hdb, path, "bin_import.idt"); 2597 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n"); 2598 2599 /* read file from the Binary table */ 2600 query = "SELECT * FROM `Binary`"; 2601 r = do_query(hdb, query, &rec); 2602 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r); 2603 2604 size = MAX_PATH; 2605 r = MsiRecordGetStringA(rec, 1, file, &size); 2606 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 2607 ok(!lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file); 2608 2609 size = MAX_PATH; 2610 memset(buf, 0, MAX_PATH); 2611 r = MsiRecordReadStream(rec, 2, buf, &size); 2612 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 2613 ok(!lstrcmpA(buf, "just some words"), "Expected 'just some words', got %s\n", buf); 2614 2615 r = MsiCloseHandle(rec); 2616 ok(r == ERROR_SUCCESS , "Failed to close record handle\n"); 2617 2618 r = MsiCloseHandle(hdb); 2619 ok(r == ERROR_SUCCESS , "Failed to close database\n"); 2620 2621 DeleteFileA("bin_import/filename1.ibd"); 2622 RemoveDirectoryA("bin_import"); 2623 DeleteFileA("bin_import.idt"); 2624 } 2625 2626 static void test_markers(void) 2627 { 2628 MSIHANDLE hdb, rec; 2629 LPCSTR query; 2630 UINT r; 2631 2632 hdb = create_db(); 2633 ok( hdb, "failed to create db\n"); 2634 2635 rec = MsiCreateRecord(3); 2636 MsiRecordSetStringA(rec, 1, "Table"); 2637 MsiRecordSetStringA(rec, 2, "Apples"); 2638 MsiRecordSetStringA(rec, 3, "Oranges"); 2639 2640 /* try a legit create */ 2641 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2642 r = run_query(hdb, 0, query); 2643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2644 MsiCloseHandle(rec); 2645 2646 /* try table name as marker */ 2647 rec = MsiCreateRecord(1); 2648 MsiRecordSetStringA(rec, 1, "Fable"); 2649 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2650 r = run_query(hdb, rec, query); 2651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2652 2653 /* verify that we just created a table called '?', not 'Fable' */ 2654 r = try_query(hdb, "SELECT * from `Fable`"); 2655 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2656 2657 r = try_query(hdb, "SELECT * from `?`"); 2658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2659 2660 /* try table name as marker without backticks */ 2661 MsiRecordSetStringA(rec, 1, "Mable"); 2662 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2663 r = run_query(hdb, rec, query); 2664 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2665 2666 /* try one column name as marker */ 2667 MsiRecordSetStringA(rec, 1, "One"); 2668 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2669 r = run_query(hdb, rec, query); 2670 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2671 MsiCloseHandle(rec); 2672 2673 /* try column names as markers */ 2674 rec = MsiCreateRecord(2); 2675 MsiRecordSetStringA(rec, 1, "One"); 2676 MsiRecordSetStringA(rec, 2, "Two"); 2677 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)"; 2678 r = run_query(hdb, rec, query); 2679 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2680 MsiCloseHandle(rec); 2681 2682 /* try names with backticks */ 2683 rec = MsiCreateRecord(3); 2684 MsiRecordSetStringA(rec, 1, "One"); 2685 MsiRecordSetStringA(rec, 2, "Two"); 2686 MsiRecordSetStringA(rec, 3, "One"); 2687 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2688 r = run_query(hdb, rec, query); 2689 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2690 2691 /* try names with backticks, minus definitions */ 2692 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)"; 2693 r = run_query(hdb, rec, query); 2694 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2695 2696 /* try names without backticks */ 2697 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)"; 2698 r = run_query(hdb, rec, query); 2699 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2700 MsiCloseHandle(rec); 2701 2702 /* try one long marker */ 2703 rec = MsiCreateRecord(1); 2704 MsiRecordSetStringA(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`"); 2705 query = "CREATE TABLE `Mable` ( ? )"; 2706 r = run_query(hdb, rec, query); 2707 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2708 MsiCloseHandle(rec); 2709 2710 /* try all names as markers */ 2711 rec = MsiCreateRecord(4); 2712 MsiRecordSetStringA(rec, 1, "Mable"); 2713 MsiRecordSetStringA(rec, 2, "One"); 2714 MsiRecordSetStringA(rec, 3, "Two"); 2715 MsiRecordSetStringA(rec, 4, "One"); 2716 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2717 r = run_query(hdb, rec, query); 2718 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2719 MsiCloseHandle(rec); 2720 2721 /* try a legit insert */ 2722 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )"; 2723 r = run_query(hdb, 0, query); 2724 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2725 2726 r = try_query(hdb, "SELECT * from `Table`"); 2727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2728 2729 /* try values as markers */ 2730 rec = MsiCreateRecord(2); 2731 MsiRecordSetInteger(rec, 1, 4); 2732 MsiRecordSetStringA(rec, 2, "hi"); 2733 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2734 r = run_query(hdb, rec, query); 2735 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2736 MsiCloseHandle(rec); 2737 2738 /* try column names and values as markers */ 2739 rec = MsiCreateRecord(4); 2740 MsiRecordSetStringA(rec, 1, "One"); 2741 MsiRecordSetStringA(rec, 2, "Two"); 2742 MsiRecordSetInteger(rec, 3, 5); 2743 MsiRecordSetStringA(rec, 4, "hi"); 2744 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )"; 2745 r = run_query(hdb, rec, query); 2746 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2747 MsiCloseHandle(rec); 2748 2749 /* try column names as markers */ 2750 rec = MsiCreateRecord(2); 2751 MsiRecordSetStringA(rec, 1, "One"); 2752 MsiRecordSetStringA(rec, 2, "Two"); 2753 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )"; 2754 r = run_query(hdb, rec, query); 2755 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2756 MsiCloseHandle(rec); 2757 2758 /* try table name as a marker */ 2759 rec = MsiCreateRecord(1); 2760 MsiRecordSetStringA(rec, 1, "Table"); 2761 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )"; 2762 r = run_query(hdb, rec, query); 2763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2764 MsiCloseHandle(rec); 2765 2766 /* try table name and values as markers */ 2767 rec = MsiCreateRecord(3); 2768 MsiRecordSetStringA(rec, 1, "Table"); 2769 MsiRecordSetInteger(rec, 2, 10); 2770 MsiRecordSetStringA(rec, 3, "haha"); 2771 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2772 r = run_query(hdb, rec, query); 2773 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2774 MsiCloseHandle(rec); 2775 2776 /* try all markers */ 2777 rec = MsiCreateRecord(5); 2778 MsiRecordSetStringA(rec, 1, "Table"); 2779 MsiRecordSetStringA(rec, 1, "One"); 2780 MsiRecordSetStringA(rec, 1, "Two"); 2781 MsiRecordSetInteger(rec, 2, 10); 2782 MsiRecordSetStringA(rec, 3, "haha"); 2783 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )"; 2784 r = run_query(hdb, rec, query); 2785 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2786 MsiCloseHandle(rec); 2787 2788 /* insert an integer as a string */ 2789 rec = MsiCreateRecord(2); 2790 MsiRecordSetStringA(rec, 1, "11"); 2791 MsiRecordSetStringA(rec, 2, "hi"); 2792 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2793 r = run_query(hdb, rec, query); 2794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2795 MsiCloseHandle(rec); 2796 2797 /* leave off the '' for the string */ 2798 rec = MsiCreateRecord(2); 2799 MsiRecordSetInteger(rec, 1, 12); 2800 MsiRecordSetStringA(rec, 2, "hi"); 2801 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )"; 2802 r = run_query(hdb, rec, query); 2803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2804 MsiCloseHandle(rec); 2805 2806 MsiCloseHandle(hdb); 2807 DeleteFileA(msifile); 2808 } 2809 2810 #define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2000 */ 2811 static void test_handle_limit(void) 2812 { 2813 int i; 2814 MSIHANDLE hdb; 2815 MSIHANDLE hviews[MY_NVIEWS]; 2816 UINT r; 2817 2818 /* create an empty db */ 2819 hdb = create_db(); 2820 ok( hdb, "failed to create db\n"); 2821 2822 memset(hviews, 0, sizeof(hviews)); 2823 2824 for (i=0; i<MY_NVIEWS; i++) { 2825 static char szQueryBuf[256] = "SELECT * from `_Tables`"; 2826 hviews[i] = 0xdeadbeeb; 2827 r = MsiDatabaseOpenViewA(hdb, szQueryBuf, &hviews[i]); 2828 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb || 2829 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1]))) 2830 break; 2831 } 2832 2833 ok( i == MY_NVIEWS, "problem opening views\n"); 2834 2835 for (i=0; i<MY_NVIEWS; i++) { 2836 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) { 2837 MsiViewClose(hviews[i]); 2838 r = MsiCloseHandle(hviews[i]); 2839 if (r != ERROR_SUCCESS) 2840 break; 2841 } 2842 } 2843 2844 ok( i == MY_NVIEWS, "problem closing views\n"); 2845 2846 r = MsiCloseHandle(hdb); 2847 ok( r == ERROR_SUCCESS, "failed to close database\n"); 2848 } 2849 2850 static void generate_transform(void) 2851 { 2852 MSIHANDLE hdb1, hdb2, hrec; 2853 LPCSTR query; 2854 UINT r; 2855 2856 /* start with two identical databases */ 2857 CopyFileA(msifile2, msifile, FALSE); 2858 2859 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb1 ); 2860 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2861 2862 r = MsiDatabaseCommit( hdb1 ); 2863 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 2864 2865 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_READONLY, &hdb2 ); 2866 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2867 2868 /* the transform between two identical database should be empty */ 2869 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, NULL, 0, 0); 2870 todo_wine { 2871 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r ); 2872 } 2873 2874 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)"; 2875 r = run_query(hdb1, 0, query); 2876 ok(r == ERROR_SUCCESS, "failed to add table\n"); 2877 2878 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )"; 2879 r = run_query(hdb1, 0, query); 2880 ok(r == ERROR_SUCCESS, "failed to add row 1\n"); 2881 2882 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )"; 2883 r = run_query(hdb1, 0, query); 2884 ok(r == ERROR_SUCCESS, "failed to add row 2\n"); 2885 2886 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1"; 2887 r = run_query(hdb1, 0, query); 2888 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2889 2890 query = "DELETE FROM `MOO` WHERE `NOO` = 3"; 2891 r = run_query(hdb1, 0, query); 2892 ok(r == ERROR_SUCCESS, "failed to delete row\n"); 2893 2894 hrec = MsiCreateRecord(2); 2895 r = MsiRecordSetInteger(hrec, 1, 1); 2896 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 2897 2898 write_file("testdata.bin", "naengmyon", 9); 2899 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 2900 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 2901 2902 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 2903 r = run_query(hdb1, hrec, query); 2904 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 2905 2906 MsiCloseHandle(hrec); 2907 2908 query = "ALTER TABLE `MOO` ADD `COW` INTEGER"; 2909 r = run_query(hdb1, 0, query); 2910 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2911 2912 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER"; 2913 r = run_query(hdb1, 0, query); 2914 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2915 2916 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1"; 2917 r = run_query(hdb1, 0, query); 2918 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2919 2920 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, " 2921 "`Value` CHAR(0) PRIMARY KEY `Property`)"; 2922 r = run_query(hdb1, 0, query); 2923 ok(r == ERROR_SUCCESS, "failed to add property table\n"); 2924 2925 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )"; 2926 r = run_query(hdb1, 0, query); 2927 ok(r == ERROR_SUCCESS, "failed to add property\n"); 2928 2929 /* database needs to be committed */ 2930 MsiDatabaseCommit(hdb1); 2931 2932 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, mstfile, 0, 0); 2933 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 2934 2935 MsiCloseHandle( hdb1 ); 2936 MsiCloseHandle( hdb2 ); 2937 2938 DeleteFileA("testdata.bin"); 2939 } 2940 2941 /* data for generating a transform */ 2942 2943 /* tables transform names - encoded as they would be in an msi database file */ 2944 static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */ 2945 static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */ 2946 static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */ 2947 static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */ 2948 static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */ 2949 static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 2950 static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */ 2951 static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */ 2952 static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */ 2953 2954 /* data in each table */ 2955 static const WCHAR data1[] = { /* AAR */ 2956 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */ 2957 0x0201, 0x0009, 0x8002, 2958 }; 2959 static const WCHAR data2[] = { /* _Columns */ 2960 0x0401, 0x0001, 0x8003, 0x0002, 0x9502, 2961 0x0401, 0x0001, 0x8004, 0x0003, 0x9502, 2962 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */ 2963 0x0401, 0x0005, 0x0000, 0x0007, 0x8502, 2964 0x0401, 0x000a, 0x0000, 0x000a, 0xad48, 2965 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00, 2966 }; 2967 static const WCHAR data3[] = { /* _Tables */ 2968 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */ 2969 0x0101, 0x000a, 2970 }; 2971 static const char data4[] = /* _StringData */ 2972 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */ 2973 static const WCHAR data5[] = { /* _StringPool */ 2974 /* len, refs */ 2975 0, 0, /* string 0 '' */ 2976 3, 2, /* string 1 'MOO' */ 2977 3, 1, /* string 2 'COW' */ 2978 3, 1, /* string 3 'PIG' */ 2979 1, 1, /* string 4 'c' */ 2980 3, 3, /* string 5 'AAR' */ 2981 3, 1, /* string 6 'CAR' */ 2982 3, 1, /* string 7 'BAR' */ 2983 2, 1, /* string 8 'vw' */ 2984 3, 1, /* string 9 'bmw' */ 2985 8, 4, /* string 10 'Property' */ 2986 5, 1, /* string 11 'Value' */ 2987 4, 1, /* string 12 'prop' */ 2988 3, 1, /* string 13 'val' */ 2989 }; 2990 /* update row, 0x0002 is a bitmask of present column data, keys are excluded */ 2991 static const WCHAR data6[] = { /* MOO */ 2992 0x000a, 0x8001, 0x0004, 0x8005, /* update row */ 2993 0x0000, 0x8003, /* delete row */ 2994 }; 2995 2996 static const WCHAR data7[] = { /* BINARY */ 2997 0x0201, 0x8001, 0x0001, 2998 }; 2999 3000 static const char data8[] = /* stream data for the BINARY table */ 3001 "naengmyon"; 3002 3003 static const WCHAR data9[] = { /* Property */ 3004 0x0201, 0x000c, 0x000d, 3005 }; 3006 3007 static const struct { 3008 LPCWSTR name; 3009 const void *data; 3010 DWORD size; 3011 } table_transform_data[] = 3012 { 3013 { name1, data1, sizeof data1 }, 3014 { name2, data2, sizeof data2 }, 3015 { name3, data3, sizeof data3 }, 3016 { name4, data4, sizeof data4 - 1 }, 3017 { name5, data5, sizeof data5 }, 3018 { name6, data6, sizeof data6 }, 3019 { name7, data7, sizeof data7 }, 3020 { name8, data8, sizeof data8 - 1 }, 3021 { name9, data9, sizeof data9 }, 3022 }; 3023 3024 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0]) 3025 3026 static void generate_transform_manual(void) 3027 { 3028 IStorage *stg = NULL; 3029 IStream *stm; 3030 WCHAR name[0x20]; 3031 HRESULT r; 3032 DWORD i, count; 3033 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE; 3034 3035 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}}; 3036 3037 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20); 3038 3039 r = StgCreateDocfile(name, mode, 0, &stg); 3040 ok(r == S_OK, "failed to create storage\n"); 3041 if (!stg) 3042 return; 3043 3044 r = IStorage_SetClass( stg, &CLSID_MsiTransform ); 3045 ok(r == S_OK, "failed to set storage type\n"); 3046 3047 for (i=0; i<NUM_TRANSFORM_TABLES; i++) 3048 { 3049 r = IStorage_CreateStream( stg, table_transform_data[i].name, 3050 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm ); 3051 if (FAILED(r)) 3052 { 3053 ok(0, "failed to create stream %08x\n", r); 3054 continue; 3055 } 3056 3057 r = IStream_Write( stm, table_transform_data[i].data, 3058 table_transform_data[i].size, &count ); 3059 if (FAILED(r) || count != table_transform_data[i].size) 3060 ok(0, "failed to write stream\n"); 3061 IStream_Release(stm); 3062 } 3063 3064 IStorage_Release(stg); 3065 } 3066 3067 static UINT set_summary_info(MSIHANDLE hdb) 3068 { 3069 UINT res; 3070 MSIHANDLE suminfo; 3071 3072 /* build summary info */ 3073 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); 3074 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); 3075 3076 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, 3077 "Installation Database"); 3078 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3079 3080 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, 3081 "Installation Database"); 3082 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3083 3084 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, 3085 "Wine Hackers"); 3086 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3087 3088 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, 3089 ";1033,2057"); 3090 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3091 3092 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, 3093 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); 3094 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3095 3096 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); 3097 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3098 3099 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); 3100 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3101 3102 res = MsiSummaryInfoPersist(suminfo); 3103 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); 3104 3105 res = MsiCloseHandle( suminfo); 3106 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); 3107 3108 return res; 3109 } 3110 3111 static MSIHANDLE create_package_db(const WCHAR *filename) 3112 { 3113 MSIHANDLE hdb = 0; 3114 UINT res; 3115 3116 DeleteFileW(msifileW); 3117 3118 /* create an empty database */ 3119 res = MsiOpenDatabaseW(filename, MSIDBOPEN_CREATE, &hdb ); 3120 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 3121 if( res != ERROR_SUCCESS ) 3122 return hdb; 3123 3124 res = MsiDatabaseCommit( hdb ); 3125 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 3126 3127 res = set_summary_info(hdb); 3128 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3129 3130 res = create_directory_table(hdb); 3131 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); 3132 3133 return hdb; 3134 } 3135 3136 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) 3137 { 3138 UINT res; 3139 CHAR szPackage[12]; 3140 MSIHANDLE hPackage; 3141 3142 sprintf(szPackage, "#%u", hdb); 3143 res = MsiOpenPackageA(szPackage, &hPackage); 3144 if (res != ERROR_SUCCESS) 3145 return res; 3146 3147 res = MsiCloseHandle(hdb); 3148 if (res != ERROR_SUCCESS) 3149 { 3150 MsiCloseHandle(hPackage); 3151 return res; 3152 } 3153 3154 *handle = hPackage; 3155 return ERROR_SUCCESS; 3156 } 3157 3158 static void test_try_transform(void) 3159 { 3160 MSIHANDLE hdb, hview, hrec, hpkg = 0; 3161 LPCSTR query; 3162 UINT r; 3163 DWORD sz; 3164 char buffer[MAX_PATH]; 3165 3166 DeleteFileA(msifile); 3167 DeleteFileA(mstfile); 3168 3169 /* create the database */ 3170 hdb = create_package_db(msifileW); 3171 ok(hdb, "Failed to create package db\n"); 3172 3173 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)"; 3174 r = run_query(hdb, 0, query); 3175 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3176 3177 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )"; 3178 r = run_query(hdb, 0, query); 3179 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3180 3181 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )"; 3182 r = run_query(hdb, 0, query); 3183 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3184 3185 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )"; 3186 r = run_query(hdb, 0, query); 3187 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3188 3189 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)"; 3190 r = run_query(hdb, 0, query); 3191 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3192 3193 hrec = MsiCreateRecord(2); 3194 r = MsiRecordSetInteger(hrec, 1, 2); 3195 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 3196 3197 write_file("testdata.bin", "lamyon", 6); 3198 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 3199 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 3200 3201 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 3202 r = run_query(hdb, hrec, query); 3203 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 3204 3205 MsiCloseHandle(hrec); 3206 3207 r = MsiDatabaseCommit( hdb ); 3208 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3209 3210 MsiCloseHandle( hdb ); 3211 DeleteFileA("testdata.bin"); 3212 3213 /* 3214 * Both these generate an equivalent transform, 3215 * but the first doesn't work in Wine yet 3216 * because MsiDatabaseGenerateTransform is unimplemented. 3217 */ 3218 if (0) 3219 generate_transform(); 3220 else 3221 generate_transform_manual(); 3222 3223 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb ); 3224 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 3225 3226 r = MsiDatabaseApplyTransformA( hdb, mstfile, 0 ); 3227 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 3228 3229 r = MsiDatabaseCommit( hdb ); 3230 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3231 3232 /* check new values */ 3233 hrec = 0; 3234 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'"; 3235 r = do_query(hdb, query, &hrec); 3236 ok(r == ERROR_SUCCESS, "select query failed\n"); 3237 MsiCloseHandle(hrec); 3238 3239 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'"; 3240 hrec = 0; 3241 r = do_query(hdb, query, &hrec); 3242 ok(r == ERROR_SUCCESS, "select query failed\n"); 3243 MsiCloseHandle(hrec); 3244 3245 /* check updated values */ 3246 hrec = 0; 3247 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'"; 3248 r = do_query(hdb, query, &hrec); 3249 ok(r == ERROR_SUCCESS, "select query failed\n"); 3250 MsiCloseHandle(hrec); 3251 3252 /* check unchanged value */ 3253 hrec = 0; 3254 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'"; 3255 r = do_query(hdb, query, &hrec); 3256 ok(r == ERROR_SUCCESS, "select query failed\n"); 3257 MsiCloseHandle(hrec); 3258 3259 /* check deleted value */ 3260 hrec = 0; 3261 query = "select * from `MOO` where `NOO` = 3"; 3262 r = do_query(hdb, query, &hrec); 3263 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n"); 3264 if (hrec) MsiCloseHandle(hrec); 3265 3266 /* check added stream */ 3267 hrec = 0; 3268 query = "select `BLOB` from `BINARY` where `ID` = 1"; 3269 r = do_query(hdb, query, &hrec); 3270 ok(r == ERROR_SUCCESS, "select query failed\n"); 3271 3272 /* check the contents of the stream */ 3273 sz = sizeof buffer; 3274 r = MsiRecordReadStream( hrec, 1, buffer, &sz ); 3275 ok(r == ERROR_SUCCESS, "read stream failed\n"); 3276 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n"); 3277 ok(sz == 9, "stream data was wrong size\n"); 3278 if (hrec) MsiCloseHandle(hrec); 3279 3280 /* check the validity of the table with a deleted row */ 3281 hrec = 0; 3282 query = "select * from `MOO`"; 3283 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3284 ok(r == ERROR_SUCCESS, "open view failed\n"); 3285 3286 r = MsiViewExecute(hview, 0); 3287 ok(r == ERROR_SUCCESS, "view execute failed\n"); 3288 3289 r = MsiViewFetch(hview, &hrec); 3290 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3291 3292 r = MsiRecordGetInteger(hrec, 1); 3293 ok(r == 1, "Expected 1, got %d\n", r); 3294 3295 sz = sizeof buffer; 3296 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3297 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3298 ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer); 3299 3300 r = MsiRecordGetInteger(hrec, 3); 3301 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3302 3303 r = MsiRecordGetInteger(hrec, 4); 3304 ok(r == 5, "Expected 5, got %d\n", r); 3305 3306 MsiCloseHandle(hrec); 3307 3308 r = MsiViewFetch(hview, &hrec); 3309 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3310 3311 r = MsiRecordGetInteger(hrec, 1); 3312 ok(r == 2, "Expected 2, got %d\n", r); 3313 3314 sz = sizeof buffer; 3315 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3316 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3317 ok(!lstrcmpA(buffer, "b"), "Expected b, got %s\n", buffer); 3318 3319 r = MsiRecordGetInteger(hrec, 3); 3320 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3321 3322 r = MsiRecordGetInteger(hrec, 4); 3323 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3324 3325 MsiCloseHandle(hrec); 3326 3327 r = MsiViewFetch(hview, &hrec); 3328 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n"); 3329 3330 MsiCloseHandle(hrec); 3331 MsiViewClose(hview); 3332 MsiCloseHandle(hview); 3333 3334 /* check that the property was added */ 3335 r = package_from_db(hdb, &hpkg); 3336 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3337 { 3338 skip("Not enough rights to perform tests\n"); 3339 goto error; 3340 } 3341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 3342 3343 sz = MAX_PATH; 3344 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz); 3345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3346 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer); 3347 3348 MsiCloseHandle(hpkg); 3349 3350 error: 3351 MsiCloseHandle(hdb); 3352 DeleteFileA(msifile); 3353 DeleteFileA(mstfile); 3354 } 3355 3356 struct join_res 3357 { 3358 const CHAR one[MAX_PATH]; 3359 const CHAR two[MAX_PATH]; 3360 }; 3361 3362 struct join_res_4col 3363 { 3364 const CHAR one[MAX_PATH]; 3365 const CHAR two[MAX_PATH]; 3366 const CHAR three[MAX_PATH]; 3367 const CHAR four[MAX_PATH]; 3368 }; 3369 3370 struct join_res_uint 3371 { 3372 UINT one; 3373 UINT two; 3374 UINT three; 3375 UINT four; 3376 UINT five; 3377 UINT six; 3378 }; 3379 3380 static const struct join_res join_res_first[] = 3381 { 3382 { "alveolar", "procerus" }, 3383 { "septum", "procerus" }, 3384 { "septum", "nasalis" }, 3385 { "ramus", "nasalis" }, 3386 { "malar", "mentalis" }, 3387 }; 3388 3389 static const struct join_res join_res_second[] = 3390 { 3391 { "nasal", "septum" }, 3392 { "mandible", "ramus" }, 3393 }; 3394 3395 static const struct join_res join_res_third[] = 3396 { 3397 { "msvcp.dll", "abcdefgh" }, 3398 { "msvcr.dll", "ijklmnop" }, 3399 }; 3400 3401 static const struct join_res join_res_fourth[] = 3402 { 3403 { "msvcp.dll.01234", "single.dll.31415" }, 3404 }; 3405 3406 static const struct join_res join_res_fifth[] = 3407 { 3408 { "malar", "procerus" }, 3409 }; 3410 3411 static const struct join_res join_res_sixth[] = 3412 { 3413 { "malar", "procerus" }, 3414 { "malar", "procerus" }, 3415 { "malar", "nasalis" }, 3416 { "malar", "nasalis" }, 3417 { "malar", "nasalis" }, 3418 { "malar", "mentalis" }, 3419 }; 3420 3421 static const struct join_res join_res_seventh[] = 3422 { 3423 { "malar", "nasalis" }, 3424 { "malar", "nasalis" }, 3425 { "malar", "nasalis" }, 3426 }; 3427 3428 static const struct join_res_4col join_res_eighth[] = 3429 { 3430 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" }, 3431 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" }, 3432 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" }, 3433 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" }, 3434 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" }, 3435 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" }, 3436 }; 3437 3438 static const struct join_res_uint join_res_ninth[] = 3439 { 3440 { 1, 2, 3, 4, 7, 8 }, 3441 { 1, 2, 5, 6, 7, 8 }, 3442 { 1, 2, 3, 4, 9, 10 }, 3443 { 1, 2, 5, 6, 9, 10 }, 3444 { 1, 2, 3, 4, 11, 12 }, 3445 { 1, 2, 5, 6, 11, 12 }, 3446 }; 3447 3448 static void test_join(void) 3449 { 3450 MSIHANDLE hdb, hview, hrec; 3451 LPCSTR query; 3452 CHAR buf[MAX_PATH]; 3453 UINT r, count; 3454 DWORD size, i; 3455 BOOL data_correct; 3456 3457 hdb = create_db(); 3458 ok( hdb, "failed to create db\n"); 3459 3460 r = create_component_table( hdb ); 3461 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); 3462 3463 r = add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" ); 3464 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3465 3466 r = add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" ); 3467 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3468 3469 r = add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" ); 3470 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3471 3472 r = add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" ); 3473 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3474 3475 r = create_feature_components_table( hdb ); 3476 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); 3477 3478 r = add_feature_components_entry( hdb, "'procerus', 'maxilla'" ); 3479 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3480 3481 r = add_feature_components_entry( hdb, "'procerus', 'nasal'" ); 3482 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3483 3484 r = add_feature_components_entry( hdb, "'nasalis', 'nasal'" ); 3485 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3486 3487 r = add_feature_components_entry( hdb, "'nasalis', 'mandible'" ); 3488 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3489 3490 r = add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" ); 3491 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3492 3493 r = add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" ); 3494 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3495 3496 r = create_std_dlls_table( hdb ); 3497 ok( r == ERROR_SUCCESS, "cannot create StdDlls table: %d\n", r ); 3498 3499 r = add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" ); 3500 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); 3501 3502 r = add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" ); 3503 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); 3504 3505 r = create_binary_table( hdb ); 3506 ok( r == ERROR_SUCCESS, "cannot create Binary table: %d\n", r ); 3507 3508 r = add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" ); 3509 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3510 3511 r = add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" ); 3512 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3513 3514 r = add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" ); 3515 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3516 3517 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 3518 r = run_query( hdb, 0, query); 3519 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3520 3521 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)"; 3522 r = run_query( hdb, 0, query); 3523 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3524 3525 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)"; 3526 r = run_query( hdb, 0, query); 3527 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3528 3529 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)"; 3530 r = run_query( hdb, 0, query); 3531 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3532 3533 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)"; 3534 r = run_query( hdb, 0, query); 3535 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3536 3537 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)"; 3538 r = run_query( hdb, 0, query); 3539 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3540 3541 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)"; 3542 r = run_query( hdb, 0, query); 3543 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3544 3545 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)"; 3546 r = run_query( hdb, 0, query); 3547 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3548 3549 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)"; 3550 r = run_query( hdb, 0, query); 3551 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3552 3553 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)"; 3554 r = run_query( hdb, 0, query); 3555 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3556 3557 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)"; 3558 r = run_query( hdb, 0, query); 3559 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3560 3561 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)"; 3562 r = run_query( hdb, 0, query); 3563 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3564 3565 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)"; 3566 r = run_query( hdb, 0, query); 3567 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3568 3569 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3570 "FROM `Component`, `FeatureComponents` " 3571 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 3572 "ORDER BY `Feature_`"; 3573 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3574 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3575 3576 r = MsiViewExecute(hview, 0); 3577 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3578 3579 i = 0; 3580 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3581 { 3582 count = MsiRecordGetFieldCount( hrec ); 3583 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3584 3585 size = MAX_PATH; 3586 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3587 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3588 ok( !lstrcmpA( buf, join_res_first[i].one ), 3589 "For (row %d, column 1) expected '%s', got %s\n", i, join_res_first[i].one, buf ); 3590 3591 size = MAX_PATH; 3592 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3593 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3594 ok( !lstrcmpA( buf, join_res_first[i].two ), 3595 "For (row %d, column 2) expected '%s', got %s\n", i, join_res_first[i].two, buf ); 3596 3597 i++; 3598 MsiCloseHandle(hrec); 3599 } 3600 3601 ok( i == 5, "Expected 5 rows, got %d\n", i ); 3602 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3603 3604 MsiViewClose(hview); 3605 MsiCloseHandle(hview); 3606 3607 /* try a join without a WHERE condition */ 3608 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3609 "FROM `Component`, `FeatureComponents` "; 3610 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3611 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3612 3613 r = MsiViewExecute(hview, 0); 3614 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3615 3616 i = 0; 3617 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3618 { 3619 i++; 3620 MsiCloseHandle(hrec); 3621 } 3622 ok( i == 24, "Expected 24 rows, got %d\n", i ); 3623 3624 MsiViewClose(hview); 3625 MsiCloseHandle(hview); 3626 3627 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component " 3628 "WHERE FeatureComponents.Component_=Component.Component " 3629 "AND (Feature_='nasalis') ORDER BY Feature_"; 3630 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3631 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3632 3633 r = MsiViewExecute(hview, 0); 3634 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3635 3636 i = 0; 3637 data_correct = TRUE; 3638 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3639 { 3640 count = MsiRecordGetFieldCount( hrec ); 3641 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3642 3643 size = MAX_PATH; 3644 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3645 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3646 if( lstrcmpA( buf, join_res_second[i].one )) 3647 data_correct = FALSE; 3648 3649 size = MAX_PATH; 3650 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3651 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3652 if( lstrcmpA( buf, join_res_second[i].two )) 3653 data_correct = FALSE; 3654 3655 i++; 3656 MsiCloseHandle(hrec); 3657 } 3658 3659 ok( data_correct, "data returned in the wrong order\n"); 3660 3661 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3662 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3663 3664 MsiViewClose(hview); 3665 MsiCloseHandle(hview); 3666 3667 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3668 "FROM `StdDlls`, `Binary` " 3669 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` " 3670 "ORDER BY `File`"; 3671 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3672 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3673 3674 r = MsiViewExecute(hview, 0); 3675 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3676 3677 i = 0; 3678 data_correct = TRUE; 3679 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3680 { 3681 count = MsiRecordGetFieldCount( hrec ); 3682 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3683 3684 size = MAX_PATH; 3685 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3686 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3687 if( lstrcmpA( buf, join_res_third[i].one ) ) 3688 data_correct = FALSE; 3689 3690 size = MAX_PATH; 3691 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3692 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3693 if( lstrcmpA( buf, join_res_third[i].two ) ) 3694 data_correct = FALSE; 3695 3696 i++; 3697 MsiCloseHandle(hrec); 3698 } 3699 ok( data_correct, "data returned in the wrong order\n"); 3700 3701 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3702 3703 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3704 3705 MsiViewClose(hview); 3706 MsiCloseHandle(hview); 3707 3708 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` " 3709 "FROM `StdDlls`, `Binary` " 3710 "WHERE `StdDlls`.`File` = `Binary`.`Data` " 3711 "ORDER BY `Name`"; 3712 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3713 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3714 3715 r = MsiViewExecute(hview, 0); 3716 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3717 3718 i = 0; 3719 data_correct = TRUE; 3720 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3721 { 3722 count = MsiRecordGetFieldCount( hrec ); 3723 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3724 3725 size = MAX_PATH; 3726 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3727 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3728 if( lstrcmpA( buf, join_res_fourth[i].one )) 3729 data_correct = FALSE; 3730 3731 size = MAX_PATH; 3732 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3733 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3734 if( lstrcmpA( buf, join_res_fourth[i].two )) 3735 data_correct = FALSE; 3736 3737 i++; 3738 MsiCloseHandle(hrec); 3739 } 3740 ok( data_correct, "data returned in the wrong order\n"); 3741 3742 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3743 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3744 3745 MsiViewClose(hview); 3746 MsiCloseHandle(hview); 3747 3748 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3749 "FROM `Component`, `FeatureComponents` " 3750 "WHERE `Component`.`Component` = 'zygomatic' " 3751 "AND `FeatureComponents`.`Component_` = 'maxilla' " 3752 "ORDER BY `Feature_`"; 3753 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3754 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3755 3756 r = MsiViewExecute(hview, 0); 3757 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3758 3759 i = 0; 3760 data_correct = TRUE; 3761 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3762 { 3763 count = MsiRecordGetFieldCount( hrec ); 3764 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3765 3766 size = MAX_PATH; 3767 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3768 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3769 if( lstrcmpA( buf, join_res_fifth[i].one )) 3770 data_correct = FALSE; 3771 3772 size = MAX_PATH; 3773 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3774 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3775 if( lstrcmpA( buf, join_res_fifth[i].two )) 3776 data_correct = FALSE; 3777 3778 i++; 3779 MsiCloseHandle(hrec); 3780 } 3781 ok( data_correct, "data returned in the wrong order\n"); 3782 3783 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3784 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3785 3786 MsiViewClose(hview); 3787 MsiCloseHandle(hview); 3788 3789 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3790 "FROM `Component`, `FeatureComponents` " 3791 "WHERE `Component` = 'zygomatic' " 3792 "ORDER BY `Feature_`"; 3793 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3794 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3795 3796 r = MsiViewExecute(hview, 0); 3797 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3798 3799 i = 0; 3800 data_correct = TRUE; 3801 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3802 { 3803 count = MsiRecordGetFieldCount( hrec ); 3804 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3805 3806 size = MAX_PATH; 3807 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3808 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3809 if( lstrcmpA( buf, join_res_sixth[i].one )) 3810 data_correct = FALSE; 3811 3812 size = MAX_PATH; 3813 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3814 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3815 if( lstrcmpA( buf, join_res_sixth[i].two )) 3816 data_correct = FALSE; 3817 3818 i++; 3819 MsiCloseHandle(hrec); 3820 } 3821 ok( data_correct, "data returned in the wrong order\n"); 3822 3823 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3824 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3825 3826 MsiViewClose(hview); 3827 MsiCloseHandle(hview); 3828 3829 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3830 "FROM `Component`, `FeatureComponents` " 3831 "WHERE `Component` = 'zygomatic' " 3832 "AND `Feature_` = 'nasalis' " 3833 "ORDER BY `Feature_`"; 3834 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3835 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3836 3837 r = MsiViewExecute(hview, 0); 3838 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3839 3840 i = 0; 3841 data_correct = TRUE; 3842 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3843 { 3844 count = MsiRecordGetFieldCount( hrec ); 3845 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3846 3847 size = MAX_PATH; 3848 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3849 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3850 if( lstrcmpA( buf, join_res_seventh[i].one )) 3851 data_correct = FALSE; 3852 3853 size = MAX_PATH; 3854 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3855 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3856 if( lstrcmpA( buf, join_res_seventh[i].two )) 3857 data_correct = FALSE; 3858 3859 i++; 3860 MsiCloseHandle(hrec); 3861 } 3862 3863 ok( data_correct, "data returned in the wrong order\n"); 3864 ok( i == 3, "Expected 3 rows, got %d\n", i ); 3865 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3866 3867 MsiViewClose(hview); 3868 MsiCloseHandle(hview); 3869 3870 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3871 "FROM `StdDlls`, `Binary` "; 3872 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3873 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3874 3875 r = MsiViewExecute(hview, 0); 3876 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3877 3878 i = 0; 3879 data_correct = TRUE; 3880 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3881 { 3882 count = MsiRecordGetFieldCount( hrec ); 3883 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3884 3885 size = MAX_PATH; 3886 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3887 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3888 if( lstrcmpA( buf, join_res_eighth[i].one )) 3889 data_correct = FALSE; 3890 3891 size = MAX_PATH; 3892 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3893 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3894 if( lstrcmpA( buf, join_res_eighth[i].four )) 3895 data_correct = FALSE; 3896 3897 i++; 3898 MsiCloseHandle(hrec); 3899 } 3900 3901 ok( data_correct, "data returned in the wrong order\n"); 3902 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3903 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3904 3905 MsiViewClose(hview); 3906 MsiCloseHandle(hview); 3907 3908 query = "SELECT * FROM `StdDlls`, `Binary` "; 3909 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3910 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3911 3912 r = MsiViewExecute(hview, 0); 3913 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3914 3915 i = 0; 3916 data_correct = TRUE; 3917 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3918 { 3919 count = MsiRecordGetFieldCount( hrec ); 3920 ok( count == 4, "Expected 4 record fields, got %d\n", count ); 3921 3922 size = MAX_PATH; 3923 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3924 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3925 if( lstrcmpA( buf, join_res_eighth[i].one )) 3926 data_correct = FALSE; 3927 3928 size = MAX_PATH; 3929 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3930 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3931 if( lstrcmpA( buf, join_res_eighth[i].two )) 3932 data_correct = FALSE; 3933 3934 size = MAX_PATH; 3935 r = MsiRecordGetStringA( hrec, 3, buf, &size ); 3936 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3937 if( lstrcmpA( buf, join_res_eighth[i].three )) 3938 data_correct = FALSE; 3939 3940 size = MAX_PATH; 3941 r = MsiRecordGetStringA( hrec, 4, buf, &size ); 3942 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3943 if( lstrcmpA( buf, join_res_eighth[i].four )) 3944 data_correct = FALSE; 3945 3946 i++; 3947 MsiCloseHandle(hrec); 3948 } 3949 ok( data_correct, "data returned in the wrong order\n"); 3950 3951 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3952 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3953 3954 MsiViewClose(hview); 3955 MsiCloseHandle(hview); 3956 3957 query = "SELECT * FROM `One`, `Two`, `Three` "; 3958 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3959 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3960 3961 r = MsiViewExecute(hview, 0); 3962 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3963 3964 i = 0; 3965 data_correct = TRUE; 3966 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3967 { 3968 count = MsiRecordGetFieldCount( hrec ); 3969 ok( count == 6, "Expected 6 record fields, got %d\n", count ); 3970 3971 r = MsiRecordGetInteger( hrec, 1 ); 3972 if( r != join_res_ninth[i].one ) 3973 data_correct = FALSE; 3974 3975 r = MsiRecordGetInteger( hrec, 2 ); 3976 if( r != join_res_ninth[i].two ) 3977 data_correct = FALSE; 3978 3979 r = MsiRecordGetInteger( hrec, 3 ); 3980 if( r != join_res_ninth[i].three ) 3981 data_correct = FALSE; 3982 3983 r = MsiRecordGetInteger( hrec, 4 ); 3984 if( r != join_res_ninth[i].four ) 3985 data_correct = FALSE; 3986 3987 r = MsiRecordGetInteger( hrec, 5 ); 3988 if( r != join_res_ninth[i].five ) 3989 data_correct = FALSE; 3990 3991 r = MsiRecordGetInteger( hrec, 6); 3992 if( r != join_res_ninth[i].six ) 3993 data_correct = FALSE; 3994 3995 i++; 3996 MsiCloseHandle(hrec); 3997 } 3998 ok( data_correct, "data returned in the wrong order\n"); 3999 4000 ok( i == 6, "Expected 6 rows, got %d\n", i ); 4001 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 4002 4003 MsiViewClose(hview); 4004 MsiCloseHandle(hview); 4005 4006 query = "SELECT * FROM `Four`, `Five`"; 4007 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4008 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 4009 4010 r = MsiViewExecute(hview, 0); 4011 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 4012 4013 r = MsiViewFetch(hview, &hrec); 4014 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4015 4016 MsiViewClose(hview); 4017 MsiCloseHandle(hview); 4018 4019 query = "SELECT * FROM `Nonexistent`, `One`"; 4020 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4021 ok( r == ERROR_BAD_QUERY_SYNTAX, 4022 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r ); 4023 4024 /* try updating a row in a join table */ 4025 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 4026 "FROM `Component`, `FeatureComponents` " 4027 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 4028 "ORDER BY `Feature_`"; 4029 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4030 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 4031 4032 r = MsiViewExecute(hview, 0); 4033 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 4034 4035 r = MsiViewFetch(hview, &hrec); 4036 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 4037 4038 r = MsiRecordSetStringA( hrec, 1, "epicranius" ); 4039 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4040 4041 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4042 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r ); 4043 4044 /* try another valid operation for joins */ 4045 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 4046 todo_wine ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r ); 4047 4048 /* try an invalid operation for joins */ 4049 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 4050 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); 4051 4052 r = MsiRecordSetStringA( hrec, 2, "epicranius" ); 4053 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4054 4055 /* primary key cannot be updated */ 4056 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4057 ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r ); 4058 4059 MsiCloseHandle(hrec); 4060 MsiViewClose(hview); 4061 MsiCloseHandle(hview); 4062 4063 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4064 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4065 4066 r = MsiViewExecute(hview, 0); 4067 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4068 4069 r = MsiViewFetch(hview, &hrec); 4070 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4071 4072 size = MAX_PATH; 4073 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 4074 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 4075 ok( !lstrcmpA( buf, "epicranius" ), "expected 'epicranius', got %s\n", buf ); 4076 4077 MsiCloseHandle(hrec); 4078 MsiViewClose(hview); 4079 MsiCloseHandle(hview); 4080 4081 MsiCloseHandle(hdb); 4082 DeleteFileA(msifile); 4083 } 4084 4085 static void test_temporary_table(void) 4086 { 4087 MSICONDITION cond; 4088 MSIHANDLE hdb = 0, view = 0, rec; 4089 const char *query; 4090 UINT r; 4091 char buf[0x10]; 4092 DWORD sz; 4093 4094 cond = MsiDatabaseIsTablePersistentA(0, NULL); 4095 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4096 4097 hdb = create_db(); 4098 ok( hdb, "failed to create db\n"); 4099 4100 cond = MsiDatabaseIsTablePersistentA(hdb, NULL); 4101 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4102 4103 cond = MsiDatabaseIsTablePersistentA(hdb, "_Tables"); 4104 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4105 4106 cond = MsiDatabaseIsTablePersistentA(hdb, "_Columns"); 4107 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4108 4109 cond = MsiDatabaseIsTablePersistentA(hdb, "_Storages"); 4110 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4111 4112 cond = MsiDatabaseIsTablePersistentA(hdb, "_Streams"); 4113 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4114 4115 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)"; 4116 r = run_query(hdb, 0, query); 4117 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4118 4119 cond = MsiDatabaseIsTablePersistentA(hdb, "P"); 4120 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4121 4122 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD"; 4123 r = run_query(hdb, 0, query); 4124 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4125 4126 cond = MsiDatabaseIsTablePersistentA(hdb, "P2"); 4127 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4128 4129 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4130 r = run_query(hdb, 0, query); 4131 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4132 4133 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4134 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4135 4136 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4137 r = run_query(hdb, 0, query); 4138 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4139 4140 query = "SELECT * FROM `T2`"; 4141 r = MsiDatabaseOpenViewA(hdb, query, &view); 4142 ok(r == ERROR_BAD_QUERY_SYNTAX, 4143 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4144 4145 cond = MsiDatabaseIsTablePersistentA(hdb, "T2"); 4146 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4147 4148 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)"; 4149 r = run_query(hdb, 0, query); 4150 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4151 4152 cond = MsiDatabaseIsTablePersistentA(hdb, "T3"); 4153 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4154 4155 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4156 r = run_query(hdb, 0, query); 4157 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n"); 4158 4159 cond = MsiDatabaseIsTablePersistentA(hdb, "T4"); 4160 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4161 4162 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD"; 4163 r = run_query(hdb, 0, query); 4164 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n"); 4165 4166 query = "select * from `T`"; 4167 r = MsiDatabaseOpenViewA(hdb, query, &view); 4168 ok(r == ERROR_SUCCESS, "failed to query table\n"); 4169 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4170 ok(r == ERROR_SUCCESS, "failed to get column info\n"); 4171 4172 sz = sizeof buf; 4173 r = MsiRecordGetStringA(rec, 1, buf, &sz); 4174 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4175 ok( 0 == strcmp("G255", buf), "wrong column type\n"); 4176 4177 sz = sizeof buf; 4178 r = MsiRecordGetStringA(rec, 2, buf, &sz); 4179 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4180 ok( 0 == strcmp("j2", buf), "wrong column type\n"); 4181 4182 MsiCloseHandle( rec ); 4183 MsiViewClose( view ); 4184 MsiCloseHandle( view ); 4185 4186 /* query the table data */ 4187 rec = 0; 4188 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec); 4189 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n"); 4190 MsiCloseHandle( rec ); 4191 4192 /* query the column data */ 4193 rec = 0; 4194 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec); 4195 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4196 if (rec) MsiCloseHandle( rec ); 4197 4198 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec); 4199 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4200 if (rec) MsiCloseHandle( rec ); 4201 4202 MsiCloseHandle( hdb ); 4203 DeleteFileA(msifile); 4204 } 4205 4206 static void test_alter(void) 4207 { 4208 MSICONDITION cond; 4209 MSIHANDLE hdb = 0; 4210 const char *query; 4211 UINT r; 4212 4213 hdb = create_db(); 4214 ok( hdb, "failed to create db\n"); 4215 4216 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4217 r = run_query(hdb, 0, query); 4218 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4219 4220 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4221 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4222 4223 query = "ALTER TABLE `T` HOLD"; 4224 r = run_query(hdb, 0, query); 4225 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r); 4226 4227 query = "ALTER TABLE `T` FREE"; 4228 r = run_query(hdb, 0, query); 4229 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4230 4231 query = "ALTER TABLE `T` FREE"; 4232 r = run_query(hdb, 0, query); 4233 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4234 4235 query = "ALTER TABLE `T` FREE"; 4236 r = run_query(hdb, 0, query); 4237 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n"); 4238 4239 query = "ALTER TABLE `T` HOLD"; 4240 r = run_query(hdb, 0, query); 4241 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r); 4242 4243 /* table T is removed */ 4244 query = "SELECT * FROM `T`"; 4245 r = run_query(hdb, 0, query); 4246 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4247 4248 /* create the table again */ 4249 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)"; 4250 r = run_query(hdb, 0, query); 4251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4252 4253 /* up the ref count */ 4254 query = "ALTER TABLE `U` HOLD"; 4255 r = run_query(hdb, 0, query); 4256 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4257 4258 /* add column, no data type */ 4259 query = "ALTER TABLE `U` ADD `C`"; 4260 r = run_query(hdb, 0, query); 4261 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4262 4263 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4264 r = run_query(hdb, 0, query); 4265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4266 4267 /* add column C again */ 4268 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4269 r = run_query(hdb, 0, query); 4270 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4271 4272 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY"; 4273 r = run_query(hdb, 0, query); 4274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4275 4276 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )"; 4277 r = run_query(hdb, 0, query); 4278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4279 4280 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD"; 4281 r = run_query(hdb, 0, query); 4282 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4283 4284 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )"; 4285 r = run_query(hdb, 0, query); 4286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4287 4288 query = "SELECT * FROM `U` WHERE `D` = 8"; 4289 r = run_query(hdb, 0, query); 4290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4291 4292 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE"; 4293 r = run_query(hdb, 0, query); 4294 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4295 4296 query = "ALTER COLUMN `D` FREE"; 4297 r = run_query(hdb, 0, query); 4298 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4299 4300 /* drop the ref count */ 4301 query = "ALTER TABLE `U` FREE"; 4302 r = run_query(hdb, 0, query); 4303 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4304 4305 /* table is not empty */ 4306 query = "SELECT * FROM `U`"; 4307 r = run_query(hdb, 0, query); 4308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4309 4310 /* column D is removed */ 4311 query = "SELECT * FROM `U` WHERE `D` = 8"; 4312 r = run_query(hdb, 0, query); 4313 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4314 4315 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )"; 4316 r = run_query(hdb, 0, query); 4317 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4318 4319 /* add the column again */ 4320 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD"; 4321 r = run_query(hdb, 0, query); 4322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4323 4324 /* up the ref count */ 4325 query = "ALTER TABLE `U` HOLD"; 4326 r = run_query(hdb, 0, query); 4327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4328 4329 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )"; 4330 r = run_query(hdb, 0, query); 4331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4332 4333 query = "SELECT * FROM `U` WHERE `E` = 16"; 4334 r = run_query(hdb, 0, query); 4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4336 4337 /* drop the ref count */ 4338 query = "ALTER TABLE `U` FREE"; 4339 r = run_query(hdb, 0, query); 4340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4341 4342 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )"; 4343 r = run_query(hdb, 0, query); 4344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4345 4346 query = "SELECT * FROM `U` WHERE `E` = 20"; 4347 r = run_query(hdb, 0, query); 4348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4349 4350 /* drop the ref count */ 4351 query = "ALTER TABLE `U` FREE"; 4352 r = run_query(hdb, 0, query); 4353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4354 4355 /* table still exists */ 4356 query = "SELECT * FROM `U`"; 4357 r = run_query(hdb, 0, query); 4358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4359 4360 /* col E is removed */ 4361 query = "SELECT * FROM `U` WHERE `E` = 20"; 4362 r = run_query(hdb, 0, query); 4363 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4364 4365 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )"; 4366 r = run_query(hdb, 0, query); 4367 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4368 4369 /* drop the ref count once more */ 4370 query = "ALTER TABLE `U` FREE"; 4371 r = run_query(hdb, 0, query); 4372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4373 4374 /* table still exists */ 4375 query = "SELECT * FROM `U`"; 4376 r = run_query(hdb, 0, query); 4377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4378 4379 MsiCloseHandle( hdb ); 4380 DeleteFileA(msifile); 4381 } 4382 4383 static void test_integers(void) 4384 { 4385 MSIHANDLE hdb = 0, view = 0, rec = 0; 4386 DWORD count, i; 4387 const char *query; 4388 UINT r; 4389 4390 /* just MsiOpenDatabase should not create a file */ 4391 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4392 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4393 4394 /* create a table */ 4395 query = "CREATE TABLE `integers` ( " 4396 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, " 4397 "`five` SHORT NOT NULL, `six` INT NOT NULL, " 4398 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL " 4399 "PRIMARY KEY `one`)"; 4400 r = MsiDatabaseOpenViewA(hdb, query, &view); 4401 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4402 r = MsiViewExecute(view, 0); 4403 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4404 r = MsiViewClose(view); 4405 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4406 r = MsiCloseHandle(view); 4407 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4408 4409 query = "SELECT * FROM `integers`"; 4410 r = MsiDatabaseOpenViewA(hdb, query, &view); 4411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4412 4413 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 4414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4415 count = MsiRecordGetFieldCount(rec); 4416 ok(count == 8, "Expected 8, got %d\n", count); 4417 ok(check_record(rec, 1, "one"), "Expected one\n"); 4418 ok(check_record(rec, 2, "two"), "Expected two\n"); 4419 ok(check_record(rec, 3, "three"), "Expected three\n"); 4420 ok(check_record(rec, 4, "four"), "Expected four\n"); 4421 ok(check_record(rec, 5, "five"), "Expected five\n"); 4422 ok(check_record(rec, 6, "six"), "Expected six\n"); 4423 ok(check_record(rec, 7, "seven"), "Expected seven\n"); 4424 ok(check_record(rec, 8, "eight"), "Expected eight\n"); 4425 MsiCloseHandle(rec); 4426 4427 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4429 count = MsiRecordGetFieldCount(rec); 4430 ok(count == 8, "Expected 8, got %d\n", count); 4431 ok(check_record(rec, 1, "I2"), "Expected I2\n"); 4432 ok(check_record(rec, 2, "I2"), "Expected I2\n"); 4433 ok(check_record(rec, 3, "I2"), "Expected I2\n"); 4434 ok(check_record(rec, 4, "I4"), "Expected I4\n"); 4435 ok(check_record(rec, 5, "i2"), "Expected i2\n"); 4436 ok(check_record(rec, 6, "i2"), "Expected i2\n"); 4437 ok(check_record(rec, 7, "i2"), "Expected i2\n"); 4438 ok(check_record(rec, 8, "i4"), "Expected i4\n"); 4439 MsiCloseHandle(rec); 4440 4441 MsiViewClose(view); 4442 MsiCloseHandle(view); 4443 4444 /* insert values into it, NULL where NOT NULL is specified */ 4445 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4446 "VALUES('', '', '', '', '', '', '', '')"; 4447 r = MsiDatabaseOpenViewA(hdb, query, &view); 4448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4449 r = MsiViewExecute(view, 0); 4450 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 4451 4452 MsiViewClose(view); 4453 MsiCloseHandle(view); 4454 4455 query = "SELECT * FROM `integers`"; 4456 r = do_query(hdb, query, &rec); 4457 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4458 4459 r = MsiRecordGetFieldCount(rec); 4460 ok(r == -1, "record count wrong: %d\n", r); 4461 4462 MsiCloseHandle(rec); 4463 4464 /* insert legitimate values into it */ 4465 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4466 "VALUES('', '2', '', '4', '5', '6', '7', '8')"; 4467 r = MsiDatabaseOpenViewA(hdb, query, &view); 4468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4469 r = MsiViewExecute(view, 0); 4470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4471 4472 query = "SELECT * FROM `integers`"; 4473 r = do_query(hdb, query, &rec); 4474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4475 4476 r = MsiRecordGetFieldCount(rec); 4477 ok(r == 8, "record count wrong: %d\n", r); 4478 4479 i = MsiRecordGetInteger(rec, 1); 4480 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4481 i = MsiRecordGetInteger(rec, 3); 4482 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4483 i = MsiRecordGetInteger(rec, 2); 4484 ok(i == 2, "Expected 2, got %d\n", i); 4485 i = MsiRecordGetInteger(rec, 4); 4486 ok(i == 4, "Expected 4, got %d\n", i); 4487 i = MsiRecordGetInteger(rec, 5); 4488 ok(i == 5, "Expected 5, got %d\n", i); 4489 i = MsiRecordGetInteger(rec, 6); 4490 ok(i == 6, "Expected 6, got %d\n", i); 4491 i = MsiRecordGetInteger(rec, 7); 4492 ok(i == 7, "Expected 7, got %d\n", i); 4493 i = MsiRecordGetInteger(rec, 8); 4494 ok(i == 8, "Expected 8, got %d\n", i); 4495 4496 MsiCloseHandle(rec); 4497 MsiViewClose(view); 4498 MsiCloseHandle(view); 4499 4500 r = MsiDatabaseCommit(hdb); 4501 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4502 4503 r = MsiCloseHandle(hdb); 4504 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4505 4506 r = DeleteFileA(msifile); 4507 ok(r == TRUE, "file didn't exist after commit\n"); 4508 } 4509 4510 static void test_update(void) 4511 { 4512 MSIHANDLE hdb = 0, view = 0, rec = 0; 4513 CHAR result[MAX_PATH]; 4514 const char *query; 4515 DWORD size; 4516 UINT r; 4517 4518 /* just MsiOpenDatabase should not create a file */ 4519 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4520 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4521 4522 /* create the Control table */ 4523 query = "CREATE TABLE `Control` ( " 4524 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, " 4525 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL," 4526 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, " 4527 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)"; 4528 r = MsiDatabaseOpenViewA(hdb, query, &view); 4529 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4530 r = MsiViewExecute(view, 0); 4531 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4532 r = MsiViewClose(view); 4533 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4534 r = MsiCloseHandle(view); 4535 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4536 4537 /* add a control */ 4538 query = "INSERT INTO `Control` ( " 4539 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4540 "`Property`, `Text`, `Control_Next`, `Help` )" 4541 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4542 r = MsiDatabaseOpenViewA(hdb, query, &view); 4543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4544 r = MsiViewExecute(view, 0); 4545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4546 r = MsiViewClose(view); 4547 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4548 r = MsiCloseHandle(view); 4549 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4550 4551 /* add a second control */ 4552 query = "INSERT INTO `Control` ( " 4553 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4554 "`Property`, `Text`, `Control_Next`, `Help` )" 4555 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')"; 4556 r = MsiDatabaseOpenViewA(hdb, query, &view); 4557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4558 r = MsiViewExecute(view, 0); 4559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4560 r = MsiViewClose(view); 4561 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4562 r = MsiCloseHandle(view); 4563 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4564 4565 /* add a third control */ 4566 query = "INSERT INTO `Control` ( " 4567 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4568 "`Property`, `Text`, `Control_Next`, `Help` )" 4569 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4570 r = MsiDatabaseOpenViewA(hdb, query, &view); 4571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4572 r = MsiViewExecute(view, 0); 4573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4574 r = MsiViewClose(view); 4575 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4576 r = MsiCloseHandle(view); 4577 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4578 4579 /* bad table */ 4580 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4581 r = MsiDatabaseOpenViewA(hdb, query, &view); 4582 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4583 4584 /* bad set column */ 4585 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4586 r = MsiDatabaseOpenViewA(hdb, query, &view); 4587 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4588 4589 /* bad where condition */ 4590 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'"; 4591 r = MsiDatabaseOpenViewA(hdb, query, &view); 4592 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4593 4594 /* just the dialog_ specified */ 4595 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4596 r = MsiDatabaseOpenViewA(hdb, query, &view); 4597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4598 r = MsiViewExecute(view, 0); 4599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4600 r = MsiViewClose(view); 4601 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4602 r = MsiCloseHandle(view); 4603 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4604 4605 /* check the modified text */ 4606 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4607 r = MsiDatabaseOpenViewA(hdb, query, &view); 4608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4609 r = MsiViewExecute(view, 0); 4610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4611 4612 r = MsiViewFetch(view, &rec); 4613 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4614 4615 size = MAX_PATH; 4616 r = MsiRecordGetStringA(rec, 1, result, &size); 4617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4618 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4619 4620 MsiCloseHandle(rec); 4621 4622 r = MsiViewFetch(view, &rec); 4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4624 4625 size = MAX_PATH; 4626 r = MsiRecordGetStringA(rec, 1, result, &size); 4627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4628 ok(!result[0], "Expected an empty string, got %s\n", result); 4629 4630 MsiCloseHandle(rec); 4631 4632 r = MsiViewFetch(view, &rec); 4633 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4634 4635 r = MsiViewClose(view); 4636 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4637 r = MsiCloseHandle(view); 4638 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4639 4640 /* dialog_ and control specified */ 4641 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'"; 4642 r = MsiDatabaseOpenViewA(hdb, query, &view); 4643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4644 r = MsiViewExecute(view, 0); 4645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4646 r = MsiViewClose(view); 4647 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4648 r = MsiCloseHandle(view); 4649 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4650 4651 /* check the modified text */ 4652 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4653 r = MsiDatabaseOpenViewA(hdb, query, &view); 4654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4655 r = MsiViewExecute(view, 0); 4656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4657 4658 r = MsiViewFetch(view, &rec); 4659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4660 4661 size = MAX_PATH; 4662 r = MsiRecordGetStringA(rec, 1, result, &size); 4663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4664 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4665 4666 MsiCloseHandle(rec); 4667 4668 r = MsiViewFetch(view, &rec); 4669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4670 4671 size = MAX_PATH; 4672 r = MsiRecordGetStringA(rec, 1, result, &size); 4673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4674 ok(!result[0], "Expected an empty string, got %s\n", result); 4675 4676 MsiCloseHandle(rec); 4677 4678 r = MsiViewFetch(view, &rec); 4679 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4680 4681 r = MsiViewClose(view); 4682 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4683 r = MsiCloseHandle(view); 4684 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4685 4686 /* no where condition */ 4687 query = "UPDATE `Control` SET `Text` = 'this is text'"; 4688 r = MsiDatabaseOpenViewA(hdb, query, &view); 4689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4690 r = MsiViewExecute(view, 0); 4691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4692 r = MsiViewClose(view); 4693 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4694 r = MsiCloseHandle(view); 4695 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4696 4697 /* check the modified text */ 4698 query = "SELECT `Text` FROM `Control`"; 4699 r = MsiDatabaseOpenViewA(hdb, query, &view); 4700 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4701 r = MsiViewExecute(view, 0); 4702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4703 4704 r = MsiViewFetch(view, &rec); 4705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4706 4707 size = MAX_PATH; 4708 r = MsiRecordGetStringA(rec, 1, result, &size); 4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4710 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4711 4712 MsiCloseHandle(rec); 4713 4714 r = MsiViewFetch(view, &rec); 4715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4716 4717 size = MAX_PATH; 4718 r = MsiRecordGetStringA(rec, 1, result, &size); 4719 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4720 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4721 4722 MsiCloseHandle(rec); 4723 4724 r = MsiViewFetch(view, &rec); 4725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4726 4727 size = MAX_PATH; 4728 r = MsiRecordGetStringA(rec, 1, result, &size); 4729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4730 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4731 4732 MsiCloseHandle(rec); 4733 4734 r = MsiViewFetch(view, &rec); 4735 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4736 4737 r = MsiViewClose(view); 4738 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4739 r = MsiCloseHandle(view); 4740 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4741 4742 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, " 4743 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)"; 4744 r = run_query(hdb, 0, query); 4745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4746 4747 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4748 "VALUES('one', 'two', 3)"; 4749 r = run_query(hdb, 0, query); 4750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4751 4752 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4753 "VALUES('three', 'four', 5)"; 4754 r = run_query(hdb, 0, query); 4755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4756 4757 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4758 "VALUES('six', 'two', 7)"; 4759 r = run_query(hdb, 0, query); 4760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4761 4762 rec = MsiCreateRecord(2); 4763 MsiRecordSetInteger(rec, 1, 8); 4764 MsiRecordSetStringA(rec, 2, "two"); 4765 4766 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?"; 4767 r = run_query(hdb, rec, query); 4768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4769 4770 MsiCloseHandle(rec); 4771 4772 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`"; 4773 r = MsiDatabaseOpenViewA(hdb, query, &view); 4774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4775 r = MsiViewExecute(view, 0); 4776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4777 4778 r = MsiViewFetch(view, &rec); 4779 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4780 4781 r = MsiRecordGetInteger(rec, 1); 4782 ok(r == 8, "Expected 8, got %d\n", r); 4783 4784 MsiCloseHandle(rec); 4785 4786 r = MsiViewFetch(view, &rec); 4787 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4788 4789 r = MsiRecordGetInteger(rec, 1); 4790 ok(r == 8, "Expected 8, got %d\n", r); 4791 4792 MsiCloseHandle(rec); 4793 4794 r = MsiViewFetch(view, &rec); 4795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4796 4797 r = MsiRecordGetInteger(rec, 1); 4798 ok(r == 5, "Expected 5, got %d\n", r); 4799 4800 MsiCloseHandle(rec); 4801 4802 r = MsiViewFetch(view, &rec); 4803 ok(r == ERROR_NO_MORE_ITEMS, "Expectd ERROR_NO_MORE_ITEMS, got %d\n", r); 4804 4805 MsiViewClose(view); 4806 MsiCloseHandle(view); 4807 4808 r = MsiDatabaseCommit(hdb); 4809 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4810 r = MsiCloseHandle(hdb); 4811 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4812 4813 DeleteFileA(msifile); 4814 } 4815 4816 static void test_special_tables(void) 4817 { 4818 const char *query; 4819 MSIHANDLE hdb = 0; 4820 UINT r; 4821 4822 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4823 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4824 4825 query = "CREATE TABLE `_Properties` ( " 4826 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4827 r = run_query(hdb, 0, query); 4828 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4829 4830 query = "CREATE TABLE `_Storages` ( " 4831 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4832 r = run_query(hdb, 0, query); 4833 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4834 4835 query = "CREATE TABLE `_Streams` ( " 4836 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4837 r = run_query(hdb, 0, query); 4838 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4839 4840 query = "CREATE TABLE `_Tables` ( " 4841 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4842 r = run_query(hdb, 0, query); 4843 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n"); 4844 4845 query = "CREATE TABLE `_Columns` ( " 4846 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4847 r = run_query(hdb, 0, query); 4848 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n"); 4849 4850 r = MsiCloseHandle(hdb); 4851 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4852 } 4853 4854 static void test_tables_order(void) 4855 { 4856 const char *query; 4857 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 4858 UINT r; 4859 char buffer[100]; 4860 DWORD sz; 4861 4862 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4863 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4864 4865 query = "CREATE TABLE `foo` ( " 4866 "`baz` INT NOT NULL PRIMARY KEY `baz`)"; 4867 r = run_query(hdb, 0, query); 4868 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4869 4870 query = "CREATE TABLE `bar` ( " 4871 "`foo` INT NOT NULL PRIMARY KEY `foo`)"; 4872 r = run_query(hdb, 0, query); 4873 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4874 4875 query = "CREATE TABLE `baz` ( " 4876 "`bar` INT NOT NULL, " 4877 "`baz` INT NOT NULL, " 4878 "`foo` INT NOT NULL PRIMARY KEY `bar`)"; 4879 r = run_query(hdb, 0, query); 4880 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4881 4882 /* The names of the tables in the _Tables table must 4883 be in the same order as these names are created in 4884 the strings table. */ 4885 query = "SELECT * FROM `_Tables`"; 4886 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4887 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4888 r = MsiViewExecute(hview, 0); 4889 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4890 4891 r = MsiViewFetch(hview, &hrec); 4892 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4893 sz = sizeof(buffer); 4894 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4896 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4897 r = MsiCloseHandle(hrec); 4898 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4899 4900 r = MsiViewFetch(hview, &hrec); 4901 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4902 sz = sizeof(buffer); 4903 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4904 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4905 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4906 r = MsiCloseHandle(hrec); 4907 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4908 4909 r = MsiViewFetch(hview, &hrec); 4910 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4911 sz = sizeof(buffer); 4912 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4914 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4915 r = MsiCloseHandle(hrec); 4916 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4917 4918 r = MsiViewClose(hview); 4919 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4920 r = MsiCloseHandle(hview); 4921 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4922 4923 /* The names of the tables in the _Columns table must 4924 be in the same order as these names are created in 4925 the strings table. */ 4926 query = "SELECT * FROM `_Columns`"; 4927 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4928 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4929 r = MsiViewExecute(hview, 0); 4930 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4931 4932 r = MsiViewFetch(hview, &hrec); 4933 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4934 sz = sizeof(buffer); 4935 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4937 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4938 sz = sizeof(buffer); 4939 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4941 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4942 r = MsiCloseHandle(hrec); 4943 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4944 4945 r = MsiViewFetch(hview, &hrec); 4946 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4947 sz = sizeof(buffer); 4948 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4949 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4950 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4951 sz = sizeof(buffer); 4952 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4954 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4955 r = MsiCloseHandle(hrec); 4956 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4957 4958 r = MsiViewFetch(hview, &hrec); 4959 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4960 sz = sizeof(buffer); 4961 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4963 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4964 sz = sizeof(buffer); 4965 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4967 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4968 r = MsiCloseHandle(hrec); 4969 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4970 4971 r = MsiViewFetch(hview, &hrec); 4972 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4973 sz = sizeof(buffer); 4974 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4976 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4977 sz = sizeof(buffer); 4978 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4979 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4980 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4981 r = MsiCloseHandle(hrec); 4982 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4983 4984 r = MsiViewFetch(hview, &hrec); 4985 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4986 sz = sizeof(buffer); 4987 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4989 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4990 sz = sizeof(buffer); 4991 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4993 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4994 r = MsiCloseHandle(hrec); 4995 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4996 4997 r = MsiViewClose(hview); 4998 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4999 r = MsiCloseHandle(hview); 5000 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5001 5002 r = MsiCloseHandle(hdb); 5003 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5004 5005 DeleteFileA(msifile); 5006 } 5007 5008 static void test_rows_order(void) 5009 { 5010 const char *query; 5011 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5012 UINT r; 5013 char buffer[100]; 5014 DWORD sz; 5015 5016 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5017 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5018 5019 query = "CREATE TABLE `foo` ( " 5020 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)"; 5021 r = run_query(hdb, 0, query); 5022 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5023 5024 r = run_query(hdb, 0, "INSERT INTO `foo` " 5025 "( `bar` ) VALUES ( 'A' )"); 5026 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5027 5028 r = run_query(hdb, 0, "INSERT INTO `foo` " 5029 "( `bar` ) VALUES ( 'B' )"); 5030 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5031 5032 r = run_query(hdb, 0, "INSERT INTO `foo` " 5033 "( `bar` ) VALUES ( 'C' )"); 5034 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5035 5036 r = run_query(hdb, 0, "INSERT INTO `foo` " 5037 "( `bar` ) VALUES ( 'D' )"); 5038 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5039 5040 r = run_query(hdb, 0, "INSERT INTO `foo` " 5041 "( `bar` ) VALUES ( 'E' )"); 5042 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5043 5044 r = run_query(hdb, 0, "INSERT INTO `foo` " 5045 "( `bar` ) VALUES ( 'F' )"); 5046 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5047 5048 query = "CREATE TABLE `bar` ( " 5049 "`foo` LONGCHAR NOT NULL, " 5050 "`baz` LONGCHAR NOT NULL " 5051 "PRIMARY KEY `foo` )"; 5052 r = run_query(hdb, 0, query); 5053 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5054 5055 r = run_query(hdb, 0, "INSERT INTO `bar` " 5056 "( `foo`, `baz` ) VALUES ( 'C', 'E' )"); 5057 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5058 5059 r = run_query(hdb, 0, "INSERT INTO `bar` " 5060 "( `foo`, `baz` ) VALUES ( 'F', 'A' )"); 5061 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5062 5063 r = run_query(hdb, 0, "INSERT INTO `bar` " 5064 "( `foo`, `baz` ) VALUES ( 'A', 'B' )"); 5065 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5066 5067 r = run_query(hdb, 0, "INSERT INTO `bar` " 5068 "( `foo`, `baz` ) VALUES ( 'D', 'E' )"); 5069 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5070 5071 /* The rows of the table must be ordered by the column values of 5072 each row. For strings, the column value is the string id 5073 in the string table. */ 5074 5075 query = "SELECT * FROM `bar`"; 5076 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5077 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5078 r = MsiViewExecute(hview, 0); 5079 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5080 5081 r = MsiViewFetch(hview, &hrec); 5082 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5083 sz = sizeof(buffer); 5084 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5086 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5087 sz = sizeof(buffer); 5088 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5090 ok(!lstrcmpA(buffer, "B"), "Expected B, got %s\n", buffer); 5091 r = MsiCloseHandle(hrec); 5092 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5093 5094 r = MsiViewFetch(hview, &hrec); 5095 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5096 sz = sizeof(buffer); 5097 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5099 ok(!lstrcmpA(buffer, "C"), "Expected E, got %s\n", buffer); 5100 sz = sizeof(buffer); 5101 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5103 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5104 r = MsiCloseHandle(hrec); 5105 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5106 5107 r = MsiViewFetch(hview, &hrec); 5108 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5109 sz = sizeof(buffer); 5110 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5112 ok(!lstrcmpA(buffer, "D"), "Expected D, got %s\n", buffer); 5113 sz = sizeof(buffer); 5114 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5116 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5117 r = MsiCloseHandle(hrec); 5118 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5119 5120 r = MsiViewFetch(hview, &hrec); 5121 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5122 sz = sizeof(buffer); 5123 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5125 ok(!lstrcmpA(buffer, "F"), "Expected F, got %s\n", buffer); 5126 sz = sizeof(buffer); 5127 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5129 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5130 r = MsiCloseHandle(hrec); 5131 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5132 5133 r = MsiViewClose(hview); 5134 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5135 r = MsiCloseHandle(hview); 5136 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5137 5138 r = MsiCloseHandle(hdb); 5139 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5140 5141 DeleteFileA(msifile); 5142 } 5143 5144 static void test_collation(void) 5145 { 5146 static const WCHAR query1[] = 5147 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5148 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5149 '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0}; 5150 static const WCHAR query2[] = 5151 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5152 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5153 '(','\'',0xe5,'\'',',','\'','D','\'',')',0}; 5154 static const WCHAR query3[] = 5155 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ', 5156 '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',', 5157 ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ', 5158 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0}; 5159 static const WCHAR query4[] = 5160 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ', 5161 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5162 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5163 static const WCHAR query5[] = 5164 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ', 5165 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5166 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5167 static const WCHAR query6[] = 5168 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E', 5169 ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0}; 5170 static const WCHAR letter_C[] = {'C',0}; 5171 static const WCHAR letter_D[] = {'D',0}; 5172 static const WCHAR letter_a_ring[] = {'a',0x30a,0}; 5173 static const WCHAR letter_a_with_ring[] = {0xe5,0}; 5174 const char *query; 5175 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5176 UINT r; 5177 char buffer[100]; 5178 WCHAR bufferW[100]; 5179 DWORD sz; 5180 5181 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5182 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5183 5184 query = "CREATE TABLE `bar` ( " 5185 "`foo` LONGCHAR NOT NULL, " 5186 "`baz` LONGCHAR NOT NULL " 5187 "PRIMARY KEY `foo` )"; 5188 r = run_query(hdb, 0, query); 5189 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5190 5191 r = run_query(hdb, 0, query); 5192 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r); 5193 5194 r = run_query(hdb, 0, "INSERT INTO `bar` " 5195 "( `foo`, `baz` ) VALUES ( '\2', 'A' )"); 5196 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5197 5198 r = run_query(hdb, 0, "INSERT INTO `bar` " 5199 "( `foo`, `baz` ) VALUES ( '\1', 'B' )"); 5200 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5201 5202 r = run_queryW(hdb, 0, query1); 5203 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5204 5205 r = run_queryW(hdb, 0, query2); 5206 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5207 5208 r = run_queryW(hdb, 0, query3); 5209 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5210 5211 r = run_queryW(hdb, 0, query4); 5212 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5213 5214 r = run_queryW(hdb, 0, query5); 5215 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5216 5217 query = "SELECT * FROM `bar`"; 5218 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5219 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5220 r = MsiViewExecute(hview, 0); 5221 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5222 5223 r = MsiViewFetch(hview, &hrec); 5224 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5225 sz = sizeof(buffer); 5226 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5228 ok(!lstrcmpA(buffer, "\2"), "Expected \\2, got '%s'\n", buffer); 5229 sz = sizeof(buffer); 5230 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5232 ok(!lstrcmpA(buffer, "A"), "Expected A, got '%s'\n", buffer); 5233 MsiCloseHandle(hrec); 5234 5235 r = MsiViewFetch(hview, &hrec); 5236 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5237 sz = sizeof(buffer); 5238 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5240 ok(!lstrcmpA(buffer, "\1"), "Expected \\1, got '%s'\n", buffer); 5241 sz = sizeof(buffer); 5242 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5244 ok(!lstrcmpA(buffer, "B"), "Expected B, got '%s'\n", buffer); 5245 MsiCloseHandle(hrec); 5246 5247 r = MsiViewFetch(hview, &hrec); 5248 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5249 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5250 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5252 ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)), 5253 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW)); 5254 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5255 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5257 ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW)); 5258 MsiCloseHandle(hrec); 5259 5260 r = MsiViewFetch(hview, &hrec); 5261 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5262 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5263 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5265 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5266 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5267 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5268 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5270 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5271 MsiCloseHandle(hrec); 5272 5273 r = MsiViewClose(hview); 5274 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5275 r = MsiCloseHandle(hview); 5276 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5277 5278 r = MsiDatabaseOpenViewW(hdb, query6, &hview); 5279 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5280 r = MsiViewExecute(hview, 0); 5281 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5282 5283 r = MsiViewFetch(hview, &hrec); 5284 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5285 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5286 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5288 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5289 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5290 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5291 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5293 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5294 MsiCloseHandle(hrec); 5295 5296 r = MsiViewFetch(hview, &hrec); 5297 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 5298 5299 r = MsiViewClose(hview); 5300 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5301 r = MsiCloseHandle(hview); 5302 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5303 5304 r = MsiCloseHandle(hdb); 5305 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5306 5307 DeleteFileA(msifile); 5308 } 5309 5310 static void test_select_markers(void) 5311 { 5312 MSIHANDLE hdb = 0, rec, view, res; 5313 LPCSTR query; 5314 UINT r; 5315 DWORD size; 5316 CHAR buf[MAX_PATH]; 5317 5318 hdb = create_db(); 5319 ok( hdb, "failed to create db\n"); 5320 5321 r = run_query(hdb, 0, 5322 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)"); 5323 ok(r == S_OK, "cannot create table: %d\n", r); 5324 5325 r = run_query(hdb, 0, "INSERT INTO `Table` " 5326 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )"); 5327 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5328 5329 r = run_query(hdb, 0, "INSERT INTO `Table` " 5330 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )"); 5331 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5332 5333 r = run_query(hdb, 0, "INSERT INTO `Table` " 5334 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )"); 5335 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5336 5337 r = run_query(hdb, 0, "INSERT INTO `Table` " 5338 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )"); 5339 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5340 5341 rec = MsiCreateRecord(2); 5342 MsiRecordSetStringA(rec, 1, "apple"); 5343 MsiRecordSetStringA(rec, 2, "two"); 5344 5345 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`"; 5346 r = MsiDatabaseOpenViewA(hdb, query, &view); 5347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5348 5349 r = MsiViewExecute(view, rec); 5350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5351 5352 r = MsiViewFetch(view, &res); 5353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5354 5355 size = MAX_PATH; 5356 r = MsiRecordGetStringA(res, 1, buf, &size); 5357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5358 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5359 5360 size = MAX_PATH; 5361 r = MsiRecordGetStringA(res, 2, buf, &size); 5362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5363 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5364 5365 r = MsiRecordGetInteger(res, 3); 5366 ok(r == 1, "Expected 1, got %d\n", r); 5367 5368 MsiCloseHandle(res); 5369 5370 r = MsiViewFetch(view, &res); 5371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5372 5373 size = MAX_PATH; 5374 r = MsiRecordGetStringA(res, 1, buf, &size); 5375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5376 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5377 5378 size = MAX_PATH; 5379 r = MsiRecordGetStringA(res, 2, buf, &size); 5380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5381 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5382 5383 r = MsiRecordGetInteger(res, 3); 5384 ok(r == 2, "Expected 2, got %d\n", r); 5385 5386 MsiCloseHandle(res); 5387 5388 r = MsiViewFetch(view, &res); 5389 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5390 5391 MsiCloseHandle(rec); 5392 MsiViewClose(view); 5393 MsiCloseHandle(view); 5394 5395 rec = MsiCreateRecord(2); 5396 MsiRecordSetStringA(rec, 1, "one"); 5397 MsiRecordSetInteger(rec, 2, 1); 5398 5399 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`"; 5400 r = MsiDatabaseOpenViewA(hdb, query, &view); 5401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5402 r = MsiViewExecute(view, rec); 5403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5404 5405 r = MsiViewFetch(view, &res); 5406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5407 5408 size = MAX_PATH; 5409 r = MsiRecordGetStringA(res, 1, buf, &size); 5410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5411 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5412 5413 size = MAX_PATH; 5414 r = MsiRecordGetStringA(res, 2, buf, &size); 5415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5416 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5417 5418 r = MsiRecordGetInteger(res, 3); 5419 ok(r == 2, "Expected 2, got %d\n", r); 5420 5421 MsiCloseHandle(res); 5422 5423 r = MsiViewFetch(view, &res); 5424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5425 5426 size = MAX_PATH; 5427 r = MsiRecordGetStringA(res, 1, buf, &size); 5428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5429 ok(!lstrcmpA(buf, "banana"), "Expected banana, got %s\n", buf); 5430 5431 size = MAX_PATH; 5432 r = MsiRecordGetStringA(res, 2, buf, &size); 5433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5434 ok(!lstrcmpA(buf, "three"), "Expected three, got %s\n", buf); 5435 5436 r = MsiRecordGetInteger(res, 3); 5437 ok(r == 3, "Expected 3, got %d\n", r); 5438 5439 MsiCloseHandle(res); 5440 5441 r = MsiViewFetch(view, &res); 5442 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5443 5444 MsiCloseHandle(rec); 5445 MsiViewClose(view); 5446 MsiCloseHandle(view); 5447 MsiCloseHandle(hdb); 5448 DeleteFileA(msifile); 5449 } 5450 5451 static void test_viewmodify_update(void) 5452 { 5453 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5454 UINT i, test_max, offset, count; 5455 const char *query; 5456 UINT r; 5457 5458 DeleteFileA(msifile); 5459 5460 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5461 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5462 5463 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5464 r = run_query( hdb, 0, query ); 5465 ok(r == ERROR_SUCCESS, "query failed\n"); 5466 5467 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)"; 5468 r = run_query( hdb, 0, query ); 5469 ok(r == ERROR_SUCCESS, "query failed\n"); 5470 5471 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)"; 5472 r = run_query( hdb, 0, query ); 5473 ok(r == ERROR_SUCCESS, "query failed\n"); 5474 5475 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)"; 5476 r = run_query( hdb, 0, query ); 5477 ok(r == ERROR_SUCCESS, "query failed\n"); 5478 5479 query = "SELECT `B` FROM `table`"; 5480 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5481 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5482 r = MsiViewExecute(hview, 0); 5483 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5484 r = MsiViewFetch(hview, &hrec); 5485 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5486 5487 r = MsiRecordSetInteger(hrec, 1, 0); 5488 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5489 5490 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5491 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5492 5493 r = MsiCloseHandle(hrec); 5494 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5495 5496 r = MsiViewClose(hview); 5497 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5498 r = MsiCloseHandle(hview); 5499 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5500 5501 query = "SELECT * FROM `table`"; 5502 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5503 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5504 r = MsiViewExecute(hview, 0); 5505 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5506 r = MsiViewFetch(hview, &hrec); 5507 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5508 5509 r = MsiRecordGetInteger(hrec, 1); 5510 ok(r == 1, "Expected 1, got %d\n", r); 5511 r = MsiRecordGetInteger(hrec, 2); 5512 ok(r == 0, "Expected 0, got %d\n", r); 5513 5514 r = MsiCloseHandle(hrec); 5515 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5516 5517 r = MsiViewFetch(hview, &hrec); 5518 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5519 5520 r = MsiRecordGetInteger(hrec, 1); 5521 ok(r == 3, "Expected 3, got %d\n", r); 5522 r = MsiRecordGetInteger(hrec, 2); 5523 ok(r == 4, "Expected 4, got %d\n", r); 5524 5525 r = MsiCloseHandle(hrec); 5526 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5527 5528 r = MsiViewFetch(hview, &hrec); 5529 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5530 5531 r = MsiRecordGetInteger(hrec, 1); 5532 ok(r == 5, "Expected 5, got %d\n", r); 5533 r = MsiRecordGetInteger(hrec, 2); 5534 ok(r == 6, "Expected 6, got %d\n", r); 5535 5536 r = MsiCloseHandle(hrec); 5537 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5538 5539 r = MsiViewFetch(hview, &hrec); 5540 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5541 5542 r = MsiViewClose(hview); 5543 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5544 r = MsiCloseHandle(hview); 5545 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5546 5547 /* loop through all elements */ 5548 query = "SELECT `B` FROM `table`"; 5549 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5550 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5551 r = MsiViewExecute(hview, 0); 5552 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5553 5554 while (TRUE) 5555 { 5556 r = MsiViewFetch(hview, &hrec); 5557 if (r != ERROR_SUCCESS) 5558 break; 5559 5560 r = MsiRecordSetInteger(hrec, 1, 0); 5561 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5562 5563 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5564 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5565 5566 r = MsiCloseHandle(hrec); 5567 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5568 } 5569 5570 r = MsiViewClose(hview); 5571 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5572 r = MsiCloseHandle(hview); 5573 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5574 5575 query = "SELECT * FROM `table`"; 5576 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5577 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5578 r = MsiViewExecute(hview, 0); 5579 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5580 r = MsiViewFetch(hview, &hrec); 5581 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5582 5583 r = MsiRecordGetInteger(hrec, 1); 5584 ok(r == 1, "Expected 1, got %d\n", r); 5585 r = MsiRecordGetInteger(hrec, 2); 5586 ok(r == 0, "Expected 0, got %d\n", r); 5587 5588 r = MsiCloseHandle(hrec); 5589 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5590 5591 r = MsiViewFetch(hview, &hrec); 5592 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5593 5594 r = MsiRecordGetInteger(hrec, 1); 5595 ok(r == 3, "Expected 3, got %d\n", r); 5596 r = MsiRecordGetInteger(hrec, 2); 5597 ok(r == 0, "Expected 0, got %d\n", r); 5598 5599 r = MsiCloseHandle(hrec); 5600 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5601 5602 r = MsiViewFetch(hview, &hrec); 5603 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5604 5605 r = MsiRecordGetInteger(hrec, 1); 5606 ok(r == 5, "Expected 5, got %d\n", r); 5607 r = MsiRecordGetInteger(hrec, 2); 5608 ok(r == 0, "Expected 0, got %d\n", r); 5609 5610 r = MsiCloseHandle(hrec); 5611 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5612 5613 r = MsiViewFetch(hview, &hrec); 5614 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5615 5616 r = MsiViewClose(hview); 5617 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5618 r = MsiCloseHandle(hview); 5619 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5620 5621 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5622 r = run_query( hdb, 0, query ); 5623 ok(r == ERROR_SUCCESS, "query failed\n"); 5624 5625 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)"; 5626 r = MsiDatabaseOpenViewA( hdb, query, &hview ); 5627 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5628 5629 test_max = 100; 5630 offset = 1234; 5631 for(i = 0; i < test_max; i++) 5632 { 5633 5634 hrec = MsiCreateRecord( 2 ); 5635 MsiRecordSetInteger( hrec, 1, test_max - i ); 5636 MsiRecordSetInteger( hrec, 2, i ); 5637 5638 r = MsiViewExecute( hview, hrec ); 5639 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5640 5641 r = MsiCloseHandle( hrec ); 5642 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5643 } 5644 5645 r = MsiViewClose( hview ); 5646 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5647 r = MsiCloseHandle( hview ); 5648 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5649 5650 /* Update. */ 5651 query = "SELECT * FROM `table2` ORDER BY `B`"; 5652 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5653 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5654 r = MsiViewExecute( hview, 0 ); 5655 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5656 5657 count = 0; 5658 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5659 { 5660 UINT b = MsiRecordGetInteger( hrec, 2 ); 5661 5662 r = MsiRecordSetInteger( hrec, 2, b + offset); 5663 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5664 5665 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec ); 5666 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5667 5668 r = MsiCloseHandle(hrec); 5669 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5670 count++; 5671 } 5672 ok(count == test_max, "Got count %d\n", count); 5673 5674 r = MsiViewClose(hview); 5675 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5676 r = MsiCloseHandle(hview); 5677 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5678 5679 /* Recheck. */ 5680 query = "SELECT * FROM `table2` ORDER BY `B`"; 5681 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5682 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5683 r = MsiViewExecute( hview, 0 ); 5684 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5685 5686 count = 0; 5687 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5688 { 5689 UINT a = MsiRecordGetInteger( hrec, 1 ); 5690 UINT b = MsiRecordGetInteger( hrec, 2 ); 5691 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n", 5692 a, b, test_max - a + offset, b); 5693 5694 r = MsiCloseHandle(hrec); 5695 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5696 count++; 5697 } 5698 ok(count == test_max, "Got count %d\n", count); 5699 5700 r = MsiViewClose(hview); 5701 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5702 r = MsiCloseHandle(hview); 5703 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5704 5705 r = MsiCloseHandle( hdb ); 5706 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5707 } 5708 5709 static void test_viewmodify_assign(void) 5710 { 5711 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5712 const char *query; 5713 UINT r; 5714 5715 /* setup database */ 5716 DeleteFileA(msifile); 5717 5718 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5719 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5720 5721 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5722 r = run_query( hdb, 0, query ); 5723 ok(r == ERROR_SUCCESS, "query failed\n"); 5724 5725 /* assign to view, new primary key */ 5726 query = "SELECT * FROM `table`"; 5727 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5728 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5729 r = MsiViewExecute(hview, 0); 5730 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5731 5732 hrec = MsiCreateRecord(2); 5733 ok(hrec != 0, "MsiCreateRecord failed\n"); 5734 5735 r = MsiRecordSetInteger(hrec, 1, 1); 5736 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5737 r = MsiRecordSetInteger(hrec, 2, 2); 5738 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5739 5740 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5741 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5742 5743 r = MsiCloseHandle(hrec); 5744 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5745 5746 r = MsiViewClose(hview); 5747 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5748 r = MsiCloseHandle(hview); 5749 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5750 5751 query = "SELECT * FROM `table`"; 5752 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5753 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5754 r = MsiViewExecute(hview, 0); 5755 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5756 r = MsiViewFetch(hview, &hrec); 5757 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5758 5759 r = MsiRecordGetInteger(hrec, 1); 5760 ok(r == 1, "Expected 1, got %d\n", r); 5761 r = MsiRecordGetInteger(hrec, 2); 5762 ok(r == 2, "Expected 2, got %d\n", r); 5763 5764 r = MsiCloseHandle(hrec); 5765 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5766 5767 r = MsiViewFetch(hview, &hrec); 5768 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5769 5770 r = MsiViewClose(hview); 5771 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5772 r = MsiCloseHandle(hview); 5773 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5774 5775 /* assign to view, primary key matches */ 5776 query = "SELECT * FROM `table`"; 5777 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5778 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5779 r = MsiViewExecute(hview, 0); 5780 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5781 5782 hrec = MsiCreateRecord(2); 5783 ok(hrec != 0, "MsiCreateRecord failed\n"); 5784 5785 r = MsiRecordSetInteger(hrec, 1, 1); 5786 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5787 r = MsiRecordSetInteger(hrec, 2, 4); 5788 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5789 5790 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5791 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5792 5793 r = MsiCloseHandle(hrec); 5794 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5795 5796 r = MsiViewClose(hview); 5797 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5798 r = MsiCloseHandle(hview); 5799 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5800 5801 query = "SELECT * FROM `table`"; 5802 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5803 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5804 r = MsiViewExecute(hview, 0); 5805 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5806 r = MsiViewFetch(hview, &hrec); 5807 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5808 5809 r = MsiRecordGetInteger(hrec, 1); 5810 ok(r == 1, "Expected 1, got %d\n", r); 5811 r = MsiRecordGetInteger(hrec, 2); 5812 ok(r == 4, "Expected 4, got %d\n", r); 5813 5814 r = MsiCloseHandle(hrec); 5815 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5816 5817 r = MsiViewFetch(hview, &hrec); 5818 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5819 5820 r = MsiViewClose(hview); 5821 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5822 r = MsiCloseHandle(hview); 5823 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5824 5825 /* close database */ 5826 r = MsiCloseHandle( hdb ); 5827 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5828 } 5829 5830 static const WCHAR data10[] = { /* MOO */ 5831 0x8001, 0x000b, 5832 }; 5833 static const WCHAR data11[] = { /* AAR */ 5834 0x8002, 0x8005, 5835 0x000c, 0x000f, 5836 }; 5837 static const char data12[] = /* _StringData */ 5838 "MOOABAARCDonetwofourfive"; 5839 static const WCHAR data13[] = { /* _StringPool */ 5840 /* len, refs */ 5841 0, 0, /* string 0 '' */ 5842 0, 0, /* string 1 '' */ 5843 0, 0, /* string 2 '' */ 5844 0, 0, /* string 3 '' */ 5845 0, 0, /* string 4 '' */ 5846 3, 3, /* string 5 'MOO' */ 5847 1, 1, /* string 6 'A' */ 5848 1, 1, /* string 7 'B' */ 5849 3, 3, /* string 8 'AAR' */ 5850 1, 1, /* string 9 'C' */ 5851 1, 1, /* string a 'D' */ 5852 3, 1, /* string b 'one' */ 5853 3, 1, /* string c 'two' */ 5854 0, 0, /* string d '' */ 5855 4, 1, /* string e 'four' */ 5856 4, 1, /* string f 'five' */ 5857 }; 5858 5859 static void test_stringtable(void) 5860 { 5861 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5862 IStorage *stg = NULL; 5863 IStream *stm; 5864 WCHAR name[0x20]; 5865 HRESULT hr; 5866 const char *query; 5867 char buffer[MAX_PATH]; 5868 WCHAR data[MAX_PATH]; 5869 DWORD sz, read; 5870 UINT r; 5871 5872 static const DWORD mode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE; 5873 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */ 5874 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */ 5875 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 5876 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */ 5877 5878 DeleteFileA(msifile); 5879 5880 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5882 5883 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)"; 5884 r = run_query(hdb, 0, query); 5885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5886 5887 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)"; 5888 r = run_query(hdb, 0, query); 5889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5890 5891 /* insert persistent row */ 5892 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')"; 5893 r = run_query(hdb, 0, query); 5894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5895 5896 /* insert persistent row */ 5897 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')"; 5898 r = run_query(hdb, 0, query); 5899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5900 5901 /* open a view */ 5902 query = "SELECT * FROM `MOO`"; 5903 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5904 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5905 r = MsiViewExecute(hview, 0); 5906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5907 5908 hrec = MsiCreateRecord(2); 5909 5910 r = MsiRecordSetInteger(hrec, 1, 3); 5911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5912 r = MsiRecordSetStringA(hrec, 2, "three"); 5913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5914 5915 /* insert a nonpersistent row */ 5916 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 5917 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5918 5919 r = MsiCloseHandle(hrec); 5920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5921 r = MsiViewClose(hview); 5922 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5923 r = MsiCloseHandle(hview); 5924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5925 5926 /* insert persistent row */ 5927 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')"; 5928 r = run_query(hdb, 0, query); 5929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5930 5931 /* insert persistent row */ 5932 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')"; 5933 r = run_query(hdb, 0, query); 5934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5935 5936 r = MsiDatabaseCommit(hdb); 5937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5938 5939 r = MsiCloseHandle(hdb); 5940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5941 5942 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 5943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5944 5945 query = "SELECT * FROM `MOO`"; 5946 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5948 5949 r = MsiViewExecute(hview, 0); 5950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5951 5952 r = MsiViewFetch(hview, &hrec); 5953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5954 5955 r = MsiRecordGetFieldCount(hrec); 5956 ok(r == 2, "Expected 2, got %d\n", r); 5957 5958 r = MsiRecordGetInteger(hrec, 1); 5959 ok(r == 1, "Expected 1, got %d\n", r); 5960 5961 sz = sizeof(buffer); 5962 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5964 ok(!lstrcmpA(buffer, "one"), "Expected one, got '%s'\n", buffer); 5965 5966 r = MsiCloseHandle(hrec); 5967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5968 5969 r = MsiViewFetch(hview, &hrec); 5970 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5971 5972 r = MsiViewClose(hview); 5973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5974 r = MsiCloseHandle(hview); 5975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5976 r = MsiCloseHandle(hrec); 5977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5978 5979 query = "SELECT * FROM `AAR`"; 5980 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5982 5983 r = MsiViewExecute(hview, 0); 5984 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5985 5986 r = MsiViewFetch(hview, &hrec); 5987 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5988 5989 r = MsiRecordGetFieldCount(hrec); 5990 ok(r == 2, "Expected 2, got %d\n", r); 5991 5992 r = MsiRecordGetInteger(hrec, 1); 5993 ok(r == 2, "Expected 2, got %d\n", r); 5994 5995 sz = sizeof(buffer); 5996 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5998 ok(!lstrcmpA(buffer, "two"), "Expected two, got '%s'\n", buffer); 5999 6000 r = MsiCloseHandle(hrec); 6001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6002 6003 r = MsiViewFetch(hview, &hrec); 6004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6005 6006 r = MsiRecordGetFieldCount(hrec); 6007 ok(r == 2, "Expected 2, got %d\n", r); 6008 6009 r = MsiRecordGetInteger(hrec, 1); 6010 ok(r == 5, "Expected 5, got %d\n", r); 6011 6012 sz = sizeof(buffer); 6013 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 6014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6015 ok(!lstrcmpA(buffer, "five"), "Expected five, got '%s'\n", buffer); 6016 6017 r = MsiCloseHandle(hrec); 6018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6019 6020 r = MsiViewFetch(hview, &hrec); 6021 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6022 6023 r = MsiViewClose(hview); 6024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6025 r = MsiCloseHandle(hview); 6026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6027 r = MsiCloseHandle(hrec); 6028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6029 r = MsiCloseHandle(hdb); 6030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6031 6032 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20); 6033 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg); 6034 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6035 ok(stg != NULL, "Expected non-NULL storage\n"); 6036 6037 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6038 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6039 ok(stm != NULL, "Expected non-NULL stream\n"); 6040 6041 hr = IStream_Read(stm, data, MAX_PATH, &read); 6042 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6043 ok(read == 4, "Expected 4, got %d\n", read); 6044 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n"); 6045 6046 hr = IStream_Release(stm); 6047 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6048 6049 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6050 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6051 ok(stm != NULL, "Expected non-NULL stream\n"); 6052 6053 hr = IStream_Read(stm, data, MAX_PATH, &read); 6054 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6055 ok(read == 8, "Expected 8, got %d\n", read); 6056 todo_wine 6057 { 6058 ok(!memcmp(data, data11, read), "Unexpected data\n"); 6059 } 6060 6061 hr = IStream_Release(stm); 6062 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6063 6064 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6065 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6066 ok(stm != NULL, "Expected non-NULL stream\n"); 6067 6068 hr = IStream_Read(stm, buffer, MAX_PATH, &read); 6069 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6070 ok(read == 24, "Expected 24, got %d\n", read); 6071 ok(!memcmp(buffer, data12, read), "Unexpected data\n"); 6072 6073 hr = IStream_Release(stm); 6074 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6075 6076 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6077 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6078 ok(stm != NULL, "Expected non-NULL stream\n"); 6079 6080 hr = IStream_Read(stm, data, MAX_PATH, &read); 6081 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6082 todo_wine 6083 { 6084 ok(read == 64, "Expected 64, got %d\n", read); 6085 ok(!memcmp(data, data13, read), "Unexpected data\n"); 6086 } 6087 6088 hr = IStream_Release(stm); 6089 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6090 6091 hr = IStorage_Release(stg); 6092 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6093 6094 DeleteFileA(msifile); 6095 } 6096 6097 static void test_viewmodify_delete(void) 6098 { 6099 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 6100 UINT r; 6101 const char *query; 6102 char buffer[0x100]; 6103 DWORD sz; 6104 6105 DeleteFileA(msifile); 6106 6107 /* just MsiOpenDatabase should not create a file */ 6108 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6110 6111 query = "CREATE TABLE `phone` ( " 6112 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 6113 "PRIMARY KEY `id`)"; 6114 r = run_query(hdb, 0, query); 6115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6116 6117 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6118 "VALUES('1', 'Alan', '5030581')"; 6119 r = run_query(hdb, 0, query); 6120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6121 6122 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6123 "VALUES('2', 'Barry', '928440')"; 6124 r = run_query(hdb, 0, query); 6125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6126 6127 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6128 "VALUES('3', 'Cindy', '2937550')"; 6129 r = run_query(hdb, 0, query); 6130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6131 6132 query = "SELECT * FROM `phone` WHERE `id` <= 2"; 6133 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6135 r = MsiViewExecute(hview, 0); 6136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6137 r = MsiViewFetch(hview, &hrec); 6138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6139 6140 /* delete 1 */ 6141 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6143 6144 r = MsiCloseHandle(hrec); 6145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6146 r = MsiViewFetch(hview, &hrec); 6147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6148 6149 /* delete 2 */ 6150 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6152 6153 r = MsiCloseHandle(hrec); 6154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6155 r = MsiViewClose(hview); 6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6157 r = MsiCloseHandle(hview); 6158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6159 6160 query = "SELECT * FROM `phone`"; 6161 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6162 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6163 r = MsiViewExecute(hview, 0); 6164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6165 r = MsiViewFetch(hview, &hrec); 6166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6167 6168 r = MsiRecordGetInteger(hrec, 1); 6169 ok(r == 3, "Expected 3, got %d\n", r); 6170 6171 sz = sizeof(buffer); 6172 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 6173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6174 ok(!lstrcmpA(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer); 6175 6176 sz = sizeof(buffer); 6177 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 6178 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6179 ok(!lstrcmpA(buffer, "2937550"), "Expected 2937550, got %s\n", buffer); 6180 6181 r = MsiCloseHandle(hrec); 6182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6183 6184 r = MsiViewFetch(hview, &hrec); 6185 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6186 6187 r = MsiViewClose(hview); 6188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6189 r = MsiCloseHandle(hview); 6190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6191 r = MsiCloseHandle(hdb); 6192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6193 } 6194 6195 static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0}; 6196 static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; 6197 static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; 6198 6199 static const WCHAR data14[] = { /* _StringPool */ 6200 /* len, refs */ 6201 0, 0, /* string 0 '' */ 6202 }; 6203 6204 static const struct { 6205 LPCWSTR name; 6206 const void *data; 6207 DWORD size; 6208 } database_table_data[] = 6209 { 6210 {_Tables, NULL, 0}, 6211 {_StringData, NULL, 0}, 6212 {_StringPool, data14, sizeof data14}, 6213 }; 6214 6215 static void enum_stream_names(IStorage *stg) 6216 { 6217 IEnumSTATSTG *stgenum = NULL; 6218 IStream *stm; 6219 HRESULT hr; 6220 STATSTG stat; 6221 ULONG n, count; 6222 BYTE data[MAX_PATH]; 6223 BYTE check[MAX_PATH]; 6224 DWORD sz; 6225 6226 memset(check, 'a', MAX_PATH); 6227 6228 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum); 6229 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6230 6231 n = 0; 6232 while(TRUE) 6233 { 6234 count = 0; 6235 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count); 6236 if(FAILED(hr) || !count) 6237 break; 6238 6239 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name), 6240 "Expected table %d name to match\n", n); 6241 6242 stm = NULL; 6243 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL, 6244 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6245 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6246 ok(stm != NULL, "Expected non-NULL stream\n"); 6247 6248 CoTaskMemFree(stat.pwcsName); 6249 6250 sz = MAX_PATH; 6251 memset(data, 'a', MAX_PATH); 6252 hr = IStream_Read(stm, data, sz, &count); 6253 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6254 6255 ok(count == database_table_data[n].size, 6256 "Expected %d, got %d\n", database_table_data[n].size, count); 6257 6258 if (!database_table_data[n].size) 6259 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n"); 6260 else 6261 ok(!memcmp(data, database_table_data[n].data, database_table_data[n].size), 6262 "Expected table %d data to match\n", n); 6263 6264 IStream_Release(stm); 6265 n++; 6266 } 6267 6268 ok(n == 3, "Expected 3, got %d\n", n); 6269 6270 IEnumSTATSTG_Release(stgenum); 6271 } 6272 6273 static void test_defaultdatabase(void) 6274 { 6275 UINT r; 6276 HRESULT hr; 6277 MSIHANDLE hdb; 6278 IStorage *stg = NULL; 6279 6280 DeleteFileA(msifile); 6281 6282 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6284 6285 r = MsiDatabaseCommit(hdb); 6286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6287 6288 MsiCloseHandle(hdb); 6289 6290 hr = StgOpenStorage(msifileW, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 6291 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6292 ok(stg != NULL, "Expected non-NULL stg\n"); 6293 6294 enum_stream_names(stg); 6295 6296 IStorage_Release(stg); 6297 DeleteFileA(msifile); 6298 } 6299 6300 static void test_order(void) 6301 { 6302 MSIHANDLE hdb, hview, hrec; 6303 CHAR buffer[MAX_PATH]; 6304 LPCSTR query; 6305 UINT r, sz; 6306 int val; 6307 6308 hdb = create_db(); 6309 ok(hdb, "failed to create db\n"); 6310 6311 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)"; 6312 r = run_query(hdb, 0, query); 6313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6314 6315 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 6316 r = run_query(hdb, 0, query); 6317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6318 6319 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )"; 6320 r = run_query(hdb, 0, query); 6321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6322 6323 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )"; 6324 r = run_query(hdb, 0, query); 6325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6326 6327 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )"; 6328 r = run_query(hdb, 0, query); 6329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6330 6331 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)"; 6332 r = run_query(hdb, 0, query); 6333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6334 6335 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )"; 6336 r = run_query(hdb, 0, query); 6337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6338 6339 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )"; 6340 r = run_query(hdb, 0, query); 6341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6342 6343 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )"; 6344 r = run_query(hdb, 0, query); 6345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6346 6347 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`"; 6348 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6350 r = MsiViewExecute(hview, 0); 6351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6352 6353 r = MsiViewFetch(hview, &hrec); 6354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6355 6356 val = MsiRecordGetInteger(hrec, 1); 6357 ok(val == 3, "Expected 3, got %d\n", val); 6358 6359 val = MsiRecordGetInteger(hrec, 2); 6360 ok(val == 4, "Expected 3, got %d\n", val); 6361 6362 MsiCloseHandle(hrec); 6363 6364 r = MsiViewFetch(hview, &hrec); 6365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6366 6367 val = MsiRecordGetInteger(hrec, 1); 6368 ok(val == 5, "Expected 5, got %d\n", val); 6369 6370 val = MsiRecordGetInteger(hrec, 2); 6371 ok(val == 6, "Expected 6, got %d\n", val); 6372 6373 MsiCloseHandle(hrec); 6374 6375 r = MsiViewFetch(hview, &hrec); 6376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6377 6378 val = MsiRecordGetInteger(hrec, 1); 6379 ok(val == 1, "Expected 1, got %d\n", val); 6380 6381 val = MsiRecordGetInteger(hrec, 2); 6382 ok(val == 2, "Expected 2, got %d\n", val); 6383 6384 MsiCloseHandle(hrec); 6385 6386 r = MsiViewFetch(hview, &hrec); 6387 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6388 6389 MsiViewClose(hview); 6390 MsiCloseHandle(hview); 6391 6392 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`"; 6393 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6395 r = MsiViewExecute(hview, 0); 6396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6397 6398 r = MsiViewFetch(hview, &hrec); 6399 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6400 6401 val = MsiRecordGetInteger(hrec, 1); 6402 ok(val == 1, "Expected 1, got %d\n", val); 6403 6404 val = MsiRecordGetInteger(hrec, 2); 6405 ok(val == 12, "Expected 12, got %d\n", val); 6406 6407 MsiCloseHandle(hrec); 6408 6409 r = MsiViewFetch(hview, &hrec); 6410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6411 6412 val = MsiRecordGetInteger(hrec, 1); 6413 ok(val == 3, "Expected 3, got %d\n", val); 6414 6415 val = MsiRecordGetInteger(hrec, 2); 6416 ok(val == 12, "Expected 12, got %d\n", val); 6417 6418 MsiCloseHandle(hrec); 6419 6420 r = MsiViewFetch(hview, &hrec); 6421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6422 6423 val = MsiRecordGetInteger(hrec, 1); 6424 ok(val == 5, "Expected 5, got %d\n", val); 6425 6426 val = MsiRecordGetInteger(hrec, 2); 6427 ok(val == 12, "Expected 12, got %d\n", val); 6428 6429 MsiCloseHandle(hrec); 6430 6431 r = MsiViewFetch(hview, &hrec); 6432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6433 6434 val = MsiRecordGetInteger(hrec, 1); 6435 ok(val == 1, "Expected 1, got %d\n", val); 6436 6437 val = MsiRecordGetInteger(hrec, 2); 6438 ok(val == 14, "Expected 14, got %d\n", val); 6439 6440 MsiCloseHandle(hrec); 6441 6442 r = MsiViewFetch(hview, &hrec); 6443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6444 6445 val = MsiRecordGetInteger(hrec, 1); 6446 ok(val == 3, "Expected 3, got %d\n", val); 6447 6448 val = MsiRecordGetInteger(hrec, 2); 6449 ok(val == 14, "Expected 14, got %d\n", val); 6450 6451 MsiCloseHandle(hrec); 6452 6453 r = MsiViewFetch(hview, &hrec); 6454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6455 6456 val = MsiRecordGetInteger(hrec, 1); 6457 ok(val == 5, "Expected 5, got %d\n", val); 6458 6459 val = MsiRecordGetInteger(hrec, 2); 6460 ok(val == 14, "Expected 14, got %d\n", val); 6461 6462 MsiCloseHandle(hrec); 6463 6464 r = MsiViewFetch(hview, &hrec); 6465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6466 6467 val = MsiRecordGetInteger(hrec, 1); 6468 ok(val == 1, "Expected 1, got %d\n", val); 6469 6470 val = MsiRecordGetInteger(hrec, 2); 6471 ok(val == 10, "Expected 10, got %d\n", val); 6472 6473 MsiCloseHandle(hrec); 6474 6475 r = MsiViewFetch(hview, &hrec); 6476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6477 6478 val = MsiRecordGetInteger(hrec, 1); 6479 ok(val == 3, "Expected 3, got %d\n", val); 6480 6481 val = MsiRecordGetInteger(hrec, 2); 6482 ok(val == 10, "Expected 10, got %d\n", val); 6483 6484 MsiCloseHandle(hrec); 6485 6486 r = MsiViewFetch(hview, &hrec); 6487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6488 6489 val = MsiRecordGetInteger(hrec, 1); 6490 ok(val == 5, "Expected 5, got %d\n", val); 6491 6492 val = MsiRecordGetInteger(hrec, 2); 6493 ok(val == 10, "Expected 10, got %d\n", val); 6494 6495 MsiCloseHandle(hrec); 6496 6497 r = MsiViewFetch(hview, &hrec); 6498 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6499 6500 MsiViewClose(hview); 6501 MsiCloseHandle(hview); 6502 6503 query = "SELECT * FROM `Empty` ORDER BY `A`"; 6504 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6506 r = MsiViewExecute(hview, 0); 6507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6508 6509 r = MsiViewFetch(hview, &hrec); 6510 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6511 6512 MsiViewClose(hview); 6513 MsiCloseHandle(hview); 6514 6515 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)"; 6516 r = run_query(hdb, 0, query); 6517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6518 6519 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)"; 6520 r = run_query(hdb, 0, query); 6521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6522 6523 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)"; 6524 r = run_query(hdb, 0, query); 6525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6526 6527 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)"; 6528 r = run_query(hdb, 0, query); 6529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6530 6531 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`"; 6532 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6534 r = MsiViewExecute(hview, 0); 6535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6536 6537 r = MsiViewFetch(hview, &hrec); 6538 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6539 6540 sz = sizeof(buffer); 6541 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 6542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6543 ok(!lstrcmpA(buffer, "dos"), "Expected \"dos\", got \"%s\"\n", buffer); 6544 6545 r = MsiRecordGetInteger(hrec, 2); 6546 ok(r == 3, "Expected 3, got %d\n", r); 6547 6548 MsiCloseHandle(hrec); 6549 6550 r = MsiViewFetch(hview, &hrec); 6551 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6552 6553 MsiViewClose(hview); 6554 MsiCloseHandle(hview); 6555 MsiCloseHandle(hdb); 6556 } 6557 6558 static void test_viewmodify_delete_temporary(void) 6559 { 6560 MSIHANDLE hdb, hview, hrec; 6561 const char *query; 6562 UINT r; 6563 6564 DeleteFileA(msifile); 6565 6566 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6567 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6568 6569 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )"; 6570 r = run_query(hdb, 0, query); 6571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6572 6573 query = "SELECT * FROM `Table`"; 6574 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6575 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6576 r = MsiViewExecute(hview, 0); 6577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6578 6579 hrec = MsiCreateRecord(1); 6580 MsiRecordSetInteger(hrec, 1, 1); 6581 6582 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6584 6585 MsiCloseHandle(hrec); 6586 6587 hrec = MsiCreateRecord(1); 6588 MsiRecordSetInteger(hrec, 1, 2); 6589 6590 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6592 6593 MsiCloseHandle(hrec); 6594 6595 hrec = MsiCreateRecord(1); 6596 MsiRecordSetInteger(hrec, 1, 3); 6597 6598 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6600 6601 MsiCloseHandle(hrec); 6602 6603 hrec = MsiCreateRecord(1); 6604 MsiRecordSetInteger(hrec, 1, 4); 6605 6606 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6608 6609 MsiCloseHandle(hrec); 6610 MsiViewClose(hview); 6611 MsiCloseHandle(hview); 6612 6613 query = "SELECT * FROM `Table` WHERE `A` = 2"; 6614 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6616 r = MsiViewExecute(hview, 0); 6617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6618 r = MsiViewFetch(hview, &hrec); 6619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6620 6621 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6622 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6623 6624 MsiCloseHandle(hrec); 6625 MsiViewClose(hview); 6626 MsiCloseHandle(hview); 6627 6628 query = "SELECT * FROM `Table` WHERE `A` = 3"; 6629 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6631 r = MsiViewExecute(hview, 0); 6632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6633 r = MsiViewFetch(hview, &hrec); 6634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6635 6636 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6638 6639 MsiCloseHandle(hrec); 6640 MsiViewClose(hview); 6641 MsiCloseHandle(hview); 6642 6643 query = "SELECT * FROM `Table` ORDER BY `A`"; 6644 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6646 r = MsiViewExecute(hview, 0); 6647 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6648 6649 r = MsiViewFetch(hview, &hrec); 6650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6651 6652 r = MsiRecordGetInteger(hrec, 1); 6653 ok(r == 1, "Expected 1, got %d\n", r); 6654 6655 MsiCloseHandle(hrec); 6656 6657 r = MsiViewFetch(hview, &hrec); 6658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6659 6660 r = MsiRecordGetInteger(hrec, 1); 6661 ok(r == 4, "Expected 4, got %d\n", r); 6662 6663 MsiCloseHandle(hrec); 6664 6665 r = MsiViewFetch(hview, &hrec); 6666 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6667 6668 MsiViewClose(hview); 6669 MsiCloseHandle(hview); 6670 MsiCloseHandle(hdb); 6671 DeleteFileA(msifile); 6672 } 6673 6674 static void test_deleterow(void) 6675 { 6676 MSIHANDLE hdb, hview, hrec; 6677 const char *query; 6678 char buf[MAX_PATH]; 6679 UINT r; 6680 DWORD size; 6681 6682 DeleteFileA(msifile); 6683 6684 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6686 6687 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6688 r = run_query(hdb, 0, query); 6689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6690 6691 query = "INSERT INTO `Table` (`A`) VALUES ('one')"; 6692 r = run_query(hdb, 0, query); 6693 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6694 6695 query = "INSERT INTO `Table` (`A`) VALUES ('two')"; 6696 r = run_query(hdb, 0, query); 6697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6698 6699 query = "DELETE FROM `Table` WHERE `A` = 'one'"; 6700 r = run_query(hdb, 0, query); 6701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6702 6703 r = MsiDatabaseCommit(hdb); 6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6705 6706 MsiCloseHandle(hdb); 6707 6708 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 6709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6710 6711 query = "SELECT * FROM `Table`"; 6712 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6714 r = MsiViewExecute(hview, 0); 6715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6716 6717 r = MsiViewFetch(hview, &hrec); 6718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6719 6720 size = MAX_PATH; 6721 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6723 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 6724 6725 MsiCloseHandle(hrec); 6726 6727 r = MsiViewFetch(hview, &hrec); 6728 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6729 6730 MsiViewClose(hview); 6731 MsiCloseHandle(hview); 6732 MsiCloseHandle(hdb); 6733 DeleteFileA(msifile); 6734 } 6735 6736 static const CHAR import_dat[] = "A\n" 6737 "s72\n" 6738 "Table\tA\n" 6739 "This is a new 'string' ok\n"; 6740 6741 static void test_quotes(void) 6742 { 6743 MSIHANDLE hdb, hview, hrec; 6744 const char *query; 6745 char buf[MAX_PATH]; 6746 UINT r; 6747 DWORD size; 6748 6749 DeleteFileA(msifile); 6750 6751 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6753 6754 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6755 r = run_query(hdb, 0, query); 6756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6757 6758 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )"; 6759 r = run_query(hdb, 0, query); 6760 ok(r == ERROR_BAD_QUERY_SYNTAX, 6761 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6762 6763 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )"; 6764 r = run_query(hdb, 0, query); 6765 ok(r == ERROR_BAD_QUERY_SYNTAX, 6766 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6767 6768 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )"; 6769 r = run_query(hdb, 0, query); 6770 ok(r == ERROR_BAD_QUERY_SYNTAX, 6771 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6772 6773 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )"; 6774 r = run_query(hdb, 0, query); 6775 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6776 6777 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )"; 6778 r = run_query(hdb, 0, query); 6779 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6780 6781 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )"; 6782 r = run_query(hdb, 0, query); 6783 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6784 6785 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )"; 6786 r = run_query(hdb, 0, query); 6787 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6788 6789 query = "SELECT * FROM `Table`"; 6790 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6792 6793 r = MsiViewExecute(hview, 0); 6794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6795 6796 r = MsiViewFetch(hview, &hrec); 6797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6798 6799 size = MAX_PATH; 6800 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6802 ok(!lstrcmpA(buf, "This is a \"string\" ok"), 6803 "Expected \"This is a \"string\" ok\", got %s\n", buf); 6804 6805 MsiCloseHandle(hrec); 6806 6807 r = MsiViewFetch(hview, &hrec); 6808 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6809 6810 MsiViewClose(hview); 6811 MsiCloseHandle(hview); 6812 6813 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char)); 6814 6815 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt"); 6816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6817 6818 DeleteFileA("import.idt"); 6819 6820 query = "SELECT * FROM `Table`"; 6821 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6823 6824 r = MsiViewExecute(hview, 0); 6825 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6826 6827 r = MsiViewFetch(hview, &hrec); 6828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6829 6830 size = MAX_PATH; 6831 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6833 ok(!lstrcmpA(buf, "This is a new 'string' ok"), 6834 "Expected \"This is a new 'string' ok\", got %s\n", buf); 6835 6836 MsiCloseHandle(hrec); 6837 6838 r = MsiViewFetch(hview, &hrec); 6839 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6840 6841 MsiViewClose(hview); 6842 MsiCloseHandle(hview); 6843 MsiCloseHandle(hdb); 6844 DeleteFileA(msifile); 6845 } 6846 6847 static void test_carriagereturn(void) 6848 { 6849 MSIHANDLE hdb, hview, hrec; 6850 const char *query; 6851 char buf[MAX_PATH]; 6852 UINT r; 6853 DWORD size; 6854 6855 DeleteFileA(msifile); 6856 6857 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6859 6860 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6861 r = run_query(hdb, 0, query); 6862 ok(r == ERROR_BAD_QUERY_SYNTAX, 6863 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6864 6865 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6866 r = run_query(hdb, 0, query); 6867 ok(r == ERROR_BAD_QUERY_SYNTAX, 6868 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6869 6870 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6871 r = run_query(hdb, 0, query); 6872 ok(r == ERROR_BAD_QUERY_SYNTAX, 6873 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6874 6875 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6876 r = run_query(hdb, 0, query); 6877 ok(r == ERROR_BAD_QUERY_SYNTAX, 6878 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6879 6880 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6881 r = run_query(hdb, 0, query); 6882 ok(r == ERROR_BAD_QUERY_SYNTAX, 6883 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6884 6885 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6886 r = run_query(hdb, 0, query); 6887 ok(r == ERROR_BAD_QUERY_SYNTAX, 6888 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6889 6890 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )"; 6891 r = run_query(hdb, 0, query); 6892 ok(r == ERROR_BAD_QUERY_SYNTAX, 6893 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6894 6895 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )"; 6896 r = run_query(hdb, 0, query); 6897 ok(r == ERROR_BAD_QUERY_SYNTAX, 6898 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6899 6900 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )"; 6901 r = run_query(hdb, 0, query); 6902 ok(r == ERROR_BAD_QUERY_SYNTAX, 6903 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6904 6905 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )"; 6906 r = run_query(hdb, 0, query); 6907 ok(r == ERROR_BAD_QUERY_SYNTAX, 6908 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6909 6910 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )"; 6911 r = run_query(hdb, 0, query); 6912 ok(r == ERROR_BAD_QUERY_SYNTAX, 6913 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6914 6915 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )"; 6916 r = run_query(hdb, 0, query); 6917 ok(r == ERROR_BAD_QUERY_SYNTAX, 6918 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6919 6920 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )"; 6921 r = run_query(hdb, 0, query); 6922 ok(r == ERROR_BAD_QUERY_SYNTAX, 6923 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6924 6925 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )"; 6926 r = run_query(hdb, 0, query); 6927 ok(r == ERROR_BAD_QUERY_SYNTAX, 6928 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6929 6930 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )"; 6931 r = run_query(hdb, 0, query); 6932 ok(r == ERROR_BAD_QUERY_SYNTAX, 6933 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6934 6935 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r"; 6936 r = run_query(hdb, 0, query); 6937 ok(r == ERROR_BAD_QUERY_SYNTAX, 6938 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6939 6940 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6941 r = run_query(hdb, 0, query); 6942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6943 6944 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6945 r = run_query(hdb, 0, query); 6946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6947 6948 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6949 r = run_query(hdb, 0, query); 6950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6951 6952 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6953 r = run_query(hdb, 0, query); 6954 ok(r == ERROR_BAD_QUERY_SYNTAX, 6955 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6956 6957 query = "CREATE TABLE `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6958 r = run_query(hdb, 0, query); 6959 ok(r == ERROR_BAD_QUERY_SYNTAX, 6960 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6961 6962 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )"; 6963 r = run_query(hdb, 0, query); 6964 ok(r == ERROR_BAD_QUERY_SYNTAX, 6965 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6966 6967 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )"; 6968 r = run_query(hdb, 0, query); 6969 ok(r == ERROR_BAD_QUERY_SYNTAX, 6970 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6971 6972 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )"; 6973 r = run_query(hdb, 0, query); 6974 ok(r == ERROR_BAD_QUERY_SYNTAX, 6975 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6976 6977 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6978 r = run_query(hdb, 0, query); 6979 ok(r == ERROR_BAD_QUERY_SYNTAX, 6980 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6981 6982 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6983 r = run_query(hdb, 0, query); 6984 ok(r == ERROR_BAD_QUERY_SYNTAX, 6985 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6986 6987 query = "SELECT * FROM `_Tables`"; 6988 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6990 r = MsiViewExecute(hview, 0); 6991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6992 6993 r = MsiViewFetch(hview, &hrec); 6994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6995 6996 size = MAX_PATH; 6997 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6999 ok(!lstrcmpA(buf, "\rOne"), "Expected \"\\rOne\", got \"%s\"\n", buf); 7000 7001 MsiCloseHandle(hrec); 7002 7003 r = MsiViewFetch(hview, &hrec); 7004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7005 7006 size = MAX_PATH; 7007 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7009 ok(!lstrcmpA(buf, "Tw\ro"), "Expected \"Tw\\ro\", got \"%s\"\n", buf); 7010 7011 MsiCloseHandle(hrec); 7012 7013 r = MsiViewFetch(hview, &hrec); 7014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7015 7016 size = MAX_PATH; 7017 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7019 ok(!lstrcmpA(buf, "Three\r"), "Expected \"Three\r\", got \"%s\"\n", buf); 7020 7021 MsiCloseHandle(hrec); 7022 7023 r = MsiViewFetch(hview, &hrec); 7024 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7025 7026 MsiViewClose(hview); 7027 MsiCloseHandle(hview); 7028 7029 MsiCloseHandle(hdb); 7030 DeleteFileA(msifile); 7031 } 7032 7033 static void test_noquotes(void) 7034 { 7035 MSIHANDLE hdb, hview, hrec; 7036 const char *query; 7037 char buf[MAX_PATH]; 7038 UINT r; 7039 DWORD size; 7040 7041 DeleteFileA(msifile); 7042 7043 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7044 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7045 7046 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7047 r = run_query(hdb, 0, query); 7048 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7049 7050 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7051 r = run_query(hdb, 0, query); 7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7053 7054 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )"; 7055 r = run_query(hdb, 0, query); 7056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7057 7058 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )"; 7059 r = run_query(hdb, 0, query); 7060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7061 7062 query = "SELECT * FROM `_Tables`"; 7063 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7065 r = MsiViewExecute(hview, 0); 7066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7067 7068 r = MsiViewFetch(hview, &hrec); 7069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7070 7071 size = MAX_PATH; 7072 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7074 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7075 7076 MsiCloseHandle(hrec); 7077 7078 r = MsiViewFetch(hview, &hrec); 7079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7080 7081 size = MAX_PATH; 7082 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7084 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7085 7086 MsiCloseHandle(hrec); 7087 7088 r = MsiViewFetch(hview, &hrec); 7089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7090 7091 size = MAX_PATH; 7092 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7094 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7095 7096 MsiCloseHandle(hrec); 7097 7098 r = MsiViewFetch(hview, &hrec); 7099 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7100 7101 MsiViewClose(hview); 7102 MsiCloseHandle(hview); 7103 7104 query = "SELECT * FROM `_Columns`"; 7105 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7107 r = MsiViewExecute(hview, 0); 7108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7109 7110 r = MsiViewFetch(hview, &hrec); 7111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7112 7113 size = MAX_PATH; 7114 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7116 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7117 7118 r = MsiRecordGetInteger(hrec, 2); 7119 ok(r == 1, "Expected 1, got %d\n", r); 7120 7121 size = MAX_PATH; 7122 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7124 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7125 7126 MsiCloseHandle(hrec); 7127 7128 r = MsiViewFetch(hview, &hrec); 7129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7130 7131 size = MAX_PATH; 7132 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7134 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7135 7136 r = MsiRecordGetInteger(hrec, 2); 7137 ok(r == 1, "Expected 1, got %d\n", r); 7138 7139 size = MAX_PATH; 7140 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7142 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7143 7144 MsiCloseHandle(hrec); 7145 7146 r = MsiViewFetch(hview, &hrec); 7147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7148 7149 size = MAX_PATH; 7150 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7152 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7153 7154 r = MsiRecordGetInteger(hrec, 2); 7155 ok(r == 1, "Expected 1, got %d\n", r); 7156 7157 size = MAX_PATH; 7158 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7160 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7161 7162 MsiCloseHandle(hrec); 7163 7164 r = MsiViewFetch(hview, &hrec); 7165 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7166 7167 MsiViewClose(hview); 7168 MsiCloseHandle(hview); 7169 7170 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )"; 7171 r = run_query(hdb, 0, query); 7172 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7173 7174 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )"; 7175 r = run_query(hdb, 0, query); 7176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7177 7178 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )"; 7179 r = run_query(hdb, 0, query); 7180 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7181 7182 query = "SELECT * FROM Table WHERE `A` = 'hi'"; 7183 r = run_query(hdb, 0, query); 7184 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7185 7186 query = "SELECT * FROM `Table` WHERE `A` = hi"; 7187 r = run_query(hdb, 0, query); 7188 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7189 7190 query = "SELECT * FROM Table"; 7191 r = run_query(hdb, 0, query); 7192 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7193 7194 query = "SELECT * FROM Table2"; 7195 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7197 r = MsiViewExecute(hview, 0); 7198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7199 7200 r = MsiViewFetch(hview, &hrec); 7201 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7202 7203 MsiViewClose(hview); 7204 MsiCloseHandle(hview); 7205 7206 query = "SELECT * FROM `Table` WHERE A = 'hi'"; 7207 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7209 r = MsiViewExecute(hview, 0); 7210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7211 7212 r = MsiViewFetch(hview, &hrec); 7213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7214 7215 size = MAX_PATH; 7216 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7218 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 7219 7220 MsiCloseHandle(hrec); 7221 7222 r = MsiViewFetch(hview, &hrec); 7223 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7224 7225 MsiViewClose(hview); 7226 MsiCloseHandle(hview); 7227 MsiCloseHandle(hdb); 7228 DeleteFileA(msifile); 7229 } 7230 7231 static void read_file_data(LPCSTR filename, LPSTR buffer) 7232 { 7233 HANDLE file; 7234 DWORD read; 7235 7236 file = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); 7237 ZeroMemory(buffer, MAX_PATH); 7238 ReadFile(file, buffer, MAX_PATH, &read, NULL); 7239 CloseHandle(file); 7240 } 7241 7242 static void test_forcecodepage(void) 7243 { 7244 MSIHANDLE hdb; 7245 const char *query; 7246 char buffer[MAX_PATH]; 7247 UINT r; 7248 7249 DeleteFileA(msifile); 7250 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 7251 7252 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7254 7255 query = "SELECT * FROM `_ForceCodepage`"; 7256 r = run_query(hdb, 0, query); 7257 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7258 7259 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7260 r = run_query(hdb, 0, query); 7261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7262 7263 query = "SELECT * FROM `_ForceCodepage`"; 7264 r = run_query(hdb, 0, query); 7265 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7266 7267 r = MsiDatabaseCommit(hdb); 7268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7269 7270 query = "SELECT * FROM `_ForceCodepage`"; 7271 r = run_query(hdb, 0, query); 7272 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7273 7274 MsiCloseHandle(hdb); 7275 7276 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 7277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7278 7279 query = "SELECT * FROM `_ForceCodepage`"; 7280 r = run_query(hdb, 0, query); 7281 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7282 7283 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7285 7286 read_file_data("forcecodepage.idt", buffer); 7287 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), 7288 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7289 7290 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 7291 7292 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7294 7295 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7297 7298 read_file_data("forcecodepage.idt", buffer); 7299 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), 7300 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7301 7302 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0); 7303 7304 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7305 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7306 7307 MsiCloseHandle(hdb); 7308 DeleteFileA(msifile); 7309 DeleteFileA("forcecodepage.idt"); 7310 } 7311 7312 static void test_viewmodify_refresh(void) 7313 { 7314 MSIHANDLE hdb, hview, hrec; 7315 const char *query; 7316 char buffer[MAX_PATH]; 7317 UINT r; 7318 DWORD size; 7319 7320 DeleteFileA(msifile); 7321 7322 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7324 7325 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )"; 7326 r = run_query(hdb, 0, query); 7327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7328 7329 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 7330 r = run_query(hdb, 0, query); 7331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7332 7333 query = "SELECT * FROM `Table`"; 7334 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7336 r = MsiViewExecute(hview, 0); 7337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7338 7339 r = MsiViewFetch(hview, &hrec); 7340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7341 7342 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'"; 7343 r = run_query(hdb, 0, query); 7344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7345 7346 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7348 7349 size = MAX_PATH; 7350 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7352 ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer); 7353 ok(size == 2, "Expected 2, got %d\n", size); 7354 7355 r = MsiRecordGetInteger(hrec, 2); 7356 ok(r == 2, "Expected 2, got %d\n", r); 7357 7358 MsiCloseHandle(hrec); 7359 MsiViewClose(hview); 7360 MsiCloseHandle(hview); 7361 7362 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )"; 7363 r = run_query(hdb, 0, query); 7364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7365 7366 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7367 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7369 r = MsiViewExecute(hview, 0); 7370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7371 7372 r = MsiViewFetch(hview, &hrec); 7373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7374 7375 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'"; 7376 r = run_query(hdb, 0, query); 7377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7378 7379 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )"; 7380 r = run_query(hdb, 0, query); 7381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7382 7383 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7385 7386 size = MAX_PATH; 7387 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7389 ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer); 7390 ok(size == 5, "Expected 5, got %d\n", size); 7391 7392 r = MsiRecordGetInteger(hrec, 2); 7393 ok(r == 2, "Expected 2, got %d\n", r); 7394 7395 MsiCloseHandle(hrec); 7396 MsiViewClose(hview); 7397 MsiCloseHandle(hview); 7398 MsiCloseHandle(hdb); 7399 DeleteFileA(msifile); 7400 } 7401 7402 static void test_where_viewmodify(void) 7403 { 7404 MSIHANDLE hdb, hview, hrec; 7405 const char *query; 7406 UINT r; 7407 7408 DeleteFileA(msifile); 7409 7410 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7412 7413 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 7414 r = run_query(hdb, 0, query); 7415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7416 7417 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )"; 7418 r = run_query(hdb, 0, query); 7419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7420 7421 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )"; 7422 r = run_query(hdb, 0, query); 7423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7424 7425 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )"; 7426 r = run_query(hdb, 0, query); 7427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7428 7429 /* `B` = 3 doesn't match, but the view shouldn't be executed */ 7430 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7431 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7433 7434 hrec = MsiCreateRecord(2); 7435 MsiRecordSetInteger(hrec, 1, 7); 7436 MsiRecordSetInteger(hrec, 2, 8); 7437 7438 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 7439 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7440 7441 MsiCloseHandle(hrec); 7442 MsiViewClose(hview); 7443 MsiCloseHandle(hview); 7444 7445 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7446 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7448 r = MsiViewExecute(hview, 0); 7449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7450 7451 r = MsiViewFetch(hview, &hrec); 7452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7453 7454 r = MsiRecordGetInteger(hrec, 1); 7455 ok(r == 7, "Expected 7, got %d\n", r); 7456 7457 r = MsiRecordGetInteger(hrec, 2); 7458 ok(r == 8, "Expected 8, got %d\n", r); 7459 7460 MsiRecordSetInteger(hrec, 2, 9); 7461 7462 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 7463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7464 7465 MsiCloseHandle(hrec); 7466 MsiViewClose(hview); 7467 MsiCloseHandle(hview); 7468 7469 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7470 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7472 r = MsiViewExecute(hview, 0); 7473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7474 7475 r = MsiViewFetch(hview, &hrec); 7476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7477 7478 r = MsiRecordGetInteger(hrec, 1); 7479 ok(r == 7, "Expected 7, got %d\n", r); 7480 7481 r = MsiRecordGetInteger(hrec, 2); 7482 ok(r == 9, "Expected 9, got %d\n", r); 7483 7484 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7"; 7485 r = run_query(hdb, 0, query); 7486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7487 7488 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7490 7491 r = MsiRecordGetInteger(hrec, 1); 7492 ok(r == 7, "Expected 7, got %d\n", r); 7493 7494 r = MsiRecordGetInteger(hrec, 2); 7495 ok(r == 10, "Expected 10, got %d\n", r); 7496 7497 MsiCloseHandle(hrec); 7498 MsiViewClose(hview); 7499 MsiCloseHandle(hview); 7500 MsiCloseHandle(hdb); 7501 } 7502 7503 static BOOL create_storage(LPCSTR name) 7504 { 7505 WCHAR nameW[MAX_PATH]; 7506 IStorage *stg; 7507 IStream *stm; 7508 HRESULT hr; 7509 DWORD count; 7510 BOOL res = FALSE; 7511 7512 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, MAX_PATH); 7513 hr = StgCreateDocfile(nameW, STGM_CREATE | STGM_READWRITE | 7514 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &stg); 7515 if (FAILED(hr)) 7516 return FALSE; 7517 7518 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 7519 0, 0, &stm); 7520 if (FAILED(hr)) 7521 goto done; 7522 7523 hr = IStream_Write(stm, "stgdata", 8, &count); 7524 if (SUCCEEDED(hr)) 7525 res = TRUE; 7526 7527 done: 7528 IStream_Release(stm); 7529 IStorage_Release(stg); 7530 7531 return res; 7532 } 7533 7534 static void test_storages_table(void) 7535 { 7536 MSIHANDLE hdb, hview, hrec; 7537 IStorage *stg, *inner; 7538 IStream *stm; 7539 char file[MAX_PATH]; 7540 char buf[MAX_PATH]; 7541 WCHAR name[MAX_PATH]; 7542 LPCSTR query; 7543 HRESULT hr; 7544 DWORD size; 7545 UINT r; 7546 7547 hdb = create_db(); 7548 ok(hdb, "failed to create db\n"); 7549 7550 r = MsiDatabaseCommit(hdb); 7551 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 7552 7553 MsiCloseHandle(hdb); 7554 7555 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb); 7556 ok(r == ERROR_SUCCESS , "Failed to open database\n"); 7557 7558 /* check the column types */ 7559 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES); 7560 ok(hrec, "failed to get column info hrecord\n"); 7561 ok(check_record(hrec, 1, "s62"), "wrong hrecord type\n"); 7562 ok(check_record(hrec, 2, "V0"), "wrong hrecord type\n"); 7563 7564 MsiCloseHandle(hrec); 7565 7566 /* now try the names */ 7567 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES); 7568 ok(hrec, "failed to get column info hrecord\n"); 7569 ok(check_record(hrec, 1, "Name"), "wrong hrecord type\n"); 7570 ok(check_record(hrec, 2, "Data"), "wrong hrecord type\n"); 7571 7572 MsiCloseHandle(hrec); 7573 7574 create_storage("storage.bin"); 7575 7576 hrec = MsiCreateRecord(2); 7577 MsiRecordSetStringA(hrec, 1, "stgname"); 7578 7579 r = MsiRecordSetStreamA(hrec, 2, "storage.bin"); 7580 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r); 7581 7582 DeleteFileA("storage.bin"); 7583 7584 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)"; 7585 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7586 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7587 7588 r = MsiViewExecute(hview, hrec); 7589 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7590 7591 MsiCloseHandle(hrec); 7592 MsiViewClose(hview); 7593 MsiCloseHandle(hview); 7594 7595 query = "SELECT `Name`, `Data` FROM `_Storages`"; 7596 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7597 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7598 7599 r = MsiViewExecute(hview, 0); 7600 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7601 7602 r = MsiViewFetch(hview, &hrec); 7603 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r); 7604 7605 size = MAX_PATH; 7606 r = MsiRecordGetStringA(hrec, 1, file, &size); 7607 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 7608 ok(!lstrcmpA(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file); 7609 7610 size = MAX_PATH; 7611 lstrcpyA(buf, "apple"); 7612 r = MsiRecordReadStream(hrec, 2, buf, &size); 7613 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r); 7614 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); 7615 ok(size == 0, "Expected 0, got %d\n", size); 7616 7617 MsiCloseHandle(hrec); 7618 7619 r = MsiViewFetch(hview, &hrec); 7620 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7621 7622 MsiViewClose(hview); 7623 MsiCloseHandle(hview); 7624 7625 MsiDatabaseCommit(hdb); 7626 MsiCloseHandle(hdb); 7627 7628 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, MAX_PATH); 7629 hr = StgOpenStorage(name, NULL, STGM_DIRECT | STGM_READ | 7630 STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 7631 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7632 ok(stg != NULL, "Expected non-NULL storage\n"); 7633 7634 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH); 7635 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 7636 NULL, 0, &inner); 7637 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7638 ok(inner != NULL, "Expected non-NULL storage\n"); 7639 7640 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH); 7641 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 7642 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7643 ok(stm != NULL, "Expected non-NULL stream\n"); 7644 7645 hr = IStream_Read(stm, buf, MAX_PATH, &size); 7646 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 7647 ok(size == 8, "Expected 8, got %d\n", size); 7648 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf); 7649 7650 IStream_Release(stm); 7651 IStorage_Release(inner); 7652 7653 IStorage_Release(stg); 7654 DeleteFileA(msifile); 7655 } 7656 7657 static void test_dbtopackage(void) 7658 { 7659 MSIHANDLE hdb, hpkg; 7660 CHAR package[12], buf[MAX_PATH]; 7661 DWORD size; 7662 UINT r; 7663 7664 /* create an empty database, transact mode */ 7665 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7666 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7667 7668 set_summary_info(hdb); 7669 7670 r = create_directory_table(hdb); 7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7672 7673 r = create_custom_action_table(hdb); 7674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7675 7676 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7678 7679 sprintf(package, "#%u", hdb); 7680 r = MsiOpenPackageA(package, &hpkg); 7681 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7682 { 7683 skip("Not enough rights to perform tests\n"); 7684 goto error; 7685 } 7686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7687 7688 /* property is not set yet */ 7689 size = MAX_PATH; 7690 lstrcpyA(buf, "kiwi"); 7691 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7693 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7694 ok(size == 0, "Expected 0, got %d\n", size); 7695 7696 /* run the custom action to set the property */ 7697 r = MsiDoActionA(hpkg, "SetProp"); 7698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7699 7700 /* property is now set */ 7701 size = MAX_PATH; 7702 lstrcpyA(buf, "kiwi"); 7703 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7705 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7706 ok(size == 5, "Expected 5, got %d\n", size); 7707 7708 MsiCloseHandle(hpkg); 7709 7710 /* reset the package */ 7711 r = MsiOpenPackageA(package, &hpkg); 7712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7713 7714 /* property is not set anymore */ 7715 size = MAX_PATH; 7716 lstrcpyA(buf, "kiwi"); 7717 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7719 todo_wine 7720 { 7721 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7722 ok(size == 0, "Expected 0, got %d\n", size); 7723 } 7724 7725 MsiCloseHandle(hdb); 7726 MsiCloseHandle(hpkg); 7727 7728 /* create an empty database, direct mode */ 7729 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb); 7730 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7731 7732 set_summary_info(hdb); 7733 7734 r = create_directory_table(hdb); 7735 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7736 7737 r = create_custom_action_table(hdb); 7738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7739 7740 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7742 7743 sprintf(package, "#%u", hdb); 7744 r = MsiOpenPackageA(package, &hpkg); 7745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7746 7747 /* property is not set yet */ 7748 size = MAX_PATH; 7749 lstrcpyA(buf, "kiwi"); 7750 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7751 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7752 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7753 ok(size == 0, "Expected 0, got %d\n", size); 7754 7755 /* run the custom action to set the property */ 7756 r = MsiDoActionA(hpkg, "SetProp"); 7757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7758 7759 /* property is now set */ 7760 size = MAX_PATH; 7761 lstrcpyA(buf, "kiwi"); 7762 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7764 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7765 ok(size == 5, "Expected 5, got %d\n", size); 7766 7767 MsiCloseHandle(hpkg); 7768 7769 /* reset the package */ 7770 r = MsiOpenPackageA(package, &hpkg); 7771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7772 7773 /* property is not set anymore */ 7774 size = MAX_PATH; 7775 lstrcpyA(buf, "kiwi"); 7776 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7777 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7778 todo_wine 7779 { 7780 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7781 ok(size == 0, "Expected 0, got %d\n", size); 7782 } 7783 7784 MsiCloseHandle(hpkg); 7785 7786 error: 7787 MsiCloseHandle(hdb); 7788 DeleteFileA(msifile); 7789 } 7790 7791 static void test_droptable(void) 7792 { 7793 MSIHANDLE hdb, hview, hrec; 7794 CHAR buf[MAX_PATH]; 7795 LPCSTR query; 7796 DWORD size; 7797 UINT r; 7798 7799 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7801 7802 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7803 r = run_query(hdb, 0, query); 7804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7805 7806 query = "SELECT * FROM `One`"; 7807 r = do_query(hdb, query, &hrec); 7808 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7809 7810 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7811 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7813 r = MsiViewExecute(hview, 0); 7814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7815 7816 r = MsiViewFetch(hview, &hrec); 7817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7818 7819 size = MAX_PATH; 7820 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7821 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7822 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7823 7824 MsiCloseHandle(hrec); 7825 MsiViewClose(hview); 7826 MsiCloseHandle(hview); 7827 7828 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7829 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7831 r = MsiViewExecute(hview, 0); 7832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7833 7834 r = MsiViewFetch(hview, &hrec); 7835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7836 7837 size = MAX_PATH; 7838 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7840 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7841 7842 r = MsiRecordGetInteger(hrec, 2); 7843 ok(r == 1, "Expected 1, got %d\n", r); 7844 7845 size = MAX_PATH; 7846 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7848 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7849 7850 MsiCloseHandle(hrec); 7851 7852 r = MsiViewFetch(hview, &hrec); 7853 ok(r == ERROR_NO_MORE_ITEMS, 7854 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7855 7856 MsiViewClose(hview); 7857 MsiCloseHandle(hview); 7858 7859 query = "DROP `One`"; 7860 r = run_query(hdb, 0, query); 7861 ok(r == ERROR_BAD_QUERY_SYNTAX, 7862 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7863 7864 query = "DROP TABLE"; 7865 r = run_query(hdb, 0, query); 7866 ok(r == ERROR_BAD_QUERY_SYNTAX, 7867 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7868 7869 query = "DROP TABLE `One`"; 7870 hview = 0; 7871 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7873 r = MsiViewExecute(hview, 0); 7874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7875 7876 r = MsiViewFetch(hview, &hrec); 7877 ok(r == ERROR_FUNCTION_FAILED, 7878 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7879 7880 MsiViewClose(hview); 7881 MsiCloseHandle(hview); 7882 7883 query = "SELECT * FROM `IDontExist`"; 7884 r = do_query(hdb, query, &hrec); 7885 ok(r == ERROR_BAD_QUERY_SYNTAX, 7886 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7887 7888 query = "SELECT * FROM `One`"; 7889 r = do_query(hdb, query, &hrec); 7890 ok(r == ERROR_BAD_QUERY_SYNTAX, 7891 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7892 7893 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7894 r = run_query(hdb, 0, query); 7895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7896 7897 query = "DROP TABLE One"; 7898 r = run_query(hdb, 0, query); 7899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7900 7901 query = "SELECT * FROM `One`"; 7902 r = do_query(hdb, query, &hrec); 7903 ok(r == ERROR_BAD_QUERY_SYNTAX, 7904 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7905 7906 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7907 r = do_query(hdb, query, &hrec); 7908 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7909 7910 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7911 r = do_query(hdb, query, &hrec); 7912 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7913 7914 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )"; 7915 r = run_query(hdb, 0, query); 7916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7917 7918 query = "SELECT * FROM `One`"; 7919 r = do_query(hdb, query, &hrec); 7920 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7921 7922 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7923 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7925 r = MsiViewExecute(hview, 0); 7926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7927 7928 r = MsiViewFetch(hview, &hrec); 7929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7930 7931 size = MAX_PATH; 7932 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7933 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7934 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7935 7936 MsiCloseHandle(hrec); 7937 MsiViewClose(hview); 7938 MsiCloseHandle(hview); 7939 7940 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7941 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7943 r = MsiViewExecute(hview, 0); 7944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7945 7946 r = MsiViewFetch(hview, &hrec); 7947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7948 7949 size = MAX_PATH; 7950 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7951 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7952 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7953 7954 r = MsiRecordGetInteger(hrec, 2); 7955 ok(r == 1, "Expected 1, got %d\n", r); 7956 7957 size = MAX_PATH; 7958 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7960 ok(!lstrcmpA(buf, "B"), "Expected \"B\", got \"%s\"\n", buf); 7961 7962 MsiCloseHandle(hrec); 7963 7964 r = MsiViewFetch(hview, &hrec); 7965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7966 7967 size = MAX_PATH; 7968 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7970 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7971 7972 r = MsiRecordGetInteger(hrec, 2); 7973 ok(r == 2, "Expected 2, got %d\n", r); 7974 7975 size = MAX_PATH; 7976 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7978 ok(!lstrcmpA(buf, "C"), "Expected \"C\", got \"%s\"\n", buf); 7979 7980 MsiCloseHandle(hrec); 7981 7982 r = MsiViewFetch(hview, &hrec); 7983 ok(r == ERROR_NO_MORE_ITEMS, 7984 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7985 7986 MsiViewClose(hview); 7987 MsiCloseHandle(hview); 7988 7989 query = "DROP TABLE One"; 7990 r = run_query(hdb, 0, query); 7991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7992 7993 query = "SELECT * FROM `One`"; 7994 r = do_query(hdb, query, &hrec); 7995 ok(r == ERROR_BAD_QUERY_SYNTAX, 7996 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7997 7998 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7999 r = do_query(hdb, query, &hrec); 8000 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8001 8002 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 8003 r = do_query(hdb, query, &hrec); 8004 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8005 8006 MsiCloseHandle(hdb); 8007 DeleteFileA(msifile); 8008 } 8009 8010 static void test_dbmerge(void) 8011 { 8012 static const WCHAR refdbW[] = {'r','e','f','d','b','.','m','s','i',0}; 8013 MSIHANDLE hdb, href, hview, hrec; 8014 CHAR buf[MAX_PATH]; 8015 LPCSTR query; 8016 DWORD size; 8017 UINT r; 8018 8019 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 8020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8021 8022 r = MsiOpenDatabaseW(refdbW, MSIDBOPEN_CREATE, &href); 8023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8024 8025 /* hDatabase is invalid */ 8026 r = MsiDatabaseMergeA(0, href, "MergeErrors"); 8027 ok(r == ERROR_INVALID_HANDLE, 8028 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8029 8030 /* hDatabaseMerge is invalid */ 8031 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors"); 8032 ok(r == ERROR_INVALID_HANDLE, 8033 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8034 8035 /* szTableName is NULL */ 8036 r = MsiDatabaseMergeA(hdb, href, NULL); 8037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8038 8039 /* szTableName is empty */ 8040 r = MsiDatabaseMergeA(hdb, href, ""); 8041 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r); 8042 8043 /* both DBs empty, szTableName is valid */ 8044 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8046 8047 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 8048 r = run_query(hdb, 0, query); 8049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8050 8051 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )"; 8052 r = run_query(href, 0, query); 8053 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8054 8055 /* column types don't match */ 8056 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8057 ok(r == ERROR_DATATYPE_MISMATCH, 8058 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8059 8060 /* nothing in MergeErrors */ 8061 query = "SELECT * FROM `MergeErrors`"; 8062 r = do_query(hdb, query, &hrec); 8063 ok(r == ERROR_BAD_QUERY_SYNTAX, 8064 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8065 8066 query = "DROP TABLE `One`"; 8067 r = run_query(hdb, 0, query); 8068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8069 8070 query = "DROP TABLE `One`"; 8071 r = run_query(href, 0, query); 8072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8073 8074 query = "CREATE TABLE `One` ( " 8075 "`A` CHAR(72), " 8076 "`B` CHAR(56), " 8077 "`C` CHAR(64) LOCALIZABLE, " 8078 "`D` LONGCHAR, " 8079 "`E` CHAR(72) NOT NULL, " 8080 "`F` CHAR(56) NOT NULL, " 8081 "`G` CHAR(64) NOT NULL LOCALIZABLE, " 8082 "`H` LONGCHAR NOT NULL " 8083 "PRIMARY KEY `A` )"; 8084 r = run_query(hdb, 0, query); 8085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8086 8087 query = "CREATE TABLE `One` ( " 8088 "`A` CHAR(64), " 8089 "`B` CHAR(64), " 8090 "`C` CHAR(64), " 8091 "`D` CHAR(64), " 8092 "`E` CHAR(64) NOT NULL, " 8093 "`F` CHAR(64) NOT NULL, " 8094 "`G` CHAR(64) NOT NULL, " 8095 "`H` CHAR(64) NOT NULL " 8096 "PRIMARY KEY `A` )"; 8097 r = run_query(href, 0, query); 8098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8099 8100 /* column string types don't match exactly */ 8101 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8102 ok(r == ERROR_SUCCESS, 8103 "Expected ERROR_SUCCESS, got %d\n", r); 8104 8105 /* nothing in MergeErrors */ 8106 query = "SELECT * FROM `MergeErrors`"; 8107 r = do_query(hdb, query, &hrec); 8108 ok(r == ERROR_BAD_QUERY_SYNTAX, 8109 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8110 8111 query = "DROP TABLE `One`"; 8112 r = run_query(hdb, 0, query); 8113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8114 8115 query = "DROP TABLE `One`"; 8116 r = run_query(href, 0, query); 8117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8118 8119 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8120 r = run_query(hdb, 0, query); 8121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8122 8123 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )"; 8124 r = run_query(href, 0, query); 8125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8126 8127 /* column names don't match */ 8128 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8129 ok(r == ERROR_DATATYPE_MISMATCH, 8130 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8131 8132 /* nothing in MergeErrors */ 8133 query = "SELECT * FROM `MergeErrors`"; 8134 r = do_query(hdb, query, &hrec); 8135 ok(r == ERROR_BAD_QUERY_SYNTAX, 8136 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8137 8138 query = "DROP TABLE `One`"; 8139 r = run_query(hdb, 0, query); 8140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8141 8142 query = "DROP TABLE `One`"; 8143 r = run_query(href, 0, query); 8144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8145 8146 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8147 r = run_query(hdb, 0, query); 8148 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8149 8150 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )"; 8151 r = run_query(href, 0, query); 8152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8153 8154 /* primary keys don't match */ 8155 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8156 ok(r == ERROR_DATATYPE_MISMATCH, 8157 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8158 8159 /* nothing in MergeErrors */ 8160 query = "SELECT * FROM `MergeErrors`"; 8161 r = do_query(hdb, query, &hrec); 8162 ok(r == ERROR_BAD_QUERY_SYNTAX, 8163 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8164 8165 query = "DROP TABLE `One`"; 8166 r = run_query(hdb, 0, query); 8167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8168 8169 query = "DROP TABLE `One`"; 8170 r = run_query(href, 0, query); 8171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8172 8173 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8174 r = run_query(hdb, 0, query); 8175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8176 8177 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )"; 8178 r = run_query(href, 0, query); 8179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8180 8181 /* number of primary keys doesn't match */ 8182 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8183 ok(r == ERROR_DATATYPE_MISMATCH, 8184 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8185 8186 /* nothing in MergeErrors */ 8187 query = "SELECT * FROM `MergeErrors`"; 8188 r = do_query(hdb, query, &hrec); 8189 ok(r == ERROR_BAD_QUERY_SYNTAX, 8190 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8191 8192 query = "DROP TABLE `One`"; 8193 r = run_query(hdb, 0, query); 8194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8195 8196 query = "DROP TABLE `One`"; 8197 r = run_query(href, 0, query); 8198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8199 8200 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8201 r = run_query(hdb, 0, query); 8202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8203 8204 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8205 r = run_query(href, 0, query); 8206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8207 8208 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8209 r = run_query(href, 0, query); 8210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8211 8212 /* number of columns doesn't match */ 8213 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8214 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8215 8216 query = "SELECT * FROM `One`"; 8217 r = do_query(hdb, query, &hrec); 8218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8219 8220 r = MsiRecordGetInteger(hrec, 1); 8221 ok(r == 1, "Expected 1, got %d\n", r); 8222 8223 r = MsiRecordGetInteger(hrec, 2); 8224 ok(r == 2, "Expected 2, got %d\n", r); 8225 8226 r = MsiRecordGetInteger(hrec, 3); 8227 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8228 8229 MsiCloseHandle(hrec); 8230 8231 /* nothing in MergeErrors */ 8232 query = "SELECT * FROM `MergeErrors`"; 8233 r = do_query(hdb, query, &hrec); 8234 ok(r == ERROR_BAD_QUERY_SYNTAX, 8235 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8236 8237 query = "DROP TABLE `One`"; 8238 r = run_query(hdb, 0, query); 8239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8240 8241 query = "DROP TABLE `One`"; 8242 r = run_query(href, 0, query); 8243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8244 8245 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8246 r = run_query(hdb, 0, query); 8247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8248 8249 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8250 r = run_query(href, 0, query); 8251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8252 8253 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8254 r = run_query(href, 0, query); 8255 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8256 8257 /* number of columns doesn't match */ 8258 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8260 8261 query = "SELECT * FROM `One`"; 8262 r = do_query(hdb, query, &hrec); 8263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8264 8265 r = MsiRecordGetInteger(hrec, 1); 8266 ok(r == 1, "Expected 1, got %d\n", r); 8267 8268 r = MsiRecordGetInteger(hrec, 2); 8269 ok(r == 2, "Expected 2, got %d\n", r); 8270 8271 r = MsiRecordGetInteger(hrec, 3); 8272 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8273 8274 MsiCloseHandle(hrec); 8275 8276 /* nothing in MergeErrors */ 8277 query = "SELECT * FROM `MergeErrors`"; 8278 r = do_query(hdb, query, &hrec); 8279 ok(r == ERROR_BAD_QUERY_SYNTAX, 8280 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8281 8282 query = "DROP TABLE `One`"; 8283 r = run_query(hdb, 0, query); 8284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8285 8286 query = "DROP TABLE `One`"; 8287 r = run_query(href, 0, query); 8288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8289 8290 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8291 r = run_query(hdb, 0, query); 8292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8293 8294 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )"; 8295 r = run_query(hdb, 0, query); 8296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8297 8298 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )"; 8299 r = run_query(hdb, 0, query); 8300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8301 8302 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8303 r = run_query(href, 0, query); 8304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8305 8306 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8307 r = run_query(href, 0, query); 8308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8309 8310 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )"; 8311 r = run_query(href, 0, query); 8312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8313 8314 /* primary keys match, rows do not */ 8315 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8316 ok(r == ERROR_FUNCTION_FAILED, 8317 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8318 8319 /* nothing in MergeErrors */ 8320 query = "SELECT * FROM `MergeErrors`"; 8321 r = do_query(hdb, query, &hrec); 8322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8323 8324 size = MAX_PATH; 8325 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8327 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 8328 8329 r = MsiRecordGetInteger(hrec, 2); 8330 ok(r == 2, "Expected 2, got %d\n", r); 8331 8332 MsiCloseHandle(hrec); 8333 8334 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview); 8335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8336 8337 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec); 8338 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8339 8340 size = MAX_PATH; 8341 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8343 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 8344 8345 size = MAX_PATH; 8346 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8348 ok(!lstrcmpA(buf, "NumRowMergeConflicts"), 8349 "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf); 8350 8351 MsiCloseHandle(hrec); 8352 8353 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec); 8354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8355 8356 size = MAX_PATH; 8357 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8359 ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf); 8360 8361 size = MAX_PATH; 8362 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8364 ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf); 8365 8366 MsiCloseHandle(hrec); 8367 MsiViewClose(hview); 8368 MsiCloseHandle(hview); 8369 8370 query = "DROP TABLE `MergeErrors`"; 8371 r = run_query(hdb, 0, query); 8372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8373 8374 query = "DROP TABLE `One`"; 8375 r = run_query(hdb, 0, query); 8376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8377 8378 query = "DROP TABLE `One`"; 8379 r = run_query(href, 0, query); 8380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8381 8382 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8383 r = run_query(href, 0, query); 8384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8385 8386 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8387 r = run_query(href, 0, query); 8388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8389 8390 /* table from merged database is not in target database */ 8391 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8393 8394 query = "SELECT * FROM `One`"; 8395 r = do_query(hdb, query, &hrec); 8396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8397 8398 r = MsiRecordGetInteger(hrec, 1); 8399 ok(r == 1, "Expected 1, got %d\n", r); 8400 8401 size = MAX_PATH; 8402 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8404 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8405 8406 MsiCloseHandle(hrec); 8407 8408 /* nothing in MergeErrors */ 8409 query = "SELECT * FROM `MergeErrors`"; 8410 r = do_query(hdb, query, &hrec); 8411 ok(r == ERROR_BAD_QUERY_SYNTAX, 8412 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8413 8414 query = "DROP TABLE `One`"; 8415 r = run_query(hdb, 0, query); 8416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8417 8418 query = "DROP TABLE `One`"; 8419 r = run_query(href, 0, query); 8420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8421 8422 query = "CREATE TABLE `One` ( " 8423 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8424 r = run_query(hdb, 0, query); 8425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8426 8427 query = "CREATE TABLE `One` ( " 8428 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8429 r = run_query(href, 0, query); 8430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8431 8432 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 8433 r = run_query(href, 0, query); 8434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8435 8436 /* primary key is string */ 8437 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8439 8440 query = "SELECT * FROM `One`"; 8441 r = do_query(hdb, query, &hrec); 8442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8443 8444 size = MAX_PATH; 8445 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8447 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8448 8449 r = MsiRecordGetInteger(hrec, 2); 8450 ok(r == 1, "Expected 1, got %d\n", r); 8451 8452 MsiCloseHandle(hrec); 8453 8454 /* nothing in MergeErrors */ 8455 query = "SELECT * FROM `MergeErrors`"; 8456 r = do_query(hdb, query, &hrec); 8457 ok(r == ERROR_BAD_QUERY_SYNTAX, 8458 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8459 8460 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 8461 8462 GetCurrentDirectoryA(MAX_PATH, buf); 8463 r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); 8464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8465 8466 query = "DROP TABLE `One`"; 8467 r = run_query(hdb, 0, query); 8468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8469 8470 query = "DROP TABLE `One`"; 8471 r = run_query(href, 0, query); 8472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8473 8474 query = "CREATE TABLE `One` ( " 8475 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8476 r = run_query(hdb, 0, query); 8477 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8478 8479 query = "CREATE TABLE `One` ( " 8480 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8481 r = run_query(href, 0, query); 8482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8483 8484 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8485 r = run_query(href, 0, query); 8486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8487 8488 /* code page does not match */ 8489 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8491 8492 query = "SELECT * FROM `One`"; 8493 r = do_query(hdb, query, &hrec); 8494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8495 8496 r = MsiRecordGetInteger(hrec, 1); 8497 ok(r == 1, "Expected 1, got %d\n", r); 8498 8499 size = MAX_PATH; 8500 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8502 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8503 8504 MsiCloseHandle(hrec); 8505 8506 /* nothing in MergeErrors */ 8507 query = "SELECT * FROM `MergeErrors`"; 8508 r = do_query(hdb, query, &hrec); 8509 ok(r == ERROR_BAD_QUERY_SYNTAX, 8510 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8511 8512 query = "DROP TABLE `One`"; 8513 r = run_query(hdb, 0, query); 8514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8515 8516 query = "DROP TABLE `One`"; 8517 r = run_query(href, 0, query); 8518 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8519 8520 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8521 r = run_query(hdb, 0, query); 8522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8523 8524 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8525 r = run_query(href, 0, query); 8526 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8527 8528 create_file("binary.dat"); 8529 hrec = MsiCreateRecord(1); 8530 MsiRecordSetStreamA(hrec, 1, "binary.dat"); 8531 8532 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )"; 8533 r = run_query(href, hrec, query); 8534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8535 8536 MsiCloseHandle(hrec); 8537 8538 /* binary data to merge */ 8539 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8541 8542 query = "SELECT * FROM `One`"; 8543 r = do_query(hdb, query, &hrec); 8544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8545 8546 r = MsiRecordGetInteger(hrec, 1); 8547 ok(r == 1, "Expected 1, got %d\n", r); 8548 8549 size = MAX_PATH; 8550 ZeroMemory(buf, MAX_PATH); 8551 r = MsiRecordReadStream(hrec, 2, buf, &size); 8552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8553 ok(!lstrcmpA(buf, "binary.dat\n"), 8554 "Expected \"binary.dat\\n\", got \"%s\"\n", buf); 8555 8556 MsiCloseHandle(hrec); 8557 8558 /* nothing in MergeErrors */ 8559 query = "SELECT * FROM `MergeErrors`"; 8560 r = do_query(hdb, query, &hrec); 8561 ok(r == ERROR_BAD_QUERY_SYNTAX, 8562 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8563 8564 query = "DROP TABLE `One`"; 8565 r = run_query(hdb, 0, query); 8566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8567 8568 query = "DROP TABLE `One`"; 8569 r = run_query(href, 0, query); 8570 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8571 8572 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8573 r = run_query(hdb, 0, query); 8574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8575 r = run_query(href, 0, query); 8576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8577 8578 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )"; 8579 r = run_query(href, 0, query); 8580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8581 8582 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )"; 8583 r = run_query(href, 0, query); 8584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8585 8586 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8588 8589 query = "SELECT * FROM `One`"; 8590 r = MsiDatabaseOpenViewA(hdb, query, &hview); 8591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8592 r = MsiViewExecute(hview, 0); 8593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8594 8595 r = MsiViewFetch(hview, &hrec); 8596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8597 8598 r = MsiRecordGetInteger(hrec, 1); 8599 ok(r == 1, "Expected 1, got %d\n", r); 8600 8601 size = MAX_PATH; 8602 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8603 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8604 ok(!lstrcmpA(buf, "foo"), "Expected \"foo\", got \"%s\"\n", buf); 8605 8606 MsiCloseHandle(hrec); 8607 8608 r = MsiViewFetch(hview, &hrec); 8609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8610 8611 r = MsiRecordGetInteger(hrec, 1); 8612 ok(r == 2, "Expected 2, got %d\n", r); 8613 8614 size = MAX_PATH; 8615 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8617 ok(!lstrcmpA(buf, "bar"), "Expected \"bar\", got \"%s\"\n", buf); 8618 8619 MsiCloseHandle(hrec); 8620 8621 r = MsiViewFetch(hview, &hrec); 8622 ok(r == ERROR_NO_MORE_ITEMS, 8623 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8624 8625 MsiViewClose(hview); 8626 MsiCloseHandle(hview); 8627 8628 MsiCloseHandle(hdb); 8629 MsiCloseHandle(href); 8630 DeleteFileA(msifile); 8631 DeleteFileW(refdbW); 8632 DeleteFileA("codepage.idt"); 8633 DeleteFileA("binary.dat"); 8634 } 8635 8636 static void test_select_with_tablenames(void) 8637 { 8638 MSIHANDLE hdb, view, rec; 8639 LPCSTR query; 8640 UINT r; 8641 int i; 8642 8643 int vals[4][2] = { 8644 {1,12}, 8645 {4,12}, 8646 {1,15}, 8647 {4,15}}; 8648 8649 hdb = create_db(); 8650 ok(hdb, "failed to create db\n"); 8651 8652 /* Build a pair of tables with the same column names, but unique data */ 8653 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8654 r = run_query(hdb, 0, query); 8655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8656 8657 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )"; 8658 r = run_query(hdb, 0, query); 8659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8660 8661 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )"; 8662 r = run_query(hdb, 0, query); 8663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8664 8665 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8666 r = run_query(hdb, 0, query); 8667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8668 8669 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )"; 8670 r = run_query(hdb, 0, query); 8671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8672 8673 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )"; 8674 r = run_query(hdb, 0, query); 8675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8676 8677 8678 /* Test that selection based on prefixing the column with the table 8679 * actually selects the right data */ 8680 8681 query = "SELECT T1.A, T2.B FROM T1,T2"; 8682 r = MsiDatabaseOpenViewA(hdb, query, &view); 8683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8684 r = MsiViewExecute(view, 0); 8685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8686 8687 for (i = 0; i < 4; i++) 8688 { 8689 r = MsiViewFetch(view, &rec); 8690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8691 8692 r = MsiRecordGetInteger(rec, 1); 8693 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r); 8694 8695 r = MsiRecordGetInteger(rec, 2); 8696 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r); 8697 8698 MsiCloseHandle(rec); 8699 } 8700 8701 r = MsiViewFetch(view, &rec); 8702 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8703 8704 MsiViewClose(view); 8705 MsiCloseHandle(view); 8706 MsiCloseHandle(hdb); 8707 DeleteFileA(msifile); 8708 } 8709 8710 static const UINT ordervals[6][3] = 8711 { 8712 { MSI_NULL_INTEGER, 12, 13 }, 8713 { 1, 2, 3 }, 8714 { 6, 4, 5 }, 8715 { 8, 9, 7 }, 8716 { 10, 11, MSI_NULL_INTEGER }, 8717 { 14, MSI_NULL_INTEGER, 15 } 8718 }; 8719 8720 static void test_insertorder(void) 8721 { 8722 MSIHANDLE hdb, view, rec; 8723 LPCSTR query; 8724 UINT r; 8725 int i; 8726 8727 hdb = create_db(); 8728 ok(hdb, "failed to create db\n"); 8729 8730 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 8731 r = run_query(hdb, 0, query); 8732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8733 8734 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8735 r = run_query(hdb, 0, query); 8736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8737 8738 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )"; 8739 r = run_query(hdb, 0, query); 8740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8741 8742 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )"; 8743 r = run_query(hdb, 0, query); 8744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8745 8746 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )"; 8747 r = run_query(hdb, 0, query); 8748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8749 8750 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )"; 8751 r = run_query(hdb, 0, query); 8752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8753 8754 /* fails because the primary key already 8755 * has an MSI_NULL_INTEGER value set above 8756 */ 8757 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )"; 8758 r = run_query(hdb, 0, query); 8759 ok(r == ERROR_FUNCTION_FAILED, 8760 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8761 8762 /* replicate the error where primary key is set twice */ 8763 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 14 )"; 8764 r = run_query(hdb, 0, query); 8765 ok(r == ERROR_FUNCTION_FAILED, 8766 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8767 8768 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )"; 8769 r = run_query(hdb, 0, query); 8770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8771 8772 query = "INSERT INTO `T` VALUES ( 16 )"; 8773 r = run_query(hdb, 0, query); 8774 ok(r == ERROR_BAD_QUERY_SYNTAX, 8775 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8776 8777 query = "INSERT INTO `T` VALUES ( 17, 18 )"; 8778 r = run_query(hdb, 0, query); 8779 ok(r == ERROR_BAD_QUERY_SYNTAX, 8780 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8781 8782 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )"; 8783 r = run_query(hdb, 0, query); 8784 ok(r == ERROR_BAD_QUERY_SYNTAX, 8785 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8786 8787 query = "SELECT * FROM `T`"; 8788 r = MsiDatabaseOpenViewA(hdb, query, &view); 8789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8790 r = MsiViewExecute(view, 0); 8791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8792 8793 for (i = 0; i < 6; i++) 8794 { 8795 r = MsiViewFetch(view, &rec); 8796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8797 8798 r = MsiRecordGetInteger(rec, 1); 8799 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8800 8801 r = MsiRecordGetInteger(rec, 2); 8802 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8803 8804 r = MsiRecordGetInteger(rec, 3); 8805 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8806 8807 MsiCloseHandle(rec); 8808 } 8809 8810 r = MsiViewFetch(view, &rec); 8811 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8812 8813 MsiViewClose(view); 8814 MsiCloseHandle(view); 8815 8816 query = "DELETE FROM `T` WHERE `A` IS NULL"; 8817 r = run_query(hdb, 0, query); 8818 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8819 8820 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY"; 8821 r = run_query(hdb, 0, query); 8822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8823 8824 query = "SELECT * FROM `T`"; 8825 r = MsiDatabaseOpenViewA(hdb, query, &view); 8826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8827 r = MsiViewExecute(view, 0); 8828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8829 8830 for (i = 0; i < 6; i++) 8831 { 8832 r = MsiViewFetch(view, &rec); 8833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8834 8835 r = MsiRecordGetInteger(rec, 1); 8836 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8837 8838 r = MsiRecordGetInteger(rec, 2); 8839 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8840 8841 r = MsiRecordGetInteger(rec, 3); 8842 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8843 8844 MsiCloseHandle(rec); 8845 } 8846 8847 r = MsiViewFetch(view, &rec); 8848 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8849 8850 MsiViewClose(view); 8851 MsiCloseHandle(view); 8852 MsiCloseHandle(hdb); 8853 DeleteFileA(msifile); 8854 } 8855 8856 static void test_columnorder(void) 8857 { 8858 MSIHANDLE hdb, view, rec; 8859 char buf[MAX_PATH]; 8860 LPCSTR query; 8861 DWORD sz; 8862 UINT r; 8863 8864 hdb = create_db(); 8865 ok(hdb, "failed to create db\n"); 8866 8867 /* Each column is a slot: 8868 * --------------------- 8869 * | B | C | A | E | D | 8870 * --------------------- 8871 * 8872 * When a column is selected as a primary key, 8873 * the column occupying the nth primary key slot is swapped 8874 * with the current position of the primary key in question: 8875 * 8876 * set primary key `D` 8877 * --------------------- --------------------- 8878 * | B | C | A | E | D | -> | D | C | A | E | B | 8879 * --------------------- --------------------- 8880 * 8881 * set primary key `E` 8882 * --------------------- --------------------- 8883 * | D | C | A | E | B | -> | D | E | A | C | B | 8884 * --------------------- --------------------- 8885 */ 8886 8887 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 8888 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 8889 "PRIMARY KEY `D`, `E`)"; 8890 r = run_query(hdb, 0, query); 8891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8892 8893 query = "SELECT * FROM `T`"; 8894 r = MsiDatabaseOpenViewA(hdb, query, &view); 8895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8896 8897 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 8898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8899 8900 sz = MAX_PATH; 8901 lstrcpyA(buf, "kiwi"); 8902 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8904 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf); 8905 8906 sz = MAX_PATH; 8907 lstrcpyA(buf, "kiwi"); 8908 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8910 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 8911 8912 sz = MAX_PATH; 8913 lstrcpyA(buf, "kiwi"); 8914 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8916 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 8917 8918 sz = MAX_PATH; 8919 lstrcpyA(buf, "kiwi"); 8920 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8922 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 8923 8924 sz = MAX_PATH; 8925 lstrcpyA(buf, "kiwi"); 8926 r = MsiRecordGetStringA(rec, 5, buf, &sz); 8927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8928 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 8929 8930 MsiCloseHandle(rec); 8931 8932 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 8933 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8934 8935 sz = MAX_PATH; 8936 lstrcpyA(buf, "kiwi"); 8937 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8939 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 8940 8941 sz = MAX_PATH; 8942 lstrcpyA(buf, "kiwi"); 8943 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8945 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 8946 8947 sz = MAX_PATH; 8948 lstrcpyA(buf, "kiwi"); 8949 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8951 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 8952 8953 sz = MAX_PATH; 8954 lstrcpyA(buf, "kiwi"); 8955 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8957 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 8958 8959 sz = MAX_PATH; 8960 lstrcpyA(buf, "kiwi"); 8961 r = MsiRecordGetStringA(rec, 5, buf, &sz); 8962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8963 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 8964 8965 MsiCloseHandle(rec); 8966 MsiViewClose(view); 8967 MsiCloseHandle(view); 8968 8969 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) " 8970 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 8971 r = run_query(hdb, 0, query); 8972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8973 8974 query = "SELECT * FROM `T`"; 8975 r = do_query(hdb, query, &rec); 8976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8977 8978 sz = MAX_PATH; 8979 lstrcpyA(buf, "kiwi"); 8980 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8982 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 8983 8984 r = MsiRecordGetInteger(rec, 2); 8985 ok(r == 3, "Expected 3, got %d\n", r); 8986 8987 sz = MAX_PATH; 8988 lstrcpyA(buf, "kiwi"); 8989 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8991 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 8992 8993 r = MsiRecordGetInteger(rec, 4); 8994 ok(r == 2, "Expected 2, got %d\n", r); 8995 8996 r = MsiRecordGetInteger(rec, 5); 8997 ok(r == 1, "Expected 1, got %d\n", r); 8998 8999 MsiCloseHandle(rec); 9000 9001 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 9002 r = MsiDatabaseOpenViewA(hdb, query, &view); 9003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9004 r = MsiViewExecute(view, 0); 9005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9006 9007 r = MsiViewFetch(view, &rec); 9008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9009 9010 sz = MAX_PATH; 9011 lstrcpyA(buf, "kiwi"); 9012 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9014 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9015 9016 r = MsiRecordGetInteger(rec, 2); 9017 ok(r == 1, "Expected 1, got %d\n", r); 9018 9019 sz = MAX_PATH; 9020 lstrcpyA(buf, "kiwi"); 9021 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9023 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9024 9025 MsiCloseHandle(rec); 9026 9027 r = MsiViewFetch(view, &rec); 9028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9029 9030 sz = MAX_PATH; 9031 lstrcpyA(buf, "kiwi"); 9032 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9034 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9035 9036 r = MsiRecordGetInteger(rec, 2); 9037 ok(r == 2, "Expected 2, got %d\n", r); 9038 9039 sz = MAX_PATH; 9040 lstrcpyA(buf, "kiwi"); 9041 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9043 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9044 9045 MsiCloseHandle(rec); 9046 9047 r = MsiViewFetch(view, &rec); 9048 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9049 9050 sz = MAX_PATH; 9051 lstrcpyA(buf, "kiwi"); 9052 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9053 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9054 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9055 9056 r = MsiRecordGetInteger(rec, 2); 9057 ok(r == 3, "Expected 3, got %d\n", r); 9058 9059 sz = MAX_PATH; 9060 lstrcpyA(buf, "kiwi"); 9061 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9063 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9064 9065 MsiCloseHandle(rec); 9066 9067 r = MsiViewFetch(view, &rec); 9068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9069 9070 sz = MAX_PATH; 9071 lstrcpyA(buf, "kiwi"); 9072 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9074 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9075 9076 r = MsiRecordGetInteger(rec, 2); 9077 ok(r == 4, "Expected 4, got %d\n", r); 9078 9079 sz = MAX_PATH; 9080 lstrcpyA(buf, "kiwi"); 9081 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9083 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9084 9085 MsiCloseHandle(rec); 9086 9087 r = MsiViewFetch(view, &rec); 9088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9089 9090 sz = MAX_PATH; 9091 lstrcpyA(buf, "kiwi"); 9092 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9094 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9095 9096 r = MsiRecordGetInteger(rec, 2); 9097 ok(r == 5, "Expected 5, got %d\n", r); 9098 9099 sz = MAX_PATH; 9100 lstrcpyA(buf, "kiwi"); 9101 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9103 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9104 9105 MsiCloseHandle(rec); 9106 9107 r = MsiViewFetch(view, &rec); 9108 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9109 9110 MsiViewClose(view); 9111 MsiCloseHandle(view); 9112 9113 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 9114 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 9115 "PRIMARY KEY `C`, `A`, `D`)"; 9116 r = run_query(hdb, 0, query); 9117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9118 9119 query = "SELECT * FROM `Z`"; 9120 r = MsiDatabaseOpenViewA(hdb, query, &view); 9121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9122 9123 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 9124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9125 9126 sz = MAX_PATH; 9127 lstrcpyA(buf, "kiwi"); 9128 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9130 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 9131 9132 sz = MAX_PATH; 9133 lstrcpyA(buf, "kiwi"); 9134 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9136 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 9137 9138 sz = MAX_PATH; 9139 lstrcpyA(buf, "kiwi"); 9140 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9142 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf); 9143 9144 sz = MAX_PATH; 9145 lstrcpyA(buf, "kiwi"); 9146 r = MsiRecordGetStringA(rec, 4, buf, &sz); 9147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9148 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 9149 9150 sz = MAX_PATH; 9151 lstrcpyA(buf, "kiwi"); 9152 r = MsiRecordGetStringA(rec, 5, buf, &sz); 9153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9154 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 9155 9156 MsiCloseHandle(rec); 9157 9158 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 9159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9160 9161 sz = MAX_PATH; 9162 lstrcpyA(buf, "kiwi"); 9163 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9165 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9166 9167 sz = MAX_PATH; 9168 lstrcpyA(buf, "kiwi"); 9169 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9171 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9172 9173 sz = MAX_PATH; 9174 lstrcpyA(buf, "kiwi"); 9175 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9177 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9178 9179 sz = MAX_PATH; 9180 lstrcpyA(buf, "kiwi"); 9181 r = MsiRecordGetStringA(rec, 4, buf, &sz); 9182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9183 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9184 9185 sz = MAX_PATH; 9186 lstrcpyA(buf, "kiwi"); 9187 r = MsiRecordGetStringA(rec, 5, buf, &sz); 9188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9189 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9190 9191 MsiCloseHandle(rec); 9192 MsiViewClose(view); 9193 MsiCloseHandle(view); 9194 9195 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) " 9196 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 9197 r = run_query(hdb, 0, query); 9198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9199 9200 query = "SELECT * FROM `Z`"; 9201 r = do_query(hdb, query, &rec); 9202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9203 9204 r = MsiRecordGetInteger(rec, 1); 9205 ok(r == 2, "Expected 2, got %d\n", r); 9206 9207 sz = MAX_PATH; 9208 lstrcpyA(buf, "kiwi"); 9209 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9211 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 9212 9213 sz = MAX_PATH; 9214 lstrcpyA(buf, "kiwi"); 9215 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9217 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 9218 9219 r = MsiRecordGetInteger(rec, 4); 9220 ok(r == 3, "Expected 3, got %d\n", r); 9221 9222 r = MsiRecordGetInteger(rec, 5); 9223 ok(r == 1, "Expected 1, got %d\n", r); 9224 9225 MsiCloseHandle(rec); 9226 9227 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 9228 r = MsiDatabaseOpenViewA(hdb, query, &view); 9229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9230 r = MsiViewExecute(view, 0); 9231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9232 9233 r = MsiViewFetch(view, &rec); 9234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9235 9236 sz = MAX_PATH; 9237 lstrcpyA(buf, "kiwi"); 9238 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9240 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9241 9242 r = MsiRecordGetInteger(rec, 2); 9243 ok(r == 1, "Expected 1, got %d\n", r); 9244 9245 sz = MAX_PATH; 9246 lstrcpyA(buf, "kiwi"); 9247 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9249 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9250 9251 MsiCloseHandle(rec); 9252 9253 r = MsiViewFetch(view, &rec); 9254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9255 9256 sz = MAX_PATH; 9257 lstrcpyA(buf, "kiwi"); 9258 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9260 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9261 9262 r = MsiRecordGetInteger(rec, 2); 9263 ok(r == 2, "Expected 2, got %d\n", r); 9264 9265 sz = MAX_PATH; 9266 lstrcpyA(buf, "kiwi"); 9267 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9269 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9270 9271 MsiCloseHandle(rec); 9272 9273 r = MsiViewFetch(view, &rec); 9274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9275 9276 sz = MAX_PATH; 9277 lstrcpyA(buf, "kiwi"); 9278 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9279 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9280 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9281 9282 r = MsiRecordGetInteger(rec, 2); 9283 ok(r == 3, "Expected 3, got %d\n", r); 9284 9285 sz = MAX_PATH; 9286 lstrcpyA(buf, "kiwi"); 9287 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9289 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9290 9291 MsiCloseHandle(rec); 9292 9293 r = MsiViewFetch(view, &rec); 9294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9295 9296 sz = MAX_PATH; 9297 lstrcpyA(buf, "kiwi"); 9298 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9299 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9300 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9301 9302 r = MsiRecordGetInteger(rec, 2); 9303 ok(r == 4, "Expected 4, got %d\n", r); 9304 9305 sz = MAX_PATH; 9306 lstrcpyA(buf, "kiwi"); 9307 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9309 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9310 9311 MsiCloseHandle(rec); 9312 9313 r = MsiViewFetch(view, &rec); 9314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9315 9316 sz = MAX_PATH; 9317 lstrcpyA(buf, "kiwi"); 9318 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9320 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9321 9322 r = MsiRecordGetInteger(rec, 2); 9323 ok(r == 5, "Expected 5, got %d\n", r); 9324 9325 sz = MAX_PATH; 9326 lstrcpyA(buf, "kiwi"); 9327 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9329 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9330 9331 MsiCloseHandle(rec); 9332 9333 r = MsiViewFetch(view, &rec); 9334 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9335 9336 MsiViewClose(view); 9337 MsiCloseHandle(view); 9338 9339 MsiCloseHandle(hdb); 9340 DeleteFileA(msifile); 9341 } 9342 9343 static void test_createtable(void) 9344 { 9345 MSIHANDLE hdb, htab = 0, hrec = 0; 9346 LPCSTR query; 9347 UINT res; 9348 DWORD size; 9349 char buffer[0x20]; 9350 9351 hdb = create_db(); 9352 ok(hdb, "failed to create db\n"); 9353 9354 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)"; 9355 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9356 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9357 if(res == ERROR_SUCCESS ) 9358 { 9359 res = MsiViewExecute( htab, hrec ); 9360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9361 9362 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9363 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9364 9365 size = sizeof(buffer); 9366 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9367 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9368 MsiCloseHandle( hrec ); 9369 9370 res = MsiViewClose( htab ); 9371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9372 9373 res = MsiCloseHandle( htab ); 9374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9375 } 9376 9377 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)"; 9378 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9379 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9380 if(res == ERROR_SUCCESS ) 9381 { 9382 res = MsiViewExecute( htab, 0 ); 9383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9384 9385 res = MsiViewClose( htab ); 9386 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9387 9388 res = MsiCloseHandle( htab ); 9389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9390 9391 query = "SELECT * FROM `a`"; 9392 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9394 9395 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9396 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9397 9398 buffer[0] = 0; 9399 size = sizeof(buffer); 9400 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9401 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9402 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9403 MsiCloseHandle( hrec ); 9404 9405 res = MsiViewClose( htab ); 9406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9407 9408 res = MsiCloseHandle( htab ); 9409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9410 9411 res = MsiDatabaseCommit(hdb); 9412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9413 9414 res = MsiCloseHandle(hdb); 9415 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9416 9417 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 9418 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9419 9420 query = "SELECT * FROM `a`"; 9421 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9422 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9423 9424 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9425 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9426 9427 buffer[0] = 0; 9428 size = sizeof(buffer); 9429 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9431 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9432 9433 res = MsiCloseHandle( hrec ); 9434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9435 9436 res = MsiViewClose( htab ); 9437 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9438 9439 res = MsiCloseHandle( htab ); 9440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9441 } 9442 9443 res = MsiDatabaseCommit(hdb); 9444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9445 9446 res = MsiCloseHandle(hdb); 9447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9448 9449 DeleteFileA(msifile); 9450 } 9451 9452 static void test_embedded_nulls(void) 9453 { 9454 static const char control_table[] = 9455 "Dialog\tText\n" 9456 "s72\tL0\n" 9457 "Control\tDialog\n" 9458 "LicenseAgreementDlg\ttext\x11\x19text\0text"; 9459 UINT r, sz; 9460 MSIHANDLE hdb, hrec; 9461 char buffer[32]; 9462 9463 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9464 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r ); 9465 9466 GetCurrentDirectoryA( MAX_PATH, CURR_DIR ); 9467 write_file( "temp_file", control_table, sizeof(control_table) ); 9468 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" ); 9469 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r ); 9470 DeleteFileA( "temp_file" ); 9471 9472 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec ); 9473 ok( r == ERROR_SUCCESS, "query failed %u\n", r ); 9474 9475 buffer[0] = 0; 9476 sz = sizeof(buffer); 9477 r = MsiRecordGetStringA( hrec, 1, buffer, &sz ); 9478 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r ); 9479 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer ); 9480 9481 MsiCloseHandle( hrec ); 9482 MsiCloseHandle( hdb ); 9483 DeleteFileA( msifile ); 9484 } 9485 9486 static void test_select_column_names(void) 9487 { 9488 MSIHANDLE hdb = 0, rec, rec2, view; 9489 char buffer[32]; 9490 UINT r, size; 9491 9492 DeleteFileA(msifile); 9493 9494 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9495 ok( r == ERROR_SUCCESS , "failed to open database: %u\n", r ); 9496 9497 r = try_query( hdb, "CREATE TABLE `t` (`a` CHAR NOT NULL, `b` CHAR PRIMARY KEY `a`)"); 9498 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9499 9500 r = try_query( hdb, "SELECT `t`.`b` FROM `t` WHERE `t`.`b` = `x`" ); 9501 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9502 9503 r = try_query( hdb, "SELECT '', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9504 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9505 9506 r = try_query( hdb, "SELECT *, `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9507 todo_wine ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 9508 9509 r = try_query( hdb, "SELECT 'b', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9510 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9511 9512 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x'" ); 9513 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9514 9515 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY `b`" ); 9516 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9517 9518 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY 'b'" ); 9519 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9520 9521 r = try_query( hdb, "SELECT 't'.'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9522 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9523 9524 r = try_query( hdb, "SELECT 'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9525 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9526 9527 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '1', '2' )" ); 9528 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9529 9530 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '3', '4' )" ); 9531 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9532 9533 r = MsiDatabaseOpenViewA( hdb, "SELECT '' FROM `t`", &view ); 9534 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9535 9536 r = MsiViewExecute( view, 0 ); 9537 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9538 9539 r = MsiViewFetch( view, &rec ); 9540 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9541 r = MsiRecordGetFieldCount( rec ); 9542 ok( r == 1, "got %u\n", r ); 9543 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec2 ); 9544 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9545 r = MsiRecordGetFieldCount( rec2 ); 9546 ok( r == 1, "got %u\n", r ); 9547 size = sizeof(buffer); 9548 memset( buffer, 0x55, sizeof(buffer) ); 9549 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9550 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9551 ok( !buffer[0], "got \"%s\"\n", buffer ); 9552 MsiCloseHandle( rec2 ); 9553 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec2 ); 9554 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9555 r = MsiRecordGetFieldCount( rec2 ); 9556 ok( r == 1, "got %u\n", r ); 9557 size = sizeof(buffer); 9558 memset( buffer, 0x55, sizeof(buffer) ); 9559 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9560 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9561 ok( !lstrcmpA( buffer, "f0" ), "got \"%s\"\n", buffer ); 9562 MsiCloseHandle( rec2 ); 9563 9564 size = sizeof(buffer); 9565 memset( buffer, 0x55, sizeof(buffer) ); 9566 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9567 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9568 ok( !buffer[0], "got \"%s\"\n", buffer ); 9569 MsiCloseHandle( rec ); 9570 9571 r = MsiViewFetch( view, &rec ); 9572 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9573 size = sizeof(buffer); 9574 memset( buffer, 0x55, sizeof(buffer) ); 9575 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9576 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9577 ok( !buffer[0], "got \"%s\"\n", buffer ); 9578 MsiCloseHandle( rec ); 9579 9580 r = MsiViewFetch( view, &rec ); 9581 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9582 MsiCloseHandle( rec ); 9583 9584 MsiViewClose( view ); 9585 MsiCloseHandle( view ); 9586 9587 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '' FROM `t`", &view ); 9588 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9589 9590 r = MsiViewExecute( view, 0 ); 9591 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9592 9593 r = MsiViewFetch( view, &rec ); 9594 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9595 r = MsiRecordGetFieldCount( rec ); 9596 ok( r == 2, "got %u\n", r ); 9597 size = sizeof(buffer); 9598 memset( buffer, 0x55, sizeof(buffer) ); 9599 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9600 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9601 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9602 MsiCloseHandle( rec ); 9603 9604 r = MsiViewFetch( view, &rec ); 9605 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9606 size = sizeof(buffer); 9607 memset( buffer, 0x55, sizeof(buffer) ); 9608 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9609 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9610 ok( !buffer[0], "got \"%s\"\n", buffer ); 9611 MsiCloseHandle( rec ); 9612 9613 r = MsiViewFetch( view, &rec ); 9614 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9615 MsiCloseHandle( rec ); 9616 9617 MsiViewClose( view ); 9618 MsiCloseHandle( view ); 9619 9620 r = MsiDatabaseOpenViewA( hdb, "SELECT '', `a` FROM `t`", &view ); 9621 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9622 9623 r = MsiViewExecute( view, 0 ); 9624 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9625 9626 r = MsiViewFetch( view, &rec ); 9627 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9628 r = MsiRecordGetFieldCount( rec ); 9629 ok( r == 2, "got %u\n", r ); 9630 size = sizeof(buffer); 9631 memset( buffer, 0x55, sizeof(buffer) ); 9632 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9633 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9634 ok( !buffer[0], "got \"%s\"\n", buffer ); 9635 size = sizeof(buffer); 9636 memset( buffer, 0x55, sizeof(buffer) ); 9637 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9638 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9639 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9640 MsiCloseHandle( rec ); 9641 9642 r = MsiViewFetch( view, &rec ); 9643 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9644 size = sizeof(buffer); 9645 memset( buffer, 0x55, sizeof(buffer) ); 9646 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9647 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9648 ok( !buffer[0], "got \"%s\"\n", buffer ); 9649 size = sizeof(buffer); 9650 memset( buffer, 0x55, sizeof(buffer) ); 9651 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9652 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9653 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9654 MsiCloseHandle( rec ); 9655 9656 r = MsiViewFetch( view, &rec ); 9657 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9658 MsiCloseHandle( rec ); 9659 9660 MsiViewClose( view ); 9661 MsiCloseHandle( view ); 9662 9663 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '', `b` FROM `t`", &view ); 9664 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9665 9666 r = MsiViewExecute( view, 0 ); 9667 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9668 9669 r = MsiViewFetch( view, &rec ); 9670 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9671 r = MsiRecordGetFieldCount( rec ); 9672 ok( r == 3, "got %u\n", r ); 9673 size = sizeof(buffer); 9674 memset( buffer, 0x55, sizeof(buffer) ); 9675 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9676 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9677 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9678 size = sizeof(buffer); 9679 memset( buffer, 0x55, sizeof(buffer) ); 9680 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9681 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9682 ok( !buffer[0], "got \"%s\"\n", buffer ); 9683 size = sizeof(buffer); 9684 memset( buffer, 0x55, sizeof(buffer) ); 9685 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9686 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9687 ok( !lstrcmpA( buffer, "2" ), "got \"%s\"\n", buffer ); 9688 MsiCloseHandle( rec ); 9689 9690 r = MsiViewFetch( view, &rec ); 9691 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9692 size = sizeof(buffer); 9693 memset( buffer, 0x55, sizeof(buffer) ); 9694 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9695 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9696 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9697 size = sizeof(buffer); 9698 memset( buffer, 0x55, sizeof(buffer) ); 9699 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9700 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9701 ok( !buffer[0], "got \"%s\"\n", buffer ); 9702 size = sizeof(buffer); 9703 memset( buffer, 0x55, sizeof(buffer) ); 9704 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9705 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9706 ok( !lstrcmpA( buffer, "4" ), "got \"%s\"\n", buffer ); 9707 MsiCloseHandle( rec ); 9708 9709 r = MsiViewFetch( view, &rec ); 9710 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9711 MsiCloseHandle( rec ); 9712 9713 MsiViewClose( view ); 9714 MsiCloseHandle( view ); 9715 9716 r = try_query( hdb, "SELECT '' FROM `t` WHERE `t`.`b` = 'x'" ); 9717 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9718 9719 r = try_query( hdb, "SELECT `` FROM `t` WHERE `t`.`b` = 'x'" ); 9720 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9721 9722 r = try_query( hdb, "SELECT `b` FROM 't' WHERE `t`.`b` = 'x'" ); 9723 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9724 9725 r = try_query( hdb, "SELECT `b` FROM `t` WHERE 'b' = 'x'" ); 9726 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9727 9728 r = try_query( hdb, "SELECT `t`.`b`, `` FROM `t` WHERE `t`.`b` = 'x'" ); 9729 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9730 9731 r = MsiCloseHandle( hdb ); 9732 ok(r == ERROR_SUCCESS , "failed to close database: %u\n", r); 9733 } 9734 9735 START_TEST(db) 9736 { 9737 test_msidatabase(); 9738 test_msiinsert(); 9739 test_msidecomposedesc(); 9740 test_msibadqueries(); 9741 test_viewmodify(); 9742 test_viewgetcolumninfo(); 9743 test_getcolinfo(); 9744 test_msiexport(); 9745 test_longstrings(); 9746 test_streamtable(); 9747 test_binary(); 9748 test_where_not_in_selected(); 9749 test_where(); 9750 test_msiimport(); 9751 test_binary_import(); 9752 test_markers(); 9753 test_handle_limit(); 9754 test_try_transform(); 9755 test_join(); 9756 test_temporary_table(); 9757 test_alter(); 9758 test_integers(); 9759 test_update(); 9760 test_special_tables(); 9761 test_tables_order(); 9762 test_rows_order(); 9763 test_select_markers(); 9764 test_viewmodify_update(); 9765 test_viewmodify_assign(); 9766 test_stringtable(); 9767 test_viewmodify_delete(); 9768 test_defaultdatabase(); 9769 test_order(); 9770 test_viewmodify_delete_temporary(); 9771 test_deleterow(); 9772 test_quotes(); 9773 test_carriagereturn(); 9774 test_noquotes(); 9775 test_forcecodepage(); 9776 test_viewmodify_refresh(); 9777 test_where_viewmodify(); 9778 test_storages_table(); 9779 test_dbtopackage(); 9780 test_droptable(); 9781 test_dbmerge(); 9782 test_select_with_tablenames(); 9783 test_insertorder(); 9784 test_columnorder(); 9785 test_suminfo_import(); 9786 test_createtable(); 9787 test_collation(); 9788 test_embedded_nulls(); 9789 test_select_column_names(); 9790 } 9791