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 = add_table_to_db(hdb, test_data); 2373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2374 2375 r = add_table_to_db(hdb, two_primary); 2376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2377 2378 r = add_table_to_db(hdb, endlines1); 2379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2380 2381 r = add_table_to_db(hdb, endlines2); 2382 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2383 2384 query = "SELECT * FROM `TestTable`"; 2385 r = MsiDatabaseOpenViewA(hdb, query, &view); 2386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2387 2388 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2390 count = MsiRecordGetFieldCount(rec); 2391 ok(count == 9, "Expected 9, got %d\n", count); 2392 ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n"); 2393 ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n"); 2394 ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n"); 2395 ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n"); 2396 ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n"); 2397 ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n"); 2398 ok(check_record(rec, 7, "String"), "Expected String\n"); 2399 ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n"); 2400 ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n"); 2401 MsiCloseHandle(rec); 2402 2403 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2405 count = MsiRecordGetFieldCount(rec); 2406 ok(count == 9, "Expected 9, got %d\n", count); 2407 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2408 ok(check_record(rec, 2, "i2"), "Expected i2\n"); 2409 ok(check_record(rec, 3, "i2"), "Expected i2\n"); 2410 ok(check_record(rec, 4, "I2"), "Expected I2\n"); 2411 ok(check_record(rec, 5, "i4"), "Expected i4\n"); 2412 ok(check_record(rec, 6, "I4"), "Expected I4\n"); 2413 ok(check_record(rec, 7, "S255"), "Expected S255\n"); 2414 ok(check_record(rec, 8, "S0"), "Expected S0\n"); 2415 ok(check_record(rec, 9, "s0"), "Expected s0\n"); 2416 MsiCloseHandle(rec); 2417 2418 query = "SELECT * FROM `TestTable`"; 2419 r = do_query(hdb, query, &rec); 2420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2421 ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n"); 2422 ok(check_record(rec, 7, "another string"), "Expected 'another string'\n"); 2423 ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n"); 2424 ok(check_record(rec, 9, "duh"), "Expected 'duh'\n"); 2425 2426 i = MsiRecordGetInteger(rec, 2); 2427 ok(i == 5, "Expected 5, got %d\n", i); 2428 2429 i = MsiRecordGetInteger(rec, 3); 2430 ok(i == 2, "Expected 2, got %d\n", i); 2431 2432 i = MsiRecordGetInteger(rec, 4); 2433 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 2434 2435 i = MsiRecordGetInteger(rec, 5); 2436 ok(i == 2147483640, "Expected 2147483640, got %d\n", i); 2437 2438 i = MsiRecordGetInteger(rec, 6); 2439 ok(i == -2147483640, "Expected -2147483640, got %d\n", i); 2440 2441 MsiCloseHandle(rec); 2442 MsiViewClose(view); 2443 MsiCloseHandle(view); 2444 2445 query = "SELECT * FROM `TwoPrimary`"; 2446 r = MsiDatabaseOpenViewA(hdb, query, &view); 2447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2448 2449 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2451 count = MsiRecordGetFieldCount(rec); 2452 ok(count == 2, "Expected 2, got %d\n", count); 2453 ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n"); 2454 ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n"); 2455 2456 MsiCloseHandle(rec); 2457 2458 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2460 count = MsiRecordGetFieldCount(rec); 2461 ok(count == 2, "Expected 2, got %d\n", count); 2462 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2463 ok(check_record(rec, 2, "s255"), "Expected s255\n"); 2464 MsiCloseHandle(rec); 2465 2466 r = MsiViewExecute(view, 0); 2467 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2468 2469 r = MsiViewFetch(view, &rec); 2470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2471 2472 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2473 ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n"); 2474 2475 MsiCloseHandle(rec); 2476 2477 r = MsiViewFetch(view, &rec); 2478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2479 2480 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2481 ok(check_record(rec, 2, "flower"), "Expected 'flower'\n"); 2482 2483 MsiCloseHandle(rec); 2484 2485 r = MsiViewFetch(view, &rec); 2486 ok(r == ERROR_NO_MORE_ITEMS, 2487 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2488 2489 r = MsiViewClose(view); 2490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2491 2492 MsiCloseHandle(view); 2493 2494 query = "SELECT * FROM `Table`"; 2495 r = MsiDatabaseOpenViewA(hdb, query, &view); 2496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2497 2498 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2500 count = MsiRecordGetFieldCount(rec); 2501 ok(count == 6, "Expected 6, got %d\n", count); 2502 ok(check_record(rec, 1, "A"), "Expected A\n"); 2503 ok(check_record(rec, 2, "B"), "Expected B\n"); 2504 ok(check_record(rec, 3, "C"), "Expected C\n"); 2505 ok(check_record(rec, 4, "D"), "Expected D\n"); 2506 ok(check_record(rec, 5, "E"), "Expected E\n"); 2507 ok(check_record(rec, 6, "F"), "Expected F\n"); 2508 MsiCloseHandle(rec); 2509 2510 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2512 count = MsiRecordGetFieldCount(rec); 2513 ok(count == 6, "Expected 6, got %d\n", count); 2514 ok(check_record(rec, 1, "s72"), "Expected s72\n"); 2515 ok(check_record(rec, 2, "s72"), "Expected s72\n"); 2516 ok(check_record(rec, 3, "s72"), "Expected s72\n"); 2517 ok(check_record(rec, 4, "s72"), "Expected s72\n"); 2518 ok(check_record(rec, 5, "s72"), "Expected s72\n"); 2519 ok(check_record(rec, 6, "s72"), "Expected s72\n"); 2520 MsiCloseHandle(rec); 2521 2522 MsiViewClose(view); 2523 MsiCloseHandle(view); 2524 2525 query = "SELECT * FROM `Table`"; 2526 r = MsiDatabaseOpenViewA(hdb, query, &view); 2527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2528 2529 r = MsiViewExecute(view, 0); 2530 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2531 2532 r = MsiViewFetch(view, &rec); 2533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2534 ok(check_record(rec, 1, "a"), "Expected 'a'\n"); 2535 ok(check_record(rec, 2, "b"), "Expected 'b'\n"); 2536 ok(check_record(rec, 3, "c"), "Expected 'c'\n"); 2537 ok(check_record(rec, 4, "d"), "Expected 'd'\n"); 2538 ok(check_record(rec, 5, "e"), "Expected 'e'\n"); 2539 ok(check_record(rec, 6, "f"), "Expected 'f'\n"); 2540 2541 MsiCloseHandle(rec); 2542 2543 r = MsiViewFetch(view, &rec); 2544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2545 ok(check_record(rec, 1, "g"), "Expected 'g'\n"); 2546 ok(check_record(rec, 2, "h"), "Expected 'h'\n"); 2547 ok(check_record(rec, 3, "i"), "Expected 'i'\n"); 2548 ok(check_record(rec, 4, "j"), "Expected 'j'\n"); 2549 ok(check_record(rec, 5, "k"), "Expected 'k'\n"); 2550 ok(check_record(rec, 6, "l"), "Expected 'l'\n"); 2551 2552 MsiCloseHandle(rec); 2553 2554 r = MsiViewFetch(view, &rec); 2555 ok(r == ERROR_NO_MORE_ITEMS, 2556 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2557 2558 MsiViewClose(view); 2559 MsiCloseHandle(view); 2560 MsiCloseHandle(hdb); 2561 DeleteFileA(msifile); 2562 } 2563 2564 static const CHAR bin_import_dat[] = "Name\tData\r\n" 2565 "s72\tV0\r\n" 2566 "Binary\tName\r\n" 2567 "filename1\tfilename1.ibd\r\n"; 2568 2569 static void test_binary_import(void) 2570 { 2571 MSIHANDLE hdb = 0, rec; 2572 char file[MAX_PATH]; 2573 char buf[MAX_PATH]; 2574 char path[MAX_PATH]; 2575 DWORD size; 2576 LPCSTR query; 2577 UINT r; 2578 2579 /* create files to import */ 2580 write_file("bin_import.idt", bin_import_dat, 2581 (sizeof(bin_import_dat) - 1) * sizeof(char)); 2582 CreateDirectoryA("bin_import", NULL); 2583 create_file_data("bin_import/filename1.ibd", "just some words", 15); 2584 2585 /* import files into database */ 2586 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2587 ok( r == ERROR_SUCCESS , "Failed to open database\n"); 2588 2589 GetCurrentDirectoryA(MAX_PATH, path); 2590 r = MsiDatabaseImportA(hdb, path, "bin_import.idt"); 2591 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n"); 2592 2593 /* read file from the Binary table */ 2594 query = "SELECT * FROM `Binary`"; 2595 r = do_query(hdb, query, &rec); 2596 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r); 2597 2598 size = MAX_PATH; 2599 r = MsiRecordGetStringA(rec, 1, file, &size); 2600 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 2601 ok(!lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file); 2602 2603 size = MAX_PATH; 2604 memset(buf, 0, MAX_PATH); 2605 r = MsiRecordReadStream(rec, 2, buf, &size); 2606 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 2607 ok(!lstrcmpA(buf, "just some words"), "Expected 'just some words', got %s\n", buf); 2608 2609 r = MsiCloseHandle(rec); 2610 ok(r == ERROR_SUCCESS , "Failed to close record handle\n"); 2611 2612 r = MsiCloseHandle(hdb); 2613 ok(r == ERROR_SUCCESS , "Failed to close database\n"); 2614 2615 DeleteFileA("bin_import/filename1.ibd"); 2616 RemoveDirectoryA("bin_import"); 2617 DeleteFileA("bin_import.idt"); 2618 } 2619 2620 static void test_markers(void) 2621 { 2622 MSIHANDLE hdb, rec; 2623 LPCSTR query; 2624 UINT r; 2625 2626 hdb = create_db(); 2627 ok( hdb, "failed to create db\n"); 2628 2629 rec = MsiCreateRecord(3); 2630 MsiRecordSetStringA(rec, 1, "Table"); 2631 MsiRecordSetStringA(rec, 2, "Apples"); 2632 MsiRecordSetStringA(rec, 3, "Oranges"); 2633 2634 /* try a legit create */ 2635 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2636 r = run_query(hdb, 0, query); 2637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2638 MsiCloseHandle(rec); 2639 2640 /* try table name as marker */ 2641 rec = MsiCreateRecord(1); 2642 MsiRecordSetStringA(rec, 1, "Fable"); 2643 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2644 r = run_query(hdb, rec, query); 2645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2646 2647 /* verify that we just created a table called '?', not 'Fable' */ 2648 r = try_query(hdb, "SELECT * from `Fable`"); 2649 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2650 2651 r = try_query(hdb, "SELECT * from `?`"); 2652 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2653 2654 /* try table name as marker without backticks */ 2655 MsiRecordSetStringA(rec, 1, "Mable"); 2656 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2657 r = run_query(hdb, rec, query); 2658 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2659 2660 /* try one column name as marker */ 2661 MsiRecordSetStringA(rec, 1, "One"); 2662 query = "CREATE TABLE `Mable` ( `?` 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 MsiCloseHandle(rec); 2666 2667 /* try column names as markers */ 2668 rec = MsiCreateRecord(2); 2669 MsiRecordSetStringA(rec, 1, "One"); 2670 MsiRecordSetStringA(rec, 2, "Two"); 2671 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)"; 2672 r = run_query(hdb, rec, query); 2673 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2674 MsiCloseHandle(rec); 2675 2676 /* try names with backticks */ 2677 rec = MsiCreateRecord(3); 2678 MsiRecordSetStringA(rec, 1, "One"); 2679 MsiRecordSetStringA(rec, 2, "Two"); 2680 MsiRecordSetStringA(rec, 3, "One"); 2681 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2682 r = run_query(hdb, rec, query); 2683 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2684 2685 /* try names with backticks, minus definitions */ 2686 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)"; 2687 r = run_query(hdb, rec, query); 2688 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2689 2690 /* try names without backticks */ 2691 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)"; 2692 r = run_query(hdb, rec, query); 2693 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2694 MsiCloseHandle(rec); 2695 2696 /* try one long marker */ 2697 rec = MsiCreateRecord(1); 2698 MsiRecordSetStringA(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`"); 2699 query = "CREATE TABLE `Mable` ( ? )"; 2700 r = run_query(hdb, rec, query); 2701 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2702 MsiCloseHandle(rec); 2703 2704 /* try all names as markers */ 2705 rec = MsiCreateRecord(4); 2706 MsiRecordSetStringA(rec, 1, "Mable"); 2707 MsiRecordSetStringA(rec, 2, "One"); 2708 MsiRecordSetStringA(rec, 3, "Two"); 2709 MsiRecordSetStringA(rec, 4, "One"); 2710 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2711 r = run_query(hdb, rec, query); 2712 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2713 MsiCloseHandle(rec); 2714 2715 /* try a legit insert */ 2716 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )"; 2717 r = run_query(hdb, 0, query); 2718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2719 2720 r = try_query(hdb, "SELECT * from `Table`"); 2721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2722 2723 /* try values as markers */ 2724 rec = MsiCreateRecord(2); 2725 MsiRecordSetInteger(rec, 1, 4); 2726 MsiRecordSetStringA(rec, 2, "hi"); 2727 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2728 r = run_query(hdb, rec, query); 2729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2730 MsiCloseHandle(rec); 2731 2732 /* try column names and values as markers */ 2733 rec = MsiCreateRecord(4); 2734 MsiRecordSetStringA(rec, 1, "One"); 2735 MsiRecordSetStringA(rec, 2, "Two"); 2736 MsiRecordSetInteger(rec, 3, 5); 2737 MsiRecordSetStringA(rec, 4, "hi"); 2738 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )"; 2739 r = run_query(hdb, rec, query); 2740 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2741 MsiCloseHandle(rec); 2742 2743 /* try column names as markers */ 2744 rec = MsiCreateRecord(2); 2745 MsiRecordSetStringA(rec, 1, "One"); 2746 MsiRecordSetStringA(rec, 2, "Two"); 2747 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )"; 2748 r = run_query(hdb, rec, query); 2749 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2750 MsiCloseHandle(rec); 2751 2752 /* try table name as a marker */ 2753 rec = MsiCreateRecord(1); 2754 MsiRecordSetStringA(rec, 1, "Table"); 2755 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )"; 2756 r = run_query(hdb, rec, query); 2757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2758 MsiCloseHandle(rec); 2759 2760 /* try table name and values as markers */ 2761 rec = MsiCreateRecord(3); 2762 MsiRecordSetStringA(rec, 1, "Table"); 2763 MsiRecordSetInteger(rec, 2, 10); 2764 MsiRecordSetStringA(rec, 3, "haha"); 2765 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2766 r = run_query(hdb, rec, query); 2767 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2768 MsiCloseHandle(rec); 2769 2770 /* try all markers */ 2771 rec = MsiCreateRecord(5); 2772 MsiRecordSetStringA(rec, 1, "Table"); 2773 MsiRecordSetStringA(rec, 1, "One"); 2774 MsiRecordSetStringA(rec, 1, "Two"); 2775 MsiRecordSetInteger(rec, 2, 10); 2776 MsiRecordSetStringA(rec, 3, "haha"); 2777 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )"; 2778 r = run_query(hdb, rec, query); 2779 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2780 MsiCloseHandle(rec); 2781 2782 /* insert an integer as a string */ 2783 rec = MsiCreateRecord(2); 2784 MsiRecordSetStringA(rec, 1, "11"); 2785 MsiRecordSetStringA(rec, 2, "hi"); 2786 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2787 r = run_query(hdb, rec, query); 2788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2789 MsiCloseHandle(rec); 2790 2791 /* leave off the '' for the string */ 2792 rec = MsiCreateRecord(2); 2793 MsiRecordSetInteger(rec, 1, 12); 2794 MsiRecordSetStringA(rec, 2, "hi"); 2795 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )"; 2796 r = run_query(hdb, rec, query); 2797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2798 MsiCloseHandle(rec); 2799 2800 MsiCloseHandle(hdb); 2801 DeleteFileA(msifile); 2802 } 2803 2804 #define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2000 */ 2805 static void test_handle_limit(void) 2806 { 2807 int i; 2808 MSIHANDLE hdb; 2809 MSIHANDLE hviews[MY_NVIEWS]; 2810 UINT r; 2811 2812 /* create an empty db */ 2813 hdb = create_db(); 2814 ok( hdb, "failed to create db\n"); 2815 2816 memset(hviews, 0, sizeof(hviews)); 2817 2818 for (i=0; i<MY_NVIEWS; i++) { 2819 static char szQueryBuf[256] = "SELECT * from `_Tables`"; 2820 hviews[i] = 0xdeadbeeb; 2821 r = MsiDatabaseOpenViewA(hdb, szQueryBuf, &hviews[i]); 2822 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb || 2823 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1]))) 2824 break; 2825 } 2826 2827 ok( i == MY_NVIEWS, "problem opening views\n"); 2828 2829 for (i=0; i<MY_NVIEWS; i++) { 2830 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) { 2831 MsiViewClose(hviews[i]); 2832 r = MsiCloseHandle(hviews[i]); 2833 if (r != ERROR_SUCCESS) 2834 break; 2835 } 2836 } 2837 2838 ok( i == MY_NVIEWS, "problem closing views\n"); 2839 2840 r = MsiCloseHandle(hdb); 2841 ok( r == ERROR_SUCCESS, "failed to close database\n"); 2842 } 2843 2844 static void generate_transform(void) 2845 { 2846 MSIHANDLE hdb1, hdb2, hrec; 2847 LPCSTR query; 2848 UINT r; 2849 2850 /* start with two identical databases */ 2851 CopyFileA(msifile2, msifile, FALSE); 2852 2853 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb1 ); 2854 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2855 2856 r = MsiDatabaseCommit( hdb1 ); 2857 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 2858 2859 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_READONLY, &hdb2 ); 2860 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2861 2862 /* the transform between two identical database should be empty */ 2863 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, NULL, 0, 0); 2864 todo_wine { 2865 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r ); 2866 } 2867 2868 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)"; 2869 r = run_query(hdb1, 0, query); 2870 ok(r == ERROR_SUCCESS, "failed to add table\n"); 2871 2872 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )"; 2873 r = run_query(hdb1, 0, query); 2874 ok(r == ERROR_SUCCESS, "failed to add row 1\n"); 2875 2876 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )"; 2877 r = run_query(hdb1, 0, query); 2878 ok(r == ERROR_SUCCESS, "failed to add row 2\n"); 2879 2880 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1"; 2881 r = run_query(hdb1, 0, query); 2882 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2883 2884 query = "DELETE FROM `MOO` WHERE `NOO` = 3"; 2885 r = run_query(hdb1, 0, query); 2886 ok(r == ERROR_SUCCESS, "failed to delete row\n"); 2887 2888 hrec = MsiCreateRecord(2); 2889 r = MsiRecordSetInteger(hrec, 1, 1); 2890 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 2891 2892 write_file("testdata.bin", "naengmyon", 9); 2893 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 2894 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 2895 2896 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 2897 r = run_query(hdb1, hrec, query); 2898 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 2899 2900 MsiCloseHandle(hrec); 2901 2902 query = "ALTER TABLE `MOO` ADD `COW` INTEGER"; 2903 r = run_query(hdb1, 0, query); 2904 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2905 2906 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER"; 2907 r = run_query(hdb1, 0, query); 2908 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2909 2910 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1"; 2911 r = run_query(hdb1, 0, query); 2912 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2913 2914 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, " 2915 "`Value` CHAR(0) PRIMARY KEY `Property`)"; 2916 r = run_query(hdb1, 0, query); 2917 ok(r == ERROR_SUCCESS, "failed to add property table\n"); 2918 2919 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )"; 2920 r = run_query(hdb1, 0, query); 2921 ok(r == ERROR_SUCCESS, "failed to add property\n"); 2922 2923 /* database needs to be committed */ 2924 MsiDatabaseCommit(hdb1); 2925 2926 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, mstfile, 0, 0); 2927 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 2928 2929 MsiCloseHandle( hdb1 ); 2930 MsiCloseHandle( hdb2 ); 2931 2932 DeleteFileA("testdata.bin"); 2933 } 2934 2935 /* data for generating a transform */ 2936 2937 /* tables transform names - encoded as they would be in an msi database file */ 2938 static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */ 2939 static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */ 2940 static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */ 2941 static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */ 2942 static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */ 2943 static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 2944 static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */ 2945 static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */ 2946 static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */ 2947 2948 /* data in each table */ 2949 static const WCHAR data1[] = { /* AAR */ 2950 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */ 2951 0x0201, 0x0009, 0x8002, 2952 }; 2953 static const WCHAR data2[] = { /* _Columns */ 2954 0x0401, 0x0001, 0x8003, 0x0002, 0x9502, 2955 0x0401, 0x0001, 0x8004, 0x0003, 0x9502, 2956 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */ 2957 0x0401, 0x0005, 0x0000, 0x0007, 0x8502, 2958 0x0401, 0x000a, 0x0000, 0x000a, 0xad48, 2959 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00, 2960 }; 2961 static const WCHAR data3[] = { /* _Tables */ 2962 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */ 2963 0x0101, 0x000a, 2964 }; 2965 static const char data4[] = /* _StringData */ 2966 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */ 2967 static const WCHAR data5[] = { /* _StringPool */ 2968 /* len, refs */ 2969 0, 0, /* string 0 '' */ 2970 3, 2, /* string 1 'MOO' */ 2971 3, 1, /* string 2 'COW' */ 2972 3, 1, /* string 3 'PIG' */ 2973 1, 1, /* string 4 'c' */ 2974 3, 3, /* string 5 'AAR' */ 2975 3, 1, /* string 6 'CAR' */ 2976 3, 1, /* string 7 'BAR' */ 2977 2, 1, /* string 8 'vw' */ 2978 3, 1, /* string 9 'bmw' */ 2979 8, 4, /* string 10 'Property' */ 2980 5, 1, /* string 11 'Value' */ 2981 4, 1, /* string 12 'prop' */ 2982 3, 1, /* string 13 'val' */ 2983 }; 2984 /* update row, 0x0002 is a bitmask of present column data, keys are excluded */ 2985 static const WCHAR data6[] = { /* MOO */ 2986 0x000a, 0x8001, 0x0004, 0x8005, /* update row */ 2987 0x0000, 0x8003, /* delete row */ 2988 }; 2989 2990 static const WCHAR data7[] = { /* BINARY */ 2991 0x0201, 0x8001, 0x0001, 2992 }; 2993 2994 static const char data8[] = /* stream data for the BINARY table */ 2995 "naengmyon"; 2996 2997 static const WCHAR data9[] = { /* Property */ 2998 0x0201, 0x000c, 0x000d, 2999 }; 3000 3001 static const struct { 3002 LPCWSTR name; 3003 const void *data; 3004 DWORD size; 3005 } table_transform_data[] = 3006 { 3007 { name1, data1, sizeof data1 }, 3008 { name2, data2, sizeof data2 }, 3009 { name3, data3, sizeof data3 }, 3010 { name4, data4, sizeof data4 - 1 }, 3011 { name5, data5, sizeof data5 }, 3012 { name6, data6, sizeof data6 }, 3013 { name7, data7, sizeof data7 }, 3014 { name8, data8, sizeof data8 - 1 }, 3015 { name9, data9, sizeof data9 }, 3016 }; 3017 3018 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0]) 3019 3020 static void generate_transform_manual(void) 3021 { 3022 IStorage *stg = NULL; 3023 IStream *stm; 3024 WCHAR name[0x20]; 3025 HRESULT r; 3026 DWORD i, count; 3027 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE; 3028 3029 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}}; 3030 3031 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20); 3032 3033 r = StgCreateDocfile(name, mode, 0, &stg); 3034 ok(r == S_OK, "failed to create storage\n"); 3035 if (!stg) 3036 return; 3037 3038 r = IStorage_SetClass( stg, &CLSID_MsiTransform ); 3039 ok(r == S_OK, "failed to set storage type\n"); 3040 3041 for (i=0; i<NUM_TRANSFORM_TABLES; i++) 3042 { 3043 r = IStorage_CreateStream( stg, table_transform_data[i].name, 3044 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm ); 3045 if (FAILED(r)) 3046 { 3047 ok(0, "failed to create stream %08x\n", r); 3048 continue; 3049 } 3050 3051 r = IStream_Write( stm, table_transform_data[i].data, 3052 table_transform_data[i].size, &count ); 3053 if (FAILED(r) || count != table_transform_data[i].size) 3054 ok(0, "failed to write stream\n"); 3055 IStream_Release(stm); 3056 } 3057 3058 IStorage_Release(stg); 3059 } 3060 3061 static UINT set_summary_info(MSIHANDLE hdb) 3062 { 3063 UINT res; 3064 MSIHANDLE suminfo; 3065 3066 /* build summary info */ 3067 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); 3068 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); 3069 3070 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, 3071 "Installation Database"); 3072 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3073 3074 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, 3075 "Installation Database"); 3076 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3077 3078 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, 3079 "Wine Hackers"); 3080 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3081 3082 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, 3083 ";1033,2057"); 3084 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3085 3086 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, 3087 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); 3088 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3089 3090 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); 3091 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3092 3093 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); 3094 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3095 3096 res = MsiSummaryInfoPersist(suminfo); 3097 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); 3098 3099 res = MsiCloseHandle( suminfo); 3100 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); 3101 3102 return res; 3103 } 3104 3105 static MSIHANDLE create_package_db(const WCHAR *filename) 3106 { 3107 MSIHANDLE hdb = 0; 3108 UINT res; 3109 3110 DeleteFileW(msifileW); 3111 3112 /* create an empty database */ 3113 res = MsiOpenDatabaseW(filename, MSIDBOPEN_CREATE, &hdb ); 3114 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 3115 if( res != ERROR_SUCCESS ) 3116 return hdb; 3117 3118 res = MsiDatabaseCommit( hdb ); 3119 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 3120 3121 res = set_summary_info(hdb); 3122 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3123 3124 res = create_directory_table(hdb); 3125 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); 3126 3127 return hdb; 3128 } 3129 3130 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) 3131 { 3132 UINT res; 3133 CHAR szPackage[12]; 3134 MSIHANDLE hPackage; 3135 3136 sprintf(szPackage, "#%u", hdb); 3137 res = MsiOpenPackageA(szPackage, &hPackage); 3138 if (res != ERROR_SUCCESS) 3139 return res; 3140 3141 res = MsiCloseHandle(hdb); 3142 if (res != ERROR_SUCCESS) 3143 { 3144 MsiCloseHandle(hPackage); 3145 return res; 3146 } 3147 3148 *handle = hPackage; 3149 return ERROR_SUCCESS; 3150 } 3151 3152 static void test_try_transform(void) 3153 { 3154 MSIHANDLE hdb, hview, hrec, hpkg = 0; 3155 LPCSTR query; 3156 UINT r; 3157 DWORD sz; 3158 char buffer[MAX_PATH]; 3159 3160 DeleteFileA(msifile); 3161 DeleteFileA(mstfile); 3162 3163 /* create the database */ 3164 hdb = create_package_db(msifileW); 3165 ok(hdb, "Failed to create package db\n"); 3166 3167 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)"; 3168 r = run_query(hdb, 0, query); 3169 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3170 3171 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )"; 3172 r = run_query(hdb, 0, query); 3173 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3174 3175 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )"; 3176 r = run_query(hdb, 0, query); 3177 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3178 3179 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )"; 3180 r = run_query(hdb, 0, query); 3181 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3182 3183 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)"; 3184 r = run_query(hdb, 0, query); 3185 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3186 3187 hrec = MsiCreateRecord(2); 3188 r = MsiRecordSetInteger(hrec, 1, 2); 3189 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 3190 3191 write_file("testdata.bin", "lamyon", 6); 3192 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 3193 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 3194 3195 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 3196 r = run_query(hdb, hrec, query); 3197 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 3198 3199 MsiCloseHandle(hrec); 3200 3201 r = MsiDatabaseCommit( hdb ); 3202 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3203 3204 MsiCloseHandle( hdb ); 3205 DeleteFileA("testdata.bin"); 3206 3207 /* 3208 * Both these generate an equivalent transform, 3209 * but the first doesn't work in Wine yet 3210 * because MsiDatabaseGenerateTransform is unimplemented. 3211 */ 3212 if (0) 3213 generate_transform(); 3214 else 3215 generate_transform_manual(); 3216 3217 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb ); 3218 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 3219 3220 r = MsiDatabaseApplyTransformA( hdb, mstfile, 0 ); 3221 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 3222 3223 r = MsiDatabaseCommit( hdb ); 3224 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3225 3226 /* check new values */ 3227 hrec = 0; 3228 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'"; 3229 r = do_query(hdb, query, &hrec); 3230 ok(r == ERROR_SUCCESS, "select query failed\n"); 3231 MsiCloseHandle(hrec); 3232 3233 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'"; 3234 hrec = 0; 3235 r = do_query(hdb, query, &hrec); 3236 ok(r == ERROR_SUCCESS, "select query failed\n"); 3237 MsiCloseHandle(hrec); 3238 3239 /* check updated values */ 3240 hrec = 0; 3241 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'"; 3242 r = do_query(hdb, query, &hrec); 3243 ok(r == ERROR_SUCCESS, "select query failed\n"); 3244 MsiCloseHandle(hrec); 3245 3246 /* check unchanged value */ 3247 hrec = 0; 3248 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'"; 3249 r = do_query(hdb, query, &hrec); 3250 ok(r == ERROR_SUCCESS, "select query failed\n"); 3251 MsiCloseHandle(hrec); 3252 3253 /* check deleted value */ 3254 hrec = 0; 3255 query = "select * from `MOO` where `NOO` = 3"; 3256 r = do_query(hdb, query, &hrec); 3257 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n"); 3258 if (hrec) MsiCloseHandle(hrec); 3259 3260 /* check added stream */ 3261 hrec = 0; 3262 query = "select `BLOB` from `BINARY` where `ID` = 1"; 3263 r = do_query(hdb, query, &hrec); 3264 ok(r == ERROR_SUCCESS, "select query failed\n"); 3265 3266 /* check the contents of the stream */ 3267 sz = sizeof buffer; 3268 r = MsiRecordReadStream( hrec, 1, buffer, &sz ); 3269 ok(r == ERROR_SUCCESS, "read stream failed\n"); 3270 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n"); 3271 ok(sz == 9, "stream data was wrong size\n"); 3272 if (hrec) MsiCloseHandle(hrec); 3273 3274 /* check the validity of the table with a deleted row */ 3275 hrec = 0; 3276 query = "select * from `MOO`"; 3277 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3278 ok(r == ERROR_SUCCESS, "open view failed\n"); 3279 3280 r = MsiViewExecute(hview, 0); 3281 ok(r == ERROR_SUCCESS, "view execute failed\n"); 3282 3283 r = MsiViewFetch(hview, &hrec); 3284 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3285 3286 r = MsiRecordGetInteger(hrec, 1); 3287 ok(r == 1, "Expected 1, got %d\n", r); 3288 3289 sz = sizeof buffer; 3290 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3291 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3292 ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer); 3293 3294 r = MsiRecordGetInteger(hrec, 3); 3295 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3296 3297 r = MsiRecordGetInteger(hrec, 4); 3298 ok(r == 5, "Expected 5, got %d\n", r); 3299 3300 MsiCloseHandle(hrec); 3301 3302 r = MsiViewFetch(hview, &hrec); 3303 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3304 3305 r = MsiRecordGetInteger(hrec, 1); 3306 ok(r == 2, "Expected 2, got %d\n", r); 3307 3308 sz = sizeof buffer; 3309 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3310 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3311 ok(!lstrcmpA(buffer, "b"), "Expected b, got %s\n", buffer); 3312 3313 r = MsiRecordGetInteger(hrec, 3); 3314 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3315 3316 r = MsiRecordGetInteger(hrec, 4); 3317 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3318 3319 MsiCloseHandle(hrec); 3320 3321 r = MsiViewFetch(hview, &hrec); 3322 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n"); 3323 3324 MsiCloseHandle(hrec); 3325 MsiViewClose(hview); 3326 MsiCloseHandle(hview); 3327 3328 /* check that the property was added */ 3329 r = package_from_db(hdb, &hpkg); 3330 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3331 { 3332 skip("Not enough rights to perform tests\n"); 3333 goto error; 3334 } 3335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 3336 3337 sz = MAX_PATH; 3338 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz); 3339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3340 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer); 3341 3342 MsiCloseHandle(hpkg); 3343 3344 error: 3345 MsiCloseHandle(hdb); 3346 DeleteFileA(msifile); 3347 DeleteFileA(mstfile); 3348 } 3349 3350 struct join_res 3351 { 3352 const CHAR one[MAX_PATH]; 3353 const CHAR two[MAX_PATH]; 3354 }; 3355 3356 struct join_res_4col 3357 { 3358 const CHAR one[MAX_PATH]; 3359 const CHAR two[MAX_PATH]; 3360 const CHAR three[MAX_PATH]; 3361 const CHAR four[MAX_PATH]; 3362 }; 3363 3364 struct join_res_uint 3365 { 3366 UINT one; 3367 UINT two; 3368 UINT three; 3369 UINT four; 3370 UINT five; 3371 UINT six; 3372 }; 3373 3374 static const struct join_res join_res_first[] = 3375 { 3376 { "alveolar", "procerus" }, 3377 { "septum", "procerus" }, 3378 { "septum", "nasalis" }, 3379 { "ramus", "nasalis" }, 3380 { "malar", "mentalis" }, 3381 }; 3382 3383 static const struct join_res join_res_second[] = 3384 { 3385 { "nasal", "septum" }, 3386 { "mandible", "ramus" }, 3387 }; 3388 3389 static const struct join_res join_res_third[] = 3390 { 3391 { "msvcp.dll", "abcdefgh" }, 3392 { "msvcr.dll", "ijklmnop" }, 3393 }; 3394 3395 static const struct join_res join_res_fourth[] = 3396 { 3397 { "msvcp.dll.01234", "single.dll.31415" }, 3398 }; 3399 3400 static const struct join_res join_res_fifth[] = 3401 { 3402 { "malar", "procerus" }, 3403 }; 3404 3405 static const struct join_res join_res_sixth[] = 3406 { 3407 { "malar", "procerus" }, 3408 { "malar", "procerus" }, 3409 { "malar", "nasalis" }, 3410 { "malar", "nasalis" }, 3411 { "malar", "nasalis" }, 3412 { "malar", "mentalis" }, 3413 }; 3414 3415 static const struct join_res join_res_seventh[] = 3416 { 3417 { "malar", "nasalis" }, 3418 { "malar", "nasalis" }, 3419 { "malar", "nasalis" }, 3420 }; 3421 3422 static const struct join_res_4col join_res_eighth[] = 3423 { 3424 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" }, 3425 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" }, 3426 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" }, 3427 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" }, 3428 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" }, 3429 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" }, 3430 }; 3431 3432 static const struct join_res_uint join_res_ninth[] = 3433 { 3434 { 1, 2, 3, 4, 7, 8 }, 3435 { 1, 2, 5, 6, 7, 8 }, 3436 { 1, 2, 3, 4, 9, 10 }, 3437 { 1, 2, 5, 6, 9, 10 }, 3438 { 1, 2, 3, 4, 11, 12 }, 3439 { 1, 2, 5, 6, 11, 12 }, 3440 }; 3441 3442 static void test_join(void) 3443 { 3444 MSIHANDLE hdb, hview, hrec; 3445 LPCSTR query; 3446 CHAR buf[MAX_PATH]; 3447 UINT r, count; 3448 DWORD size, i; 3449 BOOL data_correct; 3450 3451 hdb = create_db(); 3452 ok( hdb, "failed to create db\n"); 3453 3454 r = create_component_table( hdb ); 3455 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); 3456 3457 r = add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" ); 3458 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3459 3460 r = add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" ); 3461 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3462 3463 r = add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" ); 3464 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3465 3466 r = add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" ); 3467 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); 3468 3469 r = create_feature_components_table( hdb ); 3470 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); 3471 3472 r = add_feature_components_entry( hdb, "'procerus', 'maxilla'" ); 3473 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3474 3475 r = add_feature_components_entry( hdb, "'procerus', 'nasal'" ); 3476 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3477 3478 r = add_feature_components_entry( hdb, "'nasalis', 'nasal'" ); 3479 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3480 3481 r = add_feature_components_entry( hdb, "'nasalis', 'mandible'" ); 3482 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3483 3484 r = add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" ); 3485 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3486 3487 r = add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" ); 3488 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); 3489 3490 r = create_std_dlls_table( hdb ); 3491 ok( r == ERROR_SUCCESS, "cannot create StdDlls table: %d\n", r ); 3492 3493 r = add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" ); 3494 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); 3495 3496 r = add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" ); 3497 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); 3498 3499 r = create_binary_table( hdb ); 3500 ok( r == ERROR_SUCCESS, "cannot create Binary table: %d\n", r ); 3501 3502 r = add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" ); 3503 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3504 3505 r = add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" ); 3506 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3507 3508 r = add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" ); 3509 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); 3510 3511 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 3512 r = run_query( hdb, 0, query); 3513 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3514 3515 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)"; 3516 r = run_query( hdb, 0, query); 3517 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3518 3519 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)"; 3520 r = run_query( hdb, 0, query); 3521 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3522 3523 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)"; 3524 r = run_query( hdb, 0, query); 3525 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3526 3527 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)"; 3528 r = run_query( hdb, 0, query); 3529 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3530 3531 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)"; 3532 r = run_query( hdb, 0, query); 3533 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3534 3535 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)"; 3536 r = run_query( hdb, 0, query); 3537 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3538 3539 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)"; 3540 r = run_query( hdb, 0, query); 3541 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3542 3543 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)"; 3544 r = run_query( hdb, 0, query); 3545 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3546 3547 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)"; 3548 r = run_query( hdb, 0, query); 3549 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3550 3551 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)"; 3552 r = run_query( hdb, 0, query); 3553 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3554 3555 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)"; 3556 r = run_query( hdb, 0, query); 3557 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3558 3559 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)"; 3560 r = run_query( hdb, 0, query); 3561 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3562 3563 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3564 "FROM `Component`, `FeatureComponents` " 3565 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 3566 "ORDER BY `Feature_`"; 3567 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3568 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3569 3570 r = MsiViewExecute(hview, 0); 3571 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3572 3573 i = 0; 3574 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3575 { 3576 count = MsiRecordGetFieldCount( hrec ); 3577 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3578 3579 size = MAX_PATH; 3580 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3581 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3582 ok( !lstrcmpA( buf, join_res_first[i].one ), 3583 "For (row %d, column 1) expected '%s', got %s\n", i, join_res_first[i].one, buf ); 3584 3585 size = MAX_PATH; 3586 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3587 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3588 ok( !lstrcmpA( buf, join_res_first[i].two ), 3589 "For (row %d, column 2) expected '%s', got %s\n", i, join_res_first[i].two, buf ); 3590 3591 i++; 3592 MsiCloseHandle(hrec); 3593 } 3594 3595 ok( i == 5, "Expected 5 rows, got %d\n", i ); 3596 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3597 3598 MsiViewClose(hview); 3599 MsiCloseHandle(hview); 3600 3601 /* try a join without a WHERE condition */ 3602 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3603 "FROM `Component`, `FeatureComponents` "; 3604 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3605 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3606 3607 r = MsiViewExecute(hview, 0); 3608 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3609 3610 i = 0; 3611 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3612 { 3613 i++; 3614 MsiCloseHandle(hrec); 3615 } 3616 ok( i == 24, "Expected 24 rows, got %d\n", i ); 3617 3618 MsiViewClose(hview); 3619 MsiCloseHandle(hview); 3620 3621 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component " 3622 "WHERE FeatureComponents.Component_=Component.Component " 3623 "AND (Feature_='nasalis') ORDER BY Feature_"; 3624 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3625 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3626 3627 r = MsiViewExecute(hview, 0); 3628 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3629 3630 i = 0; 3631 data_correct = TRUE; 3632 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3633 { 3634 count = MsiRecordGetFieldCount( hrec ); 3635 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3636 3637 size = MAX_PATH; 3638 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3639 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3640 if( lstrcmpA( buf, join_res_second[i].one )) 3641 data_correct = FALSE; 3642 3643 size = MAX_PATH; 3644 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3645 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3646 if( lstrcmpA( buf, join_res_second[i].two )) 3647 data_correct = FALSE; 3648 3649 i++; 3650 MsiCloseHandle(hrec); 3651 } 3652 3653 ok( data_correct, "data returned in the wrong order\n"); 3654 3655 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3656 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3657 3658 MsiViewClose(hview); 3659 MsiCloseHandle(hview); 3660 3661 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3662 "FROM `StdDlls`, `Binary` " 3663 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` " 3664 "ORDER BY `File`"; 3665 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3666 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3667 3668 r = MsiViewExecute(hview, 0); 3669 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3670 3671 i = 0; 3672 data_correct = TRUE; 3673 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3674 { 3675 count = MsiRecordGetFieldCount( hrec ); 3676 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3677 3678 size = MAX_PATH; 3679 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3680 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3681 if( lstrcmpA( buf, join_res_third[i].one ) ) 3682 data_correct = FALSE; 3683 3684 size = MAX_PATH; 3685 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3686 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3687 if( lstrcmpA( buf, join_res_third[i].two ) ) 3688 data_correct = FALSE; 3689 3690 i++; 3691 MsiCloseHandle(hrec); 3692 } 3693 ok( data_correct, "data returned in the wrong order\n"); 3694 3695 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3696 3697 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3698 3699 MsiViewClose(hview); 3700 MsiCloseHandle(hview); 3701 3702 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` " 3703 "FROM `StdDlls`, `Binary` " 3704 "WHERE `StdDlls`.`File` = `Binary`.`Data` " 3705 "ORDER BY `Name`"; 3706 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3707 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3708 3709 r = MsiViewExecute(hview, 0); 3710 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3711 3712 i = 0; 3713 data_correct = TRUE; 3714 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3715 { 3716 count = MsiRecordGetFieldCount( hrec ); 3717 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3718 3719 size = MAX_PATH; 3720 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3721 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3722 if( lstrcmpA( buf, join_res_fourth[i].one )) 3723 data_correct = FALSE; 3724 3725 size = MAX_PATH; 3726 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3727 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3728 if( lstrcmpA( buf, join_res_fourth[i].two )) 3729 data_correct = FALSE; 3730 3731 i++; 3732 MsiCloseHandle(hrec); 3733 } 3734 ok( data_correct, "data returned in the wrong order\n"); 3735 3736 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3737 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3738 3739 MsiViewClose(hview); 3740 MsiCloseHandle(hview); 3741 3742 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3743 "FROM `Component`, `FeatureComponents` " 3744 "WHERE `Component`.`Component` = 'zygomatic' " 3745 "AND `FeatureComponents`.`Component_` = 'maxilla' " 3746 "ORDER BY `Feature_`"; 3747 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3748 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3749 3750 r = MsiViewExecute(hview, 0); 3751 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3752 3753 i = 0; 3754 data_correct = TRUE; 3755 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3756 { 3757 count = MsiRecordGetFieldCount( hrec ); 3758 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3759 3760 size = MAX_PATH; 3761 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3762 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3763 if( lstrcmpA( buf, join_res_fifth[i].one )) 3764 data_correct = FALSE; 3765 3766 size = MAX_PATH; 3767 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3768 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3769 if( lstrcmpA( buf, join_res_fifth[i].two )) 3770 data_correct = FALSE; 3771 3772 i++; 3773 MsiCloseHandle(hrec); 3774 } 3775 ok( data_correct, "data returned in the wrong order\n"); 3776 3777 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3778 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3779 3780 MsiViewClose(hview); 3781 MsiCloseHandle(hview); 3782 3783 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3784 "FROM `Component`, `FeatureComponents` " 3785 "WHERE `Component` = 'zygomatic' " 3786 "ORDER BY `Feature_`"; 3787 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3788 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3789 3790 r = MsiViewExecute(hview, 0); 3791 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3792 3793 i = 0; 3794 data_correct = TRUE; 3795 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3796 { 3797 count = MsiRecordGetFieldCount( hrec ); 3798 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3799 3800 size = MAX_PATH; 3801 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3802 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3803 if( lstrcmpA( buf, join_res_sixth[i].one )) 3804 data_correct = FALSE; 3805 3806 size = MAX_PATH; 3807 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3808 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3809 if( lstrcmpA( buf, join_res_sixth[i].two )) 3810 data_correct = FALSE; 3811 3812 i++; 3813 MsiCloseHandle(hrec); 3814 } 3815 ok( data_correct, "data returned in the wrong order\n"); 3816 3817 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3818 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3819 3820 MsiViewClose(hview); 3821 MsiCloseHandle(hview); 3822 3823 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3824 "FROM `Component`, `FeatureComponents` " 3825 "WHERE `Component` = 'zygomatic' " 3826 "AND `Feature_` = 'nasalis' " 3827 "ORDER BY `Feature_`"; 3828 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3829 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3830 3831 r = MsiViewExecute(hview, 0); 3832 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3833 3834 i = 0; 3835 data_correct = TRUE; 3836 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3837 { 3838 count = MsiRecordGetFieldCount( hrec ); 3839 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3840 3841 size = MAX_PATH; 3842 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3843 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3844 if( lstrcmpA( buf, join_res_seventh[i].one )) 3845 data_correct = FALSE; 3846 3847 size = MAX_PATH; 3848 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3849 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3850 if( lstrcmpA( buf, join_res_seventh[i].two )) 3851 data_correct = FALSE; 3852 3853 i++; 3854 MsiCloseHandle(hrec); 3855 } 3856 3857 ok( data_correct, "data returned in the wrong order\n"); 3858 ok( i == 3, "Expected 3 rows, got %d\n", i ); 3859 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3860 3861 MsiViewClose(hview); 3862 MsiCloseHandle(hview); 3863 3864 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3865 "FROM `StdDlls`, `Binary` "; 3866 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3867 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3868 3869 r = MsiViewExecute(hview, 0); 3870 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3871 3872 i = 0; 3873 data_correct = TRUE; 3874 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3875 { 3876 count = MsiRecordGetFieldCount( hrec ); 3877 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3878 3879 size = MAX_PATH; 3880 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3881 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3882 if( lstrcmpA( buf, join_res_eighth[i].one )) 3883 data_correct = FALSE; 3884 3885 size = MAX_PATH; 3886 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3887 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3888 if( lstrcmpA( buf, join_res_eighth[i].four )) 3889 data_correct = FALSE; 3890 3891 i++; 3892 MsiCloseHandle(hrec); 3893 } 3894 3895 ok( data_correct, "data returned in the wrong order\n"); 3896 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3897 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3898 3899 MsiViewClose(hview); 3900 MsiCloseHandle(hview); 3901 3902 query = "SELECT * FROM `StdDlls`, `Binary` "; 3903 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3904 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3905 3906 r = MsiViewExecute(hview, 0); 3907 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3908 3909 i = 0; 3910 data_correct = TRUE; 3911 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3912 { 3913 count = MsiRecordGetFieldCount( hrec ); 3914 ok( count == 4, "Expected 4 record fields, got %d\n", count ); 3915 3916 size = MAX_PATH; 3917 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3918 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3919 if( lstrcmpA( buf, join_res_eighth[i].one )) 3920 data_correct = FALSE; 3921 3922 size = MAX_PATH; 3923 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3924 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3925 if( lstrcmpA( buf, join_res_eighth[i].two )) 3926 data_correct = FALSE; 3927 3928 size = MAX_PATH; 3929 r = MsiRecordGetStringA( hrec, 3, buf, &size ); 3930 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3931 if( lstrcmpA( buf, join_res_eighth[i].three )) 3932 data_correct = FALSE; 3933 3934 size = MAX_PATH; 3935 r = MsiRecordGetStringA( hrec, 4, buf, &size ); 3936 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3937 if( lstrcmpA( buf, join_res_eighth[i].four )) 3938 data_correct = FALSE; 3939 3940 i++; 3941 MsiCloseHandle(hrec); 3942 } 3943 ok( data_correct, "data returned in the wrong order\n"); 3944 3945 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3946 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3947 3948 MsiViewClose(hview); 3949 MsiCloseHandle(hview); 3950 3951 query = "SELECT * FROM `One`, `Two`, `Three` "; 3952 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3953 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3954 3955 r = MsiViewExecute(hview, 0); 3956 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3957 3958 i = 0; 3959 data_correct = TRUE; 3960 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3961 { 3962 count = MsiRecordGetFieldCount( hrec ); 3963 ok( count == 6, "Expected 6 record fields, got %d\n", count ); 3964 3965 r = MsiRecordGetInteger( hrec, 1 ); 3966 if( r != join_res_ninth[i].one ) 3967 data_correct = FALSE; 3968 3969 r = MsiRecordGetInteger( hrec, 2 ); 3970 if( r != join_res_ninth[i].two ) 3971 data_correct = FALSE; 3972 3973 r = MsiRecordGetInteger( hrec, 3 ); 3974 if( r != join_res_ninth[i].three ) 3975 data_correct = FALSE; 3976 3977 r = MsiRecordGetInteger( hrec, 4 ); 3978 if( r != join_res_ninth[i].four ) 3979 data_correct = FALSE; 3980 3981 r = MsiRecordGetInteger( hrec, 5 ); 3982 if( r != join_res_ninth[i].five ) 3983 data_correct = FALSE; 3984 3985 r = MsiRecordGetInteger( hrec, 6); 3986 if( r != join_res_ninth[i].six ) 3987 data_correct = FALSE; 3988 3989 i++; 3990 MsiCloseHandle(hrec); 3991 } 3992 ok( data_correct, "data returned in the wrong order\n"); 3993 3994 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3995 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3996 3997 MsiViewClose(hview); 3998 MsiCloseHandle(hview); 3999 4000 query = "SELECT * FROM `Four`, `Five`"; 4001 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4002 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 4003 4004 r = MsiViewExecute(hview, 0); 4005 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 4006 4007 r = MsiViewFetch(hview, &hrec); 4008 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4009 4010 MsiViewClose(hview); 4011 MsiCloseHandle(hview); 4012 4013 query = "SELECT * FROM `Nonexistent`, `One`"; 4014 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4015 ok( r == ERROR_BAD_QUERY_SYNTAX, 4016 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r ); 4017 4018 /* try updating a row in a join table */ 4019 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 4020 "FROM `Component`, `FeatureComponents` " 4021 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 4022 "ORDER BY `Feature_`"; 4023 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4024 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 4025 4026 r = MsiViewExecute(hview, 0); 4027 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 4028 4029 r = MsiViewFetch(hview, &hrec); 4030 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 4031 4032 r = MsiRecordSetStringA( hrec, 1, "epicranius" ); 4033 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4034 4035 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4036 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r ); 4037 4038 /* try another valid operation for joins */ 4039 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 4040 todo_wine ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r ); 4041 4042 /* try an invalid operation for joins */ 4043 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 4044 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); 4045 4046 r = MsiRecordSetStringA( hrec, 2, "epicranius" ); 4047 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4048 4049 /* primary key cannot be updated */ 4050 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4051 ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r ); 4052 4053 MsiCloseHandle(hrec); 4054 MsiViewClose(hview); 4055 MsiCloseHandle(hview); 4056 4057 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4058 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4059 4060 r = MsiViewExecute(hview, 0); 4061 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4062 4063 r = MsiViewFetch(hview, &hrec); 4064 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4065 4066 size = MAX_PATH; 4067 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 4068 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 4069 ok( !lstrcmpA( buf, "epicranius" ), "expected 'epicranius', got %s\n", buf ); 4070 4071 MsiCloseHandle(hrec); 4072 MsiViewClose(hview); 4073 MsiCloseHandle(hview); 4074 4075 MsiCloseHandle(hdb); 4076 DeleteFileA(msifile); 4077 } 4078 4079 static void test_temporary_table(void) 4080 { 4081 MSICONDITION cond; 4082 MSIHANDLE hdb = 0, view = 0, rec; 4083 const char *query; 4084 UINT r; 4085 char buf[0x10]; 4086 DWORD sz; 4087 4088 cond = MsiDatabaseIsTablePersistentA(0, NULL); 4089 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4090 4091 hdb = create_db(); 4092 ok( hdb, "failed to create db\n"); 4093 4094 cond = MsiDatabaseIsTablePersistentA(hdb, NULL); 4095 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4096 4097 cond = MsiDatabaseIsTablePersistentA(hdb, "_Tables"); 4098 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4099 4100 cond = MsiDatabaseIsTablePersistentA(hdb, "_Columns"); 4101 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4102 4103 cond = MsiDatabaseIsTablePersistentA(hdb, "_Storages"); 4104 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4105 4106 cond = MsiDatabaseIsTablePersistentA(hdb, "_Streams"); 4107 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4108 4109 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)"; 4110 r = run_query(hdb, 0, query); 4111 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4112 4113 cond = MsiDatabaseIsTablePersistentA(hdb, "P"); 4114 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4115 4116 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD"; 4117 r = run_query(hdb, 0, query); 4118 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4119 4120 cond = MsiDatabaseIsTablePersistentA(hdb, "P2"); 4121 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4122 4123 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4124 r = run_query(hdb, 0, query); 4125 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4126 4127 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4128 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4129 4130 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4131 r = run_query(hdb, 0, query); 4132 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4133 4134 query = "SELECT * FROM `T2`"; 4135 r = MsiDatabaseOpenViewA(hdb, query, &view); 4136 ok(r == ERROR_BAD_QUERY_SYNTAX, 4137 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4138 4139 cond = MsiDatabaseIsTablePersistentA(hdb, "T2"); 4140 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4141 4142 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)"; 4143 r = run_query(hdb, 0, query); 4144 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4145 4146 cond = MsiDatabaseIsTablePersistentA(hdb, "T3"); 4147 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4148 4149 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4150 r = run_query(hdb, 0, query); 4151 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n"); 4152 4153 cond = MsiDatabaseIsTablePersistentA(hdb, "T4"); 4154 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4155 4156 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD"; 4157 r = run_query(hdb, 0, query); 4158 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n"); 4159 4160 query = "select * from `T`"; 4161 r = MsiDatabaseOpenViewA(hdb, query, &view); 4162 ok(r == ERROR_SUCCESS, "failed to query table\n"); 4163 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4164 ok(r == ERROR_SUCCESS, "failed to get column info\n"); 4165 4166 sz = sizeof buf; 4167 r = MsiRecordGetStringA(rec, 1, buf, &sz); 4168 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4169 ok( 0 == strcmp("G255", buf), "wrong column type\n"); 4170 4171 sz = sizeof buf; 4172 r = MsiRecordGetStringA(rec, 2, buf, &sz); 4173 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4174 ok( 0 == strcmp("j2", buf), "wrong column type\n"); 4175 4176 MsiCloseHandle( rec ); 4177 MsiViewClose( view ); 4178 MsiCloseHandle( view ); 4179 4180 /* query the table data */ 4181 rec = 0; 4182 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec); 4183 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n"); 4184 MsiCloseHandle( rec ); 4185 4186 /* query the column data */ 4187 rec = 0; 4188 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec); 4189 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4190 if (rec) MsiCloseHandle( rec ); 4191 4192 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec); 4193 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4194 if (rec) MsiCloseHandle( rec ); 4195 4196 MsiCloseHandle( hdb ); 4197 DeleteFileA(msifile); 4198 } 4199 4200 static void test_alter(void) 4201 { 4202 MSICONDITION cond; 4203 MSIHANDLE hdb = 0; 4204 const char *query; 4205 UINT r; 4206 4207 hdb = create_db(); 4208 ok( hdb, "failed to create db\n"); 4209 4210 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4211 r = run_query(hdb, 0, query); 4212 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4213 4214 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4215 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4216 4217 query = "ALTER TABLE `T` HOLD"; 4218 r = run_query(hdb, 0, query); 4219 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r); 4220 4221 query = "ALTER TABLE `T` FREE"; 4222 r = run_query(hdb, 0, query); 4223 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4224 4225 query = "ALTER TABLE `T` FREE"; 4226 r = run_query(hdb, 0, query); 4227 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4228 4229 query = "ALTER TABLE `T` FREE"; 4230 r = run_query(hdb, 0, query); 4231 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n"); 4232 4233 query = "ALTER TABLE `T` HOLD"; 4234 r = run_query(hdb, 0, query); 4235 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r); 4236 4237 /* table T is removed */ 4238 query = "SELECT * FROM `T`"; 4239 r = run_query(hdb, 0, query); 4240 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4241 4242 /* create the table again */ 4243 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)"; 4244 r = run_query(hdb, 0, query); 4245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4246 4247 /* up the ref count */ 4248 query = "ALTER TABLE `U` HOLD"; 4249 r = run_query(hdb, 0, query); 4250 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4251 4252 /* add column, no data type */ 4253 query = "ALTER TABLE `U` ADD `C`"; 4254 r = run_query(hdb, 0, query); 4255 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4256 4257 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4258 r = run_query(hdb, 0, query); 4259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4260 4261 /* add column C again */ 4262 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4263 r = run_query(hdb, 0, query); 4264 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4265 4266 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY"; 4267 r = run_query(hdb, 0, query); 4268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4269 4270 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )"; 4271 r = run_query(hdb, 0, query); 4272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4273 4274 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD"; 4275 r = run_query(hdb, 0, query); 4276 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4277 4278 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )"; 4279 r = run_query(hdb, 0, query); 4280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4281 4282 query = "SELECT * FROM `U` WHERE `D` = 8"; 4283 r = run_query(hdb, 0, query); 4284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4285 4286 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE"; 4287 r = run_query(hdb, 0, query); 4288 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4289 4290 query = "ALTER COLUMN `D` FREE"; 4291 r = run_query(hdb, 0, query); 4292 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4293 4294 /* drop the ref count */ 4295 query = "ALTER TABLE `U` FREE"; 4296 r = run_query(hdb, 0, query); 4297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4298 4299 /* table is not empty */ 4300 query = "SELECT * FROM `U`"; 4301 r = run_query(hdb, 0, query); 4302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4303 4304 /* column D is removed */ 4305 query = "SELECT * FROM `U` WHERE `D` = 8"; 4306 r = run_query(hdb, 0, query); 4307 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4308 4309 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )"; 4310 r = run_query(hdb, 0, query); 4311 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4312 4313 /* add the column again */ 4314 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD"; 4315 r = run_query(hdb, 0, query); 4316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4317 4318 /* up the ref count */ 4319 query = "ALTER TABLE `U` HOLD"; 4320 r = run_query(hdb, 0, query); 4321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4322 4323 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )"; 4324 r = run_query(hdb, 0, query); 4325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4326 4327 query = "SELECT * FROM `U` WHERE `E` = 16"; 4328 r = run_query(hdb, 0, query); 4329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4330 4331 /* drop the ref count */ 4332 query = "ALTER TABLE `U` FREE"; 4333 r = run_query(hdb, 0, query); 4334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4335 4336 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )"; 4337 r = run_query(hdb, 0, query); 4338 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4339 4340 query = "SELECT * FROM `U` WHERE `E` = 20"; 4341 r = run_query(hdb, 0, query); 4342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4343 4344 /* drop the ref count */ 4345 query = "ALTER TABLE `U` FREE"; 4346 r = run_query(hdb, 0, query); 4347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4348 4349 /* table still exists */ 4350 query = "SELECT * FROM `U`"; 4351 r = run_query(hdb, 0, query); 4352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4353 4354 /* col E is removed */ 4355 query = "SELECT * FROM `U` WHERE `E` = 20"; 4356 r = run_query(hdb, 0, query); 4357 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4358 4359 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )"; 4360 r = run_query(hdb, 0, query); 4361 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4362 4363 /* drop the ref count once more */ 4364 query = "ALTER TABLE `U` FREE"; 4365 r = run_query(hdb, 0, query); 4366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4367 4368 /* table still exists */ 4369 query = "SELECT * FROM `U`"; 4370 r = run_query(hdb, 0, query); 4371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4372 4373 MsiCloseHandle( hdb ); 4374 DeleteFileA(msifile); 4375 } 4376 4377 static void test_integers(void) 4378 { 4379 MSIHANDLE hdb = 0, view = 0, rec = 0; 4380 DWORD count, i; 4381 const char *query; 4382 UINT r; 4383 4384 /* just MsiOpenDatabase should not create a file */ 4385 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4386 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4387 4388 /* create a table */ 4389 query = "CREATE TABLE `integers` ( " 4390 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, " 4391 "`five` SHORT NOT NULL, `six` INT NOT NULL, " 4392 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL " 4393 "PRIMARY KEY `one`)"; 4394 r = MsiDatabaseOpenViewA(hdb, query, &view); 4395 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4396 r = MsiViewExecute(view, 0); 4397 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4398 r = MsiViewClose(view); 4399 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4400 r = MsiCloseHandle(view); 4401 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4402 4403 query = "SELECT * FROM `integers`"; 4404 r = MsiDatabaseOpenViewA(hdb, query, &view); 4405 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4406 4407 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 4408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4409 count = MsiRecordGetFieldCount(rec); 4410 ok(count == 8, "Expected 8, got %d\n", count); 4411 ok(check_record(rec, 1, "one"), "Expected one\n"); 4412 ok(check_record(rec, 2, "two"), "Expected two\n"); 4413 ok(check_record(rec, 3, "three"), "Expected three\n"); 4414 ok(check_record(rec, 4, "four"), "Expected four\n"); 4415 ok(check_record(rec, 5, "five"), "Expected five\n"); 4416 ok(check_record(rec, 6, "six"), "Expected six\n"); 4417 ok(check_record(rec, 7, "seven"), "Expected seven\n"); 4418 ok(check_record(rec, 8, "eight"), "Expected eight\n"); 4419 MsiCloseHandle(rec); 4420 4421 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4423 count = MsiRecordGetFieldCount(rec); 4424 ok(count == 8, "Expected 8, got %d\n", count); 4425 ok(check_record(rec, 1, "I2"), "Expected I2\n"); 4426 ok(check_record(rec, 2, "I2"), "Expected I2\n"); 4427 ok(check_record(rec, 3, "I2"), "Expected I2\n"); 4428 ok(check_record(rec, 4, "I4"), "Expected I4\n"); 4429 ok(check_record(rec, 5, "i2"), "Expected i2\n"); 4430 ok(check_record(rec, 6, "i2"), "Expected i2\n"); 4431 ok(check_record(rec, 7, "i2"), "Expected i2\n"); 4432 ok(check_record(rec, 8, "i4"), "Expected i4\n"); 4433 MsiCloseHandle(rec); 4434 4435 MsiViewClose(view); 4436 MsiCloseHandle(view); 4437 4438 /* insert values into it, NULL where NOT NULL is specified */ 4439 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4440 "VALUES('', '', '', '', '', '', '', '')"; 4441 r = MsiDatabaseOpenViewA(hdb, query, &view); 4442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4443 r = MsiViewExecute(view, 0); 4444 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 4445 4446 MsiViewClose(view); 4447 MsiCloseHandle(view); 4448 4449 query = "SELECT * FROM `integers`"; 4450 r = do_query(hdb, query, &rec); 4451 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4452 4453 r = MsiRecordGetFieldCount(rec); 4454 ok(r == -1, "record count wrong: %d\n", r); 4455 4456 MsiCloseHandle(rec); 4457 4458 /* insert legitimate values into it */ 4459 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4460 "VALUES('', '2', '', '4', '5', '6', '7', '8')"; 4461 r = MsiDatabaseOpenViewA(hdb, query, &view); 4462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4463 r = MsiViewExecute(view, 0); 4464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4465 4466 query = "SELECT * FROM `integers`"; 4467 r = do_query(hdb, query, &rec); 4468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4469 4470 r = MsiRecordGetFieldCount(rec); 4471 ok(r == 8, "record count wrong: %d\n", r); 4472 4473 i = MsiRecordGetInteger(rec, 1); 4474 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4475 i = MsiRecordGetInteger(rec, 3); 4476 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4477 i = MsiRecordGetInteger(rec, 2); 4478 ok(i == 2, "Expected 2, got %d\n", i); 4479 i = MsiRecordGetInteger(rec, 4); 4480 ok(i == 4, "Expected 4, got %d\n", i); 4481 i = MsiRecordGetInteger(rec, 5); 4482 ok(i == 5, "Expected 5, got %d\n", i); 4483 i = MsiRecordGetInteger(rec, 6); 4484 ok(i == 6, "Expected 6, got %d\n", i); 4485 i = MsiRecordGetInteger(rec, 7); 4486 ok(i == 7, "Expected 7, got %d\n", i); 4487 i = MsiRecordGetInteger(rec, 8); 4488 ok(i == 8, "Expected 8, got %d\n", i); 4489 4490 MsiCloseHandle(rec); 4491 MsiViewClose(view); 4492 MsiCloseHandle(view); 4493 4494 r = MsiDatabaseCommit(hdb); 4495 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4496 4497 r = MsiCloseHandle(hdb); 4498 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4499 4500 r = DeleteFileA(msifile); 4501 ok(r == TRUE, "file didn't exist after commit\n"); 4502 } 4503 4504 static void test_update(void) 4505 { 4506 MSIHANDLE hdb = 0, view = 0, rec = 0; 4507 CHAR result[MAX_PATH]; 4508 const char *query; 4509 DWORD size; 4510 UINT r; 4511 4512 /* just MsiOpenDatabase should not create a file */ 4513 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4514 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4515 4516 /* create the Control table */ 4517 query = "CREATE TABLE `Control` ( " 4518 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, " 4519 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL," 4520 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, " 4521 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)"; 4522 r = MsiDatabaseOpenViewA(hdb, query, &view); 4523 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4524 r = MsiViewExecute(view, 0); 4525 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4526 r = MsiViewClose(view); 4527 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4528 r = MsiCloseHandle(view); 4529 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4530 4531 /* add a control */ 4532 query = "INSERT INTO `Control` ( " 4533 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4534 "`Property`, `Text`, `Control_Next`, `Help` )" 4535 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4536 r = MsiDatabaseOpenViewA(hdb, query, &view); 4537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4538 r = MsiViewExecute(view, 0); 4539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4540 r = MsiViewClose(view); 4541 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4542 r = MsiCloseHandle(view); 4543 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4544 4545 /* add a second control */ 4546 query = "INSERT INTO `Control` ( " 4547 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4548 "`Property`, `Text`, `Control_Next`, `Help` )" 4549 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')"; 4550 r = MsiDatabaseOpenViewA(hdb, query, &view); 4551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4552 r = MsiViewExecute(view, 0); 4553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4554 r = MsiViewClose(view); 4555 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4556 r = MsiCloseHandle(view); 4557 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4558 4559 /* add a third control */ 4560 query = "INSERT INTO `Control` ( " 4561 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4562 "`Property`, `Text`, `Control_Next`, `Help` )" 4563 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4564 r = MsiDatabaseOpenViewA(hdb, query, &view); 4565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4566 r = MsiViewExecute(view, 0); 4567 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4568 r = MsiViewClose(view); 4569 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4570 r = MsiCloseHandle(view); 4571 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4572 4573 /* bad table */ 4574 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4575 r = MsiDatabaseOpenViewA(hdb, query, &view); 4576 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4577 4578 /* bad set column */ 4579 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4580 r = MsiDatabaseOpenViewA(hdb, query, &view); 4581 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4582 4583 /* bad where condition */ 4584 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'"; 4585 r = MsiDatabaseOpenViewA(hdb, query, &view); 4586 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4587 4588 /* just the dialog_ specified */ 4589 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4590 r = MsiDatabaseOpenViewA(hdb, query, &view); 4591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4592 r = MsiViewExecute(view, 0); 4593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4594 r = MsiViewClose(view); 4595 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4596 r = MsiCloseHandle(view); 4597 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4598 4599 /* check the modified text */ 4600 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4601 r = MsiDatabaseOpenViewA(hdb, query, &view); 4602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4603 r = MsiViewExecute(view, 0); 4604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4605 4606 r = MsiViewFetch(view, &rec); 4607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4608 4609 size = MAX_PATH; 4610 r = MsiRecordGetStringA(rec, 1, result, &size); 4611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4612 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4613 4614 MsiCloseHandle(rec); 4615 4616 r = MsiViewFetch(view, &rec); 4617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4618 4619 size = MAX_PATH; 4620 r = MsiRecordGetStringA(rec, 1, result, &size); 4621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4622 ok(!result[0], "Expected an empty string, got %s\n", result); 4623 4624 MsiCloseHandle(rec); 4625 4626 r = MsiViewFetch(view, &rec); 4627 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4628 4629 r = MsiViewClose(view); 4630 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4631 r = MsiCloseHandle(view); 4632 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4633 4634 /* dialog_ and control specified */ 4635 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'"; 4636 r = MsiDatabaseOpenViewA(hdb, query, &view); 4637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4638 r = MsiViewExecute(view, 0); 4639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4640 r = MsiViewClose(view); 4641 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4642 r = MsiCloseHandle(view); 4643 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4644 4645 /* check the modified text */ 4646 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4647 r = MsiDatabaseOpenViewA(hdb, query, &view); 4648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4649 r = MsiViewExecute(view, 0); 4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4651 4652 r = MsiViewFetch(view, &rec); 4653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4654 4655 size = MAX_PATH; 4656 r = MsiRecordGetStringA(rec, 1, result, &size); 4657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4658 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4659 4660 MsiCloseHandle(rec); 4661 4662 r = MsiViewFetch(view, &rec); 4663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4664 4665 size = MAX_PATH; 4666 r = MsiRecordGetStringA(rec, 1, result, &size); 4667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4668 ok(!result[0], "Expected an empty string, got %s\n", result); 4669 4670 MsiCloseHandle(rec); 4671 4672 r = MsiViewFetch(view, &rec); 4673 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4674 4675 r = MsiViewClose(view); 4676 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4677 r = MsiCloseHandle(view); 4678 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4679 4680 /* no where condition */ 4681 query = "UPDATE `Control` SET `Text` = 'this is text'"; 4682 r = MsiDatabaseOpenViewA(hdb, query, &view); 4683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4684 r = MsiViewExecute(view, 0); 4685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4686 r = MsiViewClose(view); 4687 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4688 r = MsiCloseHandle(view); 4689 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4690 4691 /* check the modified text */ 4692 query = "SELECT `Text` FROM `Control`"; 4693 r = MsiDatabaseOpenViewA(hdb, query, &view); 4694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4695 r = MsiViewExecute(view, 0); 4696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4697 4698 r = MsiViewFetch(view, &rec); 4699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4700 4701 size = MAX_PATH; 4702 r = MsiRecordGetStringA(rec, 1, result, &size); 4703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4704 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4705 4706 MsiCloseHandle(rec); 4707 4708 r = MsiViewFetch(view, &rec); 4709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4710 4711 size = MAX_PATH; 4712 r = MsiRecordGetStringA(rec, 1, result, &size); 4713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4714 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4715 4716 MsiCloseHandle(rec); 4717 4718 r = MsiViewFetch(view, &rec); 4719 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4720 4721 size = MAX_PATH; 4722 r = MsiRecordGetStringA(rec, 1, result, &size); 4723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4724 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4725 4726 MsiCloseHandle(rec); 4727 4728 r = MsiViewFetch(view, &rec); 4729 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4730 4731 r = MsiViewClose(view); 4732 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4733 r = MsiCloseHandle(view); 4734 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4735 4736 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, " 4737 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)"; 4738 r = run_query(hdb, 0, query); 4739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4740 4741 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4742 "VALUES('one', 'two', 3)"; 4743 r = run_query(hdb, 0, query); 4744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4745 4746 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4747 "VALUES('three', 'four', 5)"; 4748 r = run_query(hdb, 0, query); 4749 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4750 4751 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4752 "VALUES('six', 'two', 7)"; 4753 r = run_query(hdb, 0, query); 4754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4755 4756 rec = MsiCreateRecord(2); 4757 MsiRecordSetInteger(rec, 1, 8); 4758 MsiRecordSetStringA(rec, 2, "two"); 4759 4760 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?"; 4761 r = run_query(hdb, rec, query); 4762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4763 4764 MsiCloseHandle(rec); 4765 4766 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`"; 4767 r = MsiDatabaseOpenViewA(hdb, query, &view); 4768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4769 r = MsiViewExecute(view, 0); 4770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4771 4772 r = MsiViewFetch(view, &rec); 4773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4774 4775 r = MsiRecordGetInteger(rec, 1); 4776 ok(r == 8, "Expected 8, got %d\n", r); 4777 4778 MsiCloseHandle(rec); 4779 4780 r = MsiViewFetch(view, &rec); 4781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4782 4783 r = MsiRecordGetInteger(rec, 1); 4784 ok(r == 8, "Expected 8, got %d\n", r); 4785 4786 MsiCloseHandle(rec); 4787 4788 r = MsiViewFetch(view, &rec); 4789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4790 4791 r = MsiRecordGetInteger(rec, 1); 4792 ok(r == 5, "Expected 5, got %d\n", r); 4793 4794 MsiCloseHandle(rec); 4795 4796 r = MsiViewFetch(view, &rec); 4797 ok(r == ERROR_NO_MORE_ITEMS, "Expectd ERROR_NO_MORE_ITEMS, got %d\n", r); 4798 4799 MsiViewClose(view); 4800 MsiCloseHandle(view); 4801 4802 r = MsiDatabaseCommit(hdb); 4803 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4804 r = MsiCloseHandle(hdb); 4805 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4806 4807 DeleteFileA(msifile); 4808 } 4809 4810 static void test_special_tables(void) 4811 { 4812 const char *query; 4813 MSIHANDLE hdb = 0; 4814 UINT r; 4815 4816 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4817 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4818 4819 query = "CREATE TABLE `_Properties` ( " 4820 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4821 r = run_query(hdb, 0, query); 4822 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4823 4824 query = "CREATE TABLE `_Storages` ( " 4825 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4826 r = run_query(hdb, 0, query); 4827 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4828 4829 query = "CREATE TABLE `_Streams` ( " 4830 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4831 r = run_query(hdb, 0, query); 4832 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4833 4834 query = "CREATE TABLE `_Tables` ( " 4835 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4836 r = run_query(hdb, 0, query); 4837 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n"); 4838 4839 query = "CREATE TABLE `_Columns` ( " 4840 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4841 r = run_query(hdb, 0, query); 4842 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n"); 4843 4844 r = MsiCloseHandle(hdb); 4845 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4846 } 4847 4848 static void test_tables_order(void) 4849 { 4850 const char *query; 4851 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 4852 UINT r; 4853 char buffer[100]; 4854 DWORD sz; 4855 4856 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4857 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4858 4859 query = "CREATE TABLE `foo` ( " 4860 "`baz` INT NOT NULL PRIMARY KEY `baz`)"; 4861 r = run_query(hdb, 0, query); 4862 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4863 4864 query = "CREATE TABLE `bar` ( " 4865 "`foo` INT NOT NULL PRIMARY KEY `foo`)"; 4866 r = run_query(hdb, 0, query); 4867 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4868 4869 query = "CREATE TABLE `baz` ( " 4870 "`bar` INT NOT NULL, " 4871 "`baz` INT NOT NULL, " 4872 "`foo` INT NOT NULL PRIMARY KEY `bar`)"; 4873 r = run_query(hdb, 0, query); 4874 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4875 4876 /* The names of the tables in the _Tables table must 4877 be in the same order as these names are created in 4878 the strings table. */ 4879 query = "SELECT * FROM `_Tables`"; 4880 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4881 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4882 r = MsiViewExecute(hview, 0); 4883 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4884 4885 r = MsiViewFetch(hview, &hrec); 4886 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4887 sz = sizeof(buffer); 4888 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4890 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4891 r = MsiCloseHandle(hrec); 4892 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4893 4894 r = MsiViewFetch(hview, &hrec); 4895 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4896 sz = sizeof(buffer); 4897 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4899 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4900 r = MsiCloseHandle(hrec); 4901 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4902 4903 r = MsiViewFetch(hview, &hrec); 4904 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4905 sz = sizeof(buffer); 4906 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4908 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4909 r = MsiCloseHandle(hrec); 4910 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4911 4912 r = MsiViewClose(hview); 4913 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4914 r = MsiCloseHandle(hview); 4915 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4916 4917 /* The names of the tables in the _Columns table must 4918 be in the same order as these names are created in 4919 the strings table. */ 4920 query = "SELECT * FROM `_Columns`"; 4921 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4922 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4923 r = MsiViewExecute(hview, 0); 4924 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4925 4926 r = MsiViewFetch(hview, &hrec); 4927 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4928 sz = sizeof(buffer); 4929 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4931 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4932 sz = sizeof(buffer); 4933 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4935 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4936 r = MsiCloseHandle(hrec); 4937 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4938 4939 r = MsiViewFetch(hview, &hrec); 4940 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4941 sz = sizeof(buffer); 4942 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4944 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4945 sz = sizeof(buffer); 4946 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4948 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4949 r = MsiCloseHandle(hrec); 4950 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4951 4952 r = MsiViewFetch(hview, &hrec); 4953 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4954 sz = sizeof(buffer); 4955 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4957 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4958 sz = sizeof(buffer); 4959 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4961 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4962 r = MsiCloseHandle(hrec); 4963 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4964 4965 r = MsiViewFetch(hview, &hrec); 4966 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4967 sz = sizeof(buffer); 4968 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4970 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4971 sz = sizeof(buffer); 4972 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4974 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4975 r = MsiCloseHandle(hrec); 4976 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4977 4978 r = MsiViewFetch(hview, &hrec); 4979 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4980 sz = sizeof(buffer); 4981 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4983 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4984 sz = sizeof(buffer); 4985 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4987 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4988 r = MsiCloseHandle(hrec); 4989 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4990 4991 r = MsiViewClose(hview); 4992 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4993 r = MsiCloseHandle(hview); 4994 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4995 4996 r = MsiCloseHandle(hdb); 4997 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4998 4999 DeleteFileA(msifile); 5000 } 5001 5002 static void test_rows_order(void) 5003 { 5004 const char *query; 5005 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5006 UINT r; 5007 char buffer[100]; 5008 DWORD sz; 5009 5010 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5011 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5012 5013 query = "CREATE TABLE `foo` ( " 5014 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)"; 5015 r = run_query(hdb, 0, query); 5016 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5017 5018 r = run_query(hdb, 0, "INSERT INTO `foo` " 5019 "( `bar` ) VALUES ( 'A' )"); 5020 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5021 5022 r = run_query(hdb, 0, "INSERT INTO `foo` " 5023 "( `bar` ) VALUES ( 'B' )"); 5024 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5025 5026 r = run_query(hdb, 0, "INSERT INTO `foo` " 5027 "( `bar` ) VALUES ( 'C' )"); 5028 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5029 5030 r = run_query(hdb, 0, "INSERT INTO `foo` " 5031 "( `bar` ) VALUES ( 'D' )"); 5032 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5033 5034 r = run_query(hdb, 0, "INSERT INTO `foo` " 5035 "( `bar` ) VALUES ( 'E' )"); 5036 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5037 5038 r = run_query(hdb, 0, "INSERT INTO `foo` " 5039 "( `bar` ) VALUES ( 'F' )"); 5040 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5041 5042 query = "CREATE TABLE `bar` ( " 5043 "`foo` LONGCHAR NOT NULL, " 5044 "`baz` LONGCHAR NOT NULL " 5045 "PRIMARY KEY `foo` )"; 5046 r = run_query(hdb, 0, query); 5047 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5048 5049 r = run_query(hdb, 0, "INSERT INTO `bar` " 5050 "( `foo`, `baz` ) VALUES ( 'C', 'E' )"); 5051 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5052 5053 r = run_query(hdb, 0, "INSERT INTO `bar` " 5054 "( `foo`, `baz` ) VALUES ( 'F', 'A' )"); 5055 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5056 5057 r = run_query(hdb, 0, "INSERT INTO `bar` " 5058 "( `foo`, `baz` ) VALUES ( 'A', 'B' )"); 5059 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5060 5061 r = run_query(hdb, 0, "INSERT INTO `bar` " 5062 "( `foo`, `baz` ) VALUES ( 'D', 'E' )"); 5063 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5064 5065 /* The rows of the table must be ordered by the column values of 5066 each row. For strings, the column value is the string id 5067 in the string table. */ 5068 5069 query = "SELECT * FROM `bar`"; 5070 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5071 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5072 r = MsiViewExecute(hview, 0); 5073 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5074 5075 r = MsiViewFetch(hview, &hrec); 5076 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5077 sz = sizeof(buffer); 5078 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5080 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5081 sz = sizeof(buffer); 5082 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5084 ok(!lstrcmpA(buffer, "B"), "Expected B, got %s\n", buffer); 5085 r = MsiCloseHandle(hrec); 5086 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5087 5088 r = MsiViewFetch(hview, &hrec); 5089 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5090 sz = sizeof(buffer); 5091 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5093 ok(!lstrcmpA(buffer, "C"), "Expected E, got %s\n", buffer); 5094 sz = sizeof(buffer); 5095 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5096 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5097 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5098 r = MsiCloseHandle(hrec); 5099 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5100 5101 r = MsiViewFetch(hview, &hrec); 5102 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5103 sz = sizeof(buffer); 5104 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5106 ok(!lstrcmpA(buffer, "D"), "Expected D, got %s\n", buffer); 5107 sz = sizeof(buffer); 5108 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5110 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5111 r = MsiCloseHandle(hrec); 5112 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5113 5114 r = MsiViewFetch(hview, &hrec); 5115 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5116 sz = sizeof(buffer); 5117 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5119 ok(!lstrcmpA(buffer, "F"), "Expected F, got %s\n", buffer); 5120 sz = sizeof(buffer); 5121 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5123 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5124 r = MsiCloseHandle(hrec); 5125 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5126 5127 r = MsiViewClose(hview); 5128 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5129 r = MsiCloseHandle(hview); 5130 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5131 5132 r = MsiCloseHandle(hdb); 5133 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5134 5135 DeleteFileA(msifile); 5136 } 5137 5138 static void test_collation(void) 5139 { 5140 static const WCHAR query1[] = 5141 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5142 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5143 '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0}; 5144 static const WCHAR query2[] = 5145 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5146 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5147 '(','\'',0xe5,'\'',',','\'','D','\'',')',0}; 5148 static const WCHAR query3[] = 5149 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ', 5150 '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',', 5151 ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ', 5152 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0}; 5153 static const WCHAR query4[] = 5154 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ', 5155 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5156 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5157 static const WCHAR query5[] = 5158 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ', 5159 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5160 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5161 static const WCHAR query6[] = 5162 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E', 5163 ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0}; 5164 static const WCHAR letter_C[] = {'C',0}; 5165 static const WCHAR letter_D[] = {'D',0}; 5166 static const WCHAR letter_a_ring[] = {'a',0x30a,0}; 5167 static const WCHAR letter_a_with_ring[] = {0xe5,0}; 5168 const char *query; 5169 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5170 UINT r; 5171 char buffer[100]; 5172 WCHAR bufferW[100]; 5173 DWORD sz; 5174 5175 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5176 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5177 5178 query = "CREATE TABLE `bar` ( " 5179 "`foo` LONGCHAR NOT NULL, " 5180 "`baz` LONGCHAR NOT NULL " 5181 "PRIMARY KEY `foo` )"; 5182 r = run_query(hdb, 0, query); 5183 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5184 5185 r = run_query(hdb, 0, query); 5186 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r); 5187 5188 r = run_query(hdb, 0, "INSERT INTO `bar` " 5189 "( `foo`, `baz` ) VALUES ( '\2', 'A' )"); 5190 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5191 5192 r = run_query(hdb, 0, "INSERT INTO `bar` " 5193 "( `foo`, `baz` ) VALUES ( '\1', 'B' )"); 5194 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5195 5196 r = run_queryW(hdb, 0, query1); 5197 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5198 5199 r = run_queryW(hdb, 0, query2); 5200 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5201 5202 r = run_queryW(hdb, 0, query3); 5203 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5204 5205 r = run_queryW(hdb, 0, query4); 5206 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5207 5208 r = run_queryW(hdb, 0, query5); 5209 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5210 5211 query = "SELECT * FROM `bar`"; 5212 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5213 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5214 r = MsiViewExecute(hview, 0); 5215 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5216 5217 r = MsiViewFetch(hview, &hrec); 5218 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5219 sz = sizeof(buffer); 5220 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5222 ok(!lstrcmpA(buffer, "\2"), "Expected \\2, got '%s'\n", buffer); 5223 sz = sizeof(buffer); 5224 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5226 ok(!lstrcmpA(buffer, "A"), "Expected A, got '%s'\n", buffer); 5227 MsiCloseHandle(hrec); 5228 5229 r = MsiViewFetch(hview, &hrec); 5230 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5231 sz = sizeof(buffer); 5232 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5234 ok(!lstrcmpA(buffer, "\1"), "Expected \\1, got '%s'\n", buffer); 5235 sz = sizeof(buffer); 5236 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5237 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5238 ok(!lstrcmpA(buffer, "B"), "Expected B, got '%s'\n", buffer); 5239 MsiCloseHandle(hrec); 5240 5241 r = MsiViewFetch(hview, &hrec); 5242 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5243 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5244 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5246 ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)), 5247 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW)); 5248 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5249 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5251 ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW)); 5252 MsiCloseHandle(hrec); 5253 5254 r = MsiViewFetch(hview, &hrec); 5255 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5256 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5257 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5259 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5260 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5261 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5262 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5264 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5265 MsiCloseHandle(hrec); 5266 5267 r = MsiViewClose(hview); 5268 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5269 r = MsiCloseHandle(hview); 5270 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5271 5272 r = MsiDatabaseOpenViewW(hdb, query6, &hview); 5273 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5274 r = MsiViewExecute(hview, 0); 5275 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5276 5277 r = MsiViewFetch(hview, &hrec); 5278 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5279 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5280 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5282 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5283 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5284 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5285 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5287 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5288 MsiCloseHandle(hrec); 5289 5290 r = MsiViewFetch(hview, &hrec); 5291 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 5292 5293 r = MsiViewClose(hview); 5294 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5295 r = MsiCloseHandle(hview); 5296 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5297 5298 r = MsiCloseHandle(hdb); 5299 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5300 5301 DeleteFileA(msifile); 5302 } 5303 5304 static void test_select_markers(void) 5305 { 5306 MSIHANDLE hdb = 0, rec, view, res; 5307 LPCSTR query; 5308 UINT r; 5309 DWORD size; 5310 CHAR buf[MAX_PATH]; 5311 5312 hdb = create_db(); 5313 ok( hdb, "failed to create db\n"); 5314 5315 r = run_query(hdb, 0, 5316 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)"); 5317 ok(r == S_OK, "cannot create table: %d\n", r); 5318 5319 r = run_query(hdb, 0, "INSERT INTO `Table` " 5320 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )"); 5321 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5322 5323 r = run_query(hdb, 0, "INSERT INTO `Table` " 5324 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )"); 5325 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5326 5327 r = run_query(hdb, 0, "INSERT INTO `Table` " 5328 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )"); 5329 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5330 5331 r = run_query(hdb, 0, "INSERT INTO `Table` " 5332 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )"); 5333 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5334 5335 rec = MsiCreateRecord(2); 5336 MsiRecordSetStringA(rec, 1, "apple"); 5337 MsiRecordSetStringA(rec, 2, "two"); 5338 5339 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`"; 5340 r = MsiDatabaseOpenViewA(hdb, query, &view); 5341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5342 5343 r = MsiViewExecute(view, rec); 5344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5345 5346 r = MsiViewFetch(view, &res); 5347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5348 5349 size = MAX_PATH; 5350 r = MsiRecordGetStringA(res, 1, buf, &size); 5351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5352 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5353 5354 size = MAX_PATH; 5355 r = MsiRecordGetStringA(res, 2, buf, &size); 5356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5357 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5358 5359 r = MsiRecordGetInteger(res, 3); 5360 ok(r == 1, "Expected 1, got %d\n", r); 5361 5362 MsiCloseHandle(res); 5363 5364 r = MsiViewFetch(view, &res); 5365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5366 5367 size = MAX_PATH; 5368 r = MsiRecordGetStringA(res, 1, buf, &size); 5369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5370 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5371 5372 size = MAX_PATH; 5373 r = MsiRecordGetStringA(res, 2, buf, &size); 5374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5375 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5376 5377 r = MsiRecordGetInteger(res, 3); 5378 ok(r == 2, "Expected 2, got %d\n", r); 5379 5380 MsiCloseHandle(res); 5381 5382 r = MsiViewFetch(view, &res); 5383 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5384 5385 MsiCloseHandle(rec); 5386 MsiViewClose(view); 5387 MsiCloseHandle(view); 5388 5389 rec = MsiCreateRecord(2); 5390 MsiRecordSetStringA(rec, 1, "one"); 5391 MsiRecordSetInteger(rec, 2, 1); 5392 5393 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`"; 5394 r = MsiDatabaseOpenViewA(hdb, query, &view); 5395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5396 r = MsiViewExecute(view, rec); 5397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5398 5399 r = MsiViewFetch(view, &res); 5400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5401 5402 size = MAX_PATH; 5403 r = MsiRecordGetStringA(res, 1, buf, &size); 5404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5405 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5406 5407 size = MAX_PATH; 5408 r = MsiRecordGetStringA(res, 2, buf, &size); 5409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5410 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5411 5412 r = MsiRecordGetInteger(res, 3); 5413 ok(r == 2, "Expected 2, got %d\n", r); 5414 5415 MsiCloseHandle(res); 5416 5417 r = MsiViewFetch(view, &res); 5418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5419 5420 size = MAX_PATH; 5421 r = MsiRecordGetStringA(res, 1, buf, &size); 5422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5423 ok(!lstrcmpA(buf, "banana"), "Expected banana, got %s\n", buf); 5424 5425 size = MAX_PATH; 5426 r = MsiRecordGetStringA(res, 2, buf, &size); 5427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5428 ok(!lstrcmpA(buf, "three"), "Expected three, got %s\n", buf); 5429 5430 r = MsiRecordGetInteger(res, 3); 5431 ok(r == 3, "Expected 3, got %d\n", r); 5432 5433 MsiCloseHandle(res); 5434 5435 r = MsiViewFetch(view, &res); 5436 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5437 5438 MsiCloseHandle(rec); 5439 MsiViewClose(view); 5440 MsiCloseHandle(view); 5441 MsiCloseHandle(hdb); 5442 DeleteFileA(msifile); 5443 } 5444 5445 static void test_viewmodify_update(void) 5446 { 5447 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5448 UINT i, test_max, offset, count; 5449 const char *query; 5450 UINT r; 5451 5452 DeleteFileA(msifile); 5453 5454 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5455 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5456 5457 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5458 r = run_query( hdb, 0, query ); 5459 ok(r == ERROR_SUCCESS, "query failed\n"); 5460 5461 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)"; 5462 r = run_query( hdb, 0, query ); 5463 ok(r == ERROR_SUCCESS, "query failed\n"); 5464 5465 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)"; 5466 r = run_query( hdb, 0, query ); 5467 ok(r == ERROR_SUCCESS, "query failed\n"); 5468 5469 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)"; 5470 r = run_query( hdb, 0, query ); 5471 ok(r == ERROR_SUCCESS, "query failed\n"); 5472 5473 query = "SELECT `B` FROM `table`"; 5474 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5475 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5476 r = MsiViewExecute(hview, 0); 5477 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5478 r = MsiViewFetch(hview, &hrec); 5479 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5480 5481 r = MsiRecordSetInteger(hrec, 1, 0); 5482 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5483 5484 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5485 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5486 5487 r = MsiCloseHandle(hrec); 5488 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5489 5490 r = MsiViewClose(hview); 5491 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5492 r = MsiCloseHandle(hview); 5493 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5494 5495 query = "SELECT * FROM `table`"; 5496 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5497 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5498 r = MsiViewExecute(hview, 0); 5499 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5500 r = MsiViewFetch(hview, &hrec); 5501 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5502 5503 r = MsiRecordGetInteger(hrec, 1); 5504 ok(r == 1, "Expected 1, got %d\n", r); 5505 r = MsiRecordGetInteger(hrec, 2); 5506 ok(r == 0, "Expected 0, got %d\n", r); 5507 5508 r = MsiCloseHandle(hrec); 5509 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5510 5511 r = MsiViewFetch(hview, &hrec); 5512 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5513 5514 r = MsiRecordGetInteger(hrec, 1); 5515 ok(r == 3, "Expected 3, got %d\n", r); 5516 r = MsiRecordGetInteger(hrec, 2); 5517 ok(r == 4, "Expected 4, got %d\n", r); 5518 5519 r = MsiCloseHandle(hrec); 5520 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5521 5522 r = MsiViewFetch(hview, &hrec); 5523 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5524 5525 r = MsiRecordGetInteger(hrec, 1); 5526 ok(r == 5, "Expected 5, got %d\n", r); 5527 r = MsiRecordGetInteger(hrec, 2); 5528 ok(r == 6, "Expected 6, got %d\n", r); 5529 5530 r = MsiCloseHandle(hrec); 5531 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5532 5533 r = MsiViewFetch(hview, &hrec); 5534 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5535 5536 r = MsiViewClose(hview); 5537 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5538 r = MsiCloseHandle(hview); 5539 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5540 5541 /* loop through all elements */ 5542 query = "SELECT `B` FROM `table`"; 5543 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5544 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5545 r = MsiViewExecute(hview, 0); 5546 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5547 5548 while (TRUE) 5549 { 5550 r = MsiViewFetch(hview, &hrec); 5551 if (r != ERROR_SUCCESS) 5552 break; 5553 5554 r = MsiRecordSetInteger(hrec, 1, 0); 5555 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5556 5557 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5558 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5559 5560 r = MsiCloseHandle(hrec); 5561 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5562 } 5563 5564 r = MsiViewClose(hview); 5565 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5566 r = MsiCloseHandle(hview); 5567 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5568 5569 query = "SELECT * FROM `table`"; 5570 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5571 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5572 r = MsiViewExecute(hview, 0); 5573 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5574 r = MsiViewFetch(hview, &hrec); 5575 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5576 5577 r = MsiRecordGetInteger(hrec, 1); 5578 ok(r == 1, "Expected 1, got %d\n", r); 5579 r = MsiRecordGetInteger(hrec, 2); 5580 ok(r == 0, "Expected 0, got %d\n", r); 5581 5582 r = MsiCloseHandle(hrec); 5583 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5584 5585 r = MsiViewFetch(hview, &hrec); 5586 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5587 5588 r = MsiRecordGetInteger(hrec, 1); 5589 ok(r == 3, "Expected 3, got %d\n", r); 5590 r = MsiRecordGetInteger(hrec, 2); 5591 ok(r == 0, "Expected 0, got %d\n", r); 5592 5593 r = MsiCloseHandle(hrec); 5594 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5595 5596 r = MsiViewFetch(hview, &hrec); 5597 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5598 5599 r = MsiRecordGetInteger(hrec, 1); 5600 ok(r == 5, "Expected 5, got %d\n", r); 5601 r = MsiRecordGetInteger(hrec, 2); 5602 ok(r == 0, "Expected 0, got %d\n", r); 5603 5604 r = MsiCloseHandle(hrec); 5605 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5606 5607 r = MsiViewFetch(hview, &hrec); 5608 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5609 5610 r = MsiViewClose(hview); 5611 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5612 r = MsiCloseHandle(hview); 5613 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5614 5615 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5616 r = run_query( hdb, 0, query ); 5617 ok(r == ERROR_SUCCESS, "query failed\n"); 5618 5619 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)"; 5620 r = MsiDatabaseOpenViewA( hdb, query, &hview ); 5621 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5622 5623 test_max = 100; 5624 offset = 1234; 5625 for(i = 0; i < test_max; i++) 5626 { 5627 5628 hrec = MsiCreateRecord( 2 ); 5629 MsiRecordSetInteger( hrec, 1, test_max - i ); 5630 MsiRecordSetInteger( hrec, 2, i ); 5631 5632 r = MsiViewExecute( hview, hrec ); 5633 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5634 5635 r = MsiCloseHandle( hrec ); 5636 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5637 } 5638 5639 r = MsiViewClose( hview ); 5640 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5641 r = MsiCloseHandle( hview ); 5642 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5643 5644 /* Update. */ 5645 query = "SELECT * FROM `table2` ORDER BY `B`"; 5646 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5647 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5648 r = MsiViewExecute( hview, 0 ); 5649 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5650 5651 count = 0; 5652 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5653 { 5654 UINT b = MsiRecordGetInteger( hrec, 2 ); 5655 5656 r = MsiRecordSetInteger( hrec, 2, b + offset); 5657 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5658 5659 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec ); 5660 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5661 5662 r = MsiCloseHandle(hrec); 5663 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5664 count++; 5665 } 5666 ok(count == test_max, "Got count %d\n", count); 5667 5668 r = MsiViewClose(hview); 5669 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5670 r = MsiCloseHandle(hview); 5671 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5672 5673 /* Recheck. */ 5674 query = "SELECT * FROM `table2` ORDER BY `B`"; 5675 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5676 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5677 r = MsiViewExecute( hview, 0 ); 5678 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5679 5680 count = 0; 5681 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5682 { 5683 UINT a = MsiRecordGetInteger( hrec, 1 ); 5684 UINT b = MsiRecordGetInteger( hrec, 2 ); 5685 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n", 5686 a, b, test_max - a + offset, b); 5687 5688 r = MsiCloseHandle(hrec); 5689 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5690 count++; 5691 } 5692 ok(count == test_max, "Got count %d\n", count); 5693 5694 r = MsiViewClose(hview); 5695 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5696 r = MsiCloseHandle(hview); 5697 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5698 5699 r = MsiCloseHandle( hdb ); 5700 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5701 } 5702 5703 static void test_viewmodify_assign(void) 5704 { 5705 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5706 const char *query; 5707 UINT r; 5708 5709 /* setup database */ 5710 DeleteFileA(msifile); 5711 5712 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5713 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5714 5715 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5716 r = run_query( hdb, 0, query ); 5717 ok(r == ERROR_SUCCESS, "query failed\n"); 5718 5719 /* assign to view, new primary key */ 5720 query = "SELECT * FROM `table`"; 5721 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5722 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5723 r = MsiViewExecute(hview, 0); 5724 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5725 5726 hrec = MsiCreateRecord(2); 5727 ok(hrec != 0, "MsiCreateRecord failed\n"); 5728 5729 r = MsiRecordSetInteger(hrec, 1, 1); 5730 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5731 r = MsiRecordSetInteger(hrec, 2, 2); 5732 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5733 5734 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5735 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5736 5737 r = MsiCloseHandle(hrec); 5738 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5739 5740 r = MsiViewClose(hview); 5741 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5742 r = MsiCloseHandle(hview); 5743 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5744 5745 query = "SELECT * FROM `table`"; 5746 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5747 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5748 r = MsiViewExecute(hview, 0); 5749 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5750 r = MsiViewFetch(hview, &hrec); 5751 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5752 5753 r = MsiRecordGetInteger(hrec, 1); 5754 ok(r == 1, "Expected 1, got %d\n", r); 5755 r = MsiRecordGetInteger(hrec, 2); 5756 ok(r == 2, "Expected 2, got %d\n", r); 5757 5758 r = MsiCloseHandle(hrec); 5759 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5760 5761 r = MsiViewFetch(hview, &hrec); 5762 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5763 5764 r = MsiViewClose(hview); 5765 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5766 r = MsiCloseHandle(hview); 5767 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5768 5769 /* assign to view, primary key matches */ 5770 query = "SELECT * FROM `table`"; 5771 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5772 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5773 r = MsiViewExecute(hview, 0); 5774 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5775 5776 hrec = MsiCreateRecord(2); 5777 ok(hrec != 0, "MsiCreateRecord failed\n"); 5778 5779 r = MsiRecordSetInteger(hrec, 1, 1); 5780 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5781 r = MsiRecordSetInteger(hrec, 2, 4); 5782 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5783 5784 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5785 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5786 5787 r = MsiCloseHandle(hrec); 5788 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5789 5790 r = MsiViewClose(hview); 5791 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5792 r = MsiCloseHandle(hview); 5793 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5794 5795 query = "SELECT * FROM `table`"; 5796 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5797 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5798 r = MsiViewExecute(hview, 0); 5799 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5800 r = MsiViewFetch(hview, &hrec); 5801 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5802 5803 r = MsiRecordGetInteger(hrec, 1); 5804 ok(r == 1, "Expected 1, got %d\n", r); 5805 r = MsiRecordGetInteger(hrec, 2); 5806 ok(r == 4, "Expected 4, got %d\n", r); 5807 5808 r = MsiCloseHandle(hrec); 5809 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5810 5811 r = MsiViewFetch(hview, &hrec); 5812 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5813 5814 r = MsiViewClose(hview); 5815 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5816 r = MsiCloseHandle(hview); 5817 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5818 5819 /* close database */ 5820 r = MsiCloseHandle( hdb ); 5821 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5822 } 5823 5824 static const WCHAR data10[] = { /* MOO */ 5825 0x8001, 0x000b, 5826 }; 5827 static const WCHAR data11[] = { /* AAR */ 5828 0x8002, 0x8005, 5829 0x000c, 0x000f, 5830 }; 5831 static const char data12[] = /* _StringData */ 5832 "MOOABAARCDonetwofourfive"; 5833 static const WCHAR data13[] = { /* _StringPool */ 5834 /* len, refs */ 5835 0, 0, /* string 0 '' */ 5836 0, 0, /* string 1 '' */ 5837 0, 0, /* string 2 '' */ 5838 0, 0, /* string 3 '' */ 5839 0, 0, /* string 4 '' */ 5840 3, 3, /* string 5 'MOO' */ 5841 1, 1, /* string 6 'A' */ 5842 1, 1, /* string 7 'B' */ 5843 3, 3, /* string 8 'AAR' */ 5844 1, 1, /* string 9 'C' */ 5845 1, 1, /* string a 'D' */ 5846 3, 1, /* string b 'one' */ 5847 3, 1, /* string c 'two' */ 5848 0, 0, /* string d '' */ 5849 4, 1, /* string e 'four' */ 5850 4, 1, /* string f 'five' */ 5851 }; 5852 5853 static void test_stringtable(void) 5854 { 5855 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5856 IStorage *stg = NULL; 5857 IStream *stm; 5858 WCHAR name[0x20]; 5859 HRESULT hr; 5860 const char *query; 5861 char buffer[MAX_PATH]; 5862 WCHAR data[MAX_PATH]; 5863 DWORD sz, read; 5864 UINT r; 5865 5866 static const DWORD mode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE; 5867 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */ 5868 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */ 5869 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 5870 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */ 5871 5872 DeleteFileA(msifile); 5873 5874 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5876 5877 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)"; 5878 r = run_query(hdb, 0, query); 5879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5880 5881 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)"; 5882 r = run_query(hdb, 0, query); 5883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5884 5885 /* insert persistent row */ 5886 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')"; 5887 r = run_query(hdb, 0, query); 5888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5889 5890 /* insert persistent row */ 5891 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')"; 5892 r = run_query(hdb, 0, query); 5893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5894 5895 /* open a view */ 5896 query = "SELECT * FROM `MOO`"; 5897 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5899 r = MsiViewExecute(hview, 0); 5900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5901 5902 hrec = MsiCreateRecord(2); 5903 5904 r = MsiRecordSetInteger(hrec, 1, 3); 5905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5906 r = MsiRecordSetStringA(hrec, 2, "three"); 5907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5908 5909 /* insert a nonpersistent row */ 5910 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 5911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5912 5913 r = MsiCloseHandle(hrec); 5914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5915 r = MsiViewClose(hview); 5916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5917 r = MsiCloseHandle(hview); 5918 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5919 5920 /* insert persistent row */ 5921 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')"; 5922 r = run_query(hdb, 0, query); 5923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5924 5925 /* insert persistent row */ 5926 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')"; 5927 r = run_query(hdb, 0, query); 5928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5929 5930 r = MsiDatabaseCommit(hdb); 5931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5932 5933 r = MsiCloseHandle(hdb); 5934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5935 5936 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 5937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5938 5939 query = "SELECT * FROM `MOO`"; 5940 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5942 5943 r = MsiViewExecute(hview, 0); 5944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5945 5946 r = MsiViewFetch(hview, &hrec); 5947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5948 5949 r = MsiRecordGetFieldCount(hrec); 5950 ok(r == 2, "Expected 2, got %d\n", r); 5951 5952 r = MsiRecordGetInteger(hrec, 1); 5953 ok(r == 1, "Expected 1, got %d\n", r); 5954 5955 sz = sizeof(buffer); 5956 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5958 ok(!lstrcmpA(buffer, "one"), "Expected one, got '%s'\n", buffer); 5959 5960 r = MsiCloseHandle(hrec); 5961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5962 5963 r = MsiViewFetch(hview, &hrec); 5964 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5965 5966 r = MsiViewClose(hview); 5967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5968 r = MsiCloseHandle(hview); 5969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5970 r = MsiCloseHandle(hrec); 5971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5972 5973 query = "SELECT * FROM `AAR`"; 5974 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5976 5977 r = MsiViewExecute(hview, 0); 5978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5979 5980 r = MsiViewFetch(hview, &hrec); 5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5982 5983 r = MsiRecordGetFieldCount(hrec); 5984 ok(r == 2, "Expected 2, got %d\n", r); 5985 5986 r = MsiRecordGetInteger(hrec, 1); 5987 ok(r == 2, "Expected 2, got %d\n", r); 5988 5989 sz = sizeof(buffer); 5990 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5992 ok(!lstrcmpA(buffer, "two"), "Expected two, got '%s'\n", buffer); 5993 5994 r = MsiCloseHandle(hrec); 5995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5996 5997 r = MsiViewFetch(hview, &hrec); 5998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5999 6000 r = MsiRecordGetFieldCount(hrec); 6001 ok(r == 2, "Expected 2, got %d\n", r); 6002 6003 r = MsiRecordGetInteger(hrec, 1); 6004 ok(r == 5, "Expected 5, got %d\n", r); 6005 6006 sz = sizeof(buffer); 6007 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 6008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6009 ok(!lstrcmpA(buffer, "five"), "Expected five, got '%s'\n", buffer); 6010 6011 r = MsiCloseHandle(hrec); 6012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6013 6014 r = MsiViewFetch(hview, &hrec); 6015 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6016 6017 r = MsiViewClose(hview); 6018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6019 r = MsiCloseHandle(hview); 6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6021 r = MsiCloseHandle(hrec); 6022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6023 r = MsiCloseHandle(hdb); 6024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6025 6026 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20); 6027 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg); 6028 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6029 ok(stg != NULL, "Expected non-NULL storage\n"); 6030 6031 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6032 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6033 ok(stm != NULL, "Expected non-NULL stream\n"); 6034 6035 hr = IStream_Read(stm, data, MAX_PATH, &read); 6036 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6037 ok(read == 4, "Expected 4, got %d\n", read); 6038 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n"); 6039 6040 hr = IStream_Release(stm); 6041 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6042 6043 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6044 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6045 ok(stm != NULL, "Expected non-NULL stream\n"); 6046 6047 hr = IStream_Read(stm, data, MAX_PATH, &read); 6048 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6049 ok(read == 8, "Expected 8, got %d\n", read); 6050 todo_wine 6051 { 6052 ok(!memcmp(data, data11, read), "Unexpected data\n"); 6053 } 6054 6055 hr = IStream_Release(stm); 6056 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6057 6058 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6059 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6060 ok(stm != NULL, "Expected non-NULL stream\n"); 6061 6062 hr = IStream_Read(stm, buffer, MAX_PATH, &read); 6063 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6064 ok(read == 24, "Expected 24, got %d\n", read); 6065 ok(!memcmp(buffer, data12, read), "Unexpected data\n"); 6066 6067 hr = IStream_Release(stm); 6068 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6069 6070 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6071 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6072 ok(stm != NULL, "Expected non-NULL stream\n"); 6073 6074 hr = IStream_Read(stm, data, MAX_PATH, &read); 6075 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6076 todo_wine 6077 { 6078 ok(read == 64, "Expected 64, got %d\n", read); 6079 ok(!memcmp(data, data13, read), "Unexpected data\n"); 6080 } 6081 6082 hr = IStream_Release(stm); 6083 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6084 6085 hr = IStorage_Release(stg); 6086 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6087 6088 DeleteFileA(msifile); 6089 } 6090 6091 static void test_viewmodify_delete(void) 6092 { 6093 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 6094 UINT r; 6095 const char *query; 6096 char buffer[0x100]; 6097 DWORD sz; 6098 6099 DeleteFileA(msifile); 6100 6101 /* just MsiOpenDatabase should not create a file */ 6102 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6104 6105 query = "CREATE TABLE `phone` ( " 6106 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 6107 "PRIMARY KEY `id`)"; 6108 r = run_query(hdb, 0, query); 6109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6110 6111 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6112 "VALUES('1', 'Alan', '5030581')"; 6113 r = run_query(hdb, 0, query); 6114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6115 6116 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6117 "VALUES('2', 'Barry', '928440')"; 6118 r = run_query(hdb, 0, query); 6119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6120 6121 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6122 "VALUES('3', 'Cindy', '2937550')"; 6123 r = run_query(hdb, 0, query); 6124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6125 6126 query = "SELECT * FROM `phone` WHERE `id` <= 2"; 6127 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6129 r = MsiViewExecute(hview, 0); 6130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6131 r = MsiViewFetch(hview, &hrec); 6132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6133 6134 /* delete 1 */ 6135 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6137 6138 r = MsiCloseHandle(hrec); 6139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6140 r = MsiViewFetch(hview, &hrec); 6141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6142 6143 /* delete 2 */ 6144 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6146 6147 r = MsiCloseHandle(hrec); 6148 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6149 r = MsiViewClose(hview); 6150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6151 r = MsiCloseHandle(hview); 6152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6153 6154 query = "SELECT * FROM `phone`"; 6155 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6157 r = MsiViewExecute(hview, 0); 6158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6159 r = MsiViewFetch(hview, &hrec); 6160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6161 6162 r = MsiRecordGetInteger(hrec, 1); 6163 ok(r == 3, "Expected 3, got %d\n", r); 6164 6165 sz = sizeof(buffer); 6166 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 6167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6168 ok(!lstrcmpA(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer); 6169 6170 sz = sizeof(buffer); 6171 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 6172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6173 ok(!lstrcmpA(buffer, "2937550"), "Expected 2937550, got %s\n", buffer); 6174 6175 r = MsiCloseHandle(hrec); 6176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6177 6178 r = MsiViewFetch(hview, &hrec); 6179 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6180 6181 r = MsiViewClose(hview); 6182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6183 r = MsiCloseHandle(hview); 6184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6185 r = MsiCloseHandle(hdb); 6186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6187 } 6188 6189 static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0}; 6190 static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; 6191 static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; 6192 6193 static const WCHAR data14[] = { /* _StringPool */ 6194 /* len, refs */ 6195 0, 0, /* string 0 '' */ 6196 }; 6197 6198 static const struct { 6199 LPCWSTR name; 6200 const void *data; 6201 DWORD size; 6202 } database_table_data[] = 6203 { 6204 {_Tables, NULL, 0}, 6205 {_StringData, NULL, 0}, 6206 {_StringPool, data14, sizeof data14}, 6207 }; 6208 6209 static void enum_stream_names(IStorage *stg) 6210 { 6211 IEnumSTATSTG *stgenum = NULL; 6212 IStream *stm; 6213 HRESULT hr; 6214 STATSTG stat; 6215 ULONG n, count; 6216 BYTE data[MAX_PATH]; 6217 BYTE check[MAX_PATH]; 6218 DWORD sz; 6219 6220 memset(check, 'a', MAX_PATH); 6221 6222 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum); 6223 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6224 6225 n = 0; 6226 while(TRUE) 6227 { 6228 count = 0; 6229 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count); 6230 if(FAILED(hr) || !count) 6231 break; 6232 6233 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name), 6234 "Expected table %d name to match\n", n); 6235 6236 stm = NULL; 6237 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL, 6238 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6239 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6240 ok(stm != NULL, "Expected non-NULL stream\n"); 6241 6242 CoTaskMemFree(stat.pwcsName); 6243 6244 sz = MAX_PATH; 6245 memset(data, 'a', MAX_PATH); 6246 hr = IStream_Read(stm, data, sz, &count); 6247 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6248 6249 ok(count == database_table_data[n].size, 6250 "Expected %d, got %d\n", database_table_data[n].size, count); 6251 6252 if (!database_table_data[n].size) 6253 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n"); 6254 else 6255 ok(!memcmp(data, database_table_data[n].data, database_table_data[n].size), 6256 "Expected table %d data to match\n", n); 6257 6258 IStream_Release(stm); 6259 n++; 6260 } 6261 6262 ok(n == 3, "Expected 3, got %d\n", n); 6263 6264 IEnumSTATSTG_Release(stgenum); 6265 } 6266 6267 static void test_defaultdatabase(void) 6268 { 6269 UINT r; 6270 HRESULT hr; 6271 MSIHANDLE hdb; 6272 IStorage *stg = NULL; 6273 6274 DeleteFileA(msifile); 6275 6276 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6278 6279 r = MsiDatabaseCommit(hdb); 6280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6281 6282 MsiCloseHandle(hdb); 6283 6284 hr = StgOpenStorage(msifileW, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 6285 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6286 ok(stg != NULL, "Expected non-NULL stg\n"); 6287 6288 enum_stream_names(stg); 6289 6290 IStorage_Release(stg); 6291 DeleteFileA(msifile); 6292 } 6293 6294 static void test_order(void) 6295 { 6296 MSIHANDLE hdb, hview, hrec; 6297 CHAR buffer[MAX_PATH]; 6298 LPCSTR query; 6299 UINT r, sz; 6300 int val; 6301 6302 hdb = create_db(); 6303 ok(hdb, "failed to create db\n"); 6304 6305 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)"; 6306 r = run_query(hdb, 0, query); 6307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6308 6309 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 6310 r = run_query(hdb, 0, query); 6311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6312 6313 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )"; 6314 r = run_query(hdb, 0, query); 6315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6316 6317 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )"; 6318 r = run_query(hdb, 0, query); 6319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6320 6321 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )"; 6322 r = run_query(hdb, 0, query); 6323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6324 6325 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)"; 6326 r = run_query(hdb, 0, query); 6327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6328 6329 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )"; 6330 r = run_query(hdb, 0, query); 6331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6332 6333 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )"; 6334 r = run_query(hdb, 0, query); 6335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6336 6337 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )"; 6338 r = run_query(hdb, 0, query); 6339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6340 6341 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`"; 6342 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6344 r = MsiViewExecute(hview, 0); 6345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6346 6347 r = MsiViewFetch(hview, &hrec); 6348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6349 6350 val = MsiRecordGetInteger(hrec, 1); 6351 ok(val == 3, "Expected 3, got %d\n", val); 6352 6353 val = MsiRecordGetInteger(hrec, 2); 6354 ok(val == 4, "Expected 3, got %d\n", val); 6355 6356 MsiCloseHandle(hrec); 6357 6358 r = MsiViewFetch(hview, &hrec); 6359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6360 6361 val = MsiRecordGetInteger(hrec, 1); 6362 ok(val == 5, "Expected 5, got %d\n", val); 6363 6364 val = MsiRecordGetInteger(hrec, 2); 6365 ok(val == 6, "Expected 6, got %d\n", val); 6366 6367 MsiCloseHandle(hrec); 6368 6369 r = MsiViewFetch(hview, &hrec); 6370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6371 6372 val = MsiRecordGetInteger(hrec, 1); 6373 ok(val == 1, "Expected 1, got %d\n", val); 6374 6375 val = MsiRecordGetInteger(hrec, 2); 6376 ok(val == 2, "Expected 2, got %d\n", val); 6377 6378 MsiCloseHandle(hrec); 6379 6380 r = MsiViewFetch(hview, &hrec); 6381 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6382 6383 MsiViewClose(hview); 6384 MsiCloseHandle(hview); 6385 6386 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`"; 6387 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6389 r = MsiViewExecute(hview, 0); 6390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6391 6392 r = MsiViewFetch(hview, &hrec); 6393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6394 6395 val = MsiRecordGetInteger(hrec, 1); 6396 ok(val == 1, "Expected 1, got %d\n", val); 6397 6398 val = MsiRecordGetInteger(hrec, 2); 6399 ok(val == 12, "Expected 12, got %d\n", val); 6400 6401 MsiCloseHandle(hrec); 6402 6403 r = MsiViewFetch(hview, &hrec); 6404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6405 6406 val = MsiRecordGetInteger(hrec, 1); 6407 ok(val == 3, "Expected 3, got %d\n", val); 6408 6409 val = MsiRecordGetInteger(hrec, 2); 6410 ok(val == 12, "Expected 12, got %d\n", val); 6411 6412 MsiCloseHandle(hrec); 6413 6414 r = MsiViewFetch(hview, &hrec); 6415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6416 6417 val = MsiRecordGetInteger(hrec, 1); 6418 ok(val == 5, "Expected 5, got %d\n", val); 6419 6420 val = MsiRecordGetInteger(hrec, 2); 6421 ok(val == 12, "Expected 12, got %d\n", val); 6422 6423 MsiCloseHandle(hrec); 6424 6425 r = MsiViewFetch(hview, &hrec); 6426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6427 6428 val = MsiRecordGetInteger(hrec, 1); 6429 ok(val == 1, "Expected 1, got %d\n", val); 6430 6431 val = MsiRecordGetInteger(hrec, 2); 6432 ok(val == 14, "Expected 14, got %d\n", val); 6433 6434 MsiCloseHandle(hrec); 6435 6436 r = MsiViewFetch(hview, &hrec); 6437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6438 6439 val = MsiRecordGetInteger(hrec, 1); 6440 ok(val == 3, "Expected 3, got %d\n", val); 6441 6442 val = MsiRecordGetInteger(hrec, 2); 6443 ok(val == 14, "Expected 14, got %d\n", val); 6444 6445 MsiCloseHandle(hrec); 6446 6447 r = MsiViewFetch(hview, &hrec); 6448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6449 6450 val = MsiRecordGetInteger(hrec, 1); 6451 ok(val == 5, "Expected 5, got %d\n", val); 6452 6453 val = MsiRecordGetInteger(hrec, 2); 6454 ok(val == 14, "Expected 14, got %d\n", val); 6455 6456 MsiCloseHandle(hrec); 6457 6458 r = MsiViewFetch(hview, &hrec); 6459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6460 6461 val = MsiRecordGetInteger(hrec, 1); 6462 ok(val == 1, "Expected 1, got %d\n", val); 6463 6464 val = MsiRecordGetInteger(hrec, 2); 6465 ok(val == 10, "Expected 10, got %d\n", val); 6466 6467 MsiCloseHandle(hrec); 6468 6469 r = MsiViewFetch(hview, &hrec); 6470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6471 6472 val = MsiRecordGetInteger(hrec, 1); 6473 ok(val == 3, "Expected 3, got %d\n", val); 6474 6475 val = MsiRecordGetInteger(hrec, 2); 6476 ok(val == 10, "Expected 10, got %d\n", val); 6477 6478 MsiCloseHandle(hrec); 6479 6480 r = MsiViewFetch(hview, &hrec); 6481 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6482 6483 val = MsiRecordGetInteger(hrec, 1); 6484 ok(val == 5, "Expected 5, got %d\n", val); 6485 6486 val = MsiRecordGetInteger(hrec, 2); 6487 ok(val == 10, "Expected 10, got %d\n", val); 6488 6489 MsiCloseHandle(hrec); 6490 6491 r = MsiViewFetch(hview, &hrec); 6492 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6493 6494 MsiViewClose(hview); 6495 MsiCloseHandle(hview); 6496 6497 query = "SELECT * FROM `Empty` ORDER BY `A`"; 6498 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6500 r = MsiViewExecute(hview, 0); 6501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6502 6503 r = MsiViewFetch(hview, &hrec); 6504 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6505 6506 MsiViewClose(hview); 6507 MsiCloseHandle(hview); 6508 6509 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)"; 6510 r = run_query(hdb, 0, query); 6511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6512 6513 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)"; 6514 r = run_query(hdb, 0, query); 6515 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6516 6517 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)"; 6518 r = run_query(hdb, 0, query); 6519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6520 6521 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)"; 6522 r = run_query(hdb, 0, query); 6523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6524 6525 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`"; 6526 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6528 r = MsiViewExecute(hview, 0); 6529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6530 6531 r = MsiViewFetch(hview, &hrec); 6532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6533 6534 sz = sizeof(buffer); 6535 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 6536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6537 ok(!lstrcmpA(buffer, "dos"), "Expected \"dos\", got \"%s\"\n", buffer); 6538 6539 r = MsiRecordGetInteger(hrec, 2); 6540 ok(r == 3, "Expected 3, got %d\n", r); 6541 6542 MsiCloseHandle(hrec); 6543 6544 r = MsiViewFetch(hview, &hrec); 6545 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6546 6547 MsiViewClose(hview); 6548 MsiCloseHandle(hview); 6549 MsiCloseHandle(hdb); 6550 } 6551 6552 static void test_viewmodify_delete_temporary(void) 6553 { 6554 MSIHANDLE hdb, hview, hrec; 6555 const char *query; 6556 UINT r; 6557 6558 DeleteFileA(msifile); 6559 6560 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6562 6563 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )"; 6564 r = run_query(hdb, 0, query); 6565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6566 6567 query = "SELECT * FROM `Table`"; 6568 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6569 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6570 r = MsiViewExecute(hview, 0); 6571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6572 6573 hrec = MsiCreateRecord(1); 6574 MsiRecordSetInteger(hrec, 1, 1); 6575 6576 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6578 6579 MsiCloseHandle(hrec); 6580 6581 hrec = MsiCreateRecord(1); 6582 MsiRecordSetInteger(hrec, 1, 2); 6583 6584 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6586 6587 MsiCloseHandle(hrec); 6588 6589 hrec = MsiCreateRecord(1); 6590 MsiRecordSetInteger(hrec, 1, 3); 6591 6592 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6594 6595 MsiCloseHandle(hrec); 6596 6597 hrec = MsiCreateRecord(1); 6598 MsiRecordSetInteger(hrec, 1, 4); 6599 6600 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6601 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6602 6603 MsiCloseHandle(hrec); 6604 MsiViewClose(hview); 6605 MsiCloseHandle(hview); 6606 6607 query = "SELECT * FROM `Table` WHERE `A` = 2"; 6608 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6610 r = MsiViewExecute(hview, 0); 6611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6612 r = MsiViewFetch(hview, &hrec); 6613 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6614 6615 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6617 6618 MsiCloseHandle(hrec); 6619 MsiViewClose(hview); 6620 MsiCloseHandle(hview); 6621 6622 query = "SELECT * FROM `Table` WHERE `A` = 3"; 6623 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6625 r = MsiViewExecute(hview, 0); 6626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6627 r = MsiViewFetch(hview, &hrec); 6628 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6629 6630 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6632 6633 MsiCloseHandle(hrec); 6634 MsiViewClose(hview); 6635 MsiCloseHandle(hview); 6636 6637 query = "SELECT * FROM `Table` ORDER BY `A`"; 6638 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6640 r = MsiViewExecute(hview, 0); 6641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6642 6643 r = MsiViewFetch(hview, &hrec); 6644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6645 6646 r = MsiRecordGetInteger(hrec, 1); 6647 ok(r == 1, "Expected 1, got %d\n", r); 6648 6649 MsiCloseHandle(hrec); 6650 6651 r = MsiViewFetch(hview, &hrec); 6652 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6653 6654 r = MsiRecordGetInteger(hrec, 1); 6655 ok(r == 4, "Expected 4, got %d\n", r); 6656 6657 MsiCloseHandle(hrec); 6658 6659 r = MsiViewFetch(hview, &hrec); 6660 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6661 6662 MsiViewClose(hview); 6663 MsiCloseHandle(hview); 6664 MsiCloseHandle(hdb); 6665 DeleteFileA(msifile); 6666 } 6667 6668 static void test_deleterow(void) 6669 { 6670 MSIHANDLE hdb, hview, hrec; 6671 const char *query; 6672 char buf[MAX_PATH]; 6673 UINT r; 6674 DWORD size; 6675 6676 DeleteFileA(msifile); 6677 6678 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6680 6681 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6682 r = run_query(hdb, 0, query); 6683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6684 6685 query = "INSERT INTO `Table` (`A`) VALUES ('one')"; 6686 r = run_query(hdb, 0, query); 6687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6688 6689 query = "INSERT INTO `Table` (`A`) VALUES ('two')"; 6690 r = run_query(hdb, 0, query); 6691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6692 6693 query = "DELETE FROM `Table` WHERE `A` = 'one'"; 6694 r = run_query(hdb, 0, query); 6695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6696 6697 r = MsiDatabaseCommit(hdb); 6698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6699 6700 MsiCloseHandle(hdb); 6701 6702 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 6703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6704 6705 query = "SELECT * FROM `Table`"; 6706 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6707 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6708 r = MsiViewExecute(hview, 0); 6709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6710 6711 r = MsiViewFetch(hview, &hrec); 6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6713 6714 size = MAX_PATH; 6715 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6716 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6717 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 6718 6719 MsiCloseHandle(hrec); 6720 6721 r = MsiViewFetch(hview, &hrec); 6722 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6723 6724 MsiViewClose(hview); 6725 MsiCloseHandle(hview); 6726 MsiCloseHandle(hdb); 6727 DeleteFileA(msifile); 6728 } 6729 6730 static const CHAR import_dat[] = "A\n" 6731 "s72\n" 6732 "Table\tA\n" 6733 "This is a new 'string' ok\n"; 6734 6735 static void test_quotes(void) 6736 { 6737 MSIHANDLE hdb, hview, hrec; 6738 const char *query; 6739 char buf[MAX_PATH]; 6740 UINT r; 6741 DWORD size; 6742 6743 DeleteFileA(msifile); 6744 6745 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6747 6748 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6749 r = run_query(hdb, 0, query); 6750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6751 6752 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )"; 6753 r = run_query(hdb, 0, query); 6754 ok(r == ERROR_BAD_QUERY_SYNTAX, 6755 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6756 6757 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )"; 6758 r = run_query(hdb, 0, query); 6759 ok(r == ERROR_BAD_QUERY_SYNTAX, 6760 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6761 6762 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )"; 6763 r = run_query(hdb, 0, query); 6764 ok(r == ERROR_BAD_QUERY_SYNTAX, 6765 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6766 6767 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )"; 6768 r = run_query(hdb, 0, query); 6769 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6770 6771 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )"; 6772 r = run_query(hdb, 0, query); 6773 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6774 6775 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )"; 6776 r = run_query(hdb, 0, query); 6777 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6778 6779 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )"; 6780 r = run_query(hdb, 0, query); 6781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6782 6783 query = "SELECT * FROM `Table`"; 6784 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6786 6787 r = MsiViewExecute(hview, 0); 6788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6789 6790 r = MsiViewFetch(hview, &hrec); 6791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6792 6793 size = MAX_PATH; 6794 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6796 ok(!lstrcmpA(buf, "This is a \"string\" ok"), 6797 "Expected \"This is a \"string\" ok\", got %s\n", buf); 6798 6799 MsiCloseHandle(hrec); 6800 6801 r = MsiViewFetch(hview, &hrec); 6802 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6803 6804 MsiViewClose(hview); 6805 MsiCloseHandle(hview); 6806 6807 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char)); 6808 6809 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt"); 6810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6811 6812 DeleteFileA("import.idt"); 6813 6814 query = "SELECT * FROM `Table`"; 6815 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6817 6818 r = MsiViewExecute(hview, 0); 6819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6820 6821 r = MsiViewFetch(hview, &hrec); 6822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6823 6824 size = MAX_PATH; 6825 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6827 ok(!lstrcmpA(buf, "This is a new 'string' ok"), 6828 "Expected \"This is a new 'string' ok\", got %s\n", buf); 6829 6830 MsiCloseHandle(hrec); 6831 6832 r = MsiViewFetch(hview, &hrec); 6833 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6834 6835 MsiViewClose(hview); 6836 MsiCloseHandle(hview); 6837 MsiCloseHandle(hdb); 6838 DeleteFileA(msifile); 6839 } 6840 6841 static void test_carriagereturn(void) 6842 { 6843 MSIHANDLE hdb, hview, hrec; 6844 const char *query; 6845 char buf[MAX_PATH]; 6846 UINT r; 6847 DWORD size; 6848 6849 DeleteFileA(msifile); 6850 6851 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6852 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6853 6854 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6855 r = run_query(hdb, 0, query); 6856 ok(r == ERROR_BAD_QUERY_SYNTAX, 6857 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6858 6859 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6860 r = run_query(hdb, 0, query); 6861 ok(r == ERROR_BAD_QUERY_SYNTAX, 6862 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6863 6864 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6865 r = run_query(hdb, 0, query); 6866 ok(r == ERROR_BAD_QUERY_SYNTAX, 6867 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6868 6869 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6870 r = run_query(hdb, 0, query); 6871 ok(r == ERROR_BAD_QUERY_SYNTAX, 6872 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6873 6874 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6875 r = run_query(hdb, 0, query); 6876 ok(r == ERROR_BAD_QUERY_SYNTAX, 6877 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6878 6879 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6880 r = run_query(hdb, 0, query); 6881 ok(r == ERROR_BAD_QUERY_SYNTAX, 6882 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6883 6884 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )"; 6885 r = run_query(hdb, 0, query); 6886 ok(r == ERROR_BAD_QUERY_SYNTAX, 6887 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6888 6889 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )"; 6890 r = run_query(hdb, 0, query); 6891 ok(r == ERROR_BAD_QUERY_SYNTAX, 6892 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6893 6894 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )"; 6895 r = run_query(hdb, 0, query); 6896 ok(r == ERROR_BAD_QUERY_SYNTAX, 6897 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6898 6899 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )"; 6900 r = run_query(hdb, 0, query); 6901 ok(r == ERROR_BAD_QUERY_SYNTAX, 6902 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6903 6904 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )"; 6905 r = run_query(hdb, 0, query); 6906 ok(r == ERROR_BAD_QUERY_SYNTAX, 6907 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6908 6909 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )"; 6910 r = run_query(hdb, 0, query); 6911 ok(r == ERROR_BAD_QUERY_SYNTAX, 6912 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6913 6914 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )"; 6915 r = run_query(hdb, 0, query); 6916 ok(r == ERROR_BAD_QUERY_SYNTAX, 6917 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6918 6919 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )"; 6920 r = run_query(hdb, 0, query); 6921 ok(r == ERROR_BAD_QUERY_SYNTAX, 6922 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6923 6924 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )"; 6925 r = run_query(hdb, 0, query); 6926 ok(r == ERROR_BAD_QUERY_SYNTAX, 6927 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6928 6929 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r"; 6930 r = run_query(hdb, 0, query); 6931 ok(r == ERROR_BAD_QUERY_SYNTAX, 6932 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6933 6934 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6935 r = run_query(hdb, 0, query); 6936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6937 6938 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6939 r = run_query(hdb, 0, query); 6940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6941 6942 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6943 r = run_query(hdb, 0, query); 6944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6945 6946 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6947 r = run_query(hdb, 0, query); 6948 ok(r == ERROR_BAD_QUERY_SYNTAX, 6949 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6950 6951 query = "CREATE TABLE `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6952 r = run_query(hdb, 0, query); 6953 ok(r == ERROR_BAD_QUERY_SYNTAX, 6954 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6955 6956 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )"; 6957 r = run_query(hdb, 0, query); 6958 ok(r == ERROR_BAD_QUERY_SYNTAX, 6959 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6960 6961 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )"; 6962 r = run_query(hdb, 0, query); 6963 ok(r == ERROR_BAD_QUERY_SYNTAX, 6964 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6965 6966 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )"; 6967 r = run_query(hdb, 0, query); 6968 ok(r == ERROR_BAD_QUERY_SYNTAX, 6969 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6970 6971 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6972 r = run_query(hdb, 0, query); 6973 ok(r == ERROR_BAD_QUERY_SYNTAX, 6974 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6975 6976 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6977 r = run_query(hdb, 0, query); 6978 ok(r == ERROR_BAD_QUERY_SYNTAX, 6979 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6980 6981 query = "SELECT * FROM `_Tables`"; 6982 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6984 r = MsiViewExecute(hview, 0); 6985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6986 6987 r = MsiViewFetch(hview, &hrec); 6988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6989 6990 size = MAX_PATH; 6991 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6993 ok(!lstrcmpA(buf, "\rOne"), "Expected \"\\rOne\", got \"%s\"\n", buf); 6994 6995 MsiCloseHandle(hrec); 6996 6997 r = MsiViewFetch(hview, &hrec); 6998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6999 7000 size = MAX_PATH; 7001 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7003 ok(!lstrcmpA(buf, "Tw\ro"), "Expected \"Tw\\ro\", got \"%s\"\n", buf); 7004 7005 MsiCloseHandle(hrec); 7006 7007 r = MsiViewFetch(hview, &hrec); 7008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7009 7010 size = MAX_PATH; 7011 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7013 ok(!lstrcmpA(buf, "Three\r"), "Expected \"Three\r\", got \"%s\"\n", buf); 7014 7015 MsiCloseHandle(hrec); 7016 7017 r = MsiViewFetch(hview, &hrec); 7018 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7019 7020 MsiViewClose(hview); 7021 MsiCloseHandle(hview); 7022 7023 MsiCloseHandle(hdb); 7024 DeleteFileA(msifile); 7025 } 7026 7027 static void test_noquotes(void) 7028 { 7029 MSIHANDLE hdb, hview, hrec; 7030 const char *query; 7031 char buf[MAX_PATH]; 7032 UINT r; 7033 DWORD size; 7034 7035 DeleteFileA(msifile); 7036 7037 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7039 7040 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7041 r = run_query(hdb, 0, query); 7042 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7043 7044 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7045 r = run_query(hdb, 0, query); 7046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7047 7048 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )"; 7049 r = run_query(hdb, 0, query); 7050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7051 7052 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )"; 7053 r = run_query(hdb, 0, query); 7054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7055 7056 query = "SELECT * FROM `_Tables`"; 7057 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7058 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7059 r = MsiViewExecute(hview, 0); 7060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7061 7062 r = MsiViewFetch(hview, &hrec); 7063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7064 7065 size = MAX_PATH; 7066 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7068 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7069 7070 MsiCloseHandle(hrec); 7071 7072 r = MsiViewFetch(hview, &hrec); 7073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7074 7075 size = MAX_PATH; 7076 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7078 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7079 7080 MsiCloseHandle(hrec); 7081 7082 r = MsiViewFetch(hview, &hrec); 7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7084 7085 size = MAX_PATH; 7086 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7088 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7089 7090 MsiCloseHandle(hrec); 7091 7092 r = MsiViewFetch(hview, &hrec); 7093 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7094 7095 MsiViewClose(hview); 7096 MsiCloseHandle(hview); 7097 7098 query = "SELECT * FROM `_Columns`"; 7099 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7101 r = MsiViewExecute(hview, 0); 7102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7103 7104 r = MsiViewFetch(hview, &hrec); 7105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7106 7107 size = MAX_PATH; 7108 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7110 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7111 7112 r = MsiRecordGetInteger(hrec, 2); 7113 ok(r == 1, "Expected 1, got %d\n", r); 7114 7115 size = MAX_PATH; 7116 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7118 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7119 7120 MsiCloseHandle(hrec); 7121 7122 r = MsiViewFetch(hview, &hrec); 7123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7124 7125 size = MAX_PATH; 7126 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7128 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7129 7130 r = MsiRecordGetInteger(hrec, 2); 7131 ok(r == 1, "Expected 1, got %d\n", r); 7132 7133 size = MAX_PATH; 7134 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7136 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7137 7138 MsiCloseHandle(hrec); 7139 7140 r = MsiViewFetch(hview, &hrec); 7141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7142 7143 size = MAX_PATH; 7144 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7146 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7147 7148 r = MsiRecordGetInteger(hrec, 2); 7149 ok(r == 1, "Expected 1, got %d\n", r); 7150 7151 size = MAX_PATH; 7152 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7154 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7155 7156 MsiCloseHandle(hrec); 7157 7158 r = MsiViewFetch(hview, &hrec); 7159 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7160 7161 MsiViewClose(hview); 7162 MsiCloseHandle(hview); 7163 7164 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )"; 7165 r = run_query(hdb, 0, query); 7166 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7167 7168 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )"; 7169 r = run_query(hdb, 0, query); 7170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7171 7172 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )"; 7173 r = run_query(hdb, 0, query); 7174 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7175 7176 query = "SELECT * FROM Table WHERE `A` = 'hi'"; 7177 r = run_query(hdb, 0, query); 7178 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7179 7180 query = "SELECT * FROM `Table` WHERE `A` = hi"; 7181 r = run_query(hdb, 0, query); 7182 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7183 7184 query = "SELECT * FROM Table"; 7185 r = run_query(hdb, 0, query); 7186 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7187 7188 query = "SELECT * FROM Table2"; 7189 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7191 r = MsiViewExecute(hview, 0); 7192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7193 7194 r = MsiViewFetch(hview, &hrec); 7195 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7196 7197 MsiViewClose(hview); 7198 MsiCloseHandle(hview); 7199 7200 query = "SELECT * FROM `Table` WHERE A = 'hi'"; 7201 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7203 r = MsiViewExecute(hview, 0); 7204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7205 7206 r = MsiViewFetch(hview, &hrec); 7207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7208 7209 size = MAX_PATH; 7210 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7212 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 7213 7214 MsiCloseHandle(hrec); 7215 7216 r = MsiViewFetch(hview, &hrec); 7217 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7218 7219 MsiViewClose(hview); 7220 MsiCloseHandle(hview); 7221 MsiCloseHandle(hdb); 7222 DeleteFileA(msifile); 7223 } 7224 7225 static void read_file_data(LPCSTR filename, LPSTR buffer) 7226 { 7227 HANDLE file; 7228 DWORD read; 7229 7230 file = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); 7231 ZeroMemory(buffer, MAX_PATH); 7232 ReadFile(file, buffer, MAX_PATH, &read, NULL); 7233 CloseHandle(file); 7234 } 7235 7236 static void test_forcecodepage(void) 7237 { 7238 MSIHANDLE hdb; 7239 const char *query; 7240 char buffer[MAX_PATH]; 7241 UINT r; 7242 7243 DeleteFileA(msifile); 7244 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 7245 7246 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7248 7249 query = "SELECT * FROM `_ForceCodepage`"; 7250 r = run_query(hdb, 0, query); 7251 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7252 7253 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7254 r = run_query(hdb, 0, query); 7255 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7256 7257 query = "SELECT * FROM `_ForceCodepage`"; 7258 r = run_query(hdb, 0, query); 7259 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7260 7261 r = MsiDatabaseCommit(hdb); 7262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7263 7264 query = "SELECT * FROM `_ForceCodepage`"; 7265 r = run_query(hdb, 0, query); 7266 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7267 7268 MsiCloseHandle(hdb); 7269 7270 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 7271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7272 7273 query = "SELECT * FROM `_ForceCodepage`"; 7274 r = run_query(hdb, 0, query); 7275 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7276 7277 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7279 7280 read_file_data("forcecodepage.idt", buffer); 7281 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), 7282 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7283 7284 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 7285 7286 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7288 7289 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7291 7292 read_file_data("forcecodepage.idt", buffer); 7293 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), 7294 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7295 7296 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0); 7297 7298 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7299 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7300 7301 MsiCloseHandle(hdb); 7302 DeleteFileA(msifile); 7303 DeleteFileA("forcecodepage.idt"); 7304 } 7305 7306 static void test_viewmodify_refresh(void) 7307 { 7308 MSIHANDLE hdb, hview, hrec; 7309 const char *query; 7310 char buffer[MAX_PATH]; 7311 UINT r; 7312 DWORD size; 7313 7314 DeleteFileA(msifile); 7315 7316 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7318 7319 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )"; 7320 r = run_query(hdb, 0, query); 7321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7322 7323 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 7324 r = run_query(hdb, 0, query); 7325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7326 7327 query = "SELECT * FROM `Table`"; 7328 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7330 r = MsiViewExecute(hview, 0); 7331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7332 7333 r = MsiViewFetch(hview, &hrec); 7334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7335 7336 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'"; 7337 r = run_query(hdb, 0, query); 7338 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7339 7340 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7342 7343 size = MAX_PATH; 7344 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7346 ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer); 7347 ok(size == 2, "Expected 2, got %d\n", size); 7348 7349 r = MsiRecordGetInteger(hrec, 2); 7350 ok(r == 2, "Expected 2, got %d\n", r); 7351 7352 MsiCloseHandle(hrec); 7353 MsiViewClose(hview); 7354 MsiCloseHandle(hview); 7355 7356 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )"; 7357 r = run_query(hdb, 0, query); 7358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7359 7360 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7361 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7363 r = MsiViewExecute(hview, 0); 7364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7365 7366 r = MsiViewFetch(hview, &hrec); 7367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7368 7369 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'"; 7370 r = run_query(hdb, 0, query); 7371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7372 7373 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )"; 7374 r = run_query(hdb, 0, query); 7375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7376 7377 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7379 7380 size = MAX_PATH; 7381 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7383 ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer); 7384 ok(size == 5, "Expected 5, got %d\n", size); 7385 7386 r = MsiRecordGetInteger(hrec, 2); 7387 ok(r == 2, "Expected 2, got %d\n", r); 7388 7389 MsiCloseHandle(hrec); 7390 MsiViewClose(hview); 7391 MsiCloseHandle(hview); 7392 MsiCloseHandle(hdb); 7393 DeleteFileA(msifile); 7394 } 7395 7396 static void test_where_viewmodify(void) 7397 { 7398 MSIHANDLE hdb, hview, hrec; 7399 const char *query; 7400 UINT r; 7401 7402 DeleteFileA(msifile); 7403 7404 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7405 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7406 7407 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 7408 r = run_query(hdb, 0, query); 7409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7410 7411 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )"; 7412 r = run_query(hdb, 0, query); 7413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7414 7415 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )"; 7416 r = run_query(hdb, 0, query); 7417 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7418 7419 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )"; 7420 r = run_query(hdb, 0, query); 7421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7422 7423 /* `B` = 3 doesn't match, but the view shouldn't be executed */ 7424 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7425 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7427 7428 hrec = MsiCreateRecord(2); 7429 MsiRecordSetInteger(hrec, 1, 7); 7430 MsiRecordSetInteger(hrec, 2, 8); 7431 7432 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 7433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7434 7435 MsiCloseHandle(hrec); 7436 MsiViewClose(hview); 7437 MsiCloseHandle(hview); 7438 7439 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7440 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7442 r = MsiViewExecute(hview, 0); 7443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7444 7445 r = MsiViewFetch(hview, &hrec); 7446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7447 7448 r = MsiRecordGetInteger(hrec, 1); 7449 ok(r == 7, "Expected 7, got %d\n", r); 7450 7451 r = MsiRecordGetInteger(hrec, 2); 7452 ok(r == 8, "Expected 8, got %d\n", r); 7453 7454 MsiRecordSetInteger(hrec, 2, 9); 7455 7456 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 7457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7458 7459 MsiCloseHandle(hrec); 7460 MsiViewClose(hview); 7461 MsiCloseHandle(hview); 7462 7463 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7464 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7466 r = MsiViewExecute(hview, 0); 7467 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7468 7469 r = MsiViewFetch(hview, &hrec); 7470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7471 7472 r = MsiRecordGetInteger(hrec, 1); 7473 ok(r == 7, "Expected 7, got %d\n", r); 7474 7475 r = MsiRecordGetInteger(hrec, 2); 7476 ok(r == 9, "Expected 9, got %d\n", r); 7477 7478 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7"; 7479 r = run_query(hdb, 0, query); 7480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7481 7482 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7484 7485 r = MsiRecordGetInteger(hrec, 1); 7486 ok(r == 7, "Expected 7, got %d\n", r); 7487 7488 r = MsiRecordGetInteger(hrec, 2); 7489 ok(r == 10, "Expected 10, got %d\n", r); 7490 7491 MsiCloseHandle(hrec); 7492 MsiViewClose(hview); 7493 MsiCloseHandle(hview); 7494 MsiCloseHandle(hdb); 7495 } 7496 7497 static BOOL create_storage(LPCSTR name) 7498 { 7499 WCHAR nameW[MAX_PATH]; 7500 IStorage *stg; 7501 IStream *stm; 7502 HRESULT hr; 7503 DWORD count; 7504 BOOL res = FALSE; 7505 7506 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, MAX_PATH); 7507 hr = StgCreateDocfile(nameW, STGM_CREATE | STGM_READWRITE | 7508 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &stg); 7509 if (FAILED(hr)) 7510 return FALSE; 7511 7512 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 7513 0, 0, &stm); 7514 if (FAILED(hr)) 7515 goto done; 7516 7517 hr = IStream_Write(stm, "stgdata", 8, &count); 7518 if (SUCCEEDED(hr)) 7519 res = TRUE; 7520 7521 done: 7522 IStream_Release(stm); 7523 IStorage_Release(stg); 7524 7525 return res; 7526 } 7527 7528 static void test_storages_table(void) 7529 { 7530 MSIHANDLE hdb, hview, hrec; 7531 IStorage *stg, *inner; 7532 IStream *stm; 7533 char file[MAX_PATH]; 7534 char buf[MAX_PATH]; 7535 WCHAR name[MAX_PATH]; 7536 LPCSTR query; 7537 HRESULT hr; 7538 DWORD size; 7539 UINT r; 7540 7541 hdb = create_db(); 7542 ok(hdb, "failed to create db\n"); 7543 7544 r = MsiDatabaseCommit(hdb); 7545 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 7546 7547 MsiCloseHandle(hdb); 7548 7549 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb); 7550 ok(r == ERROR_SUCCESS , "Failed to open database\n"); 7551 7552 /* check the column types */ 7553 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES); 7554 ok(hrec, "failed to get column info hrecord\n"); 7555 ok(check_record(hrec, 1, "s62"), "wrong hrecord type\n"); 7556 ok(check_record(hrec, 2, "V0"), "wrong hrecord type\n"); 7557 7558 MsiCloseHandle(hrec); 7559 7560 /* now try the names */ 7561 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES); 7562 ok(hrec, "failed to get column info hrecord\n"); 7563 ok(check_record(hrec, 1, "Name"), "wrong hrecord type\n"); 7564 ok(check_record(hrec, 2, "Data"), "wrong hrecord type\n"); 7565 7566 MsiCloseHandle(hrec); 7567 7568 create_storage("storage.bin"); 7569 7570 hrec = MsiCreateRecord(2); 7571 MsiRecordSetStringA(hrec, 1, "stgname"); 7572 7573 r = MsiRecordSetStreamA(hrec, 2, "storage.bin"); 7574 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r); 7575 7576 DeleteFileA("storage.bin"); 7577 7578 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)"; 7579 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7580 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7581 7582 r = MsiViewExecute(hview, hrec); 7583 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7584 7585 MsiCloseHandle(hrec); 7586 MsiViewClose(hview); 7587 MsiCloseHandle(hview); 7588 7589 query = "SELECT `Name`, `Data` FROM `_Storages`"; 7590 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7591 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7592 7593 r = MsiViewExecute(hview, 0); 7594 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7595 7596 r = MsiViewFetch(hview, &hrec); 7597 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r); 7598 7599 size = MAX_PATH; 7600 r = MsiRecordGetStringA(hrec, 1, file, &size); 7601 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 7602 ok(!lstrcmpA(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file); 7603 7604 size = MAX_PATH; 7605 lstrcpyA(buf, "apple"); 7606 r = MsiRecordReadStream(hrec, 2, buf, &size); 7607 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r); 7608 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); 7609 ok(size == 0, "Expected 0, got %d\n", size); 7610 7611 MsiCloseHandle(hrec); 7612 7613 r = MsiViewFetch(hview, &hrec); 7614 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7615 7616 MsiViewClose(hview); 7617 MsiCloseHandle(hview); 7618 7619 MsiDatabaseCommit(hdb); 7620 MsiCloseHandle(hdb); 7621 7622 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, MAX_PATH); 7623 hr = StgOpenStorage(name, NULL, STGM_DIRECT | STGM_READ | 7624 STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 7625 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7626 ok(stg != NULL, "Expected non-NULL storage\n"); 7627 7628 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH); 7629 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 7630 NULL, 0, &inner); 7631 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7632 ok(inner != NULL, "Expected non-NULL storage\n"); 7633 7634 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH); 7635 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 7636 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7637 ok(stm != NULL, "Expected non-NULL stream\n"); 7638 7639 hr = IStream_Read(stm, buf, MAX_PATH, &size); 7640 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 7641 ok(size == 8, "Expected 8, got %d\n", size); 7642 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf); 7643 7644 IStream_Release(stm); 7645 IStorage_Release(inner); 7646 7647 IStorage_Release(stg); 7648 DeleteFileA(msifile); 7649 } 7650 7651 static void test_dbtopackage(void) 7652 { 7653 MSIHANDLE hdb, hpkg; 7654 CHAR package[12], buf[MAX_PATH]; 7655 DWORD size; 7656 UINT r; 7657 7658 /* create an empty database, transact mode */ 7659 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7660 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7661 7662 set_summary_info(hdb); 7663 7664 r = create_directory_table(hdb); 7665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7666 7667 r = create_custom_action_table(hdb); 7668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7669 7670 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7672 7673 sprintf(package, "#%u", hdb); 7674 r = MsiOpenPackageA(package, &hpkg); 7675 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7676 { 7677 skip("Not enough rights to perform tests\n"); 7678 goto error; 7679 } 7680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7681 7682 /* property is not set yet */ 7683 size = MAX_PATH; 7684 lstrcpyA(buf, "kiwi"); 7685 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7687 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7688 ok(size == 0, "Expected 0, got %d\n", size); 7689 7690 /* run the custom action to set the property */ 7691 r = MsiDoActionA(hpkg, "SetProp"); 7692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7693 7694 /* property is now set */ 7695 size = MAX_PATH; 7696 lstrcpyA(buf, "kiwi"); 7697 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7699 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7700 ok(size == 5, "Expected 5, got %d\n", size); 7701 7702 MsiCloseHandle(hpkg); 7703 7704 /* reset the package */ 7705 r = MsiOpenPackageA(package, &hpkg); 7706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7707 7708 /* property is not set anymore */ 7709 size = MAX_PATH; 7710 lstrcpyA(buf, "kiwi"); 7711 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7713 todo_wine 7714 { 7715 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7716 ok(size == 0, "Expected 0, got %d\n", size); 7717 } 7718 7719 MsiCloseHandle(hdb); 7720 MsiCloseHandle(hpkg); 7721 7722 /* create an empty database, direct mode */ 7723 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb); 7724 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7725 7726 set_summary_info(hdb); 7727 7728 r = create_directory_table(hdb); 7729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7730 7731 r = create_custom_action_table(hdb); 7732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7733 7734 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7735 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7736 7737 sprintf(package, "#%u", hdb); 7738 r = MsiOpenPackageA(package, &hpkg); 7739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7740 7741 /* property is not set yet */ 7742 size = MAX_PATH; 7743 lstrcpyA(buf, "kiwi"); 7744 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7746 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7747 ok(size == 0, "Expected 0, got %d\n", size); 7748 7749 /* run the custom action to set the property */ 7750 r = MsiDoActionA(hpkg, "SetProp"); 7751 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7752 7753 /* property is now set */ 7754 size = MAX_PATH; 7755 lstrcpyA(buf, "kiwi"); 7756 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7758 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7759 ok(size == 5, "Expected 5, got %d\n", size); 7760 7761 MsiCloseHandle(hpkg); 7762 7763 /* reset the package */ 7764 r = MsiOpenPackageA(package, &hpkg); 7765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7766 7767 /* property is not set anymore */ 7768 size = MAX_PATH; 7769 lstrcpyA(buf, "kiwi"); 7770 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7772 todo_wine 7773 { 7774 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7775 ok(size == 0, "Expected 0, got %d\n", size); 7776 } 7777 7778 MsiCloseHandle(hpkg); 7779 7780 error: 7781 MsiCloseHandle(hdb); 7782 DeleteFileA(msifile); 7783 } 7784 7785 static void test_droptable(void) 7786 { 7787 MSIHANDLE hdb, hview, hrec; 7788 CHAR buf[MAX_PATH]; 7789 LPCSTR query; 7790 DWORD size; 7791 UINT r; 7792 7793 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7795 7796 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7797 r = run_query(hdb, 0, query); 7798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7799 7800 query = "SELECT * FROM `One`"; 7801 r = do_query(hdb, query, &hrec); 7802 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7803 7804 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7805 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7807 r = MsiViewExecute(hview, 0); 7808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7809 7810 r = MsiViewFetch(hview, &hrec); 7811 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7812 7813 size = MAX_PATH; 7814 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7816 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7817 7818 MsiCloseHandle(hrec); 7819 MsiViewClose(hview); 7820 MsiCloseHandle(hview); 7821 7822 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7823 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7825 r = MsiViewExecute(hview, 0); 7826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7827 7828 r = MsiViewFetch(hview, &hrec); 7829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7830 7831 size = MAX_PATH; 7832 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7834 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7835 7836 r = MsiRecordGetInteger(hrec, 2); 7837 ok(r == 1, "Expected 1, got %d\n", r); 7838 7839 size = MAX_PATH; 7840 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7842 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7843 7844 MsiCloseHandle(hrec); 7845 7846 r = MsiViewFetch(hview, &hrec); 7847 ok(r == ERROR_NO_MORE_ITEMS, 7848 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7849 7850 MsiViewClose(hview); 7851 MsiCloseHandle(hview); 7852 7853 query = "DROP `One`"; 7854 r = run_query(hdb, 0, query); 7855 ok(r == ERROR_BAD_QUERY_SYNTAX, 7856 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7857 7858 query = "DROP TABLE"; 7859 r = run_query(hdb, 0, query); 7860 ok(r == ERROR_BAD_QUERY_SYNTAX, 7861 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7862 7863 query = "DROP TABLE `One`"; 7864 hview = 0; 7865 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7867 r = MsiViewExecute(hview, 0); 7868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7869 7870 r = MsiViewFetch(hview, &hrec); 7871 ok(r == ERROR_FUNCTION_FAILED, 7872 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7873 7874 MsiViewClose(hview); 7875 MsiCloseHandle(hview); 7876 7877 query = "SELECT * FROM `IDontExist`"; 7878 r = do_query(hdb, query, &hrec); 7879 ok(r == ERROR_BAD_QUERY_SYNTAX, 7880 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7881 7882 query = "SELECT * FROM `One`"; 7883 r = do_query(hdb, query, &hrec); 7884 ok(r == ERROR_BAD_QUERY_SYNTAX, 7885 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7886 7887 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7888 r = run_query(hdb, 0, query); 7889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7890 7891 query = "DROP TABLE One"; 7892 r = run_query(hdb, 0, query); 7893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7894 7895 query = "SELECT * FROM `One`"; 7896 r = do_query(hdb, query, &hrec); 7897 ok(r == ERROR_BAD_QUERY_SYNTAX, 7898 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7899 7900 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7901 r = do_query(hdb, query, &hrec); 7902 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7903 7904 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7905 r = do_query(hdb, query, &hrec); 7906 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7907 7908 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )"; 7909 r = run_query(hdb, 0, query); 7910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7911 7912 query = "SELECT * FROM `One`"; 7913 r = do_query(hdb, query, &hrec); 7914 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7915 7916 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7917 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7918 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7919 r = MsiViewExecute(hview, 0); 7920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7921 7922 r = MsiViewFetch(hview, &hrec); 7923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7924 7925 size = MAX_PATH; 7926 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7928 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7929 7930 MsiCloseHandle(hrec); 7931 MsiViewClose(hview); 7932 MsiCloseHandle(hview); 7933 7934 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7935 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7937 r = MsiViewExecute(hview, 0); 7938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7939 7940 r = MsiViewFetch(hview, &hrec); 7941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7942 7943 size = MAX_PATH; 7944 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7946 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7947 7948 r = MsiRecordGetInteger(hrec, 2); 7949 ok(r == 1, "Expected 1, got %d\n", r); 7950 7951 size = MAX_PATH; 7952 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7954 ok(!lstrcmpA(buf, "B"), "Expected \"B\", got \"%s\"\n", buf); 7955 7956 MsiCloseHandle(hrec); 7957 7958 r = MsiViewFetch(hview, &hrec); 7959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7960 7961 size = MAX_PATH; 7962 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7964 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7965 7966 r = MsiRecordGetInteger(hrec, 2); 7967 ok(r == 2, "Expected 2, got %d\n", r); 7968 7969 size = MAX_PATH; 7970 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7972 ok(!lstrcmpA(buf, "C"), "Expected \"C\", got \"%s\"\n", buf); 7973 7974 MsiCloseHandle(hrec); 7975 7976 r = MsiViewFetch(hview, &hrec); 7977 ok(r == ERROR_NO_MORE_ITEMS, 7978 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7979 7980 MsiViewClose(hview); 7981 MsiCloseHandle(hview); 7982 7983 query = "DROP TABLE One"; 7984 r = run_query(hdb, 0, query); 7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7986 7987 query = "SELECT * FROM `One`"; 7988 r = do_query(hdb, query, &hrec); 7989 ok(r == ERROR_BAD_QUERY_SYNTAX, 7990 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7991 7992 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7993 r = do_query(hdb, query, &hrec); 7994 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7995 7996 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7997 r = do_query(hdb, query, &hrec); 7998 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7999 8000 MsiCloseHandle(hdb); 8001 DeleteFileA(msifile); 8002 } 8003 8004 static void test_dbmerge(void) 8005 { 8006 static const WCHAR refdbW[] = {'r','e','f','d','b','.','m','s','i',0}; 8007 MSIHANDLE hdb, href, hview, hrec; 8008 CHAR buf[MAX_PATH]; 8009 LPCSTR query; 8010 DWORD size; 8011 UINT r; 8012 8013 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 8014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8015 8016 r = MsiOpenDatabaseW(refdbW, MSIDBOPEN_CREATE, &href); 8017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8018 8019 /* hDatabase is invalid */ 8020 r = MsiDatabaseMergeA(0, href, "MergeErrors"); 8021 ok(r == ERROR_INVALID_HANDLE, 8022 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8023 8024 /* hDatabaseMerge is invalid */ 8025 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors"); 8026 ok(r == ERROR_INVALID_HANDLE, 8027 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8028 8029 /* szTableName is NULL */ 8030 r = MsiDatabaseMergeA(hdb, href, NULL); 8031 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8032 8033 /* szTableName is empty */ 8034 r = MsiDatabaseMergeA(hdb, href, ""); 8035 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r); 8036 8037 /* both DBs empty, szTableName is valid */ 8038 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8040 8041 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 8042 r = run_query(hdb, 0, query); 8043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8044 8045 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )"; 8046 r = run_query(href, 0, query); 8047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8048 8049 /* column types don't match */ 8050 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8051 ok(r == ERROR_DATATYPE_MISMATCH, 8052 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8053 8054 /* nothing in MergeErrors */ 8055 query = "SELECT * FROM `MergeErrors`"; 8056 r = do_query(hdb, query, &hrec); 8057 ok(r == ERROR_BAD_QUERY_SYNTAX, 8058 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8059 8060 query = "DROP TABLE `One`"; 8061 r = run_query(hdb, 0, query); 8062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8063 8064 query = "DROP TABLE `One`"; 8065 r = run_query(href, 0, query); 8066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8067 8068 query = "CREATE TABLE `One` ( " 8069 "`A` CHAR(72), " 8070 "`B` CHAR(56), " 8071 "`C` CHAR(64) LOCALIZABLE, " 8072 "`D` LONGCHAR, " 8073 "`E` CHAR(72) NOT NULL, " 8074 "`F` CHAR(56) NOT NULL, " 8075 "`G` CHAR(64) NOT NULL LOCALIZABLE, " 8076 "`H` LONGCHAR NOT NULL " 8077 "PRIMARY KEY `A` )"; 8078 r = run_query(hdb, 0, query); 8079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8080 8081 query = "CREATE TABLE `One` ( " 8082 "`A` CHAR(64), " 8083 "`B` CHAR(64), " 8084 "`C` CHAR(64), " 8085 "`D` CHAR(64), " 8086 "`E` CHAR(64) NOT NULL, " 8087 "`F` CHAR(64) NOT NULL, " 8088 "`G` CHAR(64) NOT NULL, " 8089 "`H` CHAR(64) NOT NULL " 8090 "PRIMARY KEY `A` )"; 8091 r = run_query(href, 0, query); 8092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8093 8094 /* column string types don't match exactly */ 8095 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8096 ok(r == ERROR_SUCCESS, 8097 "Expected ERROR_SUCCESS, got %d\n", r); 8098 8099 /* nothing in MergeErrors */ 8100 query = "SELECT * FROM `MergeErrors`"; 8101 r = do_query(hdb, query, &hrec); 8102 ok(r == ERROR_BAD_QUERY_SYNTAX, 8103 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8104 8105 query = "DROP TABLE `One`"; 8106 r = run_query(hdb, 0, query); 8107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8108 8109 query = "DROP TABLE `One`"; 8110 r = run_query(href, 0, query); 8111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8112 8113 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8114 r = run_query(hdb, 0, query); 8115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8116 8117 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )"; 8118 r = run_query(href, 0, query); 8119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8120 8121 /* column names don't match */ 8122 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8123 ok(r == ERROR_DATATYPE_MISMATCH, 8124 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8125 8126 /* nothing in MergeErrors */ 8127 query = "SELECT * FROM `MergeErrors`"; 8128 r = do_query(hdb, query, &hrec); 8129 ok(r == ERROR_BAD_QUERY_SYNTAX, 8130 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8131 8132 query = "DROP TABLE `One`"; 8133 r = run_query(hdb, 0, query); 8134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8135 8136 query = "DROP TABLE `One`"; 8137 r = run_query(href, 0, query); 8138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8139 8140 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8141 r = run_query(hdb, 0, query); 8142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8143 8144 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )"; 8145 r = run_query(href, 0, query); 8146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8147 8148 /* primary keys don't match */ 8149 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8150 ok(r == ERROR_DATATYPE_MISMATCH, 8151 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8152 8153 /* nothing in MergeErrors */ 8154 query = "SELECT * FROM `MergeErrors`"; 8155 r = do_query(hdb, query, &hrec); 8156 ok(r == ERROR_BAD_QUERY_SYNTAX, 8157 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8158 8159 query = "DROP TABLE `One`"; 8160 r = run_query(hdb, 0, query); 8161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8162 8163 query = "DROP TABLE `One`"; 8164 r = run_query(href, 0, query); 8165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8166 8167 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8168 r = run_query(hdb, 0, query); 8169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8170 8171 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )"; 8172 r = run_query(href, 0, query); 8173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8174 8175 /* number of primary keys doesn't match */ 8176 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8177 ok(r == ERROR_DATATYPE_MISMATCH, 8178 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8179 8180 /* nothing in MergeErrors */ 8181 query = "SELECT * FROM `MergeErrors`"; 8182 r = do_query(hdb, query, &hrec); 8183 ok(r == ERROR_BAD_QUERY_SYNTAX, 8184 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8185 8186 query = "DROP TABLE `One`"; 8187 r = run_query(hdb, 0, query); 8188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8189 8190 query = "DROP TABLE `One`"; 8191 r = run_query(href, 0, query); 8192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8193 8194 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8195 r = run_query(hdb, 0, query); 8196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8197 8198 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8199 r = run_query(href, 0, query); 8200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8201 8202 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8203 r = run_query(href, 0, query); 8204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8205 8206 /* number of columns doesn't match */ 8207 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8209 8210 query = "SELECT * FROM `One`"; 8211 r = do_query(hdb, query, &hrec); 8212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8213 8214 r = MsiRecordGetInteger(hrec, 1); 8215 ok(r == 1, "Expected 1, got %d\n", r); 8216 8217 r = MsiRecordGetInteger(hrec, 2); 8218 ok(r == 2, "Expected 2, got %d\n", r); 8219 8220 r = MsiRecordGetInteger(hrec, 3); 8221 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8222 8223 MsiCloseHandle(hrec); 8224 8225 /* nothing in MergeErrors */ 8226 query = "SELECT * FROM `MergeErrors`"; 8227 r = do_query(hdb, query, &hrec); 8228 ok(r == ERROR_BAD_QUERY_SYNTAX, 8229 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8230 8231 query = "DROP TABLE `One`"; 8232 r = run_query(hdb, 0, query); 8233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8234 8235 query = "DROP TABLE `One`"; 8236 r = run_query(href, 0, query); 8237 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8238 8239 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8240 r = run_query(hdb, 0, query); 8241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8242 8243 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8244 r = run_query(href, 0, query); 8245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8246 8247 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8248 r = run_query(href, 0, query); 8249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8250 8251 /* number of columns doesn't match */ 8252 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8254 8255 query = "SELECT * FROM `One`"; 8256 r = do_query(hdb, query, &hrec); 8257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8258 8259 r = MsiRecordGetInteger(hrec, 1); 8260 ok(r == 1, "Expected 1, got %d\n", r); 8261 8262 r = MsiRecordGetInteger(hrec, 2); 8263 ok(r == 2, "Expected 2, got %d\n", r); 8264 8265 r = MsiRecordGetInteger(hrec, 3); 8266 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8267 8268 MsiCloseHandle(hrec); 8269 8270 /* nothing in MergeErrors */ 8271 query = "SELECT * FROM `MergeErrors`"; 8272 r = do_query(hdb, query, &hrec); 8273 ok(r == ERROR_BAD_QUERY_SYNTAX, 8274 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8275 8276 query = "DROP TABLE `One`"; 8277 r = run_query(hdb, 0, query); 8278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8279 8280 query = "DROP TABLE `One`"; 8281 r = run_query(href, 0, query); 8282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8283 8284 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8285 r = run_query(hdb, 0, query); 8286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8287 8288 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )"; 8289 r = run_query(hdb, 0, query); 8290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8291 8292 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )"; 8293 r = run_query(hdb, 0, query); 8294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8295 8296 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8297 r = run_query(href, 0, query); 8298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8299 8300 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8301 r = run_query(href, 0, query); 8302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8303 8304 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )"; 8305 r = run_query(href, 0, query); 8306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8307 8308 /* primary keys match, rows do not */ 8309 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8310 ok(r == ERROR_FUNCTION_FAILED, 8311 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8312 8313 /* nothing in MergeErrors */ 8314 query = "SELECT * FROM `MergeErrors`"; 8315 r = do_query(hdb, query, &hrec); 8316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8317 8318 size = MAX_PATH; 8319 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8321 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 8322 8323 r = MsiRecordGetInteger(hrec, 2); 8324 ok(r == 2, "Expected 2, got %d\n", r); 8325 8326 MsiCloseHandle(hrec); 8327 8328 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview); 8329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8330 8331 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec); 8332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8333 8334 size = MAX_PATH; 8335 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8337 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 8338 8339 size = MAX_PATH; 8340 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8342 ok(!lstrcmpA(buf, "NumRowMergeConflicts"), 8343 "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf); 8344 8345 MsiCloseHandle(hrec); 8346 8347 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec); 8348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8349 8350 size = MAX_PATH; 8351 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8353 ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf); 8354 8355 size = MAX_PATH; 8356 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8358 ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf); 8359 8360 MsiCloseHandle(hrec); 8361 MsiViewClose(hview); 8362 MsiCloseHandle(hview); 8363 8364 query = "DROP TABLE `MergeErrors`"; 8365 r = run_query(hdb, 0, query); 8366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8367 8368 query = "DROP TABLE `One`"; 8369 r = run_query(hdb, 0, query); 8370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8371 8372 query = "DROP TABLE `One`"; 8373 r = run_query(href, 0, query); 8374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8375 8376 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8377 r = run_query(href, 0, query); 8378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8379 8380 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8381 r = run_query(href, 0, query); 8382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8383 8384 /* table from merged database is not in target database */ 8385 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8387 8388 query = "SELECT * FROM `One`"; 8389 r = do_query(hdb, query, &hrec); 8390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8391 8392 r = MsiRecordGetInteger(hrec, 1); 8393 ok(r == 1, "Expected 1, got %d\n", r); 8394 8395 size = MAX_PATH; 8396 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8398 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8399 8400 MsiCloseHandle(hrec); 8401 8402 /* nothing in MergeErrors */ 8403 query = "SELECT * FROM `MergeErrors`"; 8404 r = do_query(hdb, query, &hrec); 8405 ok(r == ERROR_BAD_QUERY_SYNTAX, 8406 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8407 8408 query = "DROP TABLE `One`"; 8409 r = run_query(hdb, 0, query); 8410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8411 8412 query = "DROP TABLE `One`"; 8413 r = run_query(href, 0, query); 8414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8415 8416 query = "CREATE TABLE `One` ( " 8417 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8418 r = run_query(hdb, 0, query); 8419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8420 8421 query = "CREATE TABLE `One` ( " 8422 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8423 r = run_query(href, 0, query); 8424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8425 8426 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 8427 r = run_query(href, 0, query); 8428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8429 8430 /* primary key is string */ 8431 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8433 8434 query = "SELECT * FROM `One`"; 8435 r = do_query(hdb, query, &hrec); 8436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8437 8438 size = MAX_PATH; 8439 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8441 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8442 8443 r = MsiRecordGetInteger(hrec, 2); 8444 ok(r == 1, "Expected 1, got %d\n", r); 8445 8446 MsiCloseHandle(hrec); 8447 8448 /* nothing in MergeErrors */ 8449 query = "SELECT * FROM `MergeErrors`"; 8450 r = do_query(hdb, query, &hrec); 8451 ok(r == ERROR_BAD_QUERY_SYNTAX, 8452 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8453 8454 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 8455 8456 GetCurrentDirectoryA(MAX_PATH, buf); 8457 r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); 8458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8459 8460 query = "DROP TABLE `One`"; 8461 r = run_query(hdb, 0, query); 8462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8463 8464 query = "DROP TABLE `One`"; 8465 r = run_query(href, 0, query); 8466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8467 8468 query = "CREATE TABLE `One` ( " 8469 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8470 r = run_query(hdb, 0, query); 8471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8472 8473 query = "CREATE TABLE `One` ( " 8474 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8475 r = run_query(href, 0, query); 8476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8477 8478 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8479 r = run_query(href, 0, query); 8480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8481 8482 /* code page does not match */ 8483 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8485 8486 query = "SELECT * FROM `One`"; 8487 r = do_query(hdb, query, &hrec); 8488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8489 8490 r = MsiRecordGetInteger(hrec, 1); 8491 ok(r == 1, "Expected 1, got %d\n", r); 8492 8493 size = MAX_PATH; 8494 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8496 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8497 8498 MsiCloseHandle(hrec); 8499 8500 /* nothing in MergeErrors */ 8501 query = "SELECT * FROM `MergeErrors`"; 8502 r = do_query(hdb, query, &hrec); 8503 ok(r == ERROR_BAD_QUERY_SYNTAX, 8504 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8505 8506 query = "DROP TABLE `One`"; 8507 r = run_query(hdb, 0, query); 8508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8509 8510 query = "DROP TABLE `One`"; 8511 r = run_query(href, 0, query); 8512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8513 8514 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8515 r = run_query(hdb, 0, query); 8516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8517 8518 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8519 r = run_query(href, 0, query); 8520 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8521 8522 create_file("binary.dat"); 8523 hrec = MsiCreateRecord(1); 8524 MsiRecordSetStreamA(hrec, 1, "binary.dat"); 8525 8526 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )"; 8527 r = run_query(href, hrec, query); 8528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8529 8530 MsiCloseHandle(hrec); 8531 8532 /* binary data to merge */ 8533 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8535 8536 query = "SELECT * FROM `One`"; 8537 r = do_query(hdb, query, &hrec); 8538 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8539 8540 r = MsiRecordGetInteger(hrec, 1); 8541 ok(r == 1, "Expected 1, got %d\n", r); 8542 8543 size = MAX_PATH; 8544 ZeroMemory(buf, MAX_PATH); 8545 r = MsiRecordReadStream(hrec, 2, buf, &size); 8546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8547 ok(!lstrcmpA(buf, "binary.dat\n"), 8548 "Expected \"binary.dat\\n\", got \"%s\"\n", buf); 8549 8550 MsiCloseHandle(hrec); 8551 8552 /* nothing in MergeErrors */ 8553 query = "SELECT * FROM `MergeErrors`"; 8554 r = do_query(hdb, query, &hrec); 8555 ok(r == ERROR_BAD_QUERY_SYNTAX, 8556 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8557 8558 query = "DROP TABLE `One`"; 8559 r = run_query(hdb, 0, query); 8560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8561 8562 query = "DROP TABLE `One`"; 8563 r = run_query(href, 0, query); 8564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8565 8566 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8567 r = run_query(hdb, 0, query); 8568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8569 r = run_query(href, 0, query); 8570 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8571 8572 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )"; 8573 r = run_query(href, 0, query); 8574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8575 8576 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )"; 8577 r = run_query(href, 0, query); 8578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8579 8580 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8582 8583 query = "SELECT * FROM `One`"; 8584 r = MsiDatabaseOpenViewA(hdb, query, &hview); 8585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8586 r = MsiViewExecute(hview, 0); 8587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8588 8589 r = MsiViewFetch(hview, &hrec); 8590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8591 8592 r = MsiRecordGetInteger(hrec, 1); 8593 ok(r == 1, "Expected 1, got %d\n", r); 8594 8595 size = MAX_PATH; 8596 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8598 ok(!lstrcmpA(buf, "foo"), "Expected \"foo\", got \"%s\"\n", buf); 8599 8600 MsiCloseHandle(hrec); 8601 8602 r = MsiViewFetch(hview, &hrec); 8603 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8604 8605 r = MsiRecordGetInteger(hrec, 1); 8606 ok(r == 2, "Expected 2, got %d\n", r); 8607 8608 size = MAX_PATH; 8609 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8611 ok(!lstrcmpA(buf, "bar"), "Expected \"bar\", got \"%s\"\n", buf); 8612 8613 MsiCloseHandle(hrec); 8614 8615 r = MsiViewFetch(hview, &hrec); 8616 ok(r == ERROR_NO_MORE_ITEMS, 8617 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8618 8619 MsiViewClose(hview); 8620 MsiCloseHandle(hview); 8621 8622 MsiCloseHandle(hdb); 8623 MsiCloseHandle(href); 8624 DeleteFileA(msifile); 8625 DeleteFileW(refdbW); 8626 DeleteFileA("codepage.idt"); 8627 DeleteFileA("binary.dat"); 8628 } 8629 8630 static void test_select_with_tablenames(void) 8631 { 8632 MSIHANDLE hdb, view, rec; 8633 LPCSTR query; 8634 UINT r; 8635 int i; 8636 8637 int vals[4][2] = { 8638 {1,12}, 8639 {4,12}, 8640 {1,15}, 8641 {4,15}}; 8642 8643 hdb = create_db(); 8644 ok(hdb, "failed to create db\n"); 8645 8646 /* Build a pair of tables with the same column names, but unique data */ 8647 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8648 r = run_query(hdb, 0, query); 8649 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8650 8651 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )"; 8652 r = run_query(hdb, 0, query); 8653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8654 8655 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )"; 8656 r = run_query(hdb, 0, query); 8657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8658 8659 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8660 r = run_query(hdb, 0, query); 8661 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8662 8663 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )"; 8664 r = run_query(hdb, 0, query); 8665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8666 8667 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )"; 8668 r = run_query(hdb, 0, query); 8669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8670 8671 8672 /* Test that selection based on prefixing the column with the table 8673 * actually selects the right data */ 8674 8675 query = "SELECT T1.A, T2.B FROM T1,T2"; 8676 r = MsiDatabaseOpenViewA(hdb, query, &view); 8677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8678 r = MsiViewExecute(view, 0); 8679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8680 8681 for (i = 0; i < 4; i++) 8682 { 8683 r = MsiViewFetch(view, &rec); 8684 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8685 8686 r = MsiRecordGetInteger(rec, 1); 8687 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r); 8688 8689 r = MsiRecordGetInteger(rec, 2); 8690 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r); 8691 8692 MsiCloseHandle(rec); 8693 } 8694 8695 r = MsiViewFetch(view, &rec); 8696 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8697 8698 MsiViewClose(view); 8699 MsiCloseHandle(view); 8700 MsiCloseHandle(hdb); 8701 DeleteFileA(msifile); 8702 } 8703 8704 static const UINT ordervals[6][3] = 8705 { 8706 { MSI_NULL_INTEGER, 12, 13 }, 8707 { 1, 2, 3 }, 8708 { 6, 4, 5 }, 8709 { 8, 9, 7 }, 8710 { 10, 11, MSI_NULL_INTEGER }, 8711 { 14, MSI_NULL_INTEGER, 15 } 8712 }; 8713 8714 static void test_insertorder(void) 8715 { 8716 MSIHANDLE hdb, view, rec; 8717 LPCSTR query; 8718 UINT r; 8719 int i; 8720 8721 hdb = create_db(); 8722 ok(hdb, "failed to create db\n"); 8723 8724 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 8725 r = run_query(hdb, 0, query); 8726 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8727 8728 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8729 r = run_query(hdb, 0, query); 8730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8731 8732 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )"; 8733 r = run_query(hdb, 0, query); 8734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8735 8736 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )"; 8737 r = run_query(hdb, 0, query); 8738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8739 8740 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )"; 8741 r = run_query(hdb, 0, query); 8742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8743 8744 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )"; 8745 r = run_query(hdb, 0, query); 8746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8747 8748 /* fails because the primary key already 8749 * has an MSI_NULL_INTEGER value set above 8750 */ 8751 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )"; 8752 r = run_query(hdb, 0, query); 8753 ok(r == ERROR_FUNCTION_FAILED, 8754 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8755 8756 /* replicate the error where primary key is set twice */ 8757 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 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 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )"; 8763 r = run_query(hdb, 0, query); 8764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8765 8766 query = "INSERT INTO `T` VALUES ( 16 )"; 8767 r = run_query(hdb, 0, query); 8768 ok(r == ERROR_BAD_QUERY_SYNTAX, 8769 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8770 8771 query = "INSERT INTO `T` VALUES ( 17, 18 )"; 8772 r = run_query(hdb, 0, query); 8773 ok(r == ERROR_BAD_QUERY_SYNTAX, 8774 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8775 8776 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )"; 8777 r = run_query(hdb, 0, query); 8778 ok(r == ERROR_BAD_QUERY_SYNTAX, 8779 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8780 8781 query = "SELECT * FROM `T`"; 8782 r = MsiDatabaseOpenViewA(hdb, query, &view); 8783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8784 r = MsiViewExecute(view, 0); 8785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8786 8787 for (i = 0; i < 6; i++) 8788 { 8789 r = MsiViewFetch(view, &rec); 8790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8791 8792 r = MsiRecordGetInteger(rec, 1); 8793 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8794 8795 r = MsiRecordGetInteger(rec, 2); 8796 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8797 8798 r = MsiRecordGetInteger(rec, 3); 8799 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8800 8801 MsiCloseHandle(rec); 8802 } 8803 8804 r = MsiViewFetch(view, &rec); 8805 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8806 8807 MsiViewClose(view); 8808 MsiCloseHandle(view); 8809 8810 query = "DELETE FROM `T` WHERE `A` IS NULL"; 8811 r = run_query(hdb, 0, query); 8812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8813 8814 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY"; 8815 r = run_query(hdb, 0, query); 8816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8817 8818 query = "SELECT * FROM `T`"; 8819 r = MsiDatabaseOpenViewA(hdb, query, &view); 8820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8821 r = MsiViewExecute(view, 0); 8822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8823 8824 for (i = 0; i < 6; i++) 8825 { 8826 r = MsiViewFetch(view, &rec); 8827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8828 8829 r = MsiRecordGetInteger(rec, 1); 8830 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8831 8832 r = MsiRecordGetInteger(rec, 2); 8833 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8834 8835 r = MsiRecordGetInteger(rec, 3); 8836 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8837 8838 MsiCloseHandle(rec); 8839 } 8840 8841 r = MsiViewFetch(view, &rec); 8842 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8843 8844 MsiViewClose(view); 8845 MsiCloseHandle(view); 8846 MsiCloseHandle(hdb); 8847 DeleteFileA(msifile); 8848 } 8849 8850 static void test_columnorder(void) 8851 { 8852 MSIHANDLE hdb, view, rec; 8853 char buf[MAX_PATH]; 8854 LPCSTR query; 8855 DWORD sz; 8856 UINT r; 8857 8858 hdb = create_db(); 8859 ok(hdb, "failed to create db\n"); 8860 8861 /* Each column is a slot: 8862 * --------------------- 8863 * | B | C | A | E | D | 8864 * --------------------- 8865 * 8866 * When a column is selected as a primary key, 8867 * the column occupying the nth primary key slot is swapped 8868 * with the current position of the primary key in question: 8869 * 8870 * set primary key `D` 8871 * --------------------- --------------------- 8872 * | B | C | A | E | D | -> | D | C | A | E | B | 8873 * --------------------- --------------------- 8874 * 8875 * set primary key `E` 8876 * --------------------- --------------------- 8877 * | D | C | A | E | B | -> | D | E | A | C | B | 8878 * --------------------- --------------------- 8879 */ 8880 8881 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 8882 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 8883 "PRIMARY KEY `D`, `E`)"; 8884 r = run_query(hdb, 0, query); 8885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8886 8887 query = "SELECT * FROM `T`"; 8888 r = MsiDatabaseOpenViewA(hdb, query, &view); 8889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8890 8891 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 8892 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8893 8894 sz = MAX_PATH; 8895 lstrcpyA(buf, "kiwi"); 8896 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8898 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf); 8899 8900 sz = MAX_PATH; 8901 lstrcpyA(buf, "kiwi"); 8902 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8904 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 8905 8906 sz = MAX_PATH; 8907 lstrcpyA(buf, "kiwi"); 8908 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8910 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 8911 8912 sz = MAX_PATH; 8913 lstrcpyA(buf, "kiwi"); 8914 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8916 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 8917 8918 sz = MAX_PATH; 8919 lstrcpyA(buf, "kiwi"); 8920 r = MsiRecordGetStringA(rec, 5, 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 MsiCloseHandle(rec); 8925 8926 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 8927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8928 8929 sz = MAX_PATH; 8930 lstrcpyA(buf, "kiwi"); 8931 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8933 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 8934 8935 sz = MAX_PATH; 8936 lstrcpyA(buf, "kiwi"); 8937 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8939 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 8940 8941 sz = MAX_PATH; 8942 lstrcpyA(buf, "kiwi"); 8943 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8945 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 8946 8947 sz = MAX_PATH; 8948 lstrcpyA(buf, "kiwi"); 8949 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8951 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 8952 8953 sz = MAX_PATH; 8954 lstrcpyA(buf, "kiwi"); 8955 r = MsiRecordGetStringA(rec, 5, buf, &sz); 8956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8957 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 8958 8959 MsiCloseHandle(rec); 8960 MsiViewClose(view); 8961 MsiCloseHandle(view); 8962 8963 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) " 8964 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 8965 r = run_query(hdb, 0, query); 8966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8967 8968 query = "SELECT * FROM `T`"; 8969 r = do_query(hdb, query, &rec); 8970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8971 8972 sz = MAX_PATH; 8973 lstrcpyA(buf, "kiwi"); 8974 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8976 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 8977 8978 r = MsiRecordGetInteger(rec, 2); 8979 ok(r == 3, "Expected 3, got %d\n", r); 8980 8981 sz = MAX_PATH; 8982 lstrcpyA(buf, "kiwi"); 8983 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8984 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8985 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 8986 8987 r = MsiRecordGetInteger(rec, 4); 8988 ok(r == 2, "Expected 2, got %d\n", r); 8989 8990 r = MsiRecordGetInteger(rec, 5); 8991 ok(r == 1, "Expected 1, got %d\n", r); 8992 8993 MsiCloseHandle(rec); 8994 8995 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 8996 r = MsiDatabaseOpenViewA(hdb, query, &view); 8997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8998 r = MsiViewExecute(view, 0); 8999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9000 9001 r = MsiViewFetch(view, &rec); 9002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9003 9004 sz = MAX_PATH; 9005 lstrcpyA(buf, "kiwi"); 9006 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9008 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9009 9010 r = MsiRecordGetInteger(rec, 2); 9011 ok(r == 1, "Expected 1, got %d\n", r); 9012 9013 sz = MAX_PATH; 9014 lstrcpyA(buf, "kiwi"); 9015 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9017 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9018 9019 MsiCloseHandle(rec); 9020 9021 r = MsiViewFetch(view, &rec); 9022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9023 9024 sz = MAX_PATH; 9025 lstrcpyA(buf, "kiwi"); 9026 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9028 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9029 9030 r = MsiRecordGetInteger(rec, 2); 9031 ok(r == 2, "Expected 2, got %d\n", r); 9032 9033 sz = MAX_PATH; 9034 lstrcpyA(buf, "kiwi"); 9035 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9036 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9037 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9038 9039 MsiCloseHandle(rec); 9040 9041 r = MsiViewFetch(view, &rec); 9042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9043 9044 sz = MAX_PATH; 9045 lstrcpyA(buf, "kiwi"); 9046 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9048 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9049 9050 r = MsiRecordGetInteger(rec, 2); 9051 ok(r == 3, "Expected 3, got %d\n", r); 9052 9053 sz = MAX_PATH; 9054 lstrcpyA(buf, "kiwi"); 9055 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9057 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9058 9059 MsiCloseHandle(rec); 9060 9061 r = MsiViewFetch(view, &rec); 9062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9063 9064 sz = MAX_PATH; 9065 lstrcpyA(buf, "kiwi"); 9066 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9068 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9069 9070 r = MsiRecordGetInteger(rec, 2); 9071 ok(r == 4, "Expected 4, got %d\n", r); 9072 9073 sz = MAX_PATH; 9074 lstrcpyA(buf, "kiwi"); 9075 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9077 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9078 9079 MsiCloseHandle(rec); 9080 9081 r = MsiViewFetch(view, &rec); 9082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9083 9084 sz = MAX_PATH; 9085 lstrcpyA(buf, "kiwi"); 9086 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9088 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9089 9090 r = MsiRecordGetInteger(rec, 2); 9091 ok(r == 5, "Expected 5, got %d\n", r); 9092 9093 sz = MAX_PATH; 9094 lstrcpyA(buf, "kiwi"); 9095 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9096 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9097 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9098 9099 MsiCloseHandle(rec); 9100 9101 r = MsiViewFetch(view, &rec); 9102 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9103 9104 MsiViewClose(view); 9105 MsiCloseHandle(view); 9106 9107 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 9108 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 9109 "PRIMARY KEY `C`, `A`, `D`)"; 9110 r = run_query(hdb, 0, query); 9111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9112 9113 query = "SELECT * FROM `Z`"; 9114 r = MsiDatabaseOpenViewA(hdb, query, &view); 9115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9116 9117 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 9118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9119 9120 sz = MAX_PATH; 9121 lstrcpyA(buf, "kiwi"); 9122 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9124 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 9125 9126 sz = MAX_PATH; 9127 lstrcpyA(buf, "kiwi"); 9128 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9130 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 9131 9132 sz = MAX_PATH; 9133 lstrcpyA(buf, "kiwi"); 9134 r = MsiRecordGetStringA(rec, 3, 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, 4, buf, &sz); 9141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9142 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 9143 9144 sz = MAX_PATH; 9145 lstrcpyA(buf, "kiwi"); 9146 r = MsiRecordGetStringA(rec, 5, 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 MsiCloseHandle(rec); 9151 9152 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 9153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9154 9155 sz = MAX_PATH; 9156 lstrcpyA(buf, "kiwi"); 9157 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9159 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9160 9161 sz = MAX_PATH; 9162 lstrcpyA(buf, "kiwi"); 9163 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9165 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9166 9167 sz = MAX_PATH; 9168 lstrcpyA(buf, "kiwi"); 9169 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9171 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9172 9173 sz = MAX_PATH; 9174 lstrcpyA(buf, "kiwi"); 9175 r = MsiRecordGetStringA(rec, 4, buf, &sz); 9176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9177 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9178 9179 sz = MAX_PATH; 9180 lstrcpyA(buf, "kiwi"); 9181 r = MsiRecordGetStringA(rec, 5, buf, &sz); 9182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9183 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9184 9185 MsiCloseHandle(rec); 9186 MsiViewClose(view); 9187 MsiCloseHandle(view); 9188 9189 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) " 9190 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 9191 r = run_query(hdb, 0, query); 9192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9193 9194 query = "SELECT * FROM `Z`"; 9195 r = do_query(hdb, query, &rec); 9196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9197 9198 r = MsiRecordGetInteger(rec, 1); 9199 ok(r == 2, "Expected 2, got %d\n", r); 9200 9201 sz = MAX_PATH; 9202 lstrcpyA(buf, "kiwi"); 9203 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9205 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 9206 9207 sz = MAX_PATH; 9208 lstrcpyA(buf, "kiwi"); 9209 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9211 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 9212 9213 r = MsiRecordGetInteger(rec, 4); 9214 ok(r == 3, "Expected 3, got %d\n", r); 9215 9216 r = MsiRecordGetInteger(rec, 5); 9217 ok(r == 1, "Expected 1, got %d\n", r); 9218 9219 MsiCloseHandle(rec); 9220 9221 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 9222 r = MsiDatabaseOpenViewA(hdb, query, &view); 9223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9224 r = MsiViewExecute(view, 0); 9225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9226 9227 r = MsiViewFetch(view, &rec); 9228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9229 9230 sz = MAX_PATH; 9231 lstrcpyA(buf, "kiwi"); 9232 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9234 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9235 9236 r = MsiRecordGetInteger(rec, 2); 9237 ok(r == 1, "Expected 1, got %d\n", r); 9238 9239 sz = MAX_PATH; 9240 lstrcpyA(buf, "kiwi"); 9241 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9243 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9244 9245 MsiCloseHandle(rec); 9246 9247 r = MsiViewFetch(view, &rec); 9248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9249 9250 sz = MAX_PATH; 9251 lstrcpyA(buf, "kiwi"); 9252 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9254 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9255 9256 r = MsiRecordGetInteger(rec, 2); 9257 ok(r == 2, "Expected 2, got %d\n", r); 9258 9259 sz = MAX_PATH; 9260 lstrcpyA(buf, "kiwi"); 9261 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9263 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9264 9265 MsiCloseHandle(rec); 9266 9267 r = MsiViewFetch(view, &rec); 9268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9269 9270 sz = MAX_PATH; 9271 lstrcpyA(buf, "kiwi"); 9272 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9274 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9275 9276 r = MsiRecordGetInteger(rec, 2); 9277 ok(r == 3, "Expected 3, got %d\n", r); 9278 9279 sz = MAX_PATH; 9280 lstrcpyA(buf, "kiwi"); 9281 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9283 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9284 9285 MsiCloseHandle(rec); 9286 9287 r = MsiViewFetch(view, &rec); 9288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9289 9290 sz = MAX_PATH; 9291 lstrcpyA(buf, "kiwi"); 9292 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9294 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9295 9296 r = MsiRecordGetInteger(rec, 2); 9297 ok(r == 4, "Expected 4, got %d\n", r); 9298 9299 sz = MAX_PATH; 9300 lstrcpyA(buf, "kiwi"); 9301 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9303 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9304 9305 MsiCloseHandle(rec); 9306 9307 r = MsiViewFetch(view, &rec); 9308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9309 9310 sz = MAX_PATH; 9311 lstrcpyA(buf, "kiwi"); 9312 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9314 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9315 9316 r = MsiRecordGetInteger(rec, 2); 9317 ok(r == 5, "Expected 5, got %d\n", r); 9318 9319 sz = MAX_PATH; 9320 lstrcpyA(buf, "kiwi"); 9321 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9323 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9324 9325 MsiCloseHandle(rec); 9326 9327 r = MsiViewFetch(view, &rec); 9328 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9329 9330 MsiViewClose(view); 9331 MsiCloseHandle(view); 9332 9333 MsiCloseHandle(hdb); 9334 DeleteFileA(msifile); 9335 } 9336 9337 static void test_createtable(void) 9338 { 9339 MSIHANDLE hdb, htab = 0, hrec = 0; 9340 LPCSTR query; 9341 UINT res; 9342 DWORD size; 9343 char buffer[0x20]; 9344 9345 hdb = create_db(); 9346 ok(hdb, "failed to create db\n"); 9347 9348 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)"; 9349 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9351 if(res == ERROR_SUCCESS ) 9352 { 9353 res = MsiViewExecute( htab, hrec ); 9354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9355 9356 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9357 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9358 9359 size = sizeof(buffer); 9360 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9361 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9362 MsiCloseHandle( hrec ); 9363 9364 res = MsiViewClose( htab ); 9365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9366 9367 res = MsiCloseHandle( htab ); 9368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9369 } 9370 9371 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)"; 9372 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9374 if(res == ERROR_SUCCESS ) 9375 { 9376 res = MsiViewExecute( htab, 0 ); 9377 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9378 9379 res = MsiViewClose( htab ); 9380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9381 9382 res = MsiCloseHandle( htab ); 9383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9384 9385 query = "SELECT * FROM `a`"; 9386 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9388 9389 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9390 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9391 9392 buffer[0] = 0; 9393 size = sizeof(buffer); 9394 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9395 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9396 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9397 MsiCloseHandle( hrec ); 9398 9399 res = MsiViewClose( htab ); 9400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9401 9402 res = MsiCloseHandle( htab ); 9403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9404 9405 res = MsiDatabaseCommit(hdb); 9406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9407 9408 res = MsiCloseHandle(hdb); 9409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9410 9411 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 9412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9413 9414 query = "SELECT * FROM `a`"; 9415 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9416 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9417 9418 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9419 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9420 9421 buffer[0] = 0; 9422 size = sizeof(buffer); 9423 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9424 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9425 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9426 9427 res = MsiCloseHandle( hrec ); 9428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9429 9430 res = MsiViewClose( htab ); 9431 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9432 9433 res = MsiCloseHandle( htab ); 9434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9435 } 9436 9437 res = MsiDatabaseCommit(hdb); 9438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9439 9440 res = MsiCloseHandle(hdb); 9441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9442 9443 DeleteFileA(msifile); 9444 } 9445 9446 static void test_embedded_nulls(void) 9447 { 9448 static const char control_table[] = 9449 "Dialog\tText\n" 9450 "s72\tL0\n" 9451 "Control\tDialog\n" 9452 "LicenseAgreementDlg\ttext\x11\x19text\0text"; 9453 UINT r, sz; 9454 MSIHANDLE hdb, hrec; 9455 char buffer[32]; 9456 9457 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9458 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r ); 9459 9460 GetCurrentDirectoryA( MAX_PATH, CURR_DIR ); 9461 write_file( "temp_file", control_table, sizeof(control_table) ); 9462 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" ); 9463 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r ); 9464 DeleteFileA( "temp_file" ); 9465 9466 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec ); 9467 ok( r == ERROR_SUCCESS, "query failed %u\n", r ); 9468 9469 buffer[0] = 0; 9470 sz = sizeof(buffer); 9471 r = MsiRecordGetStringA( hrec, 1, buffer, &sz ); 9472 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r ); 9473 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer ); 9474 9475 MsiCloseHandle( hrec ); 9476 MsiCloseHandle( hdb ); 9477 DeleteFileA( msifile ); 9478 } 9479 9480 static void test_select_column_names(void) 9481 { 9482 MSIHANDLE hdb = 0, rec, rec2, view; 9483 char buffer[32]; 9484 UINT r, size; 9485 9486 DeleteFileA(msifile); 9487 9488 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9489 ok( r == ERROR_SUCCESS , "failed to open database: %u\n", r ); 9490 9491 r = try_query( hdb, "CREATE TABLE `t` (`a` CHAR NOT NULL, `b` CHAR PRIMARY KEY `a`)"); 9492 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9493 9494 r = try_query( hdb, "SELECT `t`.`b` FROM `t` WHERE `t`.`b` = `x`" ); 9495 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9496 9497 r = try_query( hdb, "SELECT '', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 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 todo_wine ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 9502 9503 r = try_query( hdb, "SELECT 'b', `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 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9508 9509 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY `b`" ); 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' ORDER BY 'b'" ); 9513 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9514 9515 r = try_query( hdb, "SELECT 't'.'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9516 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9517 9518 r = try_query( hdb, "SELECT 'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9519 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9520 9521 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '1', '2' )" ); 9522 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9523 9524 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '3', '4' )" ); 9525 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9526 9527 r = MsiDatabaseOpenViewA( hdb, "SELECT '' FROM `t`", &view ); 9528 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9529 9530 r = MsiViewExecute( view, 0 ); 9531 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9532 9533 r = MsiViewFetch( view, &rec ); 9534 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9535 r = MsiRecordGetFieldCount( rec ); 9536 ok( r == 1, "got %u\n", r ); 9537 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec2 ); 9538 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9539 r = MsiRecordGetFieldCount( rec2 ); 9540 ok( r == 1, "got %u\n", r ); 9541 size = sizeof(buffer); 9542 memset( buffer, 0x55, sizeof(buffer) ); 9543 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9544 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9545 ok( !buffer[0], "got \"%s\"\n", buffer ); 9546 MsiCloseHandle( rec2 ); 9547 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec2 ); 9548 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9549 r = MsiRecordGetFieldCount( rec2 ); 9550 ok( r == 1, "got %u\n", r ); 9551 size = sizeof(buffer); 9552 memset( buffer, 0x55, sizeof(buffer) ); 9553 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9554 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9555 ok( !lstrcmpA( buffer, "f0" ), "got \"%s\"\n", buffer ); 9556 MsiCloseHandle( rec2 ); 9557 9558 size = sizeof(buffer); 9559 memset( buffer, 0x55, sizeof(buffer) ); 9560 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9561 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9562 ok( !buffer[0], "got \"%s\"\n", buffer ); 9563 MsiCloseHandle( rec ); 9564 9565 r = MsiViewFetch( view, &rec ); 9566 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9567 size = sizeof(buffer); 9568 memset( buffer, 0x55, sizeof(buffer) ); 9569 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9570 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9571 ok( !buffer[0], "got \"%s\"\n", buffer ); 9572 MsiCloseHandle( rec ); 9573 9574 r = MsiViewFetch( view, &rec ); 9575 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9576 MsiCloseHandle( rec ); 9577 9578 MsiViewClose( view ); 9579 MsiCloseHandle( view ); 9580 9581 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '' FROM `t`", &view ); 9582 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9583 9584 r = MsiViewExecute( view, 0 ); 9585 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9586 9587 r = MsiViewFetch( view, &rec ); 9588 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9589 r = MsiRecordGetFieldCount( rec ); 9590 ok( r == 2, "got %u\n", r ); 9591 size = sizeof(buffer); 9592 memset( buffer, 0x55, sizeof(buffer) ); 9593 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9594 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9595 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9596 MsiCloseHandle( rec ); 9597 9598 r = MsiViewFetch( view, &rec ); 9599 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9600 size = sizeof(buffer); 9601 memset( buffer, 0x55, sizeof(buffer) ); 9602 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9603 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9604 ok( !buffer[0], "got \"%s\"\n", buffer ); 9605 MsiCloseHandle( rec ); 9606 9607 r = MsiViewFetch( view, &rec ); 9608 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9609 MsiCloseHandle( rec ); 9610 9611 MsiViewClose( view ); 9612 MsiCloseHandle( view ); 9613 9614 r = MsiDatabaseOpenViewA( hdb, "SELECT '', `a` FROM `t`", &view ); 9615 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9616 9617 r = MsiViewExecute( view, 0 ); 9618 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9619 9620 r = MsiViewFetch( view, &rec ); 9621 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9622 r = MsiRecordGetFieldCount( rec ); 9623 ok( r == 2, "got %u\n", r ); 9624 size = sizeof(buffer); 9625 memset( buffer, 0x55, sizeof(buffer) ); 9626 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9627 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9628 ok( !buffer[0], "got \"%s\"\n", buffer ); 9629 size = sizeof(buffer); 9630 memset( buffer, 0x55, sizeof(buffer) ); 9631 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9632 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9633 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9634 MsiCloseHandle( rec ); 9635 9636 r = MsiViewFetch( view, &rec ); 9637 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9638 size = sizeof(buffer); 9639 memset( buffer, 0x55, sizeof(buffer) ); 9640 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9641 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9642 ok( !buffer[0], "got \"%s\"\n", buffer ); 9643 size = sizeof(buffer); 9644 memset( buffer, 0x55, sizeof(buffer) ); 9645 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9646 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9647 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9648 MsiCloseHandle( rec ); 9649 9650 r = MsiViewFetch( view, &rec ); 9651 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9652 MsiCloseHandle( rec ); 9653 9654 MsiViewClose( view ); 9655 MsiCloseHandle( view ); 9656 9657 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '', `b` FROM `t`", &view ); 9658 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9659 9660 r = MsiViewExecute( view, 0 ); 9661 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9662 9663 r = MsiViewFetch( view, &rec ); 9664 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9665 r = MsiRecordGetFieldCount( rec ); 9666 ok( r == 3, "got %u\n", r ); 9667 size = sizeof(buffer); 9668 memset( buffer, 0x55, sizeof(buffer) ); 9669 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9670 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9671 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9672 size = sizeof(buffer); 9673 memset( buffer, 0x55, sizeof(buffer) ); 9674 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9675 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9676 ok( !buffer[0], "got \"%s\"\n", buffer ); 9677 size = sizeof(buffer); 9678 memset( buffer, 0x55, sizeof(buffer) ); 9679 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9680 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9681 ok( !lstrcmpA( buffer, "2" ), "got \"%s\"\n", buffer ); 9682 MsiCloseHandle( rec ); 9683 9684 r = MsiViewFetch( view, &rec ); 9685 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9686 size = sizeof(buffer); 9687 memset( buffer, 0x55, sizeof(buffer) ); 9688 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9689 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9690 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9691 size = sizeof(buffer); 9692 memset( buffer, 0x55, sizeof(buffer) ); 9693 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9694 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9695 ok( !buffer[0], "got \"%s\"\n", buffer ); 9696 size = sizeof(buffer); 9697 memset( buffer, 0x55, sizeof(buffer) ); 9698 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9699 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9700 ok( !lstrcmpA( buffer, "4" ), "got \"%s\"\n", buffer ); 9701 MsiCloseHandle( rec ); 9702 9703 r = MsiViewFetch( view, &rec ); 9704 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9705 MsiCloseHandle( rec ); 9706 9707 MsiViewClose( view ); 9708 MsiCloseHandle( view ); 9709 9710 r = try_query( hdb, "SELECT '' FROM `t` WHERE `t`.`b` = 'x'" ); 9711 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9712 9713 r = try_query( hdb, "SELECT `` FROM `t` WHERE `t`.`b` = 'x'" ); 9714 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9715 9716 r = try_query( hdb, "SELECT `b` FROM 't' WHERE `t`.`b` = 'x'" ); 9717 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9718 9719 r = try_query( hdb, "SELECT `b` FROM `t` WHERE 'b' = 'x'" ); 9720 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9721 9722 r = try_query( hdb, "SELECT `t`.`b`, `` FROM `t` WHERE `t`.`b` = 'x'" ); 9723 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9724 9725 r = MsiCloseHandle( hdb ); 9726 ok(r == ERROR_SUCCESS , "failed to close database: %u\n", r); 9727 } 9728 9729 START_TEST(db) 9730 { 9731 test_msidatabase(); 9732 test_msiinsert(); 9733 test_msidecomposedesc(); 9734 test_msibadqueries(); 9735 test_viewmodify(); 9736 test_viewgetcolumninfo(); 9737 test_getcolinfo(); 9738 test_msiexport(); 9739 test_longstrings(); 9740 test_streamtable(); 9741 test_binary(); 9742 test_where_not_in_selected(); 9743 test_where(); 9744 test_msiimport(); 9745 test_binary_import(); 9746 test_markers(); 9747 test_handle_limit(); 9748 test_try_transform(); 9749 test_join(); 9750 test_temporary_table(); 9751 test_alter(); 9752 test_integers(); 9753 test_update(); 9754 test_special_tables(); 9755 test_tables_order(); 9756 test_rows_order(); 9757 test_select_markers(); 9758 test_viewmodify_update(); 9759 test_viewmodify_assign(); 9760 test_stringtable(); 9761 test_viewmodify_delete(); 9762 test_defaultdatabase(); 9763 test_order(); 9764 test_viewmodify_delete_temporary(); 9765 test_deleterow(); 9766 test_quotes(); 9767 test_carriagereturn(); 9768 test_noquotes(); 9769 test_forcecodepage(); 9770 test_viewmodify_refresh(); 9771 test_where_viewmodify(); 9772 test_storages_table(); 9773 test_dbtopackage(); 9774 test_droptable(); 9775 test_dbmerge(); 9776 test_select_with_tablenames(); 9777 test_insertorder(); 9778 test_columnorder(); 9779 test_suminfo_import(); 9780 test_createtable(); 9781 test_collation(); 9782 test_embedded_nulls(); 9783 test_select_column_names(); 9784 } 9785