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 UINT r = 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 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r); 216 return r; 217 } 218 219 static UINT create_custom_action_table( MSIHANDLE hdb ) 220 { 221 UINT r = run_query( hdb, 0, 222 "CREATE TABLE `CustomAction` ( " 223 "`Action` CHAR(72) NOT NULL, " 224 "`Type` SHORT NOT NULL, " 225 "`Source` CHAR(72), " 226 "`Target` CHAR(255) " 227 "PRIMARY KEY `Action`)" ); 228 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r); 229 return r; 230 } 231 232 static UINT create_directory_table( MSIHANDLE hdb ) 233 { 234 UINT r = run_query( hdb, 0, 235 "CREATE TABLE `Directory` ( " 236 "`Directory` CHAR(255) NOT NULL, " 237 "`Directory_Parent` CHAR(255), " 238 "`DefaultDir` CHAR(255) NOT NULL " 239 "PRIMARY KEY `Directory`)" ); 240 ok(r == ERROR_SUCCESS, "Failed to create Directory table: %u\n", r); 241 return r; 242 } 243 244 static UINT create_feature_components_table( MSIHANDLE hdb ) 245 { 246 UINT r = run_query( hdb, 0, 247 "CREATE TABLE `FeatureComponents` ( " 248 "`Feature_` CHAR(38) NOT NULL, " 249 "`Component_` CHAR(72) NOT NULL " 250 "PRIMARY KEY `Feature_`, `Component_` )" ); 251 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r); 252 return r; 253 } 254 255 static UINT create_std_dlls_table( MSIHANDLE hdb ) 256 { 257 UINT r = run_query( hdb, 0, 258 "CREATE TABLE `StdDlls` ( " 259 "`File` CHAR(255) NOT NULL, " 260 "`Binary_` CHAR(72) NOT NULL " 261 "PRIMARY KEY `File` )" ); 262 ok(r == ERROR_SUCCESS, "Failed to create StdDlls table: %u\n", r); 263 return r; 264 } 265 266 static UINT create_binary_table( MSIHANDLE hdb ) 267 { 268 UINT r = run_query( hdb, 0, 269 "CREATE TABLE `Binary` ( " 270 "`Name` CHAR(72) NOT NULL, " 271 "`Data` CHAR(72) NOT NULL " 272 "PRIMARY KEY `Name` )" ); 273 ok(r == ERROR_SUCCESS, "Failed to create Binary table: %u\n", r); 274 return r; 275 } 276 277 static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert) 278 { 279 char *query; 280 UINT sz, r; 281 282 sz = strlen(values) + strlen(insert) + 1; 283 query = HeapAlloc(GetProcessHeap(), 0, sz); 284 sprintf(query, insert, values); 285 r = run_query(hdb, 0, query); 286 HeapFree(GetProcessHeap(), 0, query); 287 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r); 288 return r; 289 } 290 291 #define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \ 292 "INSERT INTO `Component` " \ 293 "(`Component`, `ComponentId`, `Directory_`, " \ 294 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") 295 296 #define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \ 297 "INSERT INTO `CustomAction` " \ 298 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") 299 300 #define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \ 301 "INSERT INTO `FeatureComponents` " \ 302 "(`Feature_`, `Component_`) VALUES( %s )") 303 304 #define add_std_dlls_entry(hdb, values) add_entry(__FILE__, __LINE__, "StdDlls", hdb, values, \ 305 "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )") 306 307 #define add_binary_entry(hdb, values) add_entry(__FILE__, __LINE__, "Binary", hdb, values, \ 308 "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )") 309 310 static void test_msiinsert(void) 311 { 312 MSIHANDLE hdb = 0, hview = 0, hview2 = 0, hrec = 0; 313 UINT r; 314 const char *query; 315 char buf[80]; 316 DWORD sz; 317 318 DeleteFileA(msifile); 319 320 /* just MsiOpenDatabase should not create a file */ 321 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 322 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 323 324 /* create a table */ 325 query = "CREATE TABLE `phone` ( " 326 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 327 "PRIMARY KEY `id`)"; 328 r = MsiDatabaseOpenViewA(hdb, query, &hview); 329 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 330 r = MsiViewExecute(hview, 0); 331 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 332 r = MsiViewClose(hview); 333 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 334 r = MsiCloseHandle(hview); 335 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 336 337 query = "SELECT * FROM phone WHERE number = '8675309'"; 338 r = MsiDatabaseOpenViewA(hdb, query, &hview2); 339 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 340 r = MsiViewExecute(hview2, 0); 341 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 342 r = MsiViewFetch(hview2, &hrec); 343 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); 344 345 /* insert a value into it */ 346 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 347 "VALUES('1', 'Abe', '8675309')"; 348 r = MsiDatabaseOpenViewA(hdb, query, &hview); 349 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 350 r = MsiViewExecute(hview, 0); 351 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 352 r = MsiViewClose(hview); 353 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 354 r = MsiCloseHandle(hview); 355 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 356 357 r = MsiViewFetch(hview2, &hrec); 358 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n"); 359 r = MsiViewExecute(hview2, 0); 360 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 361 r = MsiViewFetch(hview2, &hrec); 362 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %u\n", r); 363 364 r = MsiCloseHandle(hrec); 365 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 366 r = MsiViewClose(hview2); 367 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 368 r = MsiCloseHandle(hview2); 369 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 370 371 query = "SELECT * FROM `phone` WHERE `id` = 1"; 372 r = do_query(hdb, query, &hrec); 373 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 374 375 /* check the record contains what we put in it */ 376 r = MsiRecordGetFieldCount(hrec); 377 ok(r == 3, "record count wrong\n"); 378 379 r = MsiRecordIsNull(hrec, 0); 380 ok(r == FALSE, "field 0 not null\n"); 381 382 r = MsiRecordGetInteger(hrec, 1); 383 ok(r == 1, "field 1 contents wrong\n"); 384 sz = sizeof buf; 385 r = MsiRecordGetStringA(hrec, 2, buf, &sz); 386 ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n"); 387 ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n"); 388 sz = sizeof buf; 389 r = MsiRecordGetStringA(hrec, 3, buf, &sz); 390 ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n"); 391 ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n"); 392 393 r = MsiCloseHandle(hrec); 394 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 395 396 /* open a select query */ 397 hrec = 100; 398 query = "SELECT * FROM `phone` WHERE `id` >= 10"; 399 r = do_query(hdb, query, &hrec); 400 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 401 ok(hrec == 0, "hrec should be null\n"); 402 403 r = MsiCloseHandle(hrec); 404 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 405 406 query = "SELECT * FROM `phone` WHERE `id` < 0"; 407 r = do_query(hdb, query, &hrec); 408 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 409 410 query = "SELECT * FROM `phone` WHERE `id` <= 0"; 411 r = do_query(hdb, query, &hrec); 412 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 413 414 query = "SELECT * FROM `phone` WHERE `id` <> 1"; 415 r = do_query(hdb, query, &hrec); 416 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 417 418 query = "SELECT * FROM `phone` WHERE `id` > 10"; 419 r = do_query(hdb, query, &hrec); 420 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 421 422 /* now try a few bad INSERT xqueries */ 423 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 424 "VALUES(?, ?)"; 425 r = MsiDatabaseOpenViewA(hdb, query, &hview); 426 ok(r == ERROR_BAD_QUERY_SYNTAX, "MsiDatabaseOpenView failed\n"); 427 428 /* construct a record to insert */ 429 hrec = MsiCreateRecord(4); 430 r = MsiRecordSetInteger(hrec, 1, 2); 431 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n"); 432 r = MsiRecordSetStringA(hrec, 2, "Adam"); 433 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 434 r = MsiRecordSetStringA(hrec, 3, "96905305"); 435 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 436 437 /* insert another value, using a record and wildcards */ 438 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 439 "VALUES(?, ?, ?)"; 440 r = MsiDatabaseOpenViewA(hdb, query, &hview); 441 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 442 443 if (r == ERROR_SUCCESS) 444 { 445 r = MsiViewExecute(hview, hrec); 446 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 447 r = MsiViewClose(hview); 448 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 449 r = MsiCloseHandle(hview); 450 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 451 } 452 r = MsiCloseHandle(hrec); 453 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 454 455 r = MsiViewFetch(0, NULL); 456 ok(r == ERROR_INVALID_PARAMETER, "MsiViewFetch failed\n"); 457 458 r = MsiDatabaseCommit(hdb); 459 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 460 461 r = MsiCloseHandle(hdb); 462 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 463 464 r = DeleteFileA(msifile); 465 ok(r == TRUE, "file didn't exist after commit\n"); 466 } 467 468 static void test_msidecomposedesc(void) 469 { 470 UINT (WINAPI *pMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *); 471 char prod[MAX_FEATURE_CHARS+1], comp[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1]; 472 const char *desc; 473 UINT r; 474 DWORD len; 475 HMODULE hmod; 476 477 hmod = GetModuleHandleA("msi.dll"); 478 pMsiDecomposeDescriptorA = (void*)GetProcAddress(hmod, "MsiDecomposeDescriptorA"); 479 if (!pMsiDecomposeDescriptorA) 480 return; 481 482 /* test a valid feature descriptor */ 483 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk."; 484 len = 0; 485 prod[0] = feature[0] = comp[0] = 0; 486 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 487 ok(r == ERROR_SUCCESS, "returned an error\n"); 488 ok(len == strlen(desc), "length was wrong\n"); 489 ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n"); 490 ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n"); 491 ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n"); 492 493 /* test an invalid feature descriptor with too many characters */ 494 desc = "']gAVn-}f(ZXfeAR6.ji" 495 "ThisWillFailIfTheresMoreThanAGuidsChars>" 496 "3w2x^IGfe?CxI5heAvk."; 497 len = 0; 498 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 499 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); 500 501 /* test a feature descriptor with < instead of > */ 502 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit<3w2x^IGfe?CxI5heAvk."; 503 len = 0; 504 prod[0] = feature[0] = 0; 505 comp[0] = 0x55; 506 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 507 ok(r == ERROR_SUCCESS, "returned an error\n"); 508 ok(len == 41, "got %u\n", len); 509 ok(!strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}"), "got '%s'\n", prod); 510 ok(!strcmp(feature,"FollowTheWhiteRabbit"), "got '%s'\n", feature); 511 ok(!comp[0], "got '%s'\n", comp); 512 513 len = 0; 514 prod[0] = feature[0] = 0; 515 comp[0] = 0x55; 516 r = pMsiDecomposeDescriptorA("yh1BVN)8A$!!!!!MKKSkAlwaysInstalledIntl_1033<", prod, feature, comp, &len); 517 ok(r == ERROR_SUCCESS, "got %u\n", r); 518 ok(len == 45, "got %u\n", len); 519 ok(!strcmp(prod, "{90150000-006E-0409-0000-0000000FF1CE}"), "got '%s'\n", prod); 520 ok(!strcmp(feature, "AlwaysInstalledIntl_1033"), "got '%s'\n", feature); 521 ok(!comp[0], "got '%s'\n", comp); 522 523 /* 524 * Test a valid feature descriptor with the 525 * maximum number of characters and some trailing characters. 526 */ 527 desc = "']gAVn-}f(ZXfeAR6.ji" 528 "ThisWillWorkIfTheresLTEThanAGuidsChars>" 529 "3w2x^IGfe?CxI5heAvk." 530 "extra"; 531 len = 0; 532 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); 533 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 534 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 535 536 len = 0; 537 r = pMsiDecomposeDescriptorA(desc, prod, feature, NULL, &len); 538 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 539 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 540 541 len = 0; 542 r = pMsiDecomposeDescriptorA(desc, prod, NULL, NULL, &len); 543 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 544 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 545 546 len = 0; 547 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, &len); 548 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 549 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n"); 550 551 len = 0; 552 r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len); 553 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); 554 ok(len == 0, "length wrong\n"); 555 556 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL); 557 ok(r == ERROR_SUCCESS, "returned wrong error\n"); 558 } 559 560 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec ) 561 { 562 MSIHANDLE htab = 0; 563 UINT res; 564 565 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab ); 566 if(res == ERROR_SUCCESS ) 567 { 568 UINT r; 569 570 r = MsiViewExecute( htab, hrec ); 571 if(r != ERROR_SUCCESS ) 572 res = r; 573 574 r = MsiViewClose( htab ); 575 if(r != ERROR_SUCCESS ) 576 res = r; 577 578 r = MsiCloseHandle( htab ); 579 if(r != ERROR_SUCCESS ) 580 res = r; 581 } 582 return res; 583 } 584 585 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery ) 586 { 587 return try_query_param( hdb, szQuery, 0 ); 588 } 589 590 static UINT try_insert_query( MSIHANDLE hdb, LPCSTR szQuery ) 591 { 592 MSIHANDLE hrec = 0; 593 UINT r; 594 595 hrec = MsiCreateRecord( 1 ); 596 MsiRecordSetStringA( hrec, 1, "Hello"); 597 598 r = try_query_param( hdb, szQuery, hrec ); 599 600 MsiCloseHandle( hrec ); 601 return r; 602 } 603 604 static void test_msibadqueries(void) 605 { 606 MSIHANDLE hdb = 0; 607 UINT r; 608 609 DeleteFileA(msifile); 610 611 /* just MsiOpenDatabase should not create a file */ 612 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 613 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 614 615 r = MsiDatabaseCommit( hdb ); 616 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 617 618 r = MsiCloseHandle( hdb ); 619 ok(r == ERROR_SUCCESS , "Failed to close database\n"); 620 621 /* open it readonly */ 622 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb ); 623 ok(r == ERROR_SUCCESS , "Failed to open database r/o\n"); 624 625 /* add a table to it */ 626 r = try_query( hdb, "select * from _Tables"); 627 ok(r == ERROR_SUCCESS , "query 1 failed\n"); 628 629 r = MsiCloseHandle( hdb ); 630 ok(r == ERROR_SUCCESS , "Failed to close database r/o\n"); 631 632 /* open it read/write */ 633 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 634 ok(r == ERROR_SUCCESS , "Failed to open database r/w\n"); 635 636 /* a bunch of test queries that fail with the native MSI */ 637 638 r = try_query( hdb, "CREATE TABLE"); 639 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2a return code\n"); 640 641 r = try_query( hdb, "CREATE TABLE `a`"); 642 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2b return code\n"); 643 644 r = try_query( hdb, "CREATE TABLE `a` ()"); 645 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2c return code\n"); 646 647 r = try_query( hdb, "CREATE TABLE `a` (`b`)"); 648 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2d return code\n"); 649 650 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) )"); 651 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2e return code\n"); 652 653 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL)"); 654 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2f return code\n"); 655 656 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY)"); 657 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2g return code\n"); 658 659 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)"); 660 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2h return code\n"); 661 662 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)"); 663 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2i return code\n"); 664 665 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY 'b')"); 666 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2j return code\n"); 667 668 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')"); 669 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2k return code\n"); 670 671 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')"); 672 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2l return code\n"); 673 674 r = try_query( hdb, "CREATE TABLE `a` (`b` CHA(72) NOT NULL PRIMARY KEY `b`)"); 675 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2m return code\n"); 676 677 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(-1) NOT NULL PRIMARY KEY `b`)"); 678 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2n return code\n"); 679 680 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(720) NOT NULL PRIMARY KEY `b`)"); 681 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2o return code\n"); 682 683 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL KEY `b`)"); 684 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n"); 685 686 r = try_query( hdb, "CREATE TABLE `a` (`` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 687 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n"); 688 689 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 690 ok(r == ERROR_SUCCESS , "valid query 2z failed\n"); 691 692 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)"); 693 ok(r == ERROR_BAD_QUERY_SYNTAX , "created same table again\n"); 694 695 r = try_query( hdb, "CREATE TABLE `aa` (`b` CHAR(72) NOT NULL, `c` " 696 "CHAR(72), `d` CHAR(255) NOT NULL LOCALIZABLE PRIMARY KEY `b`)"); 697 ok(r == ERROR_SUCCESS , "query 4 failed\n"); 698 699 r = MsiDatabaseCommit( hdb ); 700 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n"); 701 702 r = try_query( hdb, "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL " 703 "PRIMARY KEY `foo`)"); 704 ok(r == ERROR_SUCCESS , "query 4 failed\n"); 705 706 r = try_insert_query( hdb, "insert into a ( `b` ) VALUES ( ? )"); 707 ok(r == ERROR_SUCCESS , "failed to insert record in db\n"); 708 709 r = MsiDatabaseCommit( hdb ); 710 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n"); 711 712 r = try_query( hdb, "CREATE TABLE `boo` (`foo` CHAR(72) NOT NULL " 713 "PRIMARY KEY `ba`)"); 714 ok(r != ERROR_SUCCESS , "query 5 succeeded\n"); 715 716 r = try_query( hdb,"CREATE TABLE `bee` (`foo` CHAR(72) NOT NULL )"); 717 ok(r != ERROR_SUCCESS , "query 6 succeeded\n"); 718 719 r = try_query( hdb, "CREATE TABLE `temp` (`t` CHAR(72) NOT NULL " 720 "PRIMARY KEY `t`)"); 721 ok(r == ERROR_SUCCESS , "query 7 failed\n"); 722 723 r = try_query( hdb, "CREATE TABLE `c` (`b` CHAR NOT NULL PRIMARY KEY `b`)"); 724 ok(r == ERROR_SUCCESS , "query 8 failed\n"); 725 726 r = try_query( hdb, "select * from c"); 727 ok(r == ERROR_SUCCESS , "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_SUCCESS, "query failed\n"); 734 735 r = try_query( hdb, "select * from 'c'"); 736 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 737 738 r = try_query( hdb, "select * from ''"); 739 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 740 741 r = try_query( hdb, "select * from c where b = x"); 742 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 743 744 r = try_query( hdb, "select * from c where b = \"x\""); 745 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 746 747 r = try_query( hdb, "select * from c where b = 'x'"); 748 ok(r == ERROR_SUCCESS, "query failed\n"); 749 750 r = try_query( hdb, "select * from c where b = '\"x'"); 751 ok(r == ERROR_SUCCESS, "query failed\n"); 752 753 if (0) /* FIXME: this query causes trouble with other tests */ 754 { 755 r = try_query( hdb, "select * from c where b = '\\\'x'"); 756 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 757 } 758 759 r = try_query( hdb, "select * from 'c'"); 760 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n"); 761 762 r = try_query( hdb, "select `c`.`b` from `c` order by `c`.`order`"); 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_BAD_QUERY_SYNTAX, "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, "select c.`b` from `c`"); 781 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 782 783 r = try_query( hdb, "select `c`.`b` from c`"); 784 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 785 786 r = try_query( hdb, "select `c`.`b` from `c"); 787 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 788 789 r = try_query( hdb, "select `c`.`b` from c"); 790 ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 791 792 r = try_query( hdb, "CREATE TABLE `\5a` (`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 \5a" ); 796 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 797 798 r = try_query( hdb, "CREATE TABLE `a\5` (`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\5" ); 802 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 803 804 r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 805 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 806 807 r = try_query( hdb, "SELECT * FROM -a" ); 808 todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 809 810 r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" ); 811 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 812 813 r = try_query( hdb, "SELECT * FROM a-" ); 814 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 815 816 r = MsiCloseHandle( hdb ); 817 ok(r == ERROR_SUCCESS , "Failed to close database transact\n"); 818 819 r = DeleteFileA( msifile ); 820 ok(r == TRUE, "file didn't exist after commit\n"); 821 } 822 823 static void test_viewmodify(void) 824 { 825 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 826 UINT r; 827 MSIDBERROR err; 828 const char *query; 829 char buffer[0x100]; 830 DWORD sz; 831 832 DeleteFileA(msifile); 833 834 /* just MsiOpenDatabase should not create a file */ 835 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 836 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 837 838 query = "CREATE TABLE `phone` ( " 839 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 840 "PRIMARY KEY `id`)"; 841 r = run_query( hdb, 0, query ); 842 ok(r == ERROR_SUCCESS, "query failed\n"); 843 844 query = "CREATE TABLE `_Validation` ( " 845 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, " 846 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, " 847 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), " 848 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)"; 849 r = run_query( hdb, 0, query ); 850 ok(r == ERROR_SUCCESS, "query failed\n"); 851 852 query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) " 853 "VALUES('phone', 'id', 'N')"; 854 r = run_query( hdb, 0, query ); 855 ok(r == ERROR_SUCCESS, "query failed\n"); 856 857 /* check what the error function reports without doing anything */ 858 sz = 0; 859 /* passing NULL as the 3rd param make function to crash on older platforms */ 860 err = MsiViewGetErrorA( 0, NULL, &sz ); 861 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n"); 862 863 /* open a view */ 864 query = "SELECT * FROM `phone`"; 865 r = MsiDatabaseOpenViewA(hdb, query, &hview); 866 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 867 868 /* see what happens with a good hview and bad args */ 869 err = MsiViewGetErrorA( hview, NULL, NULL ); 870 ok(err == MSIDBERROR_INVALIDARG || err == MSIDBERROR_NOERROR, 871 "MsiViewGetError returns %u (expected -3)\n", err); 872 err = MsiViewGetErrorA( hview, buffer, NULL ); 873 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n"); 874 875 /* see what happens with a zero length buffer */ 876 sz = 0; 877 buffer[0] = 'x'; 878 err = MsiViewGetErrorA( hview, buffer, &sz ); 879 ok(err == MSIDBERROR_MOREDATA, "MsiViewGetError return\n"); 880 ok(buffer[0] == 'x', "buffer cleared\n"); 881 ok(sz == 0, "size not zero\n"); 882 883 /* ok this one is strange */ 884 sz = 0; 885 err = MsiViewGetErrorA( hview, NULL, &sz ); 886 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 887 ok(sz == 0, "size not zero\n"); 888 889 /* see if it really has an error */ 890 sz = sizeof buffer; 891 buffer[0] = 'x'; 892 err = MsiViewGetErrorA( hview, buffer, &sz ); 893 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 894 ok(buffer[0] == 0, "buffer not cleared\n"); 895 ok(sz == 0, "size not zero\n"); 896 897 r = MsiViewExecute(hview, 0); 898 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 899 900 /* try some invalid records */ 901 r = MsiViewModify(hview, MSIMODIFY_INSERT, 0 ); 902 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n"); 903 r = MsiViewModify(hview, -1, 0 ); 904 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n"); 905 906 /* try an small record */ 907 hrec = MsiCreateRecord(1); 908 r = MsiViewModify(hview, -1, hrec ); 909 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n"); 910 911 sz = sizeof buffer; 912 buffer[0] = 'x'; 913 err = MsiViewGetErrorA( hview, buffer, &sz ); 914 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n"); 915 ok(buffer[0] == 0, "buffer not cleared\n"); 916 ok(sz == 0, "size not zero\n"); 917 918 r = MsiCloseHandle(hrec); 919 ok(r == ERROR_SUCCESS, "failed to close record\n"); 920 921 /* insert a valid record */ 922 hrec = MsiCreateRecord(3); 923 924 r = MsiRecordSetInteger(hrec, 1, 1); 925 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 926 r = MsiRecordSetStringA(hrec, 2, "bob"); 927 ok(r == ERROR_SUCCESS, "failed to set string\n"); 928 r = MsiRecordSetStringA(hrec, 3, "7654321"); 929 ok(r == ERROR_SUCCESS, "failed to set string\n"); 930 931 r = MsiViewExecute(hview, 0); 932 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 933 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 934 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 935 936 /* validate it */ 937 r = MsiViewExecute(hview, 0); 938 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 939 940 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec ); 941 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r); 942 943 sz = sizeof buffer; 944 buffer[0] = 'x'; 945 err = MsiViewGetErrorA( hview, buffer, &sz ); 946 ok(err == MSIDBERROR_DUPLICATEKEY, "MsiViewGetError returned %u\n", err); 947 ok(!strcmp(buffer, "id"), "expected \"id\" c, got \"%s\"\n", buffer); 948 ok(sz == 2, "size not 2\n"); 949 950 /* insert the same thing again */ 951 r = MsiViewExecute(hview, 0); 952 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 953 954 /* should fail ... */ 955 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 956 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 957 958 /* try to merge the same record */ 959 r = MsiViewExecute(hview, 0); 960 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 961 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec ); 962 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 963 964 r = MsiCloseHandle(hrec); 965 ok(r == ERROR_SUCCESS, "failed to close record\n"); 966 967 /* try merging a new record */ 968 hrec = MsiCreateRecord(3); 969 970 r = MsiRecordSetInteger(hrec, 1, 10); 971 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 972 r = MsiRecordSetStringA(hrec, 2, "pepe"); 973 ok(r == ERROR_SUCCESS, "failed to set string\n"); 974 r = MsiRecordSetStringA(hrec, 3, "7654321"); 975 ok(r == ERROR_SUCCESS, "failed to set string\n"); 976 977 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec ); 978 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 979 r = MsiViewExecute(hview, 0); 980 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 981 982 r = MsiCloseHandle(hrec); 983 ok(r == ERROR_SUCCESS, "failed to close record\n"); 984 985 r = MsiViewClose(hview); 986 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 987 r = MsiCloseHandle(hview); 988 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 989 990 query = "SELECT * FROM `phone`"; 991 r = MsiDatabaseOpenViewA(hdb, query, &hview); 992 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 993 994 r = MsiViewExecute(hview, 0); 995 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 996 997 r = MsiViewFetch(hview, &hrec); 998 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 999 1000 r = MsiRecordGetInteger(hrec, 1); 1001 ok(r == 1, "Expected 1, got %d\n", r); 1002 1003 sz = sizeof(buffer); 1004 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 1005 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1006 ok(!lstrcmpA(buffer, "bob"), "Expected bob, got %s\n", buffer); 1007 1008 sz = sizeof(buffer); 1009 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 1010 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1011 ok(!lstrcmpA(buffer, "7654321"), "Expected 7654321, got %s\n", buffer); 1012 1013 /* update the view, non-primary key */ 1014 r = MsiRecordSetStringA(hrec, 3, "3141592"); 1015 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n"); 1016 1017 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1018 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 1019 1020 /* do it again */ 1021 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1022 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 1023 1024 /* update the view, primary key */ 1025 r = MsiRecordSetInteger(hrec, 1, 5); 1026 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n"); 1027 1028 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1029 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1030 1031 r = MsiCloseHandle(hrec); 1032 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1033 1034 r = MsiViewClose(hview); 1035 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1036 r = MsiCloseHandle(hview); 1037 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1038 1039 query = "SELECT * FROM `phone`"; 1040 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1041 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1042 1043 r = MsiViewExecute(hview, 0); 1044 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1045 1046 r = MsiViewFetch(hview, &hrec); 1047 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1048 1049 r = MsiRecordGetInteger(hrec, 1); 1050 ok(r == 1, "Expected 1, got %d\n", r); 1051 1052 sz = sizeof(buffer); 1053 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 1054 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1055 ok(!lstrcmpA(buffer, "bob"), "Expected bob, got %s\n", buffer); 1056 1057 sz = sizeof(buffer); 1058 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 1059 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n"); 1060 ok(!lstrcmpA(buffer, "3141592"), "Expected 3141592, got %s\n", buffer); 1061 1062 r = MsiCloseHandle(hrec); 1063 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1064 1065 /* use a record that doesn't come from a view fetch */ 1066 hrec = MsiCreateRecord(3); 1067 ok(hrec != 0, "MsiCreateRecord failed\n"); 1068 1069 r = MsiRecordSetInteger(hrec, 1, 3); 1070 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1071 r = MsiRecordSetStringA(hrec, 2, "jane"); 1072 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1073 r = MsiRecordSetStringA(hrec, 3, "112358"); 1074 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1075 1076 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1077 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 1078 1079 r = MsiCloseHandle(hrec); 1080 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1081 1082 /* use a record that doesn't come from a view fetch, primary key matches */ 1083 hrec = MsiCreateRecord(3); 1084 ok(hrec != 0, "MsiCreateRecord failed\n"); 1085 1086 r = MsiRecordSetInteger(hrec, 1, 1); 1087 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1088 r = MsiRecordSetStringA(hrec, 2, "jane"); 1089 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1090 r = MsiRecordSetStringA(hrec, 3, "112358"); 1091 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1092 1093 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1094 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1095 1096 r = MsiCloseHandle(hrec); 1097 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1098 1099 hrec = MsiCreateRecord(3); 1100 1101 r = MsiRecordSetInteger(hrec, 1, 2); 1102 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1103 r = MsiRecordSetStringA(hrec, 2, "nick"); 1104 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1105 r = MsiRecordSetStringA(hrec, 3, "141421"); 1106 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1107 1108 r = MsiViewExecute(hview, 0); 1109 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1110 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); 1111 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); 1112 1113 r = MsiCloseHandle(hrec); 1114 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1115 r = MsiViewClose(hview); 1116 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1117 r = MsiCloseHandle(hview); 1118 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1119 1120 query = "SELECT * FROM `phone` WHERE `id` = 1"; 1121 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1122 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1123 r = MsiViewExecute(hview, 0); 1124 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1125 r = MsiViewFetch(hview, &hrec); 1126 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1127 1128 /* change the id to match the second row */ 1129 r = MsiRecordSetInteger(hrec, 1, 2); 1130 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1131 r = MsiRecordSetStringA(hrec, 2, "jerry"); 1132 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1133 1134 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1135 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1136 1137 r = MsiCloseHandle(hrec); 1138 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1139 r = MsiViewClose(hview); 1140 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1141 r = MsiCloseHandle(hview); 1142 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1143 1144 /* broader search */ 1145 query = "SELECT * FROM `phone` ORDER BY `id`"; 1146 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1147 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1148 r = MsiViewExecute(hview, 0); 1149 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1150 r = MsiViewFetch(hview, &hrec); 1151 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1152 1153 /* change the id to match the second row */ 1154 r = MsiRecordSetInteger(hrec, 1, 2); 1155 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 1156 r = MsiRecordSetStringA(hrec, 2, "jerry"); 1157 ok(r == ERROR_SUCCESS, "failed to set string\n"); 1158 1159 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 1160 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n"); 1161 1162 r = MsiCloseHandle(hrec); 1163 ok(r == ERROR_SUCCESS, "failed to close record\n"); 1164 r = MsiViewClose(hview); 1165 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1166 r = MsiCloseHandle(hview); 1167 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1168 1169 r = MsiCloseHandle( hdb ); 1170 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 1171 } 1172 1173 static MSIHANDLE create_db(void) 1174 { 1175 MSIHANDLE hdb = 0; 1176 UINT res; 1177 1178 DeleteFileW(msifileW); 1179 1180 /* create an empty database */ 1181 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1182 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 1183 if( res != ERROR_SUCCESS ) 1184 return hdb; 1185 1186 res = MsiDatabaseCommit( hdb ); 1187 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 1188 1189 return hdb; 1190 } 1191 1192 static void test_getcolinfo(void) 1193 { 1194 MSIHANDLE hdb, hview = 0, rec = 0; 1195 UINT r; 1196 DWORD sz; 1197 char buffer[0x20]; 1198 1199 /* create an empty db */ 1200 hdb = create_db(); 1201 ok( hdb, "failed to create db\n"); 1202 1203 /* tables should be present */ 1204 r = MsiDatabaseOpenViewA(hdb, "select * from _Tables", &hview); 1205 ok( r == ERROR_SUCCESS, "failed to open query\n"); 1206 1207 r = MsiViewExecute(hview, 0); 1208 ok( r == ERROR_SUCCESS, "failed to execute query\n"); 1209 1210 /* check that NAMES works */ 1211 rec = 0; 1212 r = MsiViewGetColumnInfo( hview, MSICOLINFO_NAMES, &rec ); 1213 ok( r == ERROR_SUCCESS, "failed to get names\n"); 1214 sz = sizeof buffer; 1215 r = MsiRecordGetStringA(rec, 1, buffer, &sz ); 1216 ok( r == ERROR_SUCCESS, "failed to get string\n"); 1217 ok( !strcmp(buffer,"Name"), "_Tables has wrong column name\n"); 1218 r = MsiCloseHandle( rec ); 1219 ok( r == ERROR_SUCCESS, "failed to close record handle\n"); 1220 1221 /* check that TYPES works */ 1222 rec = 0; 1223 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, &rec ); 1224 ok( r == ERROR_SUCCESS, "failed to get names\n"); 1225 sz = sizeof buffer; 1226 r = MsiRecordGetStringA(rec, 1, buffer, &sz ); 1227 ok( r == ERROR_SUCCESS, "failed to get string\n"); 1228 ok( !strcmp(buffer,"s64"), "_Tables has wrong column type\n"); 1229 r = MsiCloseHandle( rec ); 1230 ok( r == ERROR_SUCCESS, "failed to close record handle\n"); 1231 1232 /* check that invalid values fail */ 1233 rec = 0; 1234 r = MsiViewGetColumnInfo( hview, 100, &rec ); 1235 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n"); 1236 ok( rec == 0, "returned a record\n"); 1237 1238 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, NULL ); 1239 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n"); 1240 1241 r = MsiViewGetColumnInfo( 0, MSICOLINFO_TYPES, &rec ); 1242 ok( r == ERROR_INVALID_HANDLE, "wrong error code\n"); 1243 1244 r = MsiViewClose(hview); 1245 ok( r == ERROR_SUCCESS, "failed to close view\n"); 1246 r = MsiCloseHandle(hview); 1247 ok( r == ERROR_SUCCESS, "failed to close view handle\n"); 1248 r = MsiCloseHandle(hdb); 1249 ok( r == ERROR_SUCCESS, "failed to close database\n"); 1250 } 1251 1252 static MSIHANDLE get_column_info(MSIHANDLE hdb, const char *query, MSICOLINFO type) 1253 { 1254 MSIHANDLE hview = 0, rec = 0; 1255 UINT r; 1256 1257 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1258 if( r != ERROR_SUCCESS ) 1259 return r; 1260 1261 r = MsiViewExecute(hview, 0); 1262 if( r == ERROR_SUCCESS ) 1263 { 1264 MsiViewGetColumnInfo( hview, type, &rec ); 1265 } 1266 MsiViewClose(hview); 1267 MsiCloseHandle(hview); 1268 return rec; 1269 } 1270 1271 static UINT get_columns_table_type(MSIHANDLE hdb, const char *table, UINT field) 1272 { 1273 MSIHANDLE hview = 0, rec = 0; 1274 UINT r, type = 0; 1275 char query[0x100]; 1276 1277 sprintf(query, "select * from `_Columns` where `Table` = '%s'", table ); 1278 1279 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1280 if( r != ERROR_SUCCESS ) 1281 return r; 1282 1283 r = MsiViewExecute(hview, 0); 1284 if( r == ERROR_SUCCESS ) 1285 { 1286 while (1) 1287 { 1288 r = MsiViewFetch( hview, &rec ); 1289 if( r != ERROR_SUCCESS) 1290 break; 1291 r = MsiRecordGetInteger( rec, 2 ); 1292 if (r == field) 1293 type = MsiRecordGetInteger( rec, 4 ); 1294 MsiCloseHandle( rec ); 1295 } 1296 } 1297 MsiViewClose(hview); 1298 MsiCloseHandle(hview); 1299 return type; 1300 } 1301 1302 static BOOL check_record( MSIHANDLE rec, UINT field, LPCSTR val ) 1303 { 1304 CHAR buffer[0x20]; 1305 UINT r; 1306 DWORD sz; 1307 1308 sz = sizeof buffer; 1309 r = MsiRecordGetStringA( rec, field, buffer, &sz ); 1310 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer); 1311 } 1312 1313 static void test_viewgetcolumninfo(void) 1314 { 1315 MSIHANDLE hdb = 0, rec; 1316 UINT r; 1317 1318 hdb = create_db(); 1319 ok( hdb, "failed to create db\n"); 1320 1321 r = run_query( hdb, 0, 1322 "CREATE TABLE `Properties` " 1323 "( `Property` CHAR(255), " 1324 " `Value` CHAR(1), " 1325 " `Intvalue` INT, " 1326 " `Integervalue` INTEGER, " 1327 " `Shortvalue` SHORT, " 1328 " `Longvalue` LONG, " 1329 " `Longcharvalue` LONGCHAR, " 1330 " `Charvalue` CHAR, " 1331 " `Localizablevalue` CHAR LOCALIZABLE " 1332 " PRIMARY KEY `Property`)" ); 1333 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1334 1335 /* check the column types */ 1336 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES ); 1337 ok( rec, "failed to get column info record\n" ); 1338 1339 ok( check_record( rec, 1, "S255"), "wrong record type\n"); 1340 ok( check_record( rec, 2, "S1"), "wrong record type\n"); 1341 ok( check_record( rec, 3, "I2"), "wrong record type\n"); 1342 ok( check_record( rec, 4, "I2"), "wrong record type\n"); 1343 ok( check_record( rec, 5, "I2"), "wrong record type\n"); 1344 ok( check_record( rec, 6, "I4"), "wrong record type\n"); 1345 ok( check_record( rec, 7, "S0"), "wrong record type\n"); 1346 ok( check_record( rec, 8, "S0"), "wrong record type\n"); 1347 ok( check_record( rec, 9, "L0"), "wrong record type\n"); 1348 1349 MsiCloseHandle( rec ); 1350 1351 /* check the type in _Columns */ 1352 ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n"); 1353 ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n"); 1354 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n"); 1355 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n"); 1356 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n"); 1357 ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n"); 1358 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n"); 1359 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 8 ), "_columns table wrong\n"); 1360 ok( 0x1f00 == get_columns_table_type(hdb, "Properties", 9 ), "_columns table wrong\n"); 1361 1362 /* now try the names */ 1363 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES ); 1364 ok( rec, "failed to get column info record\n" ); 1365 1366 ok( check_record( rec, 1, "Property"), "wrong record type\n"); 1367 ok( check_record( rec, 2, "Value"), "wrong record type\n"); 1368 ok( check_record( rec, 3, "Intvalue"), "wrong record type\n"); 1369 ok( check_record( rec, 4, "Integervalue"), "wrong record type\n"); 1370 ok( check_record( rec, 5, "Shortvalue"), "wrong record type\n"); 1371 ok( check_record( rec, 6, "Longvalue"), "wrong record type\n"); 1372 ok( check_record( rec, 7, "Longcharvalue"), "wrong record type\n"); 1373 ok( check_record( rec, 8, "Charvalue"), "wrong record type\n"); 1374 ok( check_record( rec, 9, "Localizablevalue"), "wrong record type\n"); 1375 1376 MsiCloseHandle( rec ); 1377 1378 r = run_query( hdb, 0, 1379 "CREATE TABLE `Binary` " 1380 "( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" ); 1381 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1382 1383 /* check the column types */ 1384 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES ); 1385 ok( rec, "failed to get column info record\n" ); 1386 1387 ok( check_record( rec, 1, "S255"), "wrong record type\n"); 1388 ok( check_record( rec, 2, "V0"), "wrong record type\n"); 1389 1390 MsiCloseHandle( rec ); 1391 1392 /* check the type in _Columns */ 1393 ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n"); 1394 ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n"); 1395 1396 /* now try the names */ 1397 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES ); 1398 ok( rec, "failed to get column info record\n" ); 1399 1400 ok( check_record( rec, 1, "Name"), "wrong record type\n"); 1401 ok( check_record( rec, 2, "Data"), "wrong record type\n"); 1402 MsiCloseHandle( rec ); 1403 1404 r = run_query( hdb, 0, 1405 "CREATE TABLE `UIText` " 1406 "( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" ); 1407 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1408 1409 ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n"); 1410 ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n"); 1411 1412 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES ); 1413 ok( rec, "failed to get column info record\n" ); 1414 ok( check_record( rec, 1, "Key"), "wrong record type\n"); 1415 ok( check_record( rec, 2, "Text"), "wrong record type\n"); 1416 MsiCloseHandle( rec ); 1417 1418 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES ); 1419 ok( rec, "failed to get column info record\n" ); 1420 ok( check_record( rec, 1, "s72"), "wrong record type\n"); 1421 ok( check_record( rec, 2, "L255"), "wrong record type\n"); 1422 MsiCloseHandle( rec ); 1423 1424 MsiCloseHandle( hdb ); 1425 } 1426 1427 static void test_msiexport(void) 1428 { 1429 MSIHANDLE hdb = 0, hview = 0; 1430 UINT r; 1431 const char *query; 1432 char path[MAX_PATH]; 1433 const char file[] = "phone.txt"; 1434 HANDLE handle; 1435 char buffer[0x100]; 1436 DWORD length; 1437 const char expected[] = 1438 "id\tname\tnumber\r\n" 1439 "I2\tS32\tS32\r\n" 1440 "phone\tid\r\n" 1441 "1\tAbe\t8675309\r\n"; 1442 1443 DeleteFileW(msifileW); 1444 1445 /* just MsiOpenDatabase should not create a file */ 1446 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 1447 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1448 1449 /* create a table */ 1450 query = "CREATE TABLE `phone` ( " 1451 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 1452 "PRIMARY KEY `id`)"; 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 /* insert a value into it */ 1463 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 1464 "VALUES('1', 'Abe', '8675309')"; 1465 r = MsiDatabaseOpenViewA(hdb, query, &hview); 1466 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1467 r = MsiViewExecute(hview, 0); 1468 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1469 r = MsiViewClose(hview); 1470 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 1471 r = MsiCloseHandle(hview); 1472 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 1473 1474 GetCurrentDirectoryA(MAX_PATH, path); 1475 1476 r = MsiDatabaseExportA(hdb, "phone", path, file); 1477 ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n"); 1478 1479 MsiCloseHandle(hdb); 1480 1481 lstrcatA(path, "\\"); 1482 lstrcatA(path, file); 1483 1484 /* check the data that was written */ 1485 length = 0; 1486 memset(buffer, 0, sizeof buffer); 1487 handle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 1488 if (handle != INVALID_HANDLE_VALUE) 1489 { 1490 ReadFile(handle, buffer, sizeof buffer, &length, NULL); 1491 CloseHandle(handle); 1492 DeleteFileA(path); 1493 } 1494 else 1495 ok(0, "failed to open file %s\n", path); 1496 1497 ok( length == strlen(expected), "length of data wrong\n"); 1498 ok( !lstrcmpA(buffer, expected), "data doesn't match\n"); 1499 DeleteFileA(msifile); 1500 } 1501 1502 static void test_longstrings(void) 1503 { 1504 const char insert_query[] = 1505 "INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')"; 1506 char *str; 1507 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 1508 DWORD len; 1509 UINT r; 1510 const DWORD STRING_LENGTH = 0x10005; 1511 1512 DeleteFileW(msifileW); 1513 /* just MsiOpenDatabase should not create a file */ 1514 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 1515 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1516 1517 /* create a table */ 1518 r = try_query( hdb, 1519 "CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)"); 1520 ok(r == ERROR_SUCCESS, "query failed\n"); 1521 1522 /* try to insert a very long string */ 1523 str = HeapAlloc(GetProcessHeap(), 0, STRING_LENGTH+sizeof insert_query); 1524 len = strchr(insert_query, 'Z') - insert_query; 1525 strcpy(str, insert_query); 1526 memset(str+len, 'Z', STRING_LENGTH); 1527 strcpy(str+len+STRING_LENGTH, insert_query+len+1); 1528 r = try_query( hdb, str ); 1529 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1530 1531 HeapFree(GetProcessHeap(), 0, str); 1532 1533 r = MsiDatabaseCommit(hdb); 1534 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 1535 MsiCloseHandle(hdb); 1536 1537 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 1538 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 1539 1540 r = MsiDatabaseOpenViewA(hdb, "select * from `strings` where `id` = 1", &hview); 1541 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 1542 1543 r = MsiViewExecute(hview, 0); 1544 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 1545 1546 r = MsiViewFetch(hview, &hrec); 1547 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1548 1549 MsiViewClose(hview); 1550 MsiCloseHandle(hview); 1551 1552 r = MsiRecordGetStringA(hrec, 2, NULL, &len); 1553 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 1554 ok(len == STRING_LENGTH, "string length wrong\n"); 1555 1556 MsiCloseHandle(hrec); 1557 MsiCloseHandle(hdb); 1558 DeleteFileA(msifile); 1559 } 1560 1561 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size) 1562 { 1563 HANDLE file; 1564 DWORD written; 1565 1566 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 1567 if (file == INVALID_HANDLE_VALUE) 1568 return; 1569 1570 WriteFile(file, data, strlen(data), &written, NULL); 1571 WriteFile(file, "\n", strlen("\n"), &written, NULL); 1572 1573 if (size) 1574 { 1575 SetFilePointer(file, size, NULL, FILE_BEGIN); 1576 SetEndOfFile(file); 1577 } 1578 1579 CloseHandle(file); 1580 } 1581 1582 #define create_file(name) create_file_data(name, name, 0) 1583 1584 static void test_streamtable(void) 1585 { 1586 MSIHANDLE hdb = 0, rec, view, hsi; 1587 char file[MAX_PATH]; 1588 char buf[MAX_PATH]; 1589 DWORD size; 1590 UINT r; 1591 1592 hdb = create_db(); 1593 ok( hdb, "failed to create db\n"); 1594 1595 r = run_query( hdb, 0, 1596 "CREATE TABLE `Properties` " 1597 "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" ); 1598 ok( r == ERROR_SUCCESS , "Failed to create table\n" ); 1599 1600 r = run_query( hdb, 0, 1601 "INSERT INTO `Properties` " 1602 "( `Value`, `Property` ) VALUES ( 'Prop', 'value' )" ); 1603 ok( r == ERROR_SUCCESS, "Failed to add to table\n" ); 1604 1605 r = MsiDatabaseCommit( hdb ); 1606 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 1607 1608 MsiCloseHandle( hdb ); 1609 1610 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 1611 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1612 1613 /* check the column types */ 1614 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES ); 1615 ok( rec, "failed to get column info record\n" ); 1616 1617 ok( check_record( rec, 1, "s62"), "wrong record type\n"); 1618 ok( check_record( rec, 2, "V0"), "wrong record type\n"); 1619 1620 MsiCloseHandle( rec ); 1621 1622 /* now try the names */ 1623 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES ); 1624 ok( rec, "failed to get column info record\n" ); 1625 1626 ok( check_record( rec, 1, "Name"), "wrong record type\n"); 1627 ok( check_record( rec, 2, "Data"), "wrong record type\n"); 1628 1629 MsiCloseHandle( rec ); 1630 1631 r = MsiDatabaseOpenViewA( hdb, 1632 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view ); 1633 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r ); 1634 1635 r = MsiViewExecute( view, 0 ); 1636 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r ); 1637 1638 r = MsiViewFetch( view, &rec ); 1639 ok( r == ERROR_NO_MORE_ITEMS, "Unexpected result: %u\n", r ); 1640 1641 MsiCloseHandle( rec ); 1642 MsiViewClose( view ); 1643 MsiCloseHandle( view ); 1644 1645 /* create a summary information stream */ 1646 r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi ); 1647 ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r ); 1648 1649 r = MsiSummaryInfoSetPropertyA( hsi, PID_SECURITY, VT_I4, 2, NULL, NULL ); 1650 ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r ); 1651 1652 r = MsiSummaryInfoPersist( hsi ); 1653 ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r ); 1654 1655 MsiCloseHandle( hsi ); 1656 1657 r = MsiDatabaseOpenViewA( hdb, 1658 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view ); 1659 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r ); 1660 1661 r = MsiViewExecute( view, 0 ); 1662 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r ); 1663 1664 r = MsiViewFetch( view, &rec ); 1665 ok( r == ERROR_SUCCESS, "Unexpected result: %u\n", r ); 1666 1667 MsiCloseHandle( rec ); 1668 MsiViewClose( view ); 1669 MsiCloseHandle( view ); 1670 1671 /* insert a file into the _Streams table */ 1672 create_file( "test.txt" ); 1673 1674 rec = MsiCreateRecord( 2 ); 1675 MsiRecordSetStringA( rec, 1, "data" ); 1676 1677 r = MsiRecordSetStreamA( rec, 2, "test.txt" ); 1678 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1679 1680 DeleteFileA("test.txt"); 1681 1682 r = MsiDatabaseOpenViewA( hdb, 1683 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1684 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1685 1686 r = MsiViewExecute( view, rec ); 1687 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1688 1689 MsiCloseHandle( rec ); 1690 MsiViewClose( view ); 1691 MsiCloseHandle( view ); 1692 1693 /* insert another one */ 1694 create_file( "test1.txt" ); 1695 1696 rec = MsiCreateRecord( 2 ); 1697 MsiRecordSetStringA( rec, 1, "data1" ); 1698 1699 r = MsiRecordSetStreamA( rec, 2, "test1.txt" ); 1700 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1701 1702 DeleteFileA("test1.txt"); 1703 1704 r = MsiDatabaseOpenViewA( hdb, 1705 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1706 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1707 1708 r = MsiViewExecute( view, rec ); 1709 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1710 1711 MsiCloseHandle( rec ); 1712 MsiViewClose( view ); 1713 MsiCloseHandle( view ); 1714 1715 /* try again */ 1716 create_file( "test1.txt" ); 1717 1718 rec = MsiCreateRecord( 2 ); 1719 MsiRecordSetStringA( rec, 1, "data1" ); 1720 1721 r = MsiRecordSetStreamA( rec, 2, "test1.txt" ); 1722 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r ); 1723 1724 DeleteFileA( "test1.txt" ); 1725 1726 r = MsiDatabaseOpenViewA( hdb, 1727 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view ); 1728 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r ); 1729 1730 r = MsiViewExecute( view, rec ); 1731 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r ); 1732 1733 MsiCloseHandle( rec ); 1734 MsiViewClose( view ); 1735 MsiCloseHandle( view ); 1736 1737 r = MsiDatabaseOpenViewA( hdb, 1738 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view ); 1739 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1740 1741 r = MsiViewExecute( view, 0 ); 1742 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1743 1744 r = MsiViewFetch( view, &rec ); 1745 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r); 1746 1747 size = MAX_PATH; 1748 r = MsiRecordGetStringA( rec, 1, file, &size ); 1749 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1750 ok( !lstrcmpA(file, "data"), "Expected 'data', got %s\n", file); 1751 1752 size = MAX_PATH; 1753 memset(buf, 0, MAX_PATH); 1754 r = MsiRecordReadStream( rec, 2, buf, &size ); 1755 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1756 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf); 1757 1758 MsiCloseHandle( rec ); 1759 MsiViewClose( view ); 1760 MsiCloseHandle( view ); 1761 1762 r = MsiDatabaseOpenViewA( hdb, 1763 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view ); 1764 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1765 1766 r = MsiViewExecute( view, 0 ); 1767 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1768 1769 r = MsiViewFetch( view, &rec ); 1770 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 1771 1772 size = MAX_PATH; 1773 r = MsiRecordGetStringA( rec, 1, file, &size ); 1774 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1775 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file); 1776 1777 size = MAX_PATH; 1778 memset(buf, 0, MAX_PATH); 1779 r = MsiRecordReadStream( rec, 2, buf, &size ); 1780 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1781 ok( !lstrcmpA(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf); 1782 1783 MsiCloseHandle( rec ); 1784 MsiViewClose( view ); 1785 MsiCloseHandle( view ); 1786 1787 /* perform an update */ 1788 create_file( "test2.txt" ); 1789 rec = MsiCreateRecord( 1 ); 1790 1791 r = MsiRecordSetStreamA( rec, 1, "test2.txt" ); 1792 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1793 1794 DeleteFileA("test2.txt"); 1795 1796 r = MsiDatabaseOpenViewA( hdb, 1797 "UPDATE `_Streams` SET `Data` = ? WHERE `Name` = 'data1'", &view ); 1798 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1799 1800 r = MsiViewExecute( view, rec ); 1801 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1802 1803 MsiCloseHandle( rec ); 1804 MsiViewClose( view ); 1805 MsiCloseHandle( view ); 1806 1807 r = MsiDatabaseOpenViewA( hdb, 1808 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view ); 1809 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r); 1810 1811 r = MsiViewExecute( view, 0 ); 1812 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r); 1813 1814 r = MsiViewFetch( view, &rec ); 1815 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r); 1816 1817 size = MAX_PATH; 1818 r = MsiRecordGetStringA( rec, 1, file, &size ); 1819 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 1820 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file); 1821 1822 size = MAX_PATH; 1823 memset(buf, 0, MAX_PATH); 1824 r = MsiRecordReadStream( rec, 2, buf, &size ); 1825 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 1826 ok( !lstrcmpA(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf); 1827 1828 MsiCloseHandle( rec ); 1829 MsiViewClose( view ); 1830 MsiCloseHandle( view ); 1831 MsiCloseHandle( hdb ); 1832 DeleteFileA(msifile); 1833 } 1834 1835 static void test_binary(void) 1836 { 1837 MSIHANDLE hdb = 0, rec; 1838 char file[MAX_PATH]; 1839 char buf[MAX_PATH]; 1840 DWORD size; 1841 LPCSTR query; 1842 UINT r; 1843 1844 /* insert a file into the Binary table */ 1845 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1846 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1847 1848 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)"; 1849 r = run_query( hdb, 0, query ); 1850 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r ); 1851 1852 create_file( "test.txt" ); 1853 rec = MsiCreateRecord( 1 ); 1854 r = MsiRecordSetStreamA( rec, 1, "test.txt" ); 1855 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r); 1856 DeleteFileA( "test.txt" ); 1857 1858 /* try a name that exceeds maximum OLE stream name length */ 1859 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'encryption.dll.CB4E6205_F99A_4C51_ADD4_184506EFAB87', 10000, ? )"; 1860 r = run_query( hdb, rec, query ); 1861 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r ); 1862 1863 r = MsiCloseHandle( rec ); 1864 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1865 1866 r = MsiDatabaseCommit( hdb ); 1867 ok( r == ERROR_FUNCTION_FAILED , "got %u\n", r ); 1868 1869 r = MsiCloseHandle( hdb ); 1870 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1871 1872 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb ); 1873 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1874 1875 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)"; 1876 r = run_query( hdb, 0, query ); 1877 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r ); 1878 1879 create_file( "test.txt" ); 1880 rec = MsiCreateRecord( 1 ); 1881 r = MsiRecordSetStreamA( rec, 1, "test.txt" ); 1882 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r ); 1883 DeleteFileA( "test.txt" ); 1884 1885 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )"; 1886 r = run_query( hdb, rec, query ); 1887 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r ); 1888 1889 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )"; 1890 r = run_query( hdb, rec, query ); 1891 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r ); 1892 1893 r = MsiCloseHandle( rec ); 1894 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1895 1896 r = MsiDatabaseCommit( hdb ); 1897 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 1898 1899 r = MsiCloseHandle( hdb ); 1900 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1901 1902 /* read file from the Stream table */ 1903 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_READONLY, &hdb ); 1904 ok( r == ERROR_SUCCESS , "Failed to open database\n" ); 1905 1906 query = "SELECT * FROM `_Streams`"; 1907 r = do_query( hdb, query, &rec ); 1908 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r ); 1909 1910 size = MAX_PATH; 1911 r = MsiRecordGetStringA( rec, 1, file, &size ); 1912 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r ); 1913 ok( !lstrcmpA(file, "Binary.filename1.1"), "Expected 'Binary.filename1.1', got %s\n", file ); 1914 1915 size = MAX_PATH; 1916 memset( buf, 0, MAX_PATH ); 1917 r = MsiRecordReadStream( rec, 2, buf, &size ); 1918 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r ); 1919 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf ); 1920 1921 r = MsiCloseHandle( rec ); 1922 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1923 1924 /* read file from the Binary table */ 1925 query = "SELECT * FROM `Binary`"; 1926 r = do_query( hdb, query, &rec ); 1927 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r ); 1928 1929 size = MAX_PATH; 1930 r = MsiRecordGetStringA( rec, 1, file, &size ); 1931 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r ); 1932 ok( !lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file ); 1933 1934 size = MAX_PATH; 1935 memset( buf, 0, MAX_PATH ); 1936 r = MsiRecordReadStream( rec, 3, buf, &size ); 1937 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r ); 1938 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf ); 1939 1940 r = MsiCloseHandle( rec ); 1941 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" ); 1942 1943 r = MsiCloseHandle( hdb ); 1944 ok( r == ERROR_SUCCESS , "Failed to close database\n" ); 1945 1946 DeleteFileA( msifile ); 1947 } 1948 1949 static void test_where_not_in_selected(void) 1950 { 1951 MSIHANDLE hdb = 0, rec, view; 1952 LPCSTR query; 1953 UINT r; 1954 1955 hdb = create_db(); 1956 ok( hdb, "failed to create db\n"); 1957 1958 r = run_query(hdb, 0, 1959 "CREATE TABLE `IESTable` (" 1960 "`Action` CHAR(64), " 1961 "`Condition` CHAR(64), " 1962 "`Sequence` LONG PRIMARY KEY `Sequence`)"); 1963 ok( r == S_OK, "Cannot create IESTable table: %d\n", r); 1964 1965 r = run_query(hdb, 0, 1966 "CREATE TABLE `CATable` (" 1967 "`Action` CHAR(64), " 1968 "`Type` LONG PRIMARY KEY `Type`)"); 1969 ok( r == S_OK, "Cannot create CATable table: %d\n", r); 1970 1971 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1972 "( `Action`, `Condition`, `Sequence`) " 1973 "VALUES ( 'clean', 'cond4', 4)"); 1974 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1975 1976 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1977 "( `Action`, `Condition`, `Sequence`) " 1978 "VALUES ( 'depends', 'cond1', 1)"); 1979 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1980 1981 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1982 "( `Action`, `Condition`, `Sequence`) " 1983 "VALUES ( 'build', 'cond2', 2)"); 1984 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1985 1986 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1987 "( `Action`, `Condition`, `Sequence`) " 1988 "VALUES ( 'build2', 'cond6', 6)"); 1989 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1990 1991 r = run_query(hdb, 0, "INSERT INTO `IESTable` " 1992 "( `Action`, `Condition`, `Sequence`) " 1993 "VALUES ( 'build', 'cond3', 3)"); 1994 ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r ); 1995 1996 r = run_query(hdb, 0, "INSERT INTO `CATable` " 1997 "( `Action`, `Type` ) " 1998 "VALUES ( 'build', 32)"); 1999 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 2000 2001 r = run_query(hdb, 0, "INSERT INTO `CATable` " 2002 "( `Action`, `Type` ) " 2003 "VALUES ( 'depends', 64)"); 2004 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 2005 2006 r = run_query(hdb, 0, "INSERT INTO `CATable` " 2007 "( `Action`, `Type` ) " 2008 "VALUES ( 'clean', 63)"); 2009 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 2010 2011 r = run_query(hdb, 0, "INSERT INTO `CATable` " 2012 "( `Action`, `Type` ) " 2013 "VALUES ( 'build2', 34)"); 2014 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); 2015 query = "Select IESTable.Condition from CATable, IESTable where " 2016 "CATable.Action = IESTable.Action and CATable.Type = 32"; 2017 r = MsiDatabaseOpenViewA(hdb, query, &view); 2018 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 2019 2020 r = MsiViewExecute(view, 0); 2021 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 2022 2023 r = MsiViewFetch(view, &rec); 2024 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2025 2026 ok( check_record( rec, 1, "cond2"), "wrong condition\n"); 2027 2028 MsiCloseHandle( rec ); 2029 r = MsiViewFetch(view, &rec); 2030 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2031 2032 ok( check_record( rec, 1, "cond3"), "wrong condition\n"); 2033 2034 MsiCloseHandle( rec ); 2035 MsiViewClose(view); 2036 MsiCloseHandle(view); 2037 2038 MsiCloseHandle( hdb ); 2039 DeleteFileA(msifile); 2040 } 2041 2042 2043 static void test_where(void) 2044 { 2045 MSIHANDLE hdb = 0, rec, view; 2046 LPCSTR query; 2047 UINT r; 2048 DWORD size; 2049 CHAR buf[MAX_PATH]; 2050 UINT count; 2051 2052 hdb = create_db(); 2053 ok( hdb, "failed to create db\n"); 2054 2055 r = run_query( hdb, 0, 2056 "CREATE TABLE `Media` (" 2057 "`DiskId` SHORT NOT NULL, " 2058 "`LastSequence` LONG, " 2059 "`DiskPrompt` CHAR(64) LOCALIZABLE, " 2060 "`Cabinet` CHAR(255), " 2061 "`VolumeLabel` CHAR(32), " 2062 "`Source` CHAR(72) " 2063 "PRIMARY KEY `DiskId`)" ); 2064 ok( r == S_OK, "cannot create Media table: %d\n", r ); 2065 2066 r = run_query( hdb, 0, "INSERT INTO `Media` " 2067 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2068 "VALUES ( 1, 0, '', 'zero.cab', '', '' )" ); 2069 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2070 2071 r = run_query( hdb, 0, "INSERT INTO `Media` " 2072 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2073 "VALUES ( 2, 1, '', 'one.cab', '', '' )" ); 2074 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2075 2076 r = run_query( hdb, 0, "INSERT INTO `Media` " 2077 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) " 2078 "VALUES ( 3, 2, '', 'two.cab', '', '' )" ); 2079 ok( r == S_OK, "cannot add file to the Media table: %d\n", r ); 2080 2081 query = "SELECT * FROM `Media`"; 2082 r = do_query(hdb, query, &rec); 2083 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r); 2084 ok( check_record( rec, 4, "zero.cab"), "wrong cabinet\n"); 2085 MsiCloseHandle( rec ); 2086 2087 query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1"; 2088 r = do_query(hdb, query, &rec); 2089 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r); 2090 ok( check_record( rec, 4, "one.cab"), "wrong cabinet\n"); 2091 2092 r = MsiRecordGetInteger(rec, 1); 2093 ok( 2 == r, "field wrong\n"); 2094 r = MsiRecordGetInteger(rec, 2); 2095 ok( 1 == r, "field wrong\n"); 2096 MsiCloseHandle( rec ); 2097 2098 query = "SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= 1 AND DiskId >= 0"; 2099 r = MsiDatabaseOpenViewA(hdb, query, &view); 2100 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 2101 2102 r = MsiViewExecute(view, 0); 2103 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 2104 2105 r = MsiViewFetch(view, &rec); 2106 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2107 2108 count = MsiRecordGetFieldCount( rec ); 2109 ok( count == 1, "Expected 1 record fields, got %d\n", count ); 2110 2111 size = MAX_PATH; 2112 r = MsiRecordGetStringA( rec, 1, buf, &size ); 2113 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 2114 ok( !lstrcmpA( buf, "2" ), "For (row %d, column 1) expected '%d', got %s\n", 0, 2, buf ); 2115 MsiCloseHandle( rec ); 2116 2117 r = MsiViewFetch(view, &rec); 2118 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 2119 2120 size = MAX_PATH; 2121 r = MsiRecordGetStringA( rec, 1, buf, &size ); 2122 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 2123 ok( !lstrcmpA( buf, "3" ), "For (row %d, column 1) expected '%d', got %s\n", 1, 3, buf ); 2124 MsiCloseHandle( rec ); 2125 2126 r = MsiViewFetch(view, &rec); 2127 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 2128 2129 MsiViewClose(view); 2130 MsiCloseHandle(view); 2131 2132 MsiCloseHandle( rec ); 2133 2134 rec = 0; 2135 query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL"; 2136 r = do_query(hdb, query, &rec); 2137 ok( r == ERROR_SUCCESS, "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_BAD_QUERY_SYNTAX, "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_BAD_QUERY_SYNTAX, "query failed: %d\n", r ); 2150 MsiCloseHandle( rec ); 2151 2152 rec = 0; 2153 query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'"; 2154 r = do_query(hdb, query, &rec); 2155 ok( r == ERROR_SUCCESS, "query failed: %d\n", r ); 2156 MsiCloseHandle( rec ); 2157 2158 rec = 0; 2159 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'"; 2160 r = do_query(hdb, query, &rec); 2161 ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r ); 2162 MsiCloseHandle( rec ); 2163 2164 rec = MsiCreateRecord(1); 2165 MsiRecordSetStringA(rec, 1, ""); 2166 2167 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = ?"; 2168 r = MsiDatabaseOpenViewA(hdb, query, &view); 2169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2170 r = MsiViewExecute(view, rec); 2171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2172 2173 MsiCloseHandle(rec); 2174 2175 r = MsiViewFetch(view, &rec); 2176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2177 2178 MsiCloseHandle(rec); 2179 MsiViewClose(view); 2180 MsiCloseHandle(view); 2181 2182 MsiCloseHandle( hdb ); 2183 DeleteFileA(msifile); 2184 } 2185 2186 static CHAR CURR_DIR[MAX_PATH]; 2187 2188 static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n" 2189 "s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n" 2190 "TestTable\tFirstPrimaryColumn\n" 2191 "stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n"; 2192 2193 static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n" 2194 "s255\ts255\n" 2195 "TwoPrimary\tPrimaryOne\tPrimaryTwo\n" 2196 "papaya\tleaf\n" 2197 "papaya\tflower\n"; 2198 2199 static const CHAR endlines1[] = "A\tB\tC\tD\tE\tF\r\n" 2200 "s72\ts72\ts72\ts72\ts72\ts72\n" 2201 "Table\tA\r\n" 2202 "a\tb\tc\td\te\tf\n" 2203 "g\th\ti\t\rj\tk\tl\r\n"; 2204 2205 static const CHAR endlines2[] = "A\tB\tC\tD\tE\tF\r" 2206 "s72\ts72\ts72\ts72\ts72\ts72\n" 2207 "Table2\tA\r\n" 2208 "a\tb\tc\td\te\tf\n" 2209 "g\th\ti\tj\tk\tl\r\n"; 2210 2211 static const CHAR suminfo[] = "PropertyId\tValue\n" 2212 "i2\tl255\n" 2213 "_SummaryInformation\tPropertyId\n" 2214 "1\t1252\n" 2215 "2\tInstaller Database\n" 2216 "3\tInstaller description\n" 2217 "4\tWineHQ\n" 2218 "5\tInstaller\n" 2219 "6\tInstaller comments\n" 2220 "7\tIntel;1033,2057\n" 2221 "9\t{12345678-1234-1234-1234-123456789012}\n" 2222 "12\t2009/04/12 15:46:11\n" 2223 "13\t2009/04/12 15:46:11\n" 2224 "14\t200\n" 2225 "15\t2\n" 2226 "18\tVim\n" 2227 "19\t2\n"; 2228 2229 static void write_file(const CHAR *filename, const char *data, int data_size) 2230 { 2231 DWORD size; 2232 2233 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL, 2234 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 2235 WriteFile(hf, data, data_size, &size, NULL); 2236 CloseHandle(hf); 2237 } 2238 2239 static UINT add_table_to_db(MSIHANDLE hdb, LPCSTR table_data) 2240 { 2241 UINT r; 2242 2243 write_file("temp_file", table_data, (lstrlenA(table_data) - 1) * sizeof(char)); 2244 r = MsiDatabaseImportA(hdb, CURR_DIR, "temp_file"); 2245 DeleteFileA("temp_file"); 2246 2247 return r; 2248 } 2249 2250 static void test_suminfo_import(void) 2251 { 2252 MSIHANDLE hdb, hsi, view = 0; 2253 LPCSTR query; 2254 UINT r, count, size, type; 2255 char str_value[50]; 2256 INT int_value; 2257 FILETIME ft_value; 2258 2259 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 2260 2261 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2263 2264 r = add_table_to_db(hdb, suminfo); 2265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2266 2267 /* _SummaryInformation is not imported as a regular table... */ 2268 2269 query = "SELECT * FROM `_SummaryInformation`"; 2270 r = MsiDatabaseOpenViewA(hdb, query, &view); 2271 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %u\n", r); 2272 MsiCloseHandle(view); 2273 2274 /* ...its data is added to the special summary information stream */ 2275 2276 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsi); 2277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2278 2279 r = MsiSummaryInfoGetPropertyCount(hsi, &count); 2280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2281 ok(count == 14, "Expected 14, got %u\n", count); 2282 2283 r = MsiSummaryInfoGetPropertyA(hsi, PID_CODEPAGE, &type, &int_value, NULL, NULL, NULL); 2284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2285 ok(type == VT_I2, "Expected VT_I2, got %u\n", type); 2286 ok(int_value == 1252, "Expected 1252, got %d\n", int_value); 2287 2288 size = sizeof(str_value); 2289 r = MsiSummaryInfoGetPropertyA(hsi, PID_TITLE, &type, NULL, NULL, str_value, &size); 2290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2291 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2292 ok(size == 18, "Expected 18, got %u\n", size); 2293 ok(!strcmp(str_value, "Installer Database"), 2294 "Expected \"Installer Database\", got %s\n", str_value); 2295 2296 size = sizeof(str_value); 2297 r = MsiSummaryInfoGetPropertyA(hsi, PID_SUBJECT, &type, NULL, NULL, str_value, &size); 2298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2299 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2300 ok(!strcmp(str_value, "Installer description"), 2301 "Expected \"Installer description\", got %s\n", str_value); 2302 2303 size = sizeof(str_value); 2304 r = MsiSummaryInfoGetPropertyA(hsi, PID_AUTHOR, &type, NULL, NULL, str_value, &size); 2305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2306 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2307 ok(!strcmp(str_value, "WineHQ"), 2308 "Expected \"WineHQ\", got %s\n", str_value); 2309 2310 size = sizeof(str_value); 2311 r = MsiSummaryInfoGetPropertyA(hsi, PID_KEYWORDS, &type, NULL, NULL, str_value, &size); 2312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2313 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2314 ok(!strcmp(str_value, "Installer"), 2315 "Expected \"Installer\", got %s\n", str_value); 2316 2317 size = sizeof(str_value); 2318 r = MsiSummaryInfoGetPropertyA(hsi, PID_COMMENTS, &type, NULL, NULL, str_value, &size); 2319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2320 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2321 ok(!strcmp(str_value, "Installer comments"), 2322 "Expected \"Installer comments\", got %s\n", str_value); 2323 2324 size = sizeof(str_value); 2325 r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size); 2326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2327 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2328 ok(!strcmp(str_value, "Intel;1033,2057"), 2329 "Expected \"Intel;1033,2057\", got %s\n", str_value); 2330 2331 size = sizeof(str_value); 2332 r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size); 2333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2334 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2335 ok(!strcmp(str_value, "{12345678-1234-1234-1234-123456789012}"), 2336 "Expected \"{12345678-1234-1234-1234-123456789012}\", got %s\n", str_value); 2337 2338 r = MsiSummaryInfoGetPropertyA(hsi, PID_CREATE_DTM, &type, NULL, &ft_value, NULL, NULL); 2339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2340 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type); 2341 2342 r = MsiSummaryInfoGetPropertyA(hsi, PID_LASTSAVE_DTM, &type, NULL, &ft_value, NULL, NULL); 2343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2344 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type); 2345 2346 r = MsiSummaryInfoGetPropertyA(hsi, PID_PAGECOUNT, &type, &int_value, NULL, NULL, NULL); 2347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2348 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2349 ok(int_value == 200, "Expected 200, got %d\n", int_value); 2350 2351 r = MsiSummaryInfoGetPropertyA(hsi, PID_WORDCOUNT, &type, &int_value, NULL, NULL, NULL); 2352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2353 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2354 ok(int_value == 2, "Expected 2, got %d\n", int_value); 2355 2356 r = MsiSummaryInfoGetPropertyA(hsi, PID_SECURITY, &type, &int_value, NULL, NULL, NULL); 2357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2358 ok(type == VT_I4, "Expected VT_I4, got %u\n", type); 2359 ok(int_value == 2, "Expected 2, got %d\n", int_value); 2360 2361 size = sizeof(str_value); 2362 r = MsiSummaryInfoGetPropertyA(hsi, PID_APPNAME, &type, NULL, NULL, str_value, &size); 2363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 2364 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type); 2365 ok(!strcmp(str_value, "Vim"), "Expected \"Vim\", got %s\n", str_value); 2366 2367 MsiCloseHandle(hsi); 2368 MsiCloseHandle(hdb); 2369 DeleteFileA(msifile); 2370 } 2371 2372 static void test_msiimport(void) 2373 { 2374 MSIHANDLE hdb, view, rec; 2375 LPCSTR query; 2376 UINT r, count; 2377 signed int i; 2378 2379 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 2380 2381 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2383 2384 r = MsiDatabaseImportA(hdb, CURR_DIR, NULL); 2385 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); 2386 2387 r = MsiDatabaseImportA(hdb, CURR_DIR, "nonexistent"); 2388 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2389 2390 r = add_table_to_db(hdb, test_data); 2391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2392 2393 r = add_table_to_db(hdb, two_primary); 2394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2395 2396 r = add_table_to_db(hdb, endlines1); 2397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2398 2399 r = add_table_to_db(hdb, endlines2); 2400 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2401 2402 query = "SELECT * FROM `TestTable`"; 2403 r = MsiDatabaseOpenViewA(hdb, query, &view); 2404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2405 2406 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2408 count = MsiRecordGetFieldCount(rec); 2409 ok(count == 9, "Expected 9, got %d\n", count); 2410 ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n"); 2411 ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n"); 2412 ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n"); 2413 ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n"); 2414 ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n"); 2415 ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n"); 2416 ok(check_record(rec, 7, "String"), "Expected String\n"); 2417 ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n"); 2418 ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n"); 2419 MsiCloseHandle(rec); 2420 2421 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2423 count = MsiRecordGetFieldCount(rec); 2424 ok(count == 9, "Expected 9, got %d\n", count); 2425 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2426 ok(check_record(rec, 2, "i2"), "Expected i2\n"); 2427 ok(check_record(rec, 3, "i2"), "Expected i2\n"); 2428 ok(check_record(rec, 4, "I2"), "Expected I2\n"); 2429 ok(check_record(rec, 5, "i4"), "Expected i4\n"); 2430 ok(check_record(rec, 6, "I4"), "Expected I4\n"); 2431 ok(check_record(rec, 7, "S255"), "Expected S255\n"); 2432 ok(check_record(rec, 8, "S0"), "Expected S0\n"); 2433 ok(check_record(rec, 9, "s0"), "Expected s0\n"); 2434 MsiCloseHandle(rec); 2435 2436 query = "SELECT * FROM `TestTable`"; 2437 r = do_query(hdb, query, &rec); 2438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2439 ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n"); 2440 ok(check_record(rec, 7, "another string"), "Expected 'another string'\n"); 2441 ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n"); 2442 ok(check_record(rec, 9, "duh"), "Expected 'duh'\n"); 2443 2444 i = MsiRecordGetInteger(rec, 2); 2445 ok(i == 5, "Expected 5, got %d\n", i); 2446 2447 i = MsiRecordGetInteger(rec, 3); 2448 ok(i == 2, "Expected 2, got %d\n", i); 2449 2450 i = MsiRecordGetInteger(rec, 4); 2451 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 2452 2453 i = MsiRecordGetInteger(rec, 5); 2454 ok(i == 2147483640, "Expected 2147483640, got %d\n", i); 2455 2456 i = MsiRecordGetInteger(rec, 6); 2457 ok(i == -2147483640, "Expected -2147483640, got %d\n", i); 2458 2459 MsiCloseHandle(rec); 2460 MsiViewClose(view); 2461 MsiCloseHandle(view); 2462 2463 query = "SELECT * FROM `TwoPrimary`"; 2464 r = MsiDatabaseOpenViewA(hdb, query, &view); 2465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2466 2467 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2469 count = MsiRecordGetFieldCount(rec); 2470 ok(count == 2, "Expected 2, got %d\n", count); 2471 ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n"); 2472 ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n"); 2473 2474 MsiCloseHandle(rec); 2475 2476 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2477 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2478 count = MsiRecordGetFieldCount(rec); 2479 ok(count == 2, "Expected 2, got %d\n", count); 2480 ok(check_record(rec, 1, "s255"), "Expected s255\n"); 2481 ok(check_record(rec, 2, "s255"), "Expected s255\n"); 2482 MsiCloseHandle(rec); 2483 2484 r = MsiViewExecute(view, 0); 2485 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2486 2487 r = MsiViewFetch(view, &rec); 2488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2489 2490 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2491 ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n"); 2492 2493 MsiCloseHandle(rec); 2494 2495 r = MsiViewFetch(view, &rec); 2496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2497 2498 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n"); 2499 ok(check_record(rec, 2, "flower"), "Expected 'flower'\n"); 2500 2501 MsiCloseHandle(rec); 2502 2503 r = MsiViewFetch(view, &rec); 2504 ok(r == ERROR_NO_MORE_ITEMS, 2505 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2506 2507 r = MsiViewClose(view); 2508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2509 2510 MsiCloseHandle(view); 2511 2512 query = "SELECT * FROM `Table`"; 2513 r = MsiDatabaseOpenViewA(hdb, query, &view); 2514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2515 2516 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 2517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2518 count = MsiRecordGetFieldCount(rec); 2519 ok(count == 6, "Expected 6, got %d\n", count); 2520 ok(check_record(rec, 1, "A"), "Expected A\n"); 2521 ok(check_record(rec, 2, "B"), "Expected B\n"); 2522 ok(check_record(rec, 3, "C"), "Expected C\n"); 2523 ok(check_record(rec, 4, "D"), "Expected D\n"); 2524 ok(check_record(rec, 5, "E"), "Expected E\n"); 2525 ok(check_record(rec, 6, "F"), "Expected F\n"); 2526 MsiCloseHandle(rec); 2527 2528 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 2529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2530 count = MsiRecordGetFieldCount(rec); 2531 ok(count == 6, "Expected 6, got %d\n", count); 2532 ok(check_record(rec, 1, "s72"), "Expected s72\n"); 2533 ok(check_record(rec, 2, "s72"), "Expected s72\n"); 2534 ok(check_record(rec, 3, "s72"), "Expected s72\n"); 2535 ok(check_record(rec, 4, "s72"), "Expected s72\n"); 2536 ok(check_record(rec, 5, "s72"), "Expected s72\n"); 2537 ok(check_record(rec, 6, "s72"), "Expected s72\n"); 2538 MsiCloseHandle(rec); 2539 2540 MsiViewClose(view); 2541 MsiCloseHandle(view); 2542 2543 query = "SELECT * FROM `Table`"; 2544 r = MsiDatabaseOpenViewA(hdb, query, &view); 2545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2546 2547 r = MsiViewExecute(view, 0); 2548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2549 2550 r = MsiViewFetch(view, &rec); 2551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2552 ok(check_record(rec, 1, "a"), "Expected 'a'\n"); 2553 ok(check_record(rec, 2, "b"), "Expected 'b'\n"); 2554 ok(check_record(rec, 3, "c"), "Expected 'c'\n"); 2555 ok(check_record(rec, 4, "d"), "Expected 'd'\n"); 2556 ok(check_record(rec, 5, "e"), "Expected 'e'\n"); 2557 ok(check_record(rec, 6, "f"), "Expected 'f'\n"); 2558 2559 MsiCloseHandle(rec); 2560 2561 r = MsiViewFetch(view, &rec); 2562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2563 ok(check_record(rec, 1, "g"), "Expected 'g'\n"); 2564 ok(check_record(rec, 2, "h"), "Expected 'h'\n"); 2565 ok(check_record(rec, 3, "i"), "Expected 'i'\n"); 2566 ok(check_record(rec, 4, "j"), "Expected 'j'\n"); 2567 ok(check_record(rec, 5, "k"), "Expected 'k'\n"); 2568 ok(check_record(rec, 6, "l"), "Expected 'l'\n"); 2569 2570 MsiCloseHandle(rec); 2571 2572 r = MsiViewFetch(view, &rec); 2573 ok(r == ERROR_NO_MORE_ITEMS, 2574 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 2575 2576 MsiViewClose(view); 2577 MsiCloseHandle(view); 2578 MsiCloseHandle(hdb); 2579 DeleteFileA(msifile); 2580 } 2581 2582 static const CHAR bin_import_dat[] = "Name\tData\r\n" 2583 "s72\tV0\r\n" 2584 "Binary\tName\r\n" 2585 "filename1\tfilename1.ibd\r\n"; 2586 2587 static void test_binary_import(void) 2588 { 2589 MSIHANDLE hdb = 0, rec; 2590 char file[MAX_PATH]; 2591 char buf[MAX_PATH]; 2592 char path[MAX_PATH]; 2593 DWORD size; 2594 LPCSTR query; 2595 UINT r; 2596 2597 /* create files to import */ 2598 write_file("bin_import.idt", bin_import_dat, 2599 (sizeof(bin_import_dat) - 1) * sizeof(char)); 2600 CreateDirectoryA("bin_import", NULL); 2601 create_file_data("bin_import/filename1.ibd", "just some words", 15); 2602 2603 /* import files into database */ 2604 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 2605 ok( r == ERROR_SUCCESS , "Failed to open database\n"); 2606 2607 GetCurrentDirectoryA(MAX_PATH, path); 2608 r = MsiDatabaseImportA(hdb, path, "bin_import.idt"); 2609 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n"); 2610 2611 /* read file from the Binary table */ 2612 query = "SELECT * FROM `Binary`"; 2613 r = do_query(hdb, query, &rec); 2614 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r); 2615 2616 size = MAX_PATH; 2617 r = MsiRecordGetStringA(rec, 1, file, &size); 2618 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 2619 ok(!lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file); 2620 2621 size = MAX_PATH; 2622 memset(buf, 0, MAX_PATH); 2623 r = MsiRecordReadStream(rec, 2, buf, &size); 2624 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); 2625 ok(!lstrcmpA(buf, "just some words"), "Expected 'just some words', got %s\n", buf); 2626 2627 r = MsiCloseHandle(rec); 2628 ok(r == ERROR_SUCCESS , "Failed to close record handle\n"); 2629 2630 r = MsiCloseHandle(hdb); 2631 ok(r == ERROR_SUCCESS , "Failed to close database\n"); 2632 2633 DeleteFileA("bin_import/filename1.ibd"); 2634 RemoveDirectoryA("bin_import"); 2635 DeleteFileA("bin_import.idt"); 2636 } 2637 2638 static void test_markers(void) 2639 { 2640 MSIHANDLE hdb, rec; 2641 LPCSTR query; 2642 UINT r; 2643 2644 hdb = create_db(); 2645 ok( hdb, "failed to create db\n"); 2646 2647 rec = MsiCreateRecord(3); 2648 MsiRecordSetStringA(rec, 1, "Table"); 2649 MsiRecordSetStringA(rec, 2, "Apples"); 2650 MsiRecordSetStringA(rec, 3, "Oranges"); 2651 2652 /* try a legit create */ 2653 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2654 r = run_query(hdb, 0, query); 2655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2656 MsiCloseHandle(rec); 2657 2658 /* try table name as marker */ 2659 rec = MsiCreateRecord(1); 2660 MsiRecordSetStringA(rec, 1, "Fable"); 2661 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2662 r = run_query(hdb, rec, query); 2663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2664 2665 /* verify that we just created a table called '?', not 'Fable' */ 2666 r = try_query(hdb, "SELECT * from `Fable`"); 2667 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2668 2669 r = try_query(hdb, "SELECT * from `?`"); 2670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2671 2672 /* try table name as marker without backticks */ 2673 MsiRecordSetStringA(rec, 1, "Mable"); 2674 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2675 r = run_query(hdb, rec, query); 2676 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2677 2678 /* try one column name as marker */ 2679 MsiRecordSetStringA(rec, 1, "One"); 2680 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)"; 2681 r = run_query(hdb, rec, query); 2682 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2683 MsiCloseHandle(rec); 2684 2685 /* try column names as markers */ 2686 rec = MsiCreateRecord(2); 2687 MsiRecordSetStringA(rec, 1, "One"); 2688 MsiRecordSetStringA(rec, 2, "Two"); 2689 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)"; 2690 r = run_query(hdb, rec, query); 2691 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2692 MsiCloseHandle(rec); 2693 2694 /* try names with backticks */ 2695 rec = MsiCreateRecord(3); 2696 MsiRecordSetStringA(rec, 1, "One"); 2697 MsiRecordSetStringA(rec, 2, "Two"); 2698 MsiRecordSetStringA(rec, 3, "One"); 2699 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2700 r = run_query(hdb, rec, query); 2701 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2702 2703 /* try names with backticks, minus definitions */ 2704 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)"; 2705 r = run_query(hdb, rec, query); 2706 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2707 2708 /* try names without backticks */ 2709 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)"; 2710 r = run_query(hdb, rec, query); 2711 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2712 MsiCloseHandle(rec); 2713 2714 /* try one long marker */ 2715 rec = MsiCreateRecord(1); 2716 MsiRecordSetStringA(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`"); 2717 query = "CREATE TABLE `Mable` ( ? )"; 2718 r = run_query(hdb, rec, query); 2719 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2720 MsiCloseHandle(rec); 2721 2722 /* try all names as markers */ 2723 rec = MsiCreateRecord(4); 2724 MsiRecordSetStringA(rec, 1, "Mable"); 2725 MsiRecordSetStringA(rec, 2, "One"); 2726 MsiRecordSetStringA(rec, 3, "Two"); 2727 MsiRecordSetStringA(rec, 4, "One"); 2728 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)"; 2729 r = run_query(hdb, rec, query); 2730 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2731 MsiCloseHandle(rec); 2732 2733 /* try a legit insert */ 2734 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )"; 2735 r = run_query(hdb, 0, query); 2736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2737 2738 r = try_query(hdb, "SELECT * from `Table`"); 2739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2740 2741 /* try values as markers */ 2742 rec = MsiCreateRecord(2); 2743 MsiRecordSetInteger(rec, 1, 4); 2744 MsiRecordSetStringA(rec, 2, "hi"); 2745 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2746 r = run_query(hdb, rec, query); 2747 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2748 MsiCloseHandle(rec); 2749 2750 /* try column names and values as markers */ 2751 rec = MsiCreateRecord(4); 2752 MsiRecordSetStringA(rec, 1, "One"); 2753 MsiRecordSetStringA(rec, 2, "Two"); 2754 MsiRecordSetInteger(rec, 3, 5); 2755 MsiRecordSetStringA(rec, 4, "hi"); 2756 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )"; 2757 r = run_query(hdb, rec, query); 2758 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2759 MsiCloseHandle(rec); 2760 2761 /* try column names as markers */ 2762 rec = MsiCreateRecord(2); 2763 MsiRecordSetStringA(rec, 1, "One"); 2764 MsiRecordSetStringA(rec, 2, "Two"); 2765 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )"; 2766 r = run_query(hdb, rec, query); 2767 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2768 MsiCloseHandle(rec); 2769 2770 /* try table name as a marker */ 2771 rec = MsiCreateRecord(1); 2772 MsiRecordSetStringA(rec, 1, "Table"); 2773 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )"; 2774 r = run_query(hdb, rec, query); 2775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2776 MsiCloseHandle(rec); 2777 2778 /* try table name and values as markers */ 2779 rec = MsiCreateRecord(3); 2780 MsiRecordSetStringA(rec, 1, "Table"); 2781 MsiRecordSetInteger(rec, 2, 10); 2782 MsiRecordSetStringA(rec, 3, "haha"); 2783 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2784 r = run_query(hdb, rec, query); 2785 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 2786 MsiCloseHandle(rec); 2787 2788 /* try all markers */ 2789 rec = MsiCreateRecord(5); 2790 MsiRecordSetStringA(rec, 1, "Table"); 2791 MsiRecordSetStringA(rec, 1, "One"); 2792 MsiRecordSetStringA(rec, 1, "Two"); 2793 MsiRecordSetInteger(rec, 2, 10); 2794 MsiRecordSetStringA(rec, 3, "haha"); 2795 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )"; 2796 r = run_query(hdb, rec, query); 2797 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 2798 MsiCloseHandle(rec); 2799 2800 /* insert an integer as a string */ 2801 rec = MsiCreateRecord(2); 2802 MsiRecordSetStringA(rec, 1, "11"); 2803 MsiRecordSetStringA(rec, 2, "hi"); 2804 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )"; 2805 r = run_query(hdb, rec, query); 2806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2807 MsiCloseHandle(rec); 2808 2809 /* leave off the '' for the string */ 2810 rec = MsiCreateRecord(2); 2811 MsiRecordSetInteger(rec, 1, 12); 2812 MsiRecordSetStringA(rec, 2, "hi"); 2813 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )"; 2814 r = run_query(hdb, rec, query); 2815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 2816 MsiCloseHandle(rec); 2817 2818 MsiCloseHandle(hdb); 2819 DeleteFileA(msifile); 2820 } 2821 2822 #define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2000 */ 2823 static void test_handle_limit(void) 2824 { 2825 int i; 2826 MSIHANDLE hdb; 2827 MSIHANDLE hviews[MY_NVIEWS]; 2828 UINT r; 2829 2830 /* create an empty db */ 2831 hdb = create_db(); 2832 ok( hdb, "failed to create db\n"); 2833 2834 memset(hviews, 0, sizeof(hviews)); 2835 2836 for (i=0; i<MY_NVIEWS; i++) { 2837 static char szQueryBuf[256] = "SELECT * from `_Tables`"; 2838 hviews[i] = 0xdeadbeeb; 2839 r = MsiDatabaseOpenViewA(hdb, szQueryBuf, &hviews[i]); 2840 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb || 2841 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1]))) 2842 break; 2843 } 2844 2845 ok( i == MY_NVIEWS, "problem opening views\n"); 2846 2847 for (i=0; i<MY_NVIEWS; i++) { 2848 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) { 2849 MsiViewClose(hviews[i]); 2850 r = MsiCloseHandle(hviews[i]); 2851 if (r != ERROR_SUCCESS) 2852 break; 2853 } 2854 } 2855 2856 ok( i == MY_NVIEWS, "problem closing views\n"); 2857 2858 r = MsiCloseHandle(hdb); 2859 ok( r == ERROR_SUCCESS, "failed to close database\n"); 2860 } 2861 2862 static void generate_transform(void) 2863 { 2864 MSIHANDLE hdb1, hdb2, hrec; 2865 LPCSTR query; 2866 UINT r; 2867 2868 /* start with two identical databases */ 2869 CopyFileA(msifile2, msifile, FALSE); 2870 2871 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb1 ); 2872 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2873 2874 r = MsiDatabaseCommit( hdb1 ); 2875 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 2876 2877 r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_READONLY, &hdb2 ); 2878 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 2879 2880 /* the transform between two identical database should be empty */ 2881 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, NULL, 0, 0); 2882 todo_wine { 2883 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r ); 2884 } 2885 2886 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)"; 2887 r = run_query(hdb1, 0, query); 2888 ok(r == ERROR_SUCCESS, "failed to add table\n"); 2889 2890 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )"; 2891 r = run_query(hdb1, 0, query); 2892 ok(r == ERROR_SUCCESS, "failed to add row 1\n"); 2893 2894 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )"; 2895 r = run_query(hdb1, 0, query); 2896 ok(r == ERROR_SUCCESS, "failed to add row 2\n"); 2897 2898 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1"; 2899 r = run_query(hdb1, 0, query); 2900 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2901 2902 query = "DELETE FROM `MOO` WHERE `NOO` = 3"; 2903 r = run_query(hdb1, 0, query); 2904 ok(r == ERROR_SUCCESS, "failed to delete row\n"); 2905 2906 hrec = MsiCreateRecord(2); 2907 r = MsiRecordSetInteger(hrec, 1, 1); 2908 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 2909 2910 write_file("testdata.bin", "naengmyon", 9); 2911 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 2912 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 2913 2914 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 2915 r = run_query(hdb1, hrec, query); 2916 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 2917 2918 MsiCloseHandle(hrec); 2919 2920 query = "ALTER TABLE `MOO` ADD `COW` INTEGER"; 2921 r = run_query(hdb1, 0, query); 2922 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2923 2924 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER"; 2925 r = run_query(hdb1, 0, query); 2926 ok(r == ERROR_SUCCESS, "failed to add column\n"); 2927 2928 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1"; 2929 r = run_query(hdb1, 0, query); 2930 ok(r == ERROR_SUCCESS, "failed to modify row\n"); 2931 2932 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, " 2933 "`Value` CHAR(0) PRIMARY KEY `Property`)"; 2934 r = run_query(hdb1, 0, query); 2935 ok(r == ERROR_SUCCESS, "failed to add property table\n"); 2936 2937 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )"; 2938 r = run_query(hdb1, 0, query); 2939 ok(r == ERROR_SUCCESS, "failed to add property\n"); 2940 2941 /* database needs to be committed */ 2942 MsiDatabaseCommit(hdb1); 2943 2944 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, mstfile, 0, 0); 2945 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 2946 2947 MsiCloseHandle( hdb1 ); 2948 MsiCloseHandle( hdb2 ); 2949 2950 DeleteFileA("testdata.bin"); 2951 } 2952 2953 /* data for generating a transform */ 2954 2955 /* tables transform names - encoded as they would be in an msi database file */ 2956 static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */ 2957 static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */ 2958 static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */ 2959 static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */ 2960 static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */ 2961 static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 2962 static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */ 2963 static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */ 2964 static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */ 2965 2966 /* data in each table */ 2967 static const WCHAR data1[] = { /* AAR */ 2968 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */ 2969 0x0201, 0x0009, 0x8002, 2970 }; 2971 static const WCHAR data2[] = { /* _Columns */ 2972 0x0401, 0x0001, 0x8003, 0x0002, 0x9502, 2973 0x0401, 0x0001, 0x8004, 0x0003, 0x9502, 2974 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */ 2975 0x0401, 0x0005, 0x0000, 0x0007, 0x8502, 2976 0x0401, 0x000a, 0x0000, 0x000a, 0xad48, 2977 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00, 2978 }; 2979 static const WCHAR data3[] = { /* _Tables */ 2980 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */ 2981 0x0101, 0x000a, 2982 }; 2983 static const char data4[] = /* _StringData */ 2984 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */ 2985 static const WCHAR data5[] = { /* _StringPool */ 2986 /* len, refs */ 2987 0, 0, /* string 0 '' */ 2988 3, 2, /* string 1 'MOO' */ 2989 3, 1, /* string 2 'COW' */ 2990 3, 1, /* string 3 'PIG' */ 2991 1, 1, /* string 4 'c' */ 2992 3, 3, /* string 5 'AAR' */ 2993 3, 1, /* string 6 'CAR' */ 2994 3, 1, /* string 7 'BAR' */ 2995 2, 1, /* string 8 'vw' */ 2996 3, 1, /* string 9 'bmw' */ 2997 8, 4, /* string 10 'Property' */ 2998 5, 1, /* string 11 'Value' */ 2999 4, 1, /* string 12 'prop' */ 3000 3, 1, /* string 13 'val' */ 3001 }; 3002 /* update row, 0x0002 is a bitmask of present column data, keys are excluded */ 3003 static const WCHAR data6[] = { /* MOO */ 3004 0x000a, 0x8001, 0x0004, 0x8005, /* update row */ 3005 0x0000, 0x8003, /* delete row */ 3006 }; 3007 3008 static const WCHAR data7[] = { /* BINARY */ 3009 0x0201, 0x8001, 0x0001, 3010 }; 3011 3012 static const char data8[] = /* stream data for the BINARY table */ 3013 "naengmyon"; 3014 3015 static const WCHAR data9[] = { /* Property */ 3016 0x0201, 0x000c, 0x000d, 3017 }; 3018 3019 static const struct { 3020 LPCWSTR name; 3021 const void *data; 3022 DWORD size; 3023 } table_transform_data[] = 3024 { 3025 { name1, data1, sizeof data1 }, 3026 { name2, data2, sizeof data2 }, 3027 { name3, data3, sizeof data3 }, 3028 { name4, data4, sizeof data4 - 1 }, 3029 { name5, data5, sizeof data5 }, 3030 { name6, data6, sizeof data6 }, 3031 { name7, data7, sizeof data7 }, 3032 { name8, data8, sizeof data8 - 1 }, 3033 { name9, data9, sizeof data9 }, 3034 }; 3035 3036 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0]) 3037 3038 static void generate_transform_manual(void) 3039 { 3040 IStorage *stg = NULL; 3041 IStream *stm; 3042 WCHAR name[0x20]; 3043 HRESULT r; 3044 DWORD i, count; 3045 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE; 3046 3047 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}}; 3048 3049 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20); 3050 3051 r = StgCreateDocfile(name, mode, 0, &stg); 3052 ok(r == S_OK, "failed to create storage\n"); 3053 if (!stg) 3054 return; 3055 3056 r = IStorage_SetClass( stg, &CLSID_MsiTransform ); 3057 ok(r == S_OK, "failed to set storage type\n"); 3058 3059 for (i=0; i<NUM_TRANSFORM_TABLES; i++) 3060 { 3061 r = IStorage_CreateStream( stg, table_transform_data[i].name, 3062 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm ); 3063 if (FAILED(r)) 3064 { 3065 ok(0, "failed to create stream %08x\n", r); 3066 continue; 3067 } 3068 3069 r = IStream_Write( stm, table_transform_data[i].data, 3070 table_transform_data[i].size, &count ); 3071 if (FAILED(r) || count != table_transform_data[i].size) 3072 ok(0, "failed to write stream\n"); 3073 IStream_Release(stm); 3074 } 3075 3076 IStorage_Release(stg); 3077 } 3078 3079 static UINT set_summary_info(MSIHANDLE hdb) 3080 { 3081 UINT res; 3082 MSIHANDLE suminfo; 3083 3084 /* build summary info */ 3085 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); 3086 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); 3087 3088 res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, 3089 "Installation Database"); 3090 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3091 3092 res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, 3093 "Installation Database"); 3094 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3095 3096 res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, 3097 "Wine Hackers"); 3098 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3099 3100 res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, 3101 ";1033,2057"); 3102 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3103 3104 res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, 3105 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); 3106 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3107 3108 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); 3109 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3110 3111 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); 3112 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3113 3114 res = MsiSummaryInfoPersist(suminfo); 3115 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); 3116 3117 res = MsiCloseHandle( suminfo); 3118 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); 3119 3120 return res; 3121 } 3122 3123 static MSIHANDLE create_package_db(const WCHAR *filename) 3124 { 3125 MSIHANDLE hdb = 0; 3126 UINT res; 3127 3128 DeleteFileW(msifileW); 3129 3130 /* create an empty database */ 3131 res = MsiOpenDatabaseW(filename, MSIDBOPEN_CREATE, &hdb ); 3132 ok( res == ERROR_SUCCESS , "Failed to create database\n" ); 3133 if( res != ERROR_SUCCESS ) 3134 return hdb; 3135 3136 res = MsiDatabaseCommit( hdb ); 3137 ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); 3138 3139 res = set_summary_info(hdb); 3140 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); 3141 3142 create_directory_table(hdb); 3143 3144 return hdb; 3145 } 3146 3147 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) 3148 { 3149 UINT res; 3150 CHAR szPackage[12]; 3151 MSIHANDLE hPackage; 3152 3153 sprintf(szPackage, "#%u", hdb); 3154 res = MsiOpenPackageA(szPackage, &hPackage); 3155 if (res != ERROR_SUCCESS) 3156 return res; 3157 3158 res = MsiCloseHandle(hdb); 3159 if (res != ERROR_SUCCESS) 3160 { 3161 MsiCloseHandle(hPackage); 3162 return res; 3163 } 3164 3165 *handle = hPackage; 3166 return ERROR_SUCCESS; 3167 } 3168 3169 static void test_try_transform(void) 3170 { 3171 MSIHANDLE hdb, hview, hrec, hpkg = 0; 3172 LPCSTR query; 3173 UINT r; 3174 DWORD sz; 3175 char buffer[MAX_PATH]; 3176 3177 DeleteFileA(msifile); 3178 DeleteFileA(mstfile); 3179 3180 /* create the database */ 3181 hdb = create_package_db(msifileW); 3182 ok(hdb, "Failed to create package db\n"); 3183 3184 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)"; 3185 r = run_query(hdb, 0, query); 3186 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3187 3188 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )"; 3189 r = run_query(hdb, 0, query); 3190 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3191 3192 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )"; 3193 r = run_query(hdb, 0, query); 3194 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3195 3196 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )"; 3197 r = run_query(hdb, 0, query); 3198 ok(r == ERROR_SUCCESS, "failed to add row\n"); 3199 3200 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)"; 3201 r = run_query(hdb, 0, query); 3202 ok(r == ERROR_SUCCESS, "failed to add table\n"); 3203 3204 hrec = MsiCreateRecord(2); 3205 r = MsiRecordSetInteger(hrec, 1, 2); 3206 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 3207 3208 write_file("testdata.bin", "lamyon", 6); 3209 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin"); 3210 ok(r == ERROR_SUCCESS, "failed to set stream\n"); 3211 3212 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )"; 3213 r = run_query(hdb, hrec, query); 3214 ok(r == ERROR_SUCCESS, "failed to add row with blob\n"); 3215 3216 MsiCloseHandle(hrec); 3217 3218 r = MsiDatabaseCommit( hdb ); 3219 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3220 3221 MsiCloseHandle( hdb ); 3222 DeleteFileA("testdata.bin"); 3223 3224 /* 3225 * Both these generate an equivalent transform, 3226 * but the first doesn't work in Wine yet 3227 * because MsiDatabaseGenerateTransform is unimplemented. 3228 */ 3229 if (0) 3230 generate_transform(); 3231 else 3232 generate_transform_manual(); 3233 3234 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb ); 3235 ok( r == ERROR_SUCCESS , "Failed to create database\n" ); 3236 3237 r = MsiDatabaseApplyTransformA( hdb, mstfile, 0 ); 3238 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r ); 3239 3240 r = MsiDatabaseCommit( hdb ); 3241 ok( r == ERROR_SUCCESS , "Failed to commit database\n" ); 3242 3243 /* check new values */ 3244 hrec = 0; 3245 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'"; 3246 r = do_query(hdb, query, &hrec); 3247 ok(r == ERROR_SUCCESS, "select query failed\n"); 3248 MsiCloseHandle(hrec); 3249 3250 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'"; 3251 hrec = 0; 3252 r = do_query(hdb, query, &hrec); 3253 ok(r == ERROR_SUCCESS, "select query failed\n"); 3254 MsiCloseHandle(hrec); 3255 3256 /* check updated values */ 3257 hrec = 0; 3258 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'"; 3259 r = do_query(hdb, query, &hrec); 3260 ok(r == ERROR_SUCCESS, "select query failed\n"); 3261 MsiCloseHandle(hrec); 3262 3263 /* check unchanged value */ 3264 hrec = 0; 3265 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'"; 3266 r = do_query(hdb, query, &hrec); 3267 ok(r == ERROR_SUCCESS, "select query failed\n"); 3268 MsiCloseHandle(hrec); 3269 3270 /* check deleted value */ 3271 hrec = 0; 3272 query = "select * from `MOO` where `NOO` = 3"; 3273 r = do_query(hdb, query, &hrec); 3274 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n"); 3275 if (hrec) MsiCloseHandle(hrec); 3276 3277 /* check added stream */ 3278 hrec = 0; 3279 query = "select `BLOB` from `BINARY` where `ID` = 1"; 3280 r = do_query(hdb, query, &hrec); 3281 ok(r == ERROR_SUCCESS, "select query failed\n"); 3282 3283 /* check the contents of the stream */ 3284 sz = sizeof buffer; 3285 r = MsiRecordReadStream( hrec, 1, buffer, &sz ); 3286 ok(r == ERROR_SUCCESS, "read stream failed\n"); 3287 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n"); 3288 ok(sz == 9, "stream data was wrong size\n"); 3289 if (hrec) MsiCloseHandle(hrec); 3290 3291 /* check the validity of the table with a deleted row */ 3292 hrec = 0; 3293 query = "select * from `MOO`"; 3294 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3295 ok(r == ERROR_SUCCESS, "open view failed\n"); 3296 3297 r = MsiViewExecute(hview, 0); 3298 ok(r == ERROR_SUCCESS, "view execute failed\n"); 3299 3300 r = MsiViewFetch(hview, &hrec); 3301 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3302 3303 r = MsiRecordGetInteger(hrec, 1); 3304 ok(r == 1, "Expected 1, got %d\n", r); 3305 3306 sz = sizeof buffer; 3307 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3308 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3309 ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer); 3310 3311 r = MsiRecordGetInteger(hrec, 3); 3312 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3313 3314 r = MsiRecordGetInteger(hrec, 4); 3315 ok(r == 5, "Expected 5, got %d\n", r); 3316 3317 MsiCloseHandle(hrec); 3318 3319 r = MsiViewFetch(hview, &hrec); 3320 ok(r == ERROR_SUCCESS, "view fetch failed\n"); 3321 3322 r = MsiRecordGetInteger(hrec, 1); 3323 ok(r == 2, "Expected 2, got %d\n", r); 3324 3325 sz = sizeof buffer; 3326 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 3327 ok(r == ERROR_SUCCESS, "record get string failed\n"); 3328 ok(!lstrcmpA(buffer, "b"), "Expected b, got %s\n", buffer); 3329 3330 r = MsiRecordGetInteger(hrec, 3); 3331 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3332 3333 r = MsiRecordGetInteger(hrec, 4); 3334 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r); 3335 3336 MsiCloseHandle(hrec); 3337 3338 r = MsiViewFetch(hview, &hrec); 3339 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n"); 3340 3341 MsiCloseHandle(hrec); 3342 MsiViewClose(hview); 3343 MsiCloseHandle(hview); 3344 3345 /* check that the property was added */ 3346 r = package_from_db(hdb, &hpkg); 3347 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 3348 { 3349 skip("Not enough rights to perform tests\n"); 3350 goto error; 3351 } 3352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); 3353 3354 sz = MAX_PATH; 3355 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz); 3356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 3357 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer); 3358 3359 MsiCloseHandle(hpkg); 3360 3361 error: 3362 MsiCloseHandle(hdb); 3363 DeleteFileA(msifile); 3364 DeleteFileA(mstfile); 3365 } 3366 3367 struct join_res 3368 { 3369 const CHAR one[MAX_PATH]; 3370 const CHAR two[MAX_PATH]; 3371 }; 3372 3373 struct join_res_4col 3374 { 3375 const CHAR one[MAX_PATH]; 3376 const CHAR two[MAX_PATH]; 3377 const CHAR three[MAX_PATH]; 3378 const CHAR four[MAX_PATH]; 3379 }; 3380 3381 struct join_res_uint 3382 { 3383 UINT one; 3384 UINT two; 3385 UINT three; 3386 UINT four; 3387 UINT five; 3388 UINT six; 3389 }; 3390 3391 static const struct join_res join_res_first[] = 3392 { 3393 { "alveolar", "procerus" }, 3394 { "septum", "procerus" }, 3395 { "septum", "nasalis" }, 3396 { "ramus", "nasalis" }, 3397 { "malar", "mentalis" }, 3398 }; 3399 3400 static const struct join_res join_res_second[] = 3401 { 3402 { "nasal", "septum" }, 3403 { "mandible", "ramus" }, 3404 }; 3405 3406 static const struct join_res join_res_third[] = 3407 { 3408 { "msvcp.dll", "abcdefgh" }, 3409 { "msvcr.dll", "ijklmnop" }, 3410 }; 3411 3412 static const struct join_res join_res_fourth[] = 3413 { 3414 { "msvcp.dll.01234", "single.dll.31415" }, 3415 }; 3416 3417 static const struct join_res join_res_fifth[] = 3418 { 3419 { "malar", "procerus" }, 3420 }; 3421 3422 static const struct join_res join_res_sixth[] = 3423 { 3424 { "malar", "procerus" }, 3425 { "malar", "procerus" }, 3426 { "malar", "nasalis" }, 3427 { "malar", "nasalis" }, 3428 { "malar", "nasalis" }, 3429 { "malar", "mentalis" }, 3430 }; 3431 3432 static const struct join_res join_res_seventh[] = 3433 { 3434 { "malar", "nasalis" }, 3435 { "malar", "nasalis" }, 3436 { "malar", "nasalis" }, 3437 }; 3438 3439 static const struct join_res_4col join_res_eighth[] = 3440 { 3441 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" }, 3442 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" }, 3443 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" }, 3444 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" }, 3445 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" }, 3446 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" }, 3447 }; 3448 3449 static const struct join_res_uint join_res_ninth[] = 3450 { 3451 { 1, 2, 3, 4, 7, 8 }, 3452 { 1, 2, 5, 6, 7, 8 }, 3453 { 1, 2, 3, 4, 9, 10 }, 3454 { 1, 2, 5, 6, 9, 10 }, 3455 { 1, 2, 3, 4, 11, 12 }, 3456 { 1, 2, 5, 6, 11, 12 }, 3457 }; 3458 3459 static void test_join(void) 3460 { 3461 MSIHANDLE hdb, hview, hrec; 3462 LPCSTR query; 3463 CHAR buf[MAX_PATH]; 3464 UINT r, count; 3465 DWORD size, i; 3466 BOOL data_correct; 3467 3468 hdb = create_db(); 3469 ok( hdb, "failed to create db\n"); 3470 3471 create_component_table( hdb ); 3472 add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" ); 3473 add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" ); 3474 add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" ); 3475 add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" ); 3476 3477 create_feature_components_table( hdb ); 3478 add_feature_components_entry( hdb, "'procerus', 'maxilla'" ); 3479 add_feature_components_entry( hdb, "'procerus', 'nasal'" ); 3480 add_feature_components_entry( hdb, "'nasalis', 'nasal'" ); 3481 add_feature_components_entry( hdb, "'nasalis', 'mandible'" ); 3482 add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" ); 3483 add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" ); 3484 3485 create_std_dlls_table( hdb ); 3486 add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" ); 3487 add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" ); 3488 3489 create_binary_table( hdb ); 3490 add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" ); 3491 add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" ); 3492 add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" ); 3493 3494 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 3495 r = run_query( hdb, 0, query); 3496 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3497 3498 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)"; 3499 r = run_query( hdb, 0, query); 3500 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3501 3502 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)"; 3503 r = run_query( hdb, 0, query); 3504 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3505 3506 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)"; 3507 r = run_query( hdb, 0, query); 3508 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3509 3510 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)"; 3511 r = run_query( hdb, 0, query); 3512 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3513 3514 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)"; 3515 r = run_query( hdb, 0, query); 3516 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3517 3518 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)"; 3519 r = run_query( hdb, 0, query); 3520 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3521 3522 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)"; 3523 r = run_query( hdb, 0, query); 3524 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3525 3526 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)"; 3527 r = run_query( hdb, 0, query); 3528 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3529 3530 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)"; 3531 r = run_query( hdb, 0, query); 3532 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3533 3534 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)"; 3535 r = run_query( hdb, 0, query); 3536 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r ); 3537 3538 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)"; 3539 r = run_query( hdb, 0, query); 3540 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3541 3542 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)"; 3543 r = run_query( hdb, 0, query); 3544 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r ); 3545 3546 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3547 "FROM `Component`, `FeatureComponents` " 3548 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 3549 "ORDER BY `Feature_`"; 3550 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3551 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3552 3553 r = MsiViewExecute(hview, 0); 3554 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3555 3556 i = 0; 3557 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3558 { 3559 count = MsiRecordGetFieldCount( hrec ); 3560 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3561 3562 size = MAX_PATH; 3563 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3564 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3565 ok( !lstrcmpA( buf, join_res_first[i].one ), 3566 "For (row %d, column 1) expected '%s', got %s\n", i, join_res_first[i].one, buf ); 3567 3568 size = MAX_PATH; 3569 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3570 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3571 ok( !lstrcmpA( buf, join_res_first[i].two ), 3572 "For (row %d, column 2) expected '%s', got %s\n", i, join_res_first[i].two, buf ); 3573 3574 i++; 3575 MsiCloseHandle(hrec); 3576 } 3577 3578 ok( i == 5, "Expected 5 rows, got %d\n", i ); 3579 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3580 3581 MsiViewClose(hview); 3582 MsiCloseHandle(hview); 3583 3584 /* try a join without a WHERE condition */ 3585 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3586 "FROM `Component`, `FeatureComponents` "; 3587 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3588 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3589 3590 r = MsiViewExecute(hview, 0); 3591 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3592 3593 i = 0; 3594 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3595 { 3596 i++; 3597 MsiCloseHandle(hrec); 3598 } 3599 ok( i == 24, "Expected 24 rows, got %d\n", i ); 3600 3601 MsiViewClose(hview); 3602 MsiCloseHandle(hview); 3603 3604 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component " 3605 "WHERE FeatureComponents.Component_=Component.Component " 3606 "AND (Feature_='nasalis') ORDER BY Feature_"; 3607 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3608 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3609 3610 r = MsiViewExecute(hview, 0); 3611 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3612 3613 i = 0; 3614 data_correct = TRUE; 3615 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3616 { 3617 count = MsiRecordGetFieldCount( hrec ); 3618 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3619 3620 size = MAX_PATH; 3621 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3622 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3623 if( lstrcmpA( buf, join_res_second[i].one )) 3624 data_correct = FALSE; 3625 3626 size = MAX_PATH; 3627 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3628 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3629 if( lstrcmpA( buf, join_res_second[i].two )) 3630 data_correct = FALSE; 3631 3632 i++; 3633 MsiCloseHandle(hrec); 3634 } 3635 3636 ok( data_correct, "data returned in the wrong order\n"); 3637 3638 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3639 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3640 3641 MsiViewClose(hview); 3642 MsiCloseHandle(hview); 3643 3644 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3645 "FROM `StdDlls`, `Binary` " 3646 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` " 3647 "ORDER BY `File`"; 3648 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3649 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3650 3651 r = MsiViewExecute(hview, 0); 3652 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3653 3654 i = 0; 3655 data_correct = TRUE; 3656 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3657 { 3658 count = MsiRecordGetFieldCount( hrec ); 3659 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3660 3661 size = MAX_PATH; 3662 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3663 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3664 if( lstrcmpA( buf, join_res_third[i].one ) ) 3665 data_correct = FALSE; 3666 3667 size = MAX_PATH; 3668 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3669 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3670 if( lstrcmpA( buf, join_res_third[i].two ) ) 3671 data_correct = FALSE; 3672 3673 i++; 3674 MsiCloseHandle(hrec); 3675 } 3676 ok( data_correct, "data returned in the wrong order\n"); 3677 3678 ok( i == 2, "Expected 2 rows, got %d\n", i ); 3679 3680 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3681 3682 MsiViewClose(hview); 3683 MsiCloseHandle(hview); 3684 3685 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` " 3686 "FROM `StdDlls`, `Binary` " 3687 "WHERE `StdDlls`.`File` = `Binary`.`Data` " 3688 "ORDER BY `Name`"; 3689 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3690 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3691 3692 r = MsiViewExecute(hview, 0); 3693 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3694 3695 i = 0; 3696 data_correct = TRUE; 3697 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3698 { 3699 count = MsiRecordGetFieldCount( hrec ); 3700 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3701 3702 size = MAX_PATH; 3703 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3704 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3705 if( lstrcmpA( buf, join_res_fourth[i].one )) 3706 data_correct = FALSE; 3707 3708 size = MAX_PATH; 3709 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3710 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3711 if( lstrcmpA( buf, join_res_fourth[i].two )) 3712 data_correct = FALSE; 3713 3714 i++; 3715 MsiCloseHandle(hrec); 3716 } 3717 ok( data_correct, "data returned in the wrong order\n"); 3718 3719 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3720 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3721 3722 MsiViewClose(hview); 3723 MsiCloseHandle(hview); 3724 3725 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3726 "FROM `Component`, `FeatureComponents` " 3727 "WHERE `Component`.`Component` = 'zygomatic' " 3728 "AND `FeatureComponents`.`Component_` = 'maxilla' " 3729 "ORDER BY `Feature_`"; 3730 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3731 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3732 3733 r = MsiViewExecute(hview, 0); 3734 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3735 3736 i = 0; 3737 data_correct = TRUE; 3738 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3739 { 3740 count = MsiRecordGetFieldCount( hrec ); 3741 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3742 3743 size = MAX_PATH; 3744 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3745 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3746 if( lstrcmpA( buf, join_res_fifth[i].one )) 3747 data_correct = FALSE; 3748 3749 size = MAX_PATH; 3750 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3751 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3752 if( lstrcmpA( buf, join_res_fifth[i].two )) 3753 data_correct = FALSE; 3754 3755 i++; 3756 MsiCloseHandle(hrec); 3757 } 3758 ok( data_correct, "data returned in the wrong order\n"); 3759 3760 ok( i == 1, "Expected 1 rows, got %d\n", i ); 3761 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3762 3763 MsiViewClose(hview); 3764 MsiCloseHandle(hview); 3765 3766 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3767 "FROM `Component`, `FeatureComponents` " 3768 "WHERE `Component` = 'zygomatic' " 3769 "ORDER BY `Feature_`"; 3770 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3771 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3772 3773 r = MsiViewExecute(hview, 0); 3774 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3775 3776 i = 0; 3777 data_correct = TRUE; 3778 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3779 { 3780 count = MsiRecordGetFieldCount( hrec ); 3781 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3782 3783 size = MAX_PATH; 3784 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3785 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3786 if( lstrcmpA( buf, join_res_sixth[i].one )) 3787 data_correct = FALSE; 3788 3789 size = MAX_PATH; 3790 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3791 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3792 if( lstrcmpA( buf, join_res_sixth[i].two )) 3793 data_correct = FALSE; 3794 3795 i++; 3796 MsiCloseHandle(hrec); 3797 } 3798 ok( data_correct, "data returned in the wrong order\n"); 3799 3800 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3801 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3802 3803 MsiViewClose(hview); 3804 MsiCloseHandle(hview); 3805 3806 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 3807 "FROM `Component`, `FeatureComponents` " 3808 "WHERE `Component` = 'zygomatic' " 3809 "AND `Feature_` = 'nasalis' " 3810 "ORDER BY `Feature_`"; 3811 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3812 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3813 3814 r = MsiViewExecute(hview, 0); 3815 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3816 3817 i = 0; 3818 data_correct = TRUE; 3819 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3820 { 3821 count = MsiRecordGetFieldCount( hrec ); 3822 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3823 3824 size = MAX_PATH; 3825 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3826 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3827 if( lstrcmpA( buf, join_res_seventh[i].one )) 3828 data_correct = FALSE; 3829 3830 size = MAX_PATH; 3831 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3832 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3833 if( lstrcmpA( buf, join_res_seventh[i].two )) 3834 data_correct = FALSE; 3835 3836 i++; 3837 MsiCloseHandle(hrec); 3838 } 3839 3840 ok( data_correct, "data returned in the wrong order\n"); 3841 ok( i == 3, "Expected 3 rows, got %d\n", i ); 3842 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3843 3844 MsiViewClose(hview); 3845 MsiCloseHandle(hview); 3846 3847 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` " 3848 "FROM `StdDlls`, `Binary` "; 3849 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3850 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3851 3852 r = MsiViewExecute(hview, 0); 3853 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3854 3855 i = 0; 3856 data_correct = TRUE; 3857 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3858 { 3859 count = MsiRecordGetFieldCount( hrec ); 3860 ok( count == 2, "Expected 2 record fields, got %d\n", count ); 3861 3862 size = MAX_PATH; 3863 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3864 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3865 if( lstrcmpA( buf, join_res_eighth[i].one )) 3866 data_correct = FALSE; 3867 3868 size = MAX_PATH; 3869 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3870 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3871 if( lstrcmpA( buf, join_res_eighth[i].four )) 3872 data_correct = FALSE; 3873 3874 i++; 3875 MsiCloseHandle(hrec); 3876 } 3877 3878 ok( data_correct, "data returned in the wrong order\n"); 3879 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3880 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3881 3882 MsiViewClose(hview); 3883 MsiCloseHandle(hview); 3884 3885 query = "SELECT * FROM `StdDlls`, `Binary` "; 3886 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3887 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3888 3889 r = MsiViewExecute(hview, 0); 3890 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3891 3892 i = 0; 3893 data_correct = TRUE; 3894 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3895 { 3896 count = MsiRecordGetFieldCount( hrec ); 3897 ok( count == 4, "Expected 4 record fields, got %d\n", count ); 3898 3899 size = MAX_PATH; 3900 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 3901 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3902 if( lstrcmpA( buf, join_res_eighth[i].one )) 3903 data_correct = FALSE; 3904 3905 size = MAX_PATH; 3906 r = MsiRecordGetStringA( hrec, 2, buf, &size ); 3907 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3908 if( lstrcmpA( buf, join_res_eighth[i].two )) 3909 data_correct = FALSE; 3910 3911 size = MAX_PATH; 3912 r = MsiRecordGetStringA( hrec, 3, buf, &size ); 3913 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3914 if( lstrcmpA( buf, join_res_eighth[i].three )) 3915 data_correct = FALSE; 3916 3917 size = MAX_PATH; 3918 r = MsiRecordGetStringA( hrec, 4, buf, &size ); 3919 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 3920 if( lstrcmpA( buf, join_res_eighth[i].four )) 3921 data_correct = FALSE; 3922 3923 i++; 3924 MsiCloseHandle(hrec); 3925 } 3926 ok( data_correct, "data returned in the wrong order\n"); 3927 3928 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3929 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3930 3931 MsiViewClose(hview); 3932 MsiCloseHandle(hview); 3933 3934 query = "SELECT * FROM `One`, `Two`, `Three` "; 3935 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3936 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3937 3938 r = MsiViewExecute(hview, 0); 3939 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3940 3941 i = 0; 3942 data_correct = TRUE; 3943 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS) 3944 { 3945 count = MsiRecordGetFieldCount( hrec ); 3946 ok( count == 6, "Expected 6 record fields, got %d\n", count ); 3947 3948 r = MsiRecordGetInteger( hrec, 1 ); 3949 if( r != join_res_ninth[i].one ) 3950 data_correct = FALSE; 3951 3952 r = MsiRecordGetInteger( hrec, 2 ); 3953 if( r != join_res_ninth[i].two ) 3954 data_correct = FALSE; 3955 3956 r = MsiRecordGetInteger( hrec, 3 ); 3957 if( r != join_res_ninth[i].three ) 3958 data_correct = FALSE; 3959 3960 r = MsiRecordGetInteger( hrec, 4 ); 3961 if( r != join_res_ninth[i].four ) 3962 data_correct = FALSE; 3963 3964 r = MsiRecordGetInteger( hrec, 5 ); 3965 if( r != join_res_ninth[i].five ) 3966 data_correct = FALSE; 3967 3968 r = MsiRecordGetInteger( hrec, 6); 3969 if( r != join_res_ninth[i].six ) 3970 data_correct = FALSE; 3971 3972 i++; 3973 MsiCloseHandle(hrec); 3974 } 3975 ok( data_correct, "data returned in the wrong order\n"); 3976 3977 ok( i == 6, "Expected 6 rows, got %d\n", i ); 3978 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r ); 3979 3980 MsiViewClose(hview); 3981 MsiCloseHandle(hview); 3982 3983 query = "SELECT * FROM `Four`, `Five`"; 3984 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3985 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 3986 3987 r = MsiViewExecute(hview, 0); 3988 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 3989 3990 r = MsiViewFetch(hview, &hrec); 3991 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 3992 3993 MsiViewClose(hview); 3994 MsiCloseHandle(hview); 3995 3996 query = "SELECT * FROM `Nonexistent`, `One`"; 3997 r = MsiDatabaseOpenViewA(hdb, query, &hview); 3998 ok( r == ERROR_BAD_QUERY_SYNTAX, 3999 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r ); 4000 4001 /* try updating a row in a join table */ 4002 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` " 4003 "FROM `Component`, `FeatureComponents` " 4004 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` " 4005 "ORDER BY `Feature_`"; 4006 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4007 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); 4008 4009 r = MsiViewExecute(hview, 0); 4010 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); 4011 4012 r = MsiViewFetch(hview, &hrec); 4013 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); 4014 4015 r = MsiRecordSetStringA( hrec, 1, "epicranius" ); 4016 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4017 4018 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4019 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r ); 4020 4021 /* try another valid operation for joins */ 4022 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 4023 todo_wine ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r ); 4024 4025 /* try an invalid operation for joins */ 4026 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 4027 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); 4028 4029 r = MsiRecordSetStringA( hrec, 2, "epicranius" ); 4030 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); 4031 4032 /* primary key cannot be updated */ 4033 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 4034 ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r ); 4035 4036 MsiCloseHandle(hrec); 4037 MsiViewClose(hview); 4038 MsiCloseHandle(hview); 4039 4040 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4041 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4042 4043 r = MsiViewExecute(hview, 0); 4044 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4045 4046 r = MsiViewFetch(hview, &hrec); 4047 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4048 4049 size = MAX_PATH; 4050 r = MsiRecordGetStringA( hrec, 1, buf, &size ); 4051 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r ); 4052 ok( !lstrcmpA( buf, "epicranius" ), "expected 'epicranius', got %s\n", buf ); 4053 4054 MsiCloseHandle(hrec); 4055 MsiViewClose(hview); 4056 MsiCloseHandle(hview); 4057 4058 MsiCloseHandle(hdb); 4059 DeleteFileA(msifile); 4060 } 4061 4062 static void test_temporary_table(void) 4063 { 4064 MSICONDITION cond; 4065 MSIHANDLE hdb = 0, view = 0, rec; 4066 const char *query; 4067 UINT r; 4068 char buf[0x10]; 4069 DWORD sz; 4070 4071 cond = MsiDatabaseIsTablePersistentA(0, NULL); 4072 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4073 4074 hdb = create_db(); 4075 ok( hdb, "failed to create db\n"); 4076 4077 cond = MsiDatabaseIsTablePersistentA(hdb, NULL); 4078 ok( cond == MSICONDITION_ERROR, "wrong return condition\n"); 4079 4080 cond = MsiDatabaseIsTablePersistentA(hdb, "_Tables"); 4081 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4082 4083 cond = MsiDatabaseIsTablePersistentA(hdb, "_Columns"); 4084 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4085 4086 cond = MsiDatabaseIsTablePersistentA(hdb, "_Storages"); 4087 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4088 4089 cond = MsiDatabaseIsTablePersistentA(hdb, "_Streams"); 4090 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4091 4092 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)"; 4093 r = run_query(hdb, 0, query); 4094 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4095 4096 cond = MsiDatabaseIsTablePersistentA(hdb, "P"); 4097 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4098 4099 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD"; 4100 r = run_query(hdb, 0, query); 4101 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4102 4103 cond = MsiDatabaseIsTablePersistentA(hdb, "P2"); 4104 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4105 4106 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4107 r = run_query(hdb, 0, query); 4108 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4109 4110 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4111 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4112 4113 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4114 r = run_query(hdb, 0, query); 4115 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4116 4117 query = "SELECT * FROM `T2`"; 4118 r = MsiDatabaseOpenViewA(hdb, query, &view); 4119 ok(r == ERROR_BAD_QUERY_SYNTAX, 4120 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4121 4122 cond = MsiDatabaseIsTablePersistentA(hdb, "T2"); 4123 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4124 4125 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)"; 4126 r = run_query(hdb, 0, query); 4127 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4128 4129 cond = MsiDatabaseIsTablePersistentA(hdb, "T3"); 4130 ok( cond == MSICONDITION_TRUE, "wrong return condition\n"); 4131 4132 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)"; 4133 r = run_query(hdb, 0, query); 4134 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n"); 4135 4136 cond = MsiDatabaseIsTablePersistentA(hdb, "T4"); 4137 ok( cond == MSICONDITION_NONE, "wrong return condition\n"); 4138 4139 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD"; 4140 r = run_query(hdb, 0, query); 4141 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n"); 4142 4143 query = "select * from `T`"; 4144 r = MsiDatabaseOpenViewA(hdb, query, &view); 4145 ok(r == ERROR_SUCCESS, "failed to query table\n"); 4146 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4147 ok(r == ERROR_SUCCESS, "failed to get column info\n"); 4148 4149 sz = sizeof buf; 4150 r = MsiRecordGetStringA(rec, 1, buf, &sz); 4151 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4152 ok( 0 == strcmp("G255", buf), "wrong column type\n"); 4153 4154 sz = sizeof buf; 4155 r = MsiRecordGetStringA(rec, 2, buf, &sz); 4156 ok(r == ERROR_SUCCESS, "failed to get string\n"); 4157 ok( 0 == strcmp("j2", buf), "wrong column type\n"); 4158 4159 MsiCloseHandle( rec ); 4160 MsiViewClose( view ); 4161 MsiCloseHandle( view ); 4162 4163 /* query the table data */ 4164 rec = 0; 4165 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec); 4166 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n"); 4167 MsiCloseHandle( rec ); 4168 4169 /* query the column data */ 4170 rec = 0; 4171 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec); 4172 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4173 if (rec) MsiCloseHandle( rec ); 4174 4175 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec); 4176 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n"); 4177 if (rec) MsiCloseHandle( rec ); 4178 4179 MsiCloseHandle( hdb ); 4180 DeleteFileA(msifile); 4181 } 4182 4183 static void test_alter(void) 4184 { 4185 MSICONDITION cond; 4186 MSIHANDLE hdb = 0; 4187 const char *query; 4188 UINT r; 4189 4190 hdb = create_db(); 4191 ok( hdb, "failed to create db\n"); 4192 4193 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD"; 4194 r = run_query(hdb, 0, query); 4195 ok(r == ERROR_SUCCESS, "failed to add table\n"); 4196 4197 cond = MsiDatabaseIsTablePersistentA(hdb, "T"); 4198 ok( cond == MSICONDITION_FALSE, "wrong return condition\n"); 4199 4200 query = "ALTER TABLE `T` HOLD"; 4201 r = run_query(hdb, 0, query); 4202 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r); 4203 4204 query = "ALTER TABLE `T` FREE"; 4205 r = run_query(hdb, 0, query); 4206 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4207 4208 query = "ALTER TABLE `T` FREE"; 4209 r = run_query(hdb, 0, query); 4210 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4211 4212 query = "ALTER TABLE `T` FREE"; 4213 r = run_query(hdb, 0, query); 4214 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n"); 4215 4216 query = "ALTER TABLE `T` HOLD"; 4217 r = run_query(hdb, 0, query); 4218 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r); 4219 4220 /* table T is removed */ 4221 query = "SELECT * FROM `T`"; 4222 r = run_query(hdb, 0, query); 4223 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4224 4225 /* create the table again */ 4226 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)"; 4227 r = run_query(hdb, 0, query); 4228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4229 4230 /* up the ref count */ 4231 query = "ALTER TABLE `U` HOLD"; 4232 r = run_query(hdb, 0, query); 4233 ok(r == ERROR_SUCCESS, "failed to free table\n"); 4234 4235 /* add column, no data type */ 4236 query = "ALTER TABLE `U` ADD `C`"; 4237 r = run_query(hdb, 0, query); 4238 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4239 4240 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4241 r = run_query(hdb, 0, query); 4242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4243 4244 /* add column C again */ 4245 query = "ALTER TABLE `U` ADD `C` INTEGER"; 4246 r = run_query(hdb, 0, query); 4247 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4248 4249 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY"; 4250 r = run_query(hdb, 0, query); 4251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4252 4253 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )"; 4254 r = run_query(hdb, 0, query); 4255 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4256 4257 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD"; 4258 r = run_query(hdb, 0, query); 4259 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4260 4261 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )"; 4262 r = run_query(hdb, 0, query); 4263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4264 4265 query = "SELECT * FROM `U` WHERE `D` = 8"; 4266 r = run_query(hdb, 0, query); 4267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4268 4269 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE"; 4270 r = run_query(hdb, 0, query); 4271 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4272 4273 query = "ALTER COLUMN `D` FREE"; 4274 r = run_query(hdb, 0, query); 4275 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4276 4277 /* drop the ref count */ 4278 query = "ALTER TABLE `U` FREE"; 4279 r = run_query(hdb, 0, query); 4280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4281 4282 /* table is not empty */ 4283 query = "SELECT * FROM `U`"; 4284 r = run_query(hdb, 0, query); 4285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4286 4287 /* column D is removed */ 4288 query = "SELECT * FROM `U` WHERE `D` = 8"; 4289 r = run_query(hdb, 0, query); 4290 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4291 4292 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )"; 4293 r = run_query(hdb, 0, query); 4294 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4295 4296 /* add the column again */ 4297 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD"; 4298 r = run_query(hdb, 0, query); 4299 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4300 4301 /* up the ref count */ 4302 query = "ALTER TABLE `U` HOLD"; 4303 r = run_query(hdb, 0, query); 4304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4305 4306 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )"; 4307 r = run_query(hdb, 0, query); 4308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4309 4310 query = "SELECT * FROM `U` WHERE `E` = 16"; 4311 r = run_query(hdb, 0, query); 4312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4313 4314 /* drop the ref count */ 4315 query = "ALTER TABLE `U` FREE"; 4316 r = run_query(hdb, 0, query); 4317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4318 4319 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )"; 4320 r = run_query(hdb, 0, query); 4321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4322 4323 query = "SELECT * FROM `U` WHERE `E` = 20"; 4324 r = run_query(hdb, 0, query); 4325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4326 4327 /* drop the ref count */ 4328 query = "ALTER TABLE `U` FREE"; 4329 r = run_query(hdb, 0, query); 4330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4331 4332 /* table still exists */ 4333 query = "SELECT * FROM `U`"; 4334 r = run_query(hdb, 0, query); 4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4336 4337 /* col E is removed */ 4338 query = "SELECT * FROM `U` WHERE `E` = 20"; 4339 r = run_query(hdb, 0, query); 4340 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4341 4342 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )"; 4343 r = run_query(hdb, 0, query); 4344 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4345 4346 /* drop the ref count once more */ 4347 query = "ALTER TABLE `U` FREE"; 4348 r = run_query(hdb, 0, query); 4349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4350 4351 /* table still exists */ 4352 query = "SELECT * FROM `U`"; 4353 r = run_query(hdb, 0, query); 4354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4355 4356 MsiCloseHandle( hdb ); 4357 DeleteFileA(msifile); 4358 } 4359 4360 static void test_integers(void) 4361 { 4362 MSIHANDLE hdb = 0, view = 0, rec = 0; 4363 DWORD count, i; 4364 const char *query; 4365 UINT r; 4366 4367 /* just MsiOpenDatabase should not create a file */ 4368 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4369 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4370 4371 /* create a table */ 4372 query = "CREATE TABLE `integers` ( " 4373 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, " 4374 "`five` SHORT NOT NULL, `six` INT NOT NULL, " 4375 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL " 4376 "PRIMARY KEY `one`)"; 4377 r = MsiDatabaseOpenViewA(hdb, query, &view); 4378 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4379 r = MsiViewExecute(view, 0); 4380 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4381 r = MsiViewClose(view); 4382 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4383 r = MsiCloseHandle(view); 4384 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4385 4386 query = "SELECT * FROM `integers`"; 4387 r = MsiDatabaseOpenViewA(hdb, query, &view); 4388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4389 4390 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 4391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4392 count = MsiRecordGetFieldCount(rec); 4393 ok(count == 8, "Expected 8, got %d\n", count); 4394 ok(check_record(rec, 1, "one"), "Expected one\n"); 4395 ok(check_record(rec, 2, "two"), "Expected two\n"); 4396 ok(check_record(rec, 3, "three"), "Expected three\n"); 4397 ok(check_record(rec, 4, "four"), "Expected four\n"); 4398 ok(check_record(rec, 5, "five"), "Expected five\n"); 4399 ok(check_record(rec, 6, "six"), "Expected six\n"); 4400 ok(check_record(rec, 7, "seven"), "Expected seven\n"); 4401 ok(check_record(rec, 8, "eight"), "Expected eight\n"); 4402 MsiCloseHandle(rec); 4403 4404 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 4405 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4406 count = MsiRecordGetFieldCount(rec); 4407 ok(count == 8, "Expected 8, got %d\n", count); 4408 ok(check_record(rec, 1, "I2"), "Expected I2\n"); 4409 ok(check_record(rec, 2, "I2"), "Expected I2\n"); 4410 ok(check_record(rec, 3, "I2"), "Expected I2\n"); 4411 ok(check_record(rec, 4, "I4"), "Expected I4\n"); 4412 ok(check_record(rec, 5, "i2"), "Expected i2\n"); 4413 ok(check_record(rec, 6, "i2"), "Expected i2\n"); 4414 ok(check_record(rec, 7, "i2"), "Expected i2\n"); 4415 ok(check_record(rec, 8, "i4"), "Expected i4\n"); 4416 MsiCloseHandle(rec); 4417 4418 MsiViewClose(view); 4419 MsiCloseHandle(view); 4420 4421 /* insert values into it, NULL where NOT NULL is specified */ 4422 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4423 "VALUES('', '', '', '', '', '', '', '')"; 4424 r = MsiDatabaseOpenViewA(hdb, query, &view); 4425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4426 r = MsiViewExecute(view, 0); 4427 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 4428 4429 MsiViewClose(view); 4430 MsiCloseHandle(view); 4431 4432 query = "SELECT * FROM `integers`"; 4433 r = do_query(hdb, query, &rec); 4434 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4435 4436 r = MsiRecordGetFieldCount(rec); 4437 ok(r == -1, "record count wrong: %d\n", r); 4438 4439 MsiCloseHandle(rec); 4440 4441 /* insert legitimate values into it */ 4442 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )" 4443 "VALUES('', '2', '', '4', '5', '6', '7', '8')"; 4444 r = MsiDatabaseOpenViewA(hdb, query, &view); 4445 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4446 r = MsiViewExecute(view, 0); 4447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4448 4449 query = "SELECT * FROM `integers`"; 4450 r = do_query(hdb, query, &rec); 4451 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4452 4453 r = MsiRecordGetFieldCount(rec); 4454 ok(r == 8, "record count wrong: %d\n", r); 4455 4456 i = MsiRecordGetInteger(rec, 1); 4457 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4458 i = MsiRecordGetInteger(rec, 3); 4459 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i); 4460 i = MsiRecordGetInteger(rec, 2); 4461 ok(i == 2, "Expected 2, got %d\n", i); 4462 i = MsiRecordGetInteger(rec, 4); 4463 ok(i == 4, "Expected 4, got %d\n", i); 4464 i = MsiRecordGetInteger(rec, 5); 4465 ok(i == 5, "Expected 5, got %d\n", i); 4466 i = MsiRecordGetInteger(rec, 6); 4467 ok(i == 6, "Expected 6, got %d\n", i); 4468 i = MsiRecordGetInteger(rec, 7); 4469 ok(i == 7, "Expected 7, got %d\n", i); 4470 i = MsiRecordGetInteger(rec, 8); 4471 ok(i == 8, "Expected 8, got %d\n", i); 4472 4473 MsiCloseHandle(rec); 4474 MsiViewClose(view); 4475 MsiCloseHandle(view); 4476 4477 r = MsiDatabaseCommit(hdb); 4478 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4479 4480 r = MsiCloseHandle(hdb); 4481 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4482 4483 r = DeleteFileA(msifile); 4484 ok(r == TRUE, "file didn't exist after commit\n"); 4485 } 4486 4487 static void test_update(void) 4488 { 4489 MSIHANDLE hdb = 0, view = 0, rec = 0; 4490 CHAR result[MAX_PATH]; 4491 const char *query; 4492 DWORD size; 4493 UINT r; 4494 4495 /* just MsiOpenDatabase should not create a file */ 4496 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4497 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4498 4499 /* create the Control table */ 4500 query = "CREATE TABLE `Control` ( " 4501 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, " 4502 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL," 4503 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, " 4504 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)"; 4505 r = MsiDatabaseOpenViewA(hdb, query, &view); 4506 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4507 r = MsiViewExecute(view, 0); 4508 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4509 r = MsiViewClose(view); 4510 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4511 r = MsiCloseHandle(view); 4512 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4513 4514 /* add a control */ 4515 query = "INSERT INTO `Control` ( " 4516 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4517 "`Property`, `Text`, `Control_Next`, `Help` )" 4518 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4519 r = MsiDatabaseOpenViewA(hdb, query, &view); 4520 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4521 r = MsiViewExecute(view, 0); 4522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4523 r = MsiViewClose(view); 4524 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4525 r = MsiCloseHandle(view); 4526 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4527 4528 /* add a second control */ 4529 query = "INSERT INTO `Control` ( " 4530 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4531 "`Property`, `Text`, `Control_Next`, `Help` )" 4532 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')"; 4533 r = MsiDatabaseOpenViewA(hdb, query, &view); 4534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4535 r = MsiViewExecute(view, 0); 4536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4537 r = MsiViewClose(view); 4538 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4539 r = MsiCloseHandle(view); 4540 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4541 4542 /* add a third control */ 4543 query = "INSERT INTO `Control` ( " 4544 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, " 4545 "`Property`, `Text`, `Control_Next`, `Help` )" 4546 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')"; 4547 r = MsiDatabaseOpenViewA(hdb, query, &view); 4548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4549 r = MsiViewExecute(view, 0); 4550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4551 r = MsiViewClose(view); 4552 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4553 r = MsiCloseHandle(view); 4554 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4555 4556 /* bad table */ 4557 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4558 r = MsiDatabaseOpenViewA(hdb, query, &view); 4559 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4560 4561 /* bad set column */ 4562 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4563 r = MsiDatabaseOpenViewA(hdb, query, &view); 4564 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4565 4566 /* bad where condition */ 4567 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'"; 4568 r = MsiDatabaseOpenViewA(hdb, query, &view); 4569 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 4570 4571 /* just the dialog_ specified */ 4572 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'"; 4573 r = MsiDatabaseOpenViewA(hdb, query, &view); 4574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4575 r = MsiViewExecute(view, 0); 4576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4577 r = MsiViewClose(view); 4578 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4579 r = MsiCloseHandle(view); 4580 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4581 4582 /* check the modified text */ 4583 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4584 r = MsiDatabaseOpenViewA(hdb, query, &view); 4585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4586 r = MsiViewExecute(view, 0); 4587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4588 4589 r = MsiViewFetch(view, &rec); 4590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4591 4592 size = MAX_PATH; 4593 r = MsiRecordGetStringA(rec, 1, result, &size); 4594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4595 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4596 4597 MsiCloseHandle(rec); 4598 4599 r = MsiViewFetch(view, &rec); 4600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4601 4602 size = MAX_PATH; 4603 r = MsiRecordGetStringA(rec, 1, result, &size); 4604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4605 ok(!result[0], "Expected an empty string, got %s\n", result); 4606 4607 MsiCloseHandle(rec); 4608 4609 r = MsiViewFetch(view, &rec); 4610 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4611 4612 r = MsiViewClose(view); 4613 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4614 r = MsiCloseHandle(view); 4615 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4616 4617 /* dialog_ and control specified */ 4618 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'"; 4619 r = MsiDatabaseOpenViewA(hdb, query, &view); 4620 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4621 r = MsiViewExecute(view, 0); 4622 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4623 r = MsiViewClose(view); 4624 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4625 r = MsiCloseHandle(view); 4626 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4627 4628 /* check the modified text */ 4629 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'"; 4630 r = MsiDatabaseOpenViewA(hdb, query, &view); 4631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4632 r = MsiViewExecute(view, 0); 4633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4634 4635 r = MsiViewFetch(view, &rec); 4636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4637 4638 size = MAX_PATH; 4639 r = MsiRecordGetStringA(rec, 1, result, &size); 4640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4641 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4642 4643 MsiCloseHandle(rec); 4644 4645 r = MsiViewFetch(view, &rec); 4646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4647 4648 size = MAX_PATH; 4649 r = MsiRecordGetStringA(rec, 1, result, &size); 4650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4651 ok(!result[0], "Expected an empty string, got %s\n", result); 4652 4653 MsiCloseHandle(rec); 4654 4655 r = MsiViewFetch(view, &rec); 4656 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4657 4658 r = MsiViewClose(view); 4659 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4660 r = MsiCloseHandle(view); 4661 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4662 4663 /* no where condition */ 4664 query = "UPDATE `Control` SET `Text` = 'this is text'"; 4665 r = MsiDatabaseOpenViewA(hdb, query, &view); 4666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4667 r = MsiViewExecute(view, 0); 4668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4669 r = MsiViewClose(view); 4670 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4671 r = MsiCloseHandle(view); 4672 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4673 4674 /* check the modified text */ 4675 query = "SELECT `Text` FROM `Control`"; 4676 r = MsiDatabaseOpenViewA(hdb, query, &view); 4677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4678 r = MsiViewExecute(view, 0); 4679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4680 4681 r = MsiViewFetch(view, &rec); 4682 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4683 4684 size = MAX_PATH; 4685 r = MsiRecordGetStringA(rec, 1, result, &size); 4686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4687 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4688 4689 MsiCloseHandle(rec); 4690 4691 r = MsiViewFetch(view, &rec); 4692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4693 4694 size = MAX_PATH; 4695 r = MsiRecordGetStringA(rec, 1, result, &size); 4696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4697 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4698 4699 MsiCloseHandle(rec); 4700 4701 r = MsiViewFetch(view, &rec); 4702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4703 4704 size = MAX_PATH; 4705 r = MsiRecordGetStringA(rec, 1, result, &size); 4706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4707 ok(!lstrcmpA(result, "this is text"), "Expected `this is text`, got %s\n", result); 4708 4709 MsiCloseHandle(rec); 4710 4711 r = MsiViewFetch(view, &rec); 4712 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4713 4714 r = MsiViewClose(view); 4715 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4716 r = MsiCloseHandle(view); 4717 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4718 4719 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, " 4720 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)"; 4721 r = run_query(hdb, 0, query); 4722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4723 4724 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4725 "VALUES('one', 'two', 3)"; 4726 r = run_query(hdb, 0, query); 4727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4728 4729 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4730 "VALUES('three', 'four', 5)"; 4731 r = run_query(hdb, 0, query); 4732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4733 4734 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )" 4735 "VALUES('six', 'two', 7)"; 4736 r = run_query(hdb, 0, query); 4737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4738 4739 rec = MsiCreateRecord(2); 4740 MsiRecordSetInteger(rec, 1, 8); 4741 MsiRecordSetStringA(rec, 2, "two"); 4742 4743 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?"; 4744 r = run_query(hdb, rec, query); 4745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4746 4747 MsiCloseHandle(rec); 4748 4749 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`"; 4750 r = MsiDatabaseOpenViewA(hdb, query, &view); 4751 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4752 r = MsiViewExecute(view, 0); 4753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4754 4755 r = MsiViewFetch(view, &rec); 4756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4757 4758 r = MsiRecordGetInteger(rec, 1); 4759 ok(r == 8, "Expected 8, got %d\n", r); 4760 4761 MsiCloseHandle(rec); 4762 4763 r = MsiViewFetch(view, &rec); 4764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4765 4766 r = MsiRecordGetInteger(rec, 1); 4767 ok(r == 8, "Expected 8, got %d\n", r); 4768 4769 MsiCloseHandle(rec); 4770 4771 r = MsiViewFetch(view, &rec); 4772 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4773 4774 r = MsiRecordGetInteger(rec, 1); 4775 ok(r == 5, "Expected 5, got %d\n", r); 4776 4777 MsiCloseHandle(rec); 4778 4779 r = MsiViewFetch(view, &rec); 4780 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 4781 4782 MsiViewClose(view); 4783 MsiCloseHandle(view); 4784 4785 r = MsiDatabaseCommit(hdb); 4786 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n"); 4787 r = MsiCloseHandle(hdb); 4788 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4789 4790 DeleteFileA(msifile); 4791 } 4792 4793 static void test_special_tables(void) 4794 { 4795 const char *query; 4796 MSIHANDLE hdb = 0; 4797 UINT r; 4798 4799 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4800 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4801 4802 query = "CREATE TABLE `_Properties` ( " 4803 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4804 r = run_query(hdb, 0, query); 4805 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4806 4807 query = "CREATE TABLE `_Storages` ( " 4808 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4809 r = run_query(hdb, 0, query); 4810 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4811 4812 query = "CREATE TABLE `_Streams` ( " 4813 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4814 r = run_query(hdb, 0, query); 4815 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n"); 4816 4817 query = "CREATE TABLE `_Tables` ( " 4818 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4819 r = run_query(hdb, 0, query); 4820 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n"); 4821 4822 query = "CREATE TABLE `_Columns` ( " 4823 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)"; 4824 r = run_query(hdb, 0, query); 4825 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n"); 4826 4827 r = MsiCloseHandle(hdb); 4828 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4829 } 4830 4831 static void test_tables_order(void) 4832 { 4833 const char *query; 4834 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 4835 UINT r; 4836 char buffer[100]; 4837 DWORD sz; 4838 4839 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4840 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4841 4842 query = "CREATE TABLE `foo` ( " 4843 "`baz` INT NOT NULL PRIMARY KEY `baz`)"; 4844 r = run_query(hdb, 0, query); 4845 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4846 4847 query = "CREATE TABLE `bar` ( " 4848 "`foo` INT NOT NULL PRIMARY KEY `foo`)"; 4849 r = run_query(hdb, 0, query); 4850 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4851 4852 query = "CREATE TABLE `baz` ( " 4853 "`bar` INT NOT NULL, " 4854 "`baz` INT NOT NULL, " 4855 "`foo` INT NOT NULL PRIMARY KEY `bar`)"; 4856 r = run_query(hdb, 0, query); 4857 ok(r == ERROR_SUCCESS, "failed to create table\n"); 4858 4859 /* The names of the tables in the _Tables table must 4860 be in the same order as these names are created in 4861 the strings table. */ 4862 query = "SELECT * FROM `_Tables`"; 4863 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4864 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4865 r = MsiViewExecute(hview, 0); 4866 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4867 4868 r = MsiViewFetch(hview, &hrec); 4869 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4870 sz = sizeof(buffer); 4871 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4873 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4874 r = MsiCloseHandle(hrec); 4875 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4876 4877 r = MsiViewFetch(hview, &hrec); 4878 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4879 sz = sizeof(buffer); 4880 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4882 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4883 r = MsiCloseHandle(hrec); 4884 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4885 4886 r = MsiViewFetch(hview, &hrec); 4887 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4888 sz = sizeof(buffer); 4889 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4891 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4892 r = MsiCloseHandle(hrec); 4893 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4894 4895 r = MsiViewClose(hview); 4896 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4897 r = MsiCloseHandle(hview); 4898 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4899 4900 /* The names of the tables in the _Columns table must 4901 be in the same order as these names are created in 4902 the strings table. */ 4903 query = "SELECT * FROM `_Columns`"; 4904 r = MsiDatabaseOpenViewA(hdb, query, &hview); 4905 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 4906 r = MsiViewExecute(hview, 0); 4907 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 4908 4909 r = MsiViewFetch(hview, &hrec); 4910 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4911 sz = sizeof(buffer); 4912 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4914 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4915 sz = sizeof(buffer); 4916 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4917 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4918 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4919 r = MsiCloseHandle(hrec); 4920 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4921 4922 r = MsiViewFetch(hview, &hrec); 4923 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4924 sz = sizeof(buffer); 4925 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4927 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4928 sz = sizeof(buffer); 4929 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4931 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4932 r = MsiCloseHandle(hrec); 4933 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4934 4935 r = MsiViewFetch(hview, &hrec); 4936 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4937 sz = sizeof(buffer); 4938 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4940 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4941 sz = sizeof(buffer); 4942 r = MsiRecordGetStringA(hrec, 3, 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 r = MsiCloseHandle(hrec); 4946 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4947 4948 r = MsiViewFetch(hview, &hrec); 4949 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4950 sz = sizeof(buffer); 4951 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4953 ok(!lstrcmpA(buffer, "baz"), "Expected baz, got %s\n", buffer); 4954 sz = sizeof(buffer); 4955 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4957 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4958 r = MsiCloseHandle(hrec); 4959 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4960 4961 r = MsiViewFetch(hview, &hrec); 4962 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 4963 sz = sizeof(buffer); 4964 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 4965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4966 ok(!lstrcmpA(buffer, "bar"), "Expected bar, got %s\n", buffer); 4967 sz = sizeof(buffer); 4968 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 4969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 4970 ok(!lstrcmpA(buffer, "foo"), "Expected foo, got %s\n", buffer); 4971 r = MsiCloseHandle(hrec); 4972 ok(r == ERROR_SUCCESS, "failed to close record\n"); 4973 4974 r = MsiViewClose(hview); 4975 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 4976 r = MsiCloseHandle(hview); 4977 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4978 4979 r = MsiCloseHandle(hdb); 4980 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 4981 4982 DeleteFileA(msifile); 4983 } 4984 4985 static void test_rows_order(void) 4986 { 4987 const char *query; 4988 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 4989 UINT r; 4990 char buffer[100]; 4991 DWORD sz; 4992 4993 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 4994 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 4995 4996 query = "CREATE TABLE `foo` ( " 4997 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)"; 4998 r = run_query(hdb, 0, query); 4999 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5000 5001 r = run_query(hdb, 0, "INSERT INTO `foo` " 5002 "( `bar` ) VALUES ( 'A' )"); 5003 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5004 5005 r = run_query(hdb, 0, "INSERT INTO `foo` " 5006 "( `bar` ) VALUES ( 'B' )"); 5007 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5008 5009 r = run_query(hdb, 0, "INSERT INTO `foo` " 5010 "( `bar` ) VALUES ( 'C' )"); 5011 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5012 5013 r = run_query(hdb, 0, "INSERT INTO `foo` " 5014 "( `bar` ) VALUES ( 'D' )"); 5015 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5016 5017 r = run_query(hdb, 0, "INSERT INTO `foo` " 5018 "( `bar` ) VALUES ( 'E' )"); 5019 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5020 5021 r = run_query(hdb, 0, "INSERT INTO `foo` " 5022 "( `bar` ) VALUES ( 'F' )"); 5023 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5024 5025 query = "CREATE TABLE `bar` ( " 5026 "`foo` LONGCHAR NOT NULL, " 5027 "`baz` LONGCHAR NOT NULL " 5028 "PRIMARY KEY `foo` )"; 5029 r = run_query(hdb, 0, query); 5030 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5031 5032 r = run_query(hdb, 0, "INSERT INTO `bar` " 5033 "( `foo`, `baz` ) VALUES ( 'C', 'E' )"); 5034 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5035 5036 r = run_query(hdb, 0, "INSERT INTO `bar` " 5037 "( `foo`, `baz` ) VALUES ( 'F', 'A' )"); 5038 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5039 5040 r = run_query(hdb, 0, "INSERT INTO `bar` " 5041 "( `foo`, `baz` ) VALUES ( 'A', 'B' )"); 5042 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5043 5044 r = run_query(hdb, 0, "INSERT INTO `bar` " 5045 "( `foo`, `baz` ) VALUES ( 'D', 'E' )"); 5046 ok(r == ERROR_SUCCESS, "cannot add value to table\n"); 5047 5048 /* The rows of the table must be ordered by the column values of 5049 each row. For strings, the column value is the string id 5050 in the string table. */ 5051 5052 query = "SELECT * FROM `bar`"; 5053 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5054 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5055 r = MsiViewExecute(hview, 0); 5056 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5057 5058 r = MsiViewFetch(hview, &hrec); 5059 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5060 sz = sizeof(buffer); 5061 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5063 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5064 sz = sizeof(buffer); 5065 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5067 ok(!lstrcmpA(buffer, "B"), "Expected B, got %s\n", buffer); 5068 r = MsiCloseHandle(hrec); 5069 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5070 5071 r = MsiViewFetch(hview, &hrec); 5072 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5073 sz = sizeof(buffer); 5074 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5076 ok(!lstrcmpA(buffer, "C"), "Expected E, got %s\n", buffer); 5077 sz = sizeof(buffer); 5078 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5080 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5081 r = MsiCloseHandle(hrec); 5082 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5083 5084 r = MsiViewFetch(hview, &hrec); 5085 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5086 sz = sizeof(buffer); 5087 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5089 ok(!lstrcmpA(buffer, "D"), "Expected D, got %s\n", buffer); 5090 sz = sizeof(buffer); 5091 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5093 ok(!lstrcmpA(buffer, "E"), "Expected E, got %s\n", buffer); 5094 r = MsiCloseHandle(hrec); 5095 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5096 5097 r = MsiViewFetch(hview, &hrec); 5098 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5099 sz = sizeof(buffer); 5100 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5102 ok(!lstrcmpA(buffer, "F"), "Expected F, got %s\n", buffer); 5103 sz = sizeof(buffer); 5104 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5106 ok(!lstrcmpA(buffer, "A"), "Expected A, got %s\n", buffer); 5107 r = MsiCloseHandle(hrec); 5108 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5109 5110 r = MsiViewClose(hview); 5111 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5112 r = MsiCloseHandle(hview); 5113 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5114 5115 r = MsiCloseHandle(hdb); 5116 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5117 5118 DeleteFileA(msifile); 5119 } 5120 5121 static void test_collation(void) 5122 { 5123 static const WCHAR query1[] = 5124 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5125 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5126 '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0}; 5127 static const WCHAR query2[] = 5128 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ', 5129 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ', 5130 '(','\'',0xe5,'\'',',','\'','D','\'',')',0}; 5131 static const WCHAR query3[] = 5132 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ', 5133 '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',', 5134 ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ', 5135 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0}; 5136 static const WCHAR query4[] = 5137 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ', 5138 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5139 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5140 static const WCHAR query5[] = 5141 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ', 5142 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ', 5143 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0}; 5144 static const WCHAR query6[] = 5145 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E', 5146 ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0}; 5147 static const WCHAR letter_C[] = {'C',0}; 5148 static const WCHAR letter_D[] = {'D',0}; 5149 static const WCHAR letter_a_ring[] = {'a',0x30a,0}; 5150 static const WCHAR letter_a_with_ring[] = {0xe5,0}; 5151 const char *query; 5152 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5153 UINT r; 5154 char buffer[100]; 5155 WCHAR bufferW[100]; 5156 DWORD sz; 5157 5158 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5159 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5160 5161 query = "CREATE TABLE `bar` ( " 5162 "`foo` LONGCHAR NOT NULL, " 5163 "`baz` LONGCHAR NOT NULL " 5164 "PRIMARY KEY `foo` )"; 5165 r = run_query(hdb, 0, query); 5166 ok(r == ERROR_SUCCESS, "failed to create table\n"); 5167 5168 r = run_query(hdb, 0, query); 5169 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r); 5170 5171 r = run_query(hdb, 0, "INSERT INTO `bar` " 5172 "( `foo`, `baz` ) VALUES ( '\2', 'A' )"); 5173 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5174 5175 r = run_query(hdb, 0, "INSERT INTO `bar` " 5176 "( `foo`, `baz` ) VALUES ( '\1', 'B' )"); 5177 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5178 5179 r = run_queryW(hdb, 0, query1); 5180 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5181 5182 r = run_queryW(hdb, 0, query2); 5183 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r); 5184 5185 r = run_queryW(hdb, 0, query3); 5186 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5187 5188 r = run_queryW(hdb, 0, query4); 5189 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5190 5191 r = run_queryW(hdb, 0, query5); 5192 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r); 5193 5194 query = "SELECT * FROM `bar`"; 5195 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5196 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5197 r = MsiViewExecute(hview, 0); 5198 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5199 5200 r = MsiViewFetch(hview, &hrec); 5201 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5202 sz = sizeof(buffer); 5203 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5205 ok(!lstrcmpA(buffer, "\2"), "Expected \\2, got '%s'\n", buffer); 5206 sz = sizeof(buffer); 5207 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5209 ok(!lstrcmpA(buffer, "A"), "Expected A, got '%s'\n", buffer); 5210 MsiCloseHandle(hrec); 5211 5212 r = MsiViewFetch(hview, &hrec); 5213 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5214 sz = sizeof(buffer); 5215 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 5216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5217 ok(!lstrcmpA(buffer, "\1"), "Expected \\1, got '%s'\n", buffer); 5218 sz = sizeof(buffer); 5219 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5221 ok(!lstrcmpA(buffer, "B"), "Expected B, got '%s'\n", buffer); 5222 MsiCloseHandle(hrec); 5223 5224 r = MsiViewFetch(hview, &hrec); 5225 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5226 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5227 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5229 ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)), 5230 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW)); 5231 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5232 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5234 ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW)); 5235 MsiCloseHandle(hrec); 5236 5237 r = MsiViewFetch(hview, &hrec); 5238 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5239 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5240 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5242 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5243 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5244 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5245 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5246 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5247 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5248 MsiCloseHandle(hrec); 5249 5250 r = MsiViewClose(hview); 5251 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5252 r = MsiCloseHandle(hview); 5253 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5254 5255 r = MsiDatabaseOpenViewW(hdb, query6, &hview); 5256 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5257 r = MsiViewExecute(hview, 0); 5258 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5259 5260 r = MsiViewFetch(hview, &hrec); 5261 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5262 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5263 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz); 5264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5265 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)), 5266 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW)); 5267 sz = sizeof(bufferW) / sizeof(bufferW[0]); 5268 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz); 5269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5270 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW)); 5271 MsiCloseHandle(hrec); 5272 5273 r = MsiViewFetch(hview, &hrec); 5274 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n"); 5275 5276 r = MsiViewClose(hview); 5277 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5278 r = MsiCloseHandle(hview); 5279 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5280 5281 r = MsiCloseHandle(hdb); 5282 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5283 5284 DeleteFileA(msifile); 5285 } 5286 5287 static void test_select_markers(void) 5288 { 5289 MSIHANDLE hdb = 0, rec, view, res; 5290 LPCSTR query; 5291 UINT r; 5292 DWORD size; 5293 CHAR buf[MAX_PATH]; 5294 5295 hdb = create_db(); 5296 ok( hdb, "failed to create db\n"); 5297 5298 r = run_query(hdb, 0, 5299 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)"); 5300 ok(r == S_OK, "cannot create table: %d\n", r); 5301 5302 r = run_query(hdb, 0, "INSERT INTO `Table` " 5303 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )"); 5304 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5305 5306 r = run_query(hdb, 0, "INSERT INTO `Table` " 5307 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )"); 5308 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5309 5310 r = run_query(hdb, 0, "INSERT INTO `Table` " 5311 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )"); 5312 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5313 5314 r = run_query(hdb, 0, "INSERT INTO `Table` " 5315 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )"); 5316 ok(r == S_OK, "cannot add file to the Media table: %d\n", r); 5317 5318 rec = MsiCreateRecord(2); 5319 MsiRecordSetStringA(rec, 1, "apple"); 5320 MsiRecordSetStringA(rec, 2, "two"); 5321 5322 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`"; 5323 r = MsiDatabaseOpenViewA(hdb, query, &view); 5324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5325 5326 r = MsiViewExecute(view, rec); 5327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5328 5329 r = MsiViewFetch(view, &res); 5330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5331 5332 size = MAX_PATH; 5333 r = MsiRecordGetStringA(res, 1, buf, &size); 5334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5335 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5336 5337 size = MAX_PATH; 5338 r = MsiRecordGetStringA(res, 2, buf, &size); 5339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5340 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5341 5342 r = MsiRecordGetInteger(res, 3); 5343 ok(r == 1, "Expected 1, got %d\n", r); 5344 5345 MsiCloseHandle(res); 5346 5347 r = MsiViewFetch(view, &res); 5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5349 5350 size = MAX_PATH; 5351 r = MsiRecordGetStringA(res, 1, buf, &size); 5352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5353 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5354 5355 size = MAX_PATH; 5356 r = MsiRecordGetStringA(res, 2, buf, &size); 5357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5358 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5359 5360 r = MsiRecordGetInteger(res, 3); 5361 ok(r == 2, "Expected 2, got %d\n", r); 5362 5363 MsiCloseHandle(res); 5364 5365 r = MsiViewFetch(view, &res); 5366 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5367 5368 MsiCloseHandle(rec); 5369 MsiViewClose(view); 5370 MsiCloseHandle(view); 5371 5372 rec = MsiCreateRecord(2); 5373 MsiRecordSetStringA(rec, 1, "one"); 5374 MsiRecordSetInteger(rec, 2, 1); 5375 5376 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`"; 5377 r = MsiDatabaseOpenViewA(hdb, query, &view); 5378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5379 r = MsiViewExecute(view, rec); 5380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5381 5382 r = MsiViewFetch(view, &res); 5383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5384 5385 size = MAX_PATH; 5386 r = MsiRecordGetStringA(res, 1, buf, &size); 5387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5388 ok(!lstrcmpA(buf, "apple"), "Expected apple, got %s\n", buf); 5389 5390 size = MAX_PATH; 5391 r = MsiRecordGetStringA(res, 2, buf, &size); 5392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5393 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 5394 5395 r = MsiRecordGetInteger(res, 3); 5396 ok(r == 2, "Expected 2, got %d\n", r); 5397 5398 MsiCloseHandle(res); 5399 5400 r = MsiViewFetch(view, &res); 5401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5402 5403 size = MAX_PATH; 5404 r = MsiRecordGetStringA(res, 1, buf, &size); 5405 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5406 ok(!lstrcmpA(buf, "banana"), "Expected banana, got %s\n", buf); 5407 5408 size = MAX_PATH; 5409 r = MsiRecordGetStringA(res, 2, buf, &size); 5410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5411 ok(!lstrcmpA(buf, "three"), "Expected three, got %s\n", buf); 5412 5413 r = MsiRecordGetInteger(res, 3); 5414 ok(r == 3, "Expected 3, got %d\n", r); 5415 5416 MsiCloseHandle(res); 5417 5418 r = MsiViewFetch(view, &res); 5419 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5420 5421 MsiCloseHandle(rec); 5422 MsiViewClose(view); 5423 MsiCloseHandle(view); 5424 MsiCloseHandle(hdb); 5425 DeleteFileA(msifile); 5426 } 5427 5428 static void test_viewmodify_update(void) 5429 { 5430 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5431 UINT i, test_max, offset, count; 5432 const char *query; 5433 UINT r; 5434 5435 DeleteFileA(msifile); 5436 5437 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5438 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5439 5440 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5441 r = run_query( hdb, 0, query ); 5442 ok(r == ERROR_SUCCESS, "query failed\n"); 5443 5444 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)"; 5445 r = run_query( hdb, 0, query ); 5446 ok(r == ERROR_SUCCESS, "query failed\n"); 5447 5448 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)"; 5449 r = run_query( hdb, 0, query ); 5450 ok(r == ERROR_SUCCESS, "query failed\n"); 5451 5452 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)"; 5453 r = run_query( hdb, 0, query ); 5454 ok(r == ERROR_SUCCESS, "query failed\n"); 5455 5456 query = "SELECT `B` FROM `table`"; 5457 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5458 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5459 r = MsiViewExecute(hview, 0); 5460 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5461 r = MsiViewFetch(hview, &hrec); 5462 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5463 5464 r = MsiRecordSetInteger(hrec, 1, 0); 5465 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5466 5467 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5468 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5469 5470 r = MsiCloseHandle(hrec); 5471 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5472 5473 r = MsiViewClose(hview); 5474 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5475 r = MsiCloseHandle(hview); 5476 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5477 5478 query = "SELECT * FROM `table`"; 5479 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5480 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5481 r = MsiViewExecute(hview, 0); 5482 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5483 r = MsiViewFetch(hview, &hrec); 5484 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5485 5486 r = MsiRecordGetInteger(hrec, 1); 5487 ok(r == 1, "Expected 1, got %d\n", r); 5488 r = MsiRecordGetInteger(hrec, 2); 5489 ok(r == 0, "Expected 0, got %d\n", r); 5490 5491 r = MsiCloseHandle(hrec); 5492 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5493 5494 r = MsiViewFetch(hview, &hrec); 5495 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5496 5497 r = MsiRecordGetInteger(hrec, 1); 5498 ok(r == 3, "Expected 3, got %d\n", r); 5499 r = MsiRecordGetInteger(hrec, 2); 5500 ok(r == 4, "Expected 4, got %d\n", r); 5501 5502 r = MsiCloseHandle(hrec); 5503 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5504 5505 r = MsiViewFetch(hview, &hrec); 5506 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5507 5508 r = MsiRecordGetInteger(hrec, 1); 5509 ok(r == 5, "Expected 5, got %d\n", r); 5510 r = MsiRecordGetInteger(hrec, 2); 5511 ok(r == 6, "Expected 6, got %d\n", r); 5512 5513 r = MsiCloseHandle(hrec); 5514 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5515 5516 r = MsiViewFetch(hview, &hrec); 5517 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5518 5519 r = MsiViewClose(hview); 5520 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5521 r = MsiCloseHandle(hview); 5522 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5523 5524 /* loop through all elements */ 5525 query = "SELECT `B` FROM `table`"; 5526 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5527 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5528 r = MsiViewExecute(hview, 0); 5529 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5530 5531 while (TRUE) 5532 { 5533 r = MsiViewFetch(hview, &hrec); 5534 if (r != ERROR_SUCCESS) 5535 break; 5536 5537 r = MsiRecordSetInteger(hrec, 1, 0); 5538 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5539 5540 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 5541 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5542 5543 r = MsiCloseHandle(hrec); 5544 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5545 } 5546 5547 r = MsiViewClose(hview); 5548 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5549 r = MsiCloseHandle(hview); 5550 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5551 5552 query = "SELECT * FROM `table`"; 5553 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5554 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5555 r = MsiViewExecute(hview, 0); 5556 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5557 r = MsiViewFetch(hview, &hrec); 5558 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5559 5560 r = MsiRecordGetInteger(hrec, 1); 5561 ok(r == 1, "Expected 1, got %d\n", r); 5562 r = MsiRecordGetInteger(hrec, 2); 5563 ok(r == 0, "Expected 0, got %d\n", r); 5564 5565 r = MsiCloseHandle(hrec); 5566 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5567 5568 r = MsiViewFetch(hview, &hrec); 5569 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5570 5571 r = MsiRecordGetInteger(hrec, 1); 5572 ok(r == 3, "Expected 3, got %d\n", r); 5573 r = MsiRecordGetInteger(hrec, 2); 5574 ok(r == 0, "Expected 0, got %d\n", r); 5575 5576 r = MsiCloseHandle(hrec); 5577 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5578 5579 r = MsiViewFetch(hview, &hrec); 5580 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5581 5582 r = MsiRecordGetInteger(hrec, 1); 5583 ok(r == 5, "Expected 5, got %d\n", r); 5584 r = MsiRecordGetInteger(hrec, 2); 5585 ok(r == 0, "Expected 0, got %d\n", r); 5586 5587 r = MsiCloseHandle(hrec); 5588 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5589 5590 r = MsiViewFetch(hview, &hrec); 5591 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5592 5593 r = MsiViewClose(hview); 5594 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5595 r = MsiCloseHandle(hview); 5596 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5597 5598 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5599 r = run_query( hdb, 0, query ); 5600 ok(r == ERROR_SUCCESS, "query failed\n"); 5601 5602 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)"; 5603 r = MsiDatabaseOpenViewA( hdb, query, &hview ); 5604 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5605 5606 test_max = 100; 5607 offset = 1234; 5608 for(i = 0; i < test_max; i++) 5609 { 5610 5611 hrec = MsiCreateRecord( 2 ); 5612 MsiRecordSetInteger( hrec, 1, test_max - i ); 5613 MsiRecordSetInteger( hrec, 2, i ); 5614 5615 r = MsiViewExecute( hview, hrec ); 5616 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5617 5618 r = MsiCloseHandle( hrec ); 5619 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5620 } 5621 5622 r = MsiViewClose( hview ); 5623 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5624 r = MsiCloseHandle( hview ); 5625 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5626 5627 /* Update. */ 5628 query = "SELECT * FROM `table2` ORDER BY `B`"; 5629 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5630 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5631 r = MsiViewExecute( hview, 0 ); 5632 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5633 5634 count = 0; 5635 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5636 { 5637 UINT b = MsiRecordGetInteger( hrec, 2 ); 5638 5639 r = MsiRecordSetInteger( hrec, 2, b + offset); 5640 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5641 5642 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec ); 5643 ok(r == ERROR_SUCCESS, "Got %d\n", r); 5644 5645 r = MsiCloseHandle(hrec); 5646 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5647 count++; 5648 } 5649 ok(count == test_max, "Got count %d\n", count); 5650 5651 r = MsiViewClose(hview); 5652 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5653 r = MsiCloseHandle(hview); 5654 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5655 5656 /* Recheck. */ 5657 query = "SELECT * FROM `table2` ORDER BY `B`"; 5658 r = MsiDatabaseOpenViewA( hdb, query, &hview); 5659 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5660 r = MsiViewExecute( hview, 0 ); 5661 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5662 5663 count = 0; 5664 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS) 5665 { 5666 UINT a = MsiRecordGetInteger( hrec, 1 ); 5667 UINT b = MsiRecordGetInteger( hrec, 2 ); 5668 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n", 5669 a, b, test_max - a + offset, b); 5670 5671 r = MsiCloseHandle(hrec); 5672 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5673 count++; 5674 } 5675 ok(count == test_max, "Got count %d\n", count); 5676 5677 r = MsiViewClose(hview); 5678 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5679 r = MsiCloseHandle(hview); 5680 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5681 5682 r = MsiCloseHandle( hdb ); 5683 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5684 } 5685 5686 static void test_viewmodify_assign(void) 5687 { 5688 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5689 const char *query; 5690 UINT r; 5691 5692 /* setup database */ 5693 DeleteFileA(msifile); 5694 5695 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5696 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); 5697 5698 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)"; 5699 r = run_query( hdb, 0, query ); 5700 ok(r == ERROR_SUCCESS, "query failed\n"); 5701 5702 /* assign to view, new primary key */ 5703 query = "SELECT * FROM `table`"; 5704 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5705 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5706 r = MsiViewExecute(hview, 0); 5707 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5708 5709 hrec = MsiCreateRecord(2); 5710 ok(hrec != 0, "MsiCreateRecord failed\n"); 5711 5712 r = MsiRecordSetInteger(hrec, 1, 1); 5713 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5714 r = MsiRecordSetInteger(hrec, 2, 2); 5715 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5716 5717 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5718 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5719 5720 r = MsiCloseHandle(hrec); 5721 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5722 5723 r = MsiViewClose(hview); 5724 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5725 r = MsiCloseHandle(hview); 5726 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5727 5728 query = "SELECT * FROM `table`"; 5729 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5730 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5731 r = MsiViewExecute(hview, 0); 5732 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5733 r = MsiViewFetch(hview, &hrec); 5734 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5735 5736 r = MsiRecordGetInteger(hrec, 1); 5737 ok(r == 1, "Expected 1, got %d\n", r); 5738 r = MsiRecordGetInteger(hrec, 2); 5739 ok(r == 2, "Expected 2, got %d\n", r); 5740 5741 r = MsiCloseHandle(hrec); 5742 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5743 5744 r = MsiViewFetch(hview, &hrec); 5745 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5746 5747 r = MsiViewClose(hview); 5748 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5749 r = MsiCloseHandle(hview); 5750 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5751 5752 /* assign to view, primary key matches */ 5753 query = "SELECT * FROM `table`"; 5754 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5755 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5756 r = MsiViewExecute(hview, 0); 5757 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5758 5759 hrec = MsiCreateRecord(2); 5760 ok(hrec != 0, "MsiCreateRecord failed\n"); 5761 5762 r = MsiRecordSetInteger(hrec, 1, 1); 5763 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5764 r = MsiRecordSetInteger(hrec, 2, 4); 5765 ok(r == ERROR_SUCCESS, "failed to set integer\n"); 5766 5767 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); 5768 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r); 5769 5770 r = MsiCloseHandle(hrec); 5771 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5772 5773 r = MsiViewClose(hview); 5774 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5775 r = MsiCloseHandle(hview); 5776 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5777 5778 query = "SELECT * FROM `table`"; 5779 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5780 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); 5781 r = MsiViewExecute(hview, 0); 5782 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); 5783 r = MsiViewFetch(hview, &hrec); 5784 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); 5785 5786 r = MsiRecordGetInteger(hrec, 1); 5787 ok(r == 1, "Expected 1, got %d\n", r); 5788 r = MsiRecordGetInteger(hrec, 2); 5789 ok(r == 4, "Expected 4, got %d\n", r); 5790 5791 r = MsiCloseHandle(hrec); 5792 ok(r == ERROR_SUCCESS, "failed to close record\n"); 5793 5794 r = MsiViewFetch(hview, &hrec); 5795 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5796 5797 r = MsiViewClose(hview); 5798 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); 5799 r = MsiCloseHandle(hview); 5800 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); 5801 5802 /* close database */ 5803 r = MsiCloseHandle( hdb ); 5804 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n"); 5805 } 5806 5807 static const WCHAR data10[] = { /* MOO */ 5808 0x8001, 0x000b, 5809 }; 5810 static const WCHAR data11[] = { /* AAR */ 5811 0x8002, 0x8005, 5812 0x000c, 0x000f, 5813 }; 5814 static const char data12[] = /* _StringData */ 5815 "MOOABAARCDonetwofourfive"; 5816 static const WCHAR data13[] = { /* _StringPool */ 5817 /* len, refs */ 5818 0, 0, /* string 0 '' */ 5819 0, 0, /* string 1 '' */ 5820 0, 0, /* string 2 '' */ 5821 0, 0, /* string 3 '' */ 5822 0, 0, /* string 4 '' */ 5823 3, 3, /* string 5 'MOO' */ 5824 1, 1, /* string 6 'A' */ 5825 1, 1, /* string 7 'B' */ 5826 3, 3, /* string 8 'AAR' */ 5827 1, 1, /* string 9 'C' */ 5828 1, 1, /* string a 'D' */ 5829 3, 1, /* string b 'one' */ 5830 3, 1, /* string c 'two' */ 5831 0, 0, /* string d '' */ 5832 4, 1, /* string e 'four' */ 5833 4, 1, /* string f 'five' */ 5834 }; 5835 5836 static void test_stringtable(void) 5837 { 5838 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 5839 IStorage *stg = NULL; 5840 IStream *stm; 5841 WCHAR name[0x20]; 5842 HRESULT hr; 5843 const char *query; 5844 char buffer[MAX_PATH]; 5845 WCHAR data[MAX_PATH]; 5846 DWORD sz, read; 5847 UINT r; 5848 5849 static const DWORD mode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE; 5850 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */ 5851 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */ 5852 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */ 5853 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */ 5854 5855 DeleteFileA(msifile); 5856 5857 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 5858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5859 5860 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)"; 5861 r = run_query(hdb, 0, query); 5862 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5863 5864 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)"; 5865 r = run_query(hdb, 0, query); 5866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5867 5868 /* insert persistent row */ 5869 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')"; 5870 r = run_query(hdb, 0, query); 5871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5872 5873 /* insert persistent row */ 5874 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')"; 5875 r = run_query(hdb, 0, query); 5876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5877 5878 /* open a view */ 5879 query = "SELECT * FROM `MOO`"; 5880 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5881 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5882 r = MsiViewExecute(hview, 0); 5883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5884 5885 hrec = MsiCreateRecord(2); 5886 5887 r = MsiRecordSetInteger(hrec, 1, 3); 5888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5889 r = MsiRecordSetStringA(hrec, 2, "three"); 5890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5891 5892 /* insert a nonpersistent row */ 5893 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 5894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5895 5896 r = MsiCloseHandle(hrec); 5897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5898 r = MsiViewClose(hview); 5899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5900 r = MsiCloseHandle(hview); 5901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5902 5903 /* insert persistent row */ 5904 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')"; 5905 r = run_query(hdb, 0, query); 5906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5907 5908 /* insert persistent row */ 5909 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')"; 5910 r = run_query(hdb, 0, query); 5911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5912 5913 r = MsiDatabaseCommit(hdb); 5914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5915 5916 r = MsiCloseHandle(hdb); 5917 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5918 5919 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 5920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5921 5922 query = "SELECT * FROM `MOO`"; 5923 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5925 5926 r = MsiViewExecute(hview, 0); 5927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5928 5929 r = MsiViewFetch(hview, &hrec); 5930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5931 5932 r = MsiRecordGetFieldCount(hrec); 5933 ok(r == 2, "Expected 2, got %d\n", r); 5934 5935 r = MsiRecordGetInteger(hrec, 1); 5936 ok(r == 1, "Expected 1, got %d\n", r); 5937 5938 sz = sizeof(buffer); 5939 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5941 ok(!lstrcmpA(buffer, "one"), "Expected one, got '%s'\n", buffer); 5942 5943 r = MsiCloseHandle(hrec); 5944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5945 5946 r = MsiViewFetch(hview, &hrec); 5947 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5948 5949 r = MsiViewClose(hview); 5950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5951 r = MsiCloseHandle(hview); 5952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5953 r = MsiCloseHandle(hrec); 5954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5955 5956 query = "SELECT * FROM `AAR`"; 5957 r = MsiDatabaseOpenViewA(hdb, query, &hview); 5958 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5959 5960 r = MsiViewExecute(hview, 0); 5961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5962 5963 r = MsiViewFetch(hview, &hrec); 5964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5965 5966 r = MsiRecordGetFieldCount(hrec); 5967 ok(r == 2, "Expected 2, got %d\n", r); 5968 5969 r = MsiRecordGetInteger(hrec, 1); 5970 ok(r == 2, "Expected 2, got %d\n", r); 5971 5972 sz = sizeof(buffer); 5973 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 5974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 5975 ok(!lstrcmpA(buffer, "two"), "Expected two, got '%s'\n", buffer); 5976 5977 r = MsiCloseHandle(hrec); 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 == 5, "Expected 5, 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, "five"), "Expected five, 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_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 5999 6000 r = MsiViewClose(hview); 6001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6002 r = MsiCloseHandle(hview); 6003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6004 r = MsiCloseHandle(hrec); 6005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6006 r = MsiCloseHandle(hdb); 6007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6008 6009 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20); 6010 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg); 6011 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6012 ok(stg != NULL, "Expected non-NULL storage\n"); 6013 6014 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6015 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6016 ok(stm != NULL, "Expected non-NULL stream\n"); 6017 6018 hr = IStream_Read(stm, data, MAX_PATH, &read); 6019 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6020 ok(read == 4, "Expected 4, got %d\n", read); 6021 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n"); 6022 6023 hr = IStream_Release(stm); 6024 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6025 6026 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6027 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6028 ok(stm != NULL, "Expected non-NULL stream\n"); 6029 6030 hr = IStream_Read(stm, data, MAX_PATH, &read); 6031 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6032 ok(read == 8, "Expected 8, got %d\n", read); 6033 todo_wine 6034 { 6035 ok(!memcmp(data, data11, read), "Unexpected data\n"); 6036 } 6037 6038 hr = IStream_Release(stm); 6039 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6040 6041 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6042 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6043 ok(stm != NULL, "Expected non-NULL stream\n"); 6044 6045 hr = IStream_Read(stm, buffer, MAX_PATH, &read); 6046 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6047 ok(read == 24, "Expected 24, got %d\n", read); 6048 ok(!memcmp(buffer, data12, read), "Unexpected data\n"); 6049 6050 hr = IStream_Release(stm); 6051 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6052 6053 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6054 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6055 ok(stm != NULL, "Expected non-NULL stream\n"); 6056 6057 hr = IStream_Read(stm, data, MAX_PATH, &read); 6058 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6059 todo_wine 6060 { 6061 ok(read == 64, "Expected 64, got %d\n", read); 6062 ok(!memcmp(data, data13, read), "Unexpected data\n"); 6063 } 6064 6065 hr = IStream_Release(stm); 6066 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6067 6068 hr = IStorage_Release(stg); 6069 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 6070 6071 DeleteFileA(msifile); 6072 } 6073 6074 static void test_viewmodify_delete(void) 6075 { 6076 MSIHANDLE hdb = 0, hview = 0, hrec = 0; 6077 UINT r; 6078 const char *query; 6079 char buffer[0x100]; 6080 DWORD sz; 6081 6082 DeleteFileA(msifile); 6083 6084 /* just MsiOpenDatabase should not create a file */ 6085 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6087 6088 query = "CREATE TABLE `phone` ( " 6089 "`id` INT, `name` CHAR(32), `number` CHAR(32) " 6090 "PRIMARY KEY `id`)"; 6091 r = run_query(hdb, 0, query); 6092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6093 6094 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6095 "VALUES('1', 'Alan', '5030581')"; 6096 r = run_query(hdb, 0, query); 6097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6098 6099 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6100 "VALUES('2', 'Barry', '928440')"; 6101 r = run_query(hdb, 0, query); 6102 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6103 6104 query = "INSERT INTO `phone` ( `id`, `name`, `number` )" 6105 "VALUES('3', 'Cindy', '2937550')"; 6106 r = run_query(hdb, 0, query); 6107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6108 6109 query = "SELECT * FROM `phone` WHERE `id` <= 2"; 6110 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6112 r = MsiViewExecute(hview, 0); 6113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6114 r = MsiViewFetch(hview, &hrec); 6115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6116 6117 /* delete 1 */ 6118 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6120 6121 r = MsiCloseHandle(hrec); 6122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6123 r = MsiViewFetch(hview, &hrec); 6124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6125 6126 /* delete 2 */ 6127 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6129 6130 r = MsiCloseHandle(hrec); 6131 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6132 r = MsiViewClose(hview); 6133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6134 r = MsiCloseHandle(hview); 6135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6136 6137 query = "SELECT * FROM `phone`"; 6138 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6140 r = MsiViewExecute(hview, 0); 6141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6142 r = MsiViewFetch(hview, &hrec); 6143 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6144 6145 r = MsiRecordGetInteger(hrec, 1); 6146 ok(r == 3, "Expected 3, got %d\n", r); 6147 6148 sz = sizeof(buffer); 6149 r = MsiRecordGetStringA(hrec, 2, buffer, &sz); 6150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6151 ok(!lstrcmpA(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer); 6152 6153 sz = sizeof(buffer); 6154 r = MsiRecordGetStringA(hrec, 3, buffer, &sz); 6155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6156 ok(!lstrcmpA(buffer, "2937550"), "Expected 2937550, got %s\n", buffer); 6157 6158 r = MsiCloseHandle(hrec); 6159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6160 6161 r = MsiViewFetch(hview, &hrec); 6162 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6163 6164 r = MsiViewClose(hview); 6165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6166 r = MsiCloseHandle(hview); 6167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6168 r = MsiCloseHandle(hdb); 6169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6170 } 6171 6172 static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0}; 6173 static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; 6174 static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; 6175 6176 static const WCHAR data14[] = { /* _StringPool */ 6177 /* len, refs */ 6178 0, 0, /* string 0 '' */ 6179 }; 6180 6181 static const struct { 6182 LPCWSTR name; 6183 const void *data; 6184 DWORD size; 6185 } database_table_data[] = 6186 { 6187 {_Tables, NULL, 0}, 6188 {_StringData, NULL, 0}, 6189 {_StringPool, data14, sizeof data14}, 6190 }; 6191 6192 static void enum_stream_names(IStorage *stg) 6193 { 6194 IEnumSTATSTG *stgenum = NULL; 6195 IStream *stm; 6196 HRESULT hr; 6197 STATSTG stat; 6198 ULONG n, count; 6199 BYTE data[MAX_PATH]; 6200 BYTE check[MAX_PATH]; 6201 DWORD sz; 6202 6203 memset(check, 'a', MAX_PATH); 6204 6205 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum); 6206 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6207 6208 n = 0; 6209 while(TRUE) 6210 { 6211 count = 0; 6212 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count); 6213 if(FAILED(hr) || !count) 6214 break; 6215 6216 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name), 6217 "Expected table %d name to match\n", n); 6218 6219 stm = NULL; 6220 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL, 6221 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 6222 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6223 ok(stm != NULL, "Expected non-NULL stream\n"); 6224 6225 CoTaskMemFree(stat.pwcsName); 6226 6227 sz = MAX_PATH; 6228 memset(data, 'a', MAX_PATH); 6229 hr = IStream_Read(stm, data, sz, &count); 6230 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6231 6232 ok(count == database_table_data[n].size, 6233 "Expected %d, got %d\n", database_table_data[n].size, count); 6234 6235 if (!database_table_data[n].size) 6236 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n"); 6237 else 6238 ok(!memcmp(data, database_table_data[n].data, database_table_data[n].size), 6239 "Expected table %d data to match\n", n); 6240 6241 IStream_Release(stm); 6242 n++; 6243 } 6244 6245 ok(n == 3, "Expected 3, got %d\n", n); 6246 6247 IEnumSTATSTG_Release(stgenum); 6248 } 6249 6250 static void test_defaultdatabase(void) 6251 { 6252 UINT r; 6253 HRESULT hr; 6254 MSIHANDLE hdb; 6255 IStorage *stg = NULL; 6256 6257 DeleteFileA(msifile); 6258 6259 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6261 6262 r = MsiDatabaseCommit(hdb); 6263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6264 6265 MsiCloseHandle(hdb); 6266 6267 hr = StgOpenStorage(msifileW, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 6268 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 6269 ok(stg != NULL, "Expected non-NULL stg\n"); 6270 6271 enum_stream_names(stg); 6272 6273 IStorage_Release(stg); 6274 DeleteFileA(msifile); 6275 } 6276 6277 static void test_order(void) 6278 { 6279 MSIHANDLE hdb, hview, hrec; 6280 CHAR buffer[MAX_PATH]; 6281 LPCSTR query; 6282 UINT r, sz; 6283 int val; 6284 6285 hdb = create_db(); 6286 ok(hdb, "failed to create db\n"); 6287 6288 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)"; 6289 r = run_query(hdb, 0, query); 6290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6291 6292 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 6293 r = run_query(hdb, 0, query); 6294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6295 6296 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )"; 6297 r = run_query(hdb, 0, query); 6298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6299 6300 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )"; 6301 r = run_query(hdb, 0, query); 6302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6303 6304 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )"; 6305 r = run_query(hdb, 0, query); 6306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6307 6308 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)"; 6309 r = run_query(hdb, 0, query); 6310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6311 6312 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )"; 6313 r = run_query(hdb, 0, query); 6314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6315 6316 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )"; 6317 r = run_query(hdb, 0, query); 6318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6319 6320 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )"; 6321 r = run_query(hdb, 0, query); 6322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6323 6324 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`"; 6325 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6327 r = MsiViewExecute(hview, 0); 6328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6329 6330 r = MsiViewFetch(hview, &hrec); 6331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6332 6333 val = MsiRecordGetInteger(hrec, 1); 6334 ok(val == 3, "Expected 3, got %d\n", val); 6335 6336 val = MsiRecordGetInteger(hrec, 2); 6337 ok(val == 4, "Expected 3, got %d\n", val); 6338 6339 MsiCloseHandle(hrec); 6340 6341 r = MsiViewFetch(hview, &hrec); 6342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6343 6344 val = MsiRecordGetInteger(hrec, 1); 6345 ok(val == 5, "Expected 5, got %d\n", val); 6346 6347 val = MsiRecordGetInteger(hrec, 2); 6348 ok(val == 6, "Expected 6, got %d\n", val); 6349 6350 MsiCloseHandle(hrec); 6351 6352 r = MsiViewFetch(hview, &hrec); 6353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6354 6355 val = MsiRecordGetInteger(hrec, 1); 6356 ok(val == 1, "Expected 1, got %d\n", val); 6357 6358 val = MsiRecordGetInteger(hrec, 2); 6359 ok(val == 2, "Expected 2, got %d\n", val); 6360 6361 MsiCloseHandle(hrec); 6362 6363 r = MsiViewFetch(hview, &hrec); 6364 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6365 6366 MsiViewClose(hview); 6367 MsiCloseHandle(hview); 6368 6369 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`"; 6370 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6372 r = MsiViewExecute(hview, 0); 6373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6374 6375 r = MsiViewFetch(hview, &hrec); 6376 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6377 6378 val = MsiRecordGetInteger(hrec, 1); 6379 ok(val == 1, "Expected 1, got %d\n", val); 6380 6381 val = MsiRecordGetInteger(hrec, 2); 6382 ok(val == 12, "Expected 12, got %d\n", val); 6383 6384 MsiCloseHandle(hrec); 6385 6386 r = MsiViewFetch(hview, &hrec); 6387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6388 6389 val = MsiRecordGetInteger(hrec, 1); 6390 ok(val == 3, "Expected 3, got %d\n", val); 6391 6392 val = MsiRecordGetInteger(hrec, 2); 6393 ok(val == 12, "Expected 12, got %d\n", val); 6394 6395 MsiCloseHandle(hrec); 6396 6397 r = MsiViewFetch(hview, &hrec); 6398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6399 6400 val = MsiRecordGetInteger(hrec, 1); 6401 ok(val == 5, "Expected 5, got %d\n", val); 6402 6403 val = MsiRecordGetInteger(hrec, 2); 6404 ok(val == 12, "Expected 12, got %d\n", val); 6405 6406 MsiCloseHandle(hrec); 6407 6408 r = MsiViewFetch(hview, &hrec); 6409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6410 6411 val = MsiRecordGetInteger(hrec, 1); 6412 ok(val == 1, "Expected 1, got %d\n", val); 6413 6414 val = MsiRecordGetInteger(hrec, 2); 6415 ok(val == 14, "Expected 14, got %d\n", val); 6416 6417 MsiCloseHandle(hrec); 6418 6419 r = MsiViewFetch(hview, &hrec); 6420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6421 6422 val = MsiRecordGetInteger(hrec, 1); 6423 ok(val == 3, "Expected 3, got %d\n", val); 6424 6425 val = MsiRecordGetInteger(hrec, 2); 6426 ok(val == 14, "Expected 14, got %d\n", val); 6427 6428 MsiCloseHandle(hrec); 6429 6430 r = MsiViewFetch(hview, &hrec); 6431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6432 6433 val = MsiRecordGetInteger(hrec, 1); 6434 ok(val == 5, "Expected 5, got %d\n", val); 6435 6436 val = MsiRecordGetInteger(hrec, 2); 6437 ok(val == 14, "Expected 14, got %d\n", val); 6438 6439 MsiCloseHandle(hrec); 6440 6441 r = MsiViewFetch(hview, &hrec); 6442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6443 6444 val = MsiRecordGetInteger(hrec, 1); 6445 ok(val == 1, "Expected 1, got %d\n", val); 6446 6447 val = MsiRecordGetInteger(hrec, 2); 6448 ok(val == 10, "Expected 10, got %d\n", val); 6449 6450 MsiCloseHandle(hrec); 6451 6452 r = MsiViewFetch(hview, &hrec); 6453 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6454 6455 val = MsiRecordGetInteger(hrec, 1); 6456 ok(val == 3, "Expected 3, got %d\n", val); 6457 6458 val = MsiRecordGetInteger(hrec, 2); 6459 ok(val == 10, "Expected 10, got %d\n", val); 6460 6461 MsiCloseHandle(hrec); 6462 6463 r = MsiViewFetch(hview, &hrec); 6464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6465 6466 val = MsiRecordGetInteger(hrec, 1); 6467 ok(val == 5, "Expected 5, got %d\n", val); 6468 6469 val = MsiRecordGetInteger(hrec, 2); 6470 ok(val == 10, "Expected 10, got %d\n", val); 6471 6472 MsiCloseHandle(hrec); 6473 6474 r = MsiViewFetch(hview, &hrec); 6475 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6476 6477 MsiViewClose(hview); 6478 MsiCloseHandle(hview); 6479 6480 query = "SELECT * FROM `Empty` ORDER BY `A`"; 6481 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6483 r = MsiViewExecute(hview, 0); 6484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6485 6486 r = MsiViewFetch(hview, &hrec); 6487 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6488 6489 MsiViewClose(hview); 6490 MsiCloseHandle(hview); 6491 6492 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)"; 6493 r = run_query(hdb, 0, query); 6494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6495 6496 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)"; 6497 r = run_query(hdb, 0, query); 6498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6499 6500 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)"; 6501 r = run_query(hdb, 0, query); 6502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6503 6504 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)"; 6505 r = run_query(hdb, 0, query); 6506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6507 6508 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`"; 6509 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6511 r = MsiViewExecute(hview, 0); 6512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6513 6514 r = MsiViewFetch(hview, &hrec); 6515 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6516 6517 sz = sizeof(buffer); 6518 r = MsiRecordGetStringA(hrec, 1, buffer, &sz); 6519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6520 ok(!lstrcmpA(buffer, "dos"), "Expected \"dos\", got \"%s\"\n", buffer); 6521 6522 r = MsiRecordGetInteger(hrec, 2); 6523 ok(r == 3, "Expected 3, got %d\n", r); 6524 6525 MsiCloseHandle(hrec); 6526 6527 r = MsiViewFetch(hview, &hrec); 6528 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6529 6530 MsiViewClose(hview); 6531 MsiCloseHandle(hview); 6532 MsiCloseHandle(hdb); 6533 } 6534 6535 static void test_viewmodify_delete_temporary(void) 6536 { 6537 MSIHANDLE hdb, hview, hrec; 6538 const char *query; 6539 UINT r; 6540 6541 DeleteFileA(msifile); 6542 6543 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6545 6546 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )"; 6547 r = run_query(hdb, 0, query); 6548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6549 6550 query = "SELECT * FROM `Table`"; 6551 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6553 r = MsiViewExecute(hview, 0); 6554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6555 6556 hrec = MsiCreateRecord(1); 6557 MsiRecordSetInteger(hrec, 1, 1); 6558 6559 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6561 6562 MsiCloseHandle(hrec); 6563 6564 hrec = MsiCreateRecord(1); 6565 MsiRecordSetInteger(hrec, 1, 2); 6566 6567 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6569 6570 MsiCloseHandle(hrec); 6571 6572 hrec = MsiCreateRecord(1); 6573 MsiRecordSetInteger(hrec, 1, 3); 6574 6575 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); 6576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6577 6578 MsiCloseHandle(hrec); 6579 6580 hrec = MsiCreateRecord(1); 6581 MsiRecordSetInteger(hrec, 1, 4); 6582 6583 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 6584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6585 6586 MsiCloseHandle(hrec); 6587 MsiViewClose(hview); 6588 MsiCloseHandle(hview); 6589 6590 query = "SELECT * FROM `Table` WHERE `A` = 2"; 6591 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6593 r = MsiViewExecute(hview, 0); 6594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6595 r = MsiViewFetch(hview, &hrec); 6596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6597 6598 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6600 6601 MsiCloseHandle(hrec); 6602 MsiViewClose(hview); 6603 MsiCloseHandle(hview); 6604 6605 query = "SELECT * FROM `Table` WHERE `A` = 3"; 6606 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6608 r = MsiViewExecute(hview, 0); 6609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6610 r = MsiViewFetch(hview, &hrec); 6611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6612 6613 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); 6614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6615 6616 MsiCloseHandle(hrec); 6617 MsiViewClose(hview); 6618 MsiCloseHandle(hview); 6619 6620 query = "SELECT * FROM `Table` ORDER BY `A`"; 6621 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6622 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6623 r = MsiViewExecute(hview, 0); 6624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6625 6626 r = MsiViewFetch(hview, &hrec); 6627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6628 6629 r = MsiRecordGetInteger(hrec, 1); 6630 ok(r == 1, "Expected 1, got %d\n", r); 6631 6632 MsiCloseHandle(hrec); 6633 6634 r = MsiViewFetch(hview, &hrec); 6635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6636 6637 r = MsiRecordGetInteger(hrec, 1); 6638 ok(r == 4, "Expected 4, got %d\n", r); 6639 6640 MsiCloseHandle(hrec); 6641 6642 r = MsiViewFetch(hview, &hrec); 6643 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6644 6645 MsiViewClose(hview); 6646 MsiCloseHandle(hview); 6647 MsiCloseHandle(hdb); 6648 DeleteFileA(msifile); 6649 } 6650 6651 static void test_deleterow(void) 6652 { 6653 MSIHANDLE hdb, hview, hrec; 6654 const char *query; 6655 char buf[MAX_PATH]; 6656 UINT r; 6657 DWORD size; 6658 6659 DeleteFileA(msifile); 6660 6661 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6662 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6663 6664 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6665 r = run_query(hdb, 0, query); 6666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6667 6668 query = "INSERT INTO `Table` (`A`) VALUES ('one')"; 6669 r = run_query(hdb, 0, query); 6670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6671 6672 query = "INSERT INTO `Table` (`A`) VALUES ('two')"; 6673 r = run_query(hdb, 0, query); 6674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6675 6676 query = "DELETE FROM `Table` WHERE `A` = 'one'"; 6677 r = run_query(hdb, 0, query); 6678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6679 6680 r = MsiDatabaseCommit(hdb); 6681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6682 6683 MsiCloseHandle(hdb); 6684 6685 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb); 6686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6687 6688 query = "SELECT * FROM `Table`"; 6689 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6691 r = MsiViewExecute(hview, 0); 6692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6693 6694 r = MsiViewFetch(hview, &hrec); 6695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6696 6697 size = MAX_PATH; 6698 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6700 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf); 6701 6702 MsiCloseHandle(hrec); 6703 6704 r = MsiViewFetch(hview, &hrec); 6705 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6706 6707 MsiViewClose(hview); 6708 MsiCloseHandle(hview); 6709 MsiCloseHandle(hdb); 6710 DeleteFileA(msifile); 6711 } 6712 6713 static const CHAR import_dat[] = "A\n" 6714 "s72\n" 6715 "Table\tA\n" 6716 "This is a new 'string' ok\n"; 6717 6718 static void test_quotes(void) 6719 { 6720 MSIHANDLE hdb, hview, hrec; 6721 const char *query; 6722 char buf[MAX_PATH]; 6723 UINT r; 6724 DWORD size; 6725 6726 DeleteFileA(msifile); 6727 6728 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6730 6731 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6732 r = run_query(hdb, 0, query); 6733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6734 6735 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )"; 6736 r = run_query(hdb, 0, query); 6737 ok(r == ERROR_BAD_QUERY_SYNTAX, 6738 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6739 6740 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )"; 6741 r = run_query(hdb, 0, query); 6742 ok(r == ERROR_BAD_QUERY_SYNTAX, 6743 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6744 6745 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )"; 6746 r = run_query(hdb, 0, query); 6747 ok(r == ERROR_BAD_QUERY_SYNTAX, 6748 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6749 6750 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )"; 6751 r = run_query(hdb, 0, query); 6752 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6753 6754 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )"; 6755 r = run_query(hdb, 0, query); 6756 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6757 6758 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )"; 6759 r = run_query(hdb, 0, query); 6760 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6761 6762 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )"; 6763 r = run_query(hdb, 0, query); 6764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6765 6766 query = "SELECT * FROM `Table`"; 6767 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6769 6770 r = MsiViewExecute(hview, 0); 6771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6772 6773 r = MsiViewFetch(hview, &hrec); 6774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6775 6776 size = MAX_PATH; 6777 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6778 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6779 ok(!lstrcmpA(buf, "This is a \"string\" ok"), 6780 "Expected \"This is a \"string\" ok\", got %s\n", buf); 6781 6782 MsiCloseHandle(hrec); 6783 6784 r = MsiViewFetch(hview, &hrec); 6785 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6786 6787 MsiViewClose(hview); 6788 MsiCloseHandle(hview); 6789 6790 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char)); 6791 6792 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt"); 6793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6794 6795 DeleteFileA("import.idt"); 6796 6797 query = "SELECT * FROM `Table`"; 6798 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6800 6801 r = MsiViewExecute(hview, 0); 6802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6803 6804 r = MsiViewFetch(hview, &hrec); 6805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6806 6807 size = MAX_PATH; 6808 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6810 ok(!lstrcmpA(buf, "This is a new 'string' ok"), 6811 "Expected \"This is a new 'string' ok\", got %s\n", buf); 6812 6813 MsiCloseHandle(hrec); 6814 6815 r = MsiViewFetch(hview, &hrec); 6816 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 6817 6818 MsiViewClose(hview); 6819 MsiCloseHandle(hview); 6820 MsiCloseHandle(hdb); 6821 DeleteFileA(msifile); 6822 } 6823 6824 static void test_carriagereturn(void) 6825 { 6826 MSIHANDLE hdb, hview, hrec; 6827 const char *query; 6828 char buf[MAX_PATH]; 6829 UINT r; 6830 DWORD size; 6831 6832 DeleteFileA(msifile); 6833 6834 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 6835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6836 6837 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6838 r = run_query(hdb, 0, query); 6839 ok(r == ERROR_BAD_QUERY_SYNTAX, 6840 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6841 6842 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6843 r = run_query(hdb, 0, query); 6844 ok(r == ERROR_BAD_QUERY_SYNTAX, 6845 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6846 6847 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6848 r = run_query(hdb, 0, query); 6849 ok(r == ERROR_BAD_QUERY_SYNTAX, 6850 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6851 6852 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6853 r = run_query(hdb, 0, query); 6854 ok(r == ERROR_BAD_QUERY_SYNTAX, 6855 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6856 6857 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6858 r = run_query(hdb, 0, query); 6859 ok(r == ERROR_BAD_QUERY_SYNTAX, 6860 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6861 6862 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6863 r = run_query(hdb, 0, query); 6864 ok(r == ERROR_BAD_QUERY_SYNTAX, 6865 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6866 6867 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )"; 6868 r = run_query(hdb, 0, query); 6869 ok(r == ERROR_BAD_QUERY_SYNTAX, 6870 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6871 6872 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )"; 6873 r = run_query(hdb, 0, query); 6874 ok(r == ERROR_BAD_QUERY_SYNTAX, 6875 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6876 6877 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )"; 6878 r = run_query(hdb, 0, query); 6879 ok(r == ERROR_BAD_QUERY_SYNTAX, 6880 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6881 6882 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )"; 6883 r = run_query(hdb, 0, query); 6884 ok(r == ERROR_BAD_QUERY_SYNTAX, 6885 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6886 6887 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )"; 6888 r = run_query(hdb, 0, query); 6889 ok(r == ERROR_BAD_QUERY_SYNTAX, 6890 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6891 6892 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )"; 6893 r = run_query(hdb, 0, query); 6894 ok(r == ERROR_BAD_QUERY_SYNTAX, 6895 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6896 6897 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )"; 6898 r = run_query(hdb, 0, query); 6899 ok(r == ERROR_BAD_QUERY_SYNTAX, 6900 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6901 6902 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )"; 6903 r = run_query(hdb, 0, query); 6904 ok(r == ERROR_BAD_QUERY_SYNTAX, 6905 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6906 6907 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )"; 6908 r = run_query(hdb, 0, query); 6909 ok(r == ERROR_BAD_QUERY_SYNTAX, 6910 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6911 6912 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r"; 6913 r = run_query(hdb, 0, query); 6914 ok(r == ERROR_BAD_QUERY_SYNTAX, 6915 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6916 6917 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6918 r = run_query(hdb, 0, query); 6919 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6920 6921 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6922 r = run_query(hdb, 0, query); 6923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6924 6925 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6926 r = run_query(hdb, 0, query); 6927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6928 6929 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 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 `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 6935 r = run_query(hdb, 0, query); 6936 ok(r == ERROR_BAD_QUERY_SYNTAX, 6937 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6938 6939 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )"; 6940 r = run_query(hdb, 0, query); 6941 ok(r == ERROR_BAD_QUERY_SYNTAX, 6942 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6943 6944 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )"; 6945 r = run_query(hdb, 0, query); 6946 ok(r == ERROR_BAD_QUERY_SYNTAX, 6947 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6948 6949 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )"; 6950 r = run_query(hdb, 0, query); 6951 ok(r == ERROR_BAD_QUERY_SYNTAX, 6952 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6953 6954 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6955 r = run_query(hdb, 0, query); 6956 ok(r == ERROR_BAD_QUERY_SYNTAX, 6957 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6958 6959 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )"; 6960 r = run_query(hdb, 0, query); 6961 ok(r == ERROR_BAD_QUERY_SYNTAX, 6962 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 6963 6964 query = "SELECT * FROM `_Tables`"; 6965 r = MsiDatabaseOpenViewA(hdb, query, &hview); 6966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6967 r = MsiViewExecute(hview, 0); 6968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6969 6970 r = MsiViewFetch(hview, &hrec); 6971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6972 6973 size = MAX_PATH; 6974 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6976 ok(!lstrcmpA(buf, "\rOne"), "Expected \"\\rOne\", got \"%s\"\n", buf); 6977 6978 MsiCloseHandle(hrec); 6979 6980 r = MsiViewFetch(hview, &hrec); 6981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6982 6983 size = MAX_PATH; 6984 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6986 ok(!lstrcmpA(buf, "Tw\ro"), "Expected \"Tw\\ro\", got \"%s\"\n", buf); 6987 6988 MsiCloseHandle(hrec); 6989 6990 r = MsiViewFetch(hview, &hrec); 6991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6992 6993 size = MAX_PATH; 6994 r = MsiRecordGetStringA(hrec, 1, buf, &size); 6995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 6996 ok(!lstrcmpA(buf, "Three\r"), "Expected \"Three\r\", got \"%s\"\n", buf); 6997 6998 MsiCloseHandle(hrec); 6999 7000 r = MsiViewFetch(hview, &hrec); 7001 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7002 7003 MsiViewClose(hview); 7004 MsiCloseHandle(hview); 7005 7006 MsiCloseHandle(hdb); 7007 DeleteFileA(msifile); 7008 } 7009 7010 static void test_noquotes(void) 7011 { 7012 MSIHANDLE hdb, hview, hrec; 7013 const char *query; 7014 char buf[MAX_PATH]; 7015 UINT r; 7016 DWORD size; 7017 7018 DeleteFileA(msifile); 7019 7020 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7021 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7022 7023 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7024 r = run_query(hdb, 0, query); 7025 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7026 7027 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7028 r = run_query(hdb, 0, query); 7029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7030 7031 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )"; 7032 r = run_query(hdb, 0, query); 7033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7034 7035 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )"; 7036 r = run_query(hdb, 0, query); 7037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7038 7039 query = "SELECT * FROM `_Tables`"; 7040 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7042 r = MsiViewExecute(hview, 0); 7043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7044 7045 r = MsiViewFetch(hview, &hrec); 7046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7047 7048 size = MAX_PATH; 7049 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7051 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7052 7053 MsiCloseHandle(hrec); 7054 7055 r = MsiViewFetch(hview, &hrec); 7056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7057 7058 size = MAX_PATH; 7059 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7061 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7062 7063 MsiCloseHandle(hrec); 7064 7065 r = MsiViewFetch(hview, &hrec); 7066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7067 7068 size = MAX_PATH; 7069 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7071 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7072 7073 MsiCloseHandle(hrec); 7074 7075 r = MsiViewFetch(hview, &hrec); 7076 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7077 7078 MsiViewClose(hview); 7079 MsiCloseHandle(hview); 7080 7081 query = "SELECT * FROM `_Columns`"; 7082 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7084 r = MsiViewExecute(hview, 0); 7085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7086 7087 r = MsiViewFetch(hview, &hrec); 7088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7089 7090 size = MAX_PATH; 7091 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7093 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 7094 7095 r = MsiRecordGetInteger(hrec, 2); 7096 ok(r == 1, "Expected 1, got %d\n", r); 7097 7098 size = MAX_PATH; 7099 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7101 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7102 7103 MsiCloseHandle(hrec); 7104 7105 r = MsiViewFetch(hview, &hrec); 7106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7107 7108 size = MAX_PATH; 7109 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7111 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf); 7112 7113 r = MsiRecordGetInteger(hrec, 2); 7114 ok(r == 1, "Expected 1, got %d\n", r); 7115 7116 size = MAX_PATH; 7117 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7119 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7120 7121 MsiCloseHandle(hrec); 7122 7123 r = MsiViewFetch(hview, &hrec); 7124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7125 7126 size = MAX_PATH; 7127 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7129 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf); 7130 7131 r = MsiRecordGetInteger(hrec, 2); 7132 ok(r == 1, "Expected 1, got %d\n", r); 7133 7134 size = MAX_PATH; 7135 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7137 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7138 7139 MsiCloseHandle(hrec); 7140 7141 r = MsiViewFetch(hview, &hrec); 7142 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7143 7144 MsiViewClose(hview); 7145 MsiCloseHandle(hview); 7146 7147 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )"; 7148 r = run_query(hdb, 0, query); 7149 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7150 7151 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )"; 7152 r = run_query(hdb, 0, query); 7153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7154 7155 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )"; 7156 r = run_query(hdb, 0, query); 7157 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7158 7159 query = "SELECT * FROM Table WHERE `A` = 'hi'"; 7160 r = run_query(hdb, 0, query); 7161 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7162 7163 query = "SELECT * FROM `Table` WHERE `A` = hi"; 7164 r = run_query(hdb, 0, query); 7165 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7166 7167 query = "SELECT * FROM Table"; 7168 r = run_query(hdb, 0, query); 7169 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7170 7171 query = "SELECT * FROM Table2"; 7172 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7174 r = MsiViewExecute(hview, 0); 7175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7176 7177 r = MsiViewFetch(hview, &hrec); 7178 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7179 7180 MsiViewClose(hview); 7181 MsiCloseHandle(hview); 7182 7183 query = "SELECT * FROM `Table` WHERE A = 'hi'"; 7184 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7186 r = MsiViewExecute(hview, 0); 7187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7188 7189 r = MsiViewFetch(hview, &hrec); 7190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7191 7192 size = MAX_PATH; 7193 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7195 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 7196 7197 MsiCloseHandle(hrec); 7198 7199 r = MsiViewFetch(hview, &hrec); 7200 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7201 7202 MsiViewClose(hview); 7203 MsiCloseHandle(hview); 7204 MsiCloseHandle(hdb); 7205 DeleteFileA(msifile); 7206 } 7207 7208 static void read_file_data(LPCSTR filename, LPSTR buffer) 7209 { 7210 HANDLE file; 7211 DWORD read; 7212 7213 file = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); 7214 ZeroMemory(buffer, MAX_PATH); 7215 ReadFile(file, buffer, MAX_PATH, &read, NULL); 7216 CloseHandle(file); 7217 } 7218 7219 static void test_forcecodepage(void) 7220 { 7221 MSIHANDLE hdb; 7222 const char *query; 7223 char buffer[MAX_PATH]; 7224 UINT r; 7225 7226 DeleteFileA(msifile); 7227 GetCurrentDirectoryA(MAX_PATH, CURR_DIR); 7228 7229 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7231 7232 query = "SELECT * FROM `_ForceCodepage`"; 7233 r = run_query(hdb, 0, query); 7234 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7235 7236 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )"; 7237 r = run_query(hdb, 0, query); 7238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7239 7240 query = "SELECT * FROM `_ForceCodepage`"; 7241 r = run_query(hdb, 0, query); 7242 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7243 7244 r = MsiDatabaseCommit(hdb); 7245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7246 7247 query = "SELECT * FROM `_ForceCodepage`"; 7248 r = run_query(hdb, 0, query); 7249 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7250 7251 MsiCloseHandle(hdb); 7252 7253 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_DIRECT, &hdb); 7254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7255 7256 query = "SELECT * FROM `_ForceCodepage`"; 7257 r = run_query(hdb, 0, query); 7258 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7259 7260 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7262 7263 read_file_data("forcecodepage.idt", buffer); 7264 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"), 7265 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7266 7267 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 7268 7269 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7271 7272 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt"); 7273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7274 7275 read_file_data("forcecodepage.idt", buffer); 7276 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"), 7277 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer); 7278 7279 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0); 7280 7281 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); 7282 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7283 7284 MsiCloseHandle(hdb); 7285 DeleteFileA(msifile); 7286 DeleteFileA("forcecodepage.idt"); 7287 } 7288 7289 static void test_viewmodify_refresh(void) 7290 { 7291 MSIHANDLE hdb, hview, hrec; 7292 const char *query; 7293 char buffer[MAX_PATH]; 7294 UINT r; 7295 DWORD size; 7296 7297 DeleteFileA(msifile); 7298 7299 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7301 7302 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )"; 7303 r = run_query(hdb, 0, query); 7304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7305 7306 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 7307 r = run_query(hdb, 0, query); 7308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7309 7310 query = "SELECT * FROM `Table`"; 7311 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7313 r = MsiViewExecute(hview, 0); 7314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7315 7316 r = MsiViewFetch(hview, &hrec); 7317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7318 7319 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'"; 7320 r = run_query(hdb, 0, query); 7321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7322 7323 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7325 7326 size = MAX_PATH; 7327 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7329 ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer); 7330 ok(size == 2, "Expected 2, got %d\n", size); 7331 7332 r = MsiRecordGetInteger(hrec, 2); 7333 ok(r == 2, "Expected 2, got %d\n", r); 7334 7335 MsiCloseHandle(hrec); 7336 MsiViewClose(hview); 7337 MsiCloseHandle(hview); 7338 7339 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )"; 7340 r = run_query(hdb, 0, query); 7341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7342 7343 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7344 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7346 r = MsiViewExecute(hview, 0); 7347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7348 7349 r = MsiViewFetch(hview, &hrec); 7350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7351 7352 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'"; 7353 r = run_query(hdb, 0, query); 7354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7355 7356 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )"; 7357 r = run_query(hdb, 0, query); 7358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7359 7360 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7362 7363 size = MAX_PATH; 7364 r = MsiRecordGetStringA(hrec, 1, buffer, &size); 7365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7366 ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer); 7367 ok(size == 5, "Expected 5, got %d\n", size); 7368 7369 r = MsiRecordGetInteger(hrec, 2); 7370 ok(r == 2, "Expected 2, got %d\n", r); 7371 7372 MsiCloseHandle(hrec); 7373 MsiViewClose(hview); 7374 MsiCloseHandle(hview); 7375 MsiCloseHandle(hdb); 7376 DeleteFileA(msifile); 7377 } 7378 7379 static void test_where_viewmodify(void) 7380 { 7381 MSIHANDLE hdb, hview, hrec; 7382 const char *query; 7383 UINT r; 7384 7385 DeleteFileA(msifile); 7386 7387 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7389 7390 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 7391 r = run_query(hdb, 0, query); 7392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7393 7394 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )"; 7395 r = run_query(hdb, 0, query); 7396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7397 7398 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )"; 7399 r = run_query(hdb, 0, query); 7400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7401 7402 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )"; 7403 r = run_query(hdb, 0, query); 7404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7405 7406 /* `B` = 3 doesn't match, but the view shouldn't be executed */ 7407 query = "SELECT * FROM `Table` WHERE `B` = 3"; 7408 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7410 7411 hrec = MsiCreateRecord(2); 7412 MsiRecordSetInteger(hrec, 1, 7); 7413 MsiRecordSetInteger(hrec, 2, 8); 7414 7415 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); 7416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7417 7418 MsiCloseHandle(hrec); 7419 MsiViewClose(hview); 7420 MsiCloseHandle(hview); 7421 7422 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7423 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7425 r = MsiViewExecute(hview, 0); 7426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7427 7428 r = MsiViewFetch(hview, &hrec); 7429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7430 7431 r = MsiRecordGetInteger(hrec, 1); 7432 ok(r == 7, "Expected 7, got %d\n", r); 7433 7434 r = MsiRecordGetInteger(hrec, 2); 7435 ok(r == 8, "Expected 8, got %d\n", r); 7436 7437 MsiRecordSetInteger(hrec, 2, 9); 7438 7439 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); 7440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7441 7442 MsiCloseHandle(hrec); 7443 MsiViewClose(hview); 7444 MsiCloseHandle(hview); 7445 7446 query = "SELECT * FROM `Table` WHERE `A` = 7"; 7447 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7449 r = MsiViewExecute(hview, 0); 7450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7451 7452 r = MsiViewFetch(hview, &hrec); 7453 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7454 7455 r = MsiRecordGetInteger(hrec, 1); 7456 ok(r == 7, "Expected 7, got %d\n", r); 7457 7458 r = MsiRecordGetInteger(hrec, 2); 7459 ok(r == 9, "Expected 9, got %d\n", r); 7460 7461 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7"; 7462 r = run_query(hdb, 0, query); 7463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7464 7465 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); 7466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7467 7468 r = MsiRecordGetInteger(hrec, 1); 7469 ok(r == 7, "Expected 7, got %d\n", r); 7470 7471 r = MsiRecordGetInteger(hrec, 2); 7472 ok(r == 10, "Expected 10, got %d\n", r); 7473 7474 MsiCloseHandle(hrec); 7475 MsiViewClose(hview); 7476 MsiCloseHandle(hview); 7477 MsiCloseHandle(hdb); 7478 } 7479 7480 static BOOL create_storage(LPCSTR name) 7481 { 7482 WCHAR nameW[MAX_PATH]; 7483 IStorage *stg; 7484 IStream *stm; 7485 HRESULT hr; 7486 DWORD count; 7487 BOOL res = FALSE; 7488 7489 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, MAX_PATH); 7490 hr = StgCreateDocfile(nameW, STGM_CREATE | STGM_READWRITE | 7491 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &stg); 7492 if (FAILED(hr)) 7493 return FALSE; 7494 7495 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 7496 0, 0, &stm); 7497 if (FAILED(hr)) 7498 goto done; 7499 7500 hr = IStream_Write(stm, "stgdata", 8, &count); 7501 if (SUCCEEDED(hr)) 7502 res = TRUE; 7503 7504 done: 7505 IStream_Release(stm); 7506 IStorage_Release(stg); 7507 7508 return res; 7509 } 7510 7511 static void test_storages_table(void) 7512 { 7513 MSIHANDLE hdb, hview, hrec; 7514 IStorage *stg, *inner; 7515 IStream *stm; 7516 char file[MAX_PATH]; 7517 char buf[MAX_PATH]; 7518 WCHAR name[MAX_PATH]; 7519 LPCSTR query; 7520 HRESULT hr; 7521 DWORD size; 7522 UINT r; 7523 7524 hdb = create_db(); 7525 ok(hdb, "failed to create db\n"); 7526 7527 r = MsiDatabaseCommit(hdb); 7528 ok(r == ERROR_SUCCESS , "Failed to commit database\n"); 7529 7530 MsiCloseHandle(hdb); 7531 7532 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb); 7533 ok(r == ERROR_SUCCESS , "Failed to open database\n"); 7534 7535 /* check the column types */ 7536 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES); 7537 ok(hrec, "failed to get column info hrecord\n"); 7538 ok(check_record(hrec, 1, "s62"), "wrong hrecord type\n"); 7539 ok(check_record(hrec, 2, "V0"), "wrong hrecord type\n"); 7540 7541 MsiCloseHandle(hrec); 7542 7543 /* now try the names */ 7544 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES); 7545 ok(hrec, "failed to get column info hrecord\n"); 7546 ok(check_record(hrec, 1, "Name"), "wrong hrecord type\n"); 7547 ok(check_record(hrec, 2, "Data"), "wrong hrecord type\n"); 7548 7549 MsiCloseHandle(hrec); 7550 7551 create_storage("storage.bin"); 7552 7553 hrec = MsiCreateRecord(2); 7554 MsiRecordSetStringA(hrec, 1, "stgname"); 7555 7556 r = MsiRecordSetStreamA(hrec, 2, "storage.bin"); 7557 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r); 7558 7559 DeleteFileA("storage.bin"); 7560 7561 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)"; 7562 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7563 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7564 7565 r = MsiViewExecute(hview, hrec); 7566 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7567 7568 MsiCloseHandle(hrec); 7569 MsiViewClose(hview); 7570 MsiCloseHandle(hview); 7571 7572 query = "SELECT `Name`, `Data` FROM `_Storages`"; 7573 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7574 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r); 7575 7576 r = MsiViewExecute(hview, 0); 7577 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r); 7578 7579 r = MsiViewFetch(hview, &hrec); 7580 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r); 7581 7582 size = MAX_PATH; 7583 r = MsiRecordGetStringA(hrec, 1, file, &size); 7584 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r); 7585 ok(!lstrcmpA(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file); 7586 7587 size = MAX_PATH; 7588 lstrcpyA(buf, "apple"); 7589 r = MsiRecordReadStream(hrec, 2, buf, &size); 7590 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r); 7591 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf); 7592 ok(size == 0, "Expected 0, got %d\n", size); 7593 7594 MsiCloseHandle(hrec); 7595 7596 r = MsiViewFetch(hview, &hrec); 7597 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7598 7599 MsiViewClose(hview); 7600 MsiCloseHandle(hview); 7601 7602 MsiDatabaseCommit(hdb); 7603 MsiCloseHandle(hdb); 7604 7605 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, MAX_PATH); 7606 hr = StgOpenStorage(name, NULL, STGM_DIRECT | STGM_READ | 7607 STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 7608 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7609 ok(stg != NULL, "Expected non-NULL storage\n"); 7610 7611 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH); 7612 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 7613 NULL, 0, &inner); 7614 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7615 ok(inner != NULL, "Expected non-NULL storage\n"); 7616 7617 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH); 7618 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); 7619 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); 7620 ok(stm != NULL, "Expected non-NULL stream\n"); 7621 7622 hr = IStream_Read(stm, buf, MAX_PATH, &size); 7623 ok(hr == S_OK, "Expected S_OK, got %d\n", hr); 7624 ok(size == 8, "Expected 8, got %d\n", size); 7625 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf); 7626 7627 IStream_Release(stm); 7628 IStorage_Release(inner); 7629 7630 IStorage_Release(stg); 7631 DeleteFileA(msifile); 7632 } 7633 7634 static void test_dbtopackage(void) 7635 { 7636 MSIHANDLE hdb, hpkg; 7637 CHAR package[12], buf[MAX_PATH]; 7638 DWORD size; 7639 UINT r; 7640 7641 /* create an empty database, transact mode */ 7642 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7643 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7644 7645 set_summary_info(hdb); 7646 7647 create_directory_table(hdb); 7648 7649 create_custom_action_table(hdb); 7650 add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7651 7652 sprintf(package, "#%u", hdb); 7653 r = MsiOpenPackageA(package, &hpkg); 7654 if (r == ERROR_INSTALL_PACKAGE_REJECTED) 7655 { 7656 skip("Not enough rights to perform tests\n"); 7657 goto error; 7658 } 7659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7660 7661 /* property is not set yet */ 7662 size = MAX_PATH; 7663 lstrcpyA(buf, "kiwi"); 7664 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7666 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7667 ok(size == 0, "Expected 0, got %d\n", size); 7668 7669 /* run the custom action to set the property */ 7670 r = MsiDoActionA(hpkg, "SetProp"); 7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7672 7673 /* property is now set */ 7674 size = MAX_PATH; 7675 lstrcpyA(buf, "kiwi"); 7676 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7678 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7679 ok(size == 5, "Expected 5, got %d\n", size); 7680 7681 MsiCloseHandle(hpkg); 7682 7683 /* reset the package */ 7684 r = MsiOpenPackageA(package, &hpkg); 7685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7686 7687 /* property is not set anymore */ 7688 size = MAX_PATH; 7689 lstrcpyA(buf, "kiwi"); 7690 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7692 todo_wine 7693 { 7694 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7695 ok(size == 0, "Expected 0, got %d\n", size); 7696 } 7697 7698 MsiCloseHandle(hdb); 7699 MsiCloseHandle(hpkg); 7700 7701 /* create an empty database, direct mode */ 7702 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb); 7703 ok(r == ERROR_SUCCESS, "Failed to create database\n"); 7704 7705 set_summary_info(hdb); 7706 7707 create_directory_table(hdb); 7708 7709 create_custom_action_table(hdb); 7710 add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); 7711 7712 sprintf(package, "#%u", hdb); 7713 r = MsiOpenPackageA(package, &hpkg); 7714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7715 7716 /* property is not set yet */ 7717 size = MAX_PATH; 7718 lstrcpyA(buf, "kiwi"); 7719 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7720 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7721 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7722 ok(size == 0, "Expected 0, got %d\n", size); 7723 7724 /* run the custom action to set the property */ 7725 r = MsiDoActionA(hpkg, "SetProp"); 7726 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7727 7728 /* property is now set */ 7729 size = MAX_PATH; 7730 lstrcpyA(buf, "kiwi"); 7731 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7733 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf); 7734 ok(size == 5, "Expected 5, got %d\n", size); 7735 7736 MsiCloseHandle(hpkg); 7737 7738 /* reset the package */ 7739 r = MsiOpenPackageA(package, &hpkg); 7740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7741 7742 /* property is not set anymore */ 7743 size = MAX_PATH; 7744 lstrcpyA(buf, "kiwi"); 7745 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size); 7746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7747 todo_wine 7748 { 7749 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); 7750 ok(size == 0, "Expected 0, got %d\n", size); 7751 } 7752 7753 MsiCloseHandle(hpkg); 7754 7755 error: 7756 MsiCloseHandle(hdb); 7757 DeleteFileA(msifile); 7758 } 7759 7760 static void test_droptable(void) 7761 { 7762 MSIHANDLE hdb, hview, hrec; 7763 CHAR buf[MAX_PATH]; 7764 LPCSTR query; 7765 DWORD size; 7766 UINT r; 7767 7768 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7770 7771 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7772 r = run_query(hdb, 0, query); 7773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7774 7775 query = "SELECT * FROM `One`"; 7776 r = do_query(hdb, query, &hrec); 7777 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7778 7779 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7780 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7782 r = MsiViewExecute(hview, 0); 7783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7784 7785 r = MsiViewFetch(hview, &hrec); 7786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7787 7788 size = MAX_PATH; 7789 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7791 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7792 7793 MsiCloseHandle(hrec); 7794 MsiViewClose(hview); 7795 MsiCloseHandle(hview); 7796 7797 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7798 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7800 r = MsiViewExecute(hview, 0); 7801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7802 7803 r = MsiViewFetch(hview, &hrec); 7804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7805 7806 size = MAX_PATH; 7807 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7809 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7810 7811 r = MsiRecordGetInteger(hrec, 2); 7812 ok(r == 1, "Expected 1, got %d\n", r); 7813 7814 size = MAX_PATH; 7815 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7817 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf); 7818 7819 MsiCloseHandle(hrec); 7820 7821 r = MsiViewFetch(hview, &hrec); 7822 ok(r == ERROR_NO_MORE_ITEMS, 7823 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7824 7825 MsiViewClose(hview); 7826 MsiCloseHandle(hview); 7827 7828 query = "DROP `One`"; 7829 r = run_query(hdb, 0, query); 7830 ok(r == ERROR_BAD_QUERY_SYNTAX, 7831 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7832 7833 query = "DROP TABLE"; 7834 r = run_query(hdb, 0, query); 7835 ok(r == ERROR_BAD_QUERY_SYNTAX, 7836 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7837 7838 query = "DROP TABLE `One`"; 7839 hview = 0; 7840 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7842 r = MsiViewExecute(hview, 0); 7843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7844 7845 r = MsiViewFetch(hview, &hrec); 7846 ok(r == ERROR_FUNCTION_FAILED, 7847 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 7848 7849 MsiViewClose(hview); 7850 MsiCloseHandle(hview); 7851 7852 query = "SELECT * FROM `IDontExist`"; 7853 r = do_query(hdb, query, &hrec); 7854 ok(r == ERROR_BAD_QUERY_SYNTAX, 7855 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7856 7857 query = "SELECT * FROM `One`"; 7858 r = do_query(hdb, query, &hrec); 7859 ok(r == ERROR_BAD_QUERY_SYNTAX, 7860 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7861 7862 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 7863 r = run_query(hdb, 0, query); 7864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7865 7866 query = "DROP TABLE One"; 7867 r = run_query(hdb, 0, query); 7868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7869 7870 query = "SELECT * FROM `One`"; 7871 r = do_query(hdb, query, &hrec); 7872 ok(r == ERROR_BAD_QUERY_SYNTAX, 7873 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7874 7875 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7876 r = do_query(hdb, query, &hrec); 7877 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7878 7879 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7880 r = do_query(hdb, query, &hrec); 7881 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7882 7883 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )"; 7884 r = run_query(hdb, 0, query); 7885 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7886 7887 query = "SELECT * FROM `One`"; 7888 r = do_query(hdb, query, &hrec); 7889 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7890 7891 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7892 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7894 r = MsiViewExecute(hview, 0); 7895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7896 7897 r = MsiViewFetch(hview, &hrec); 7898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7899 7900 size = MAX_PATH; 7901 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7903 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7904 7905 MsiCloseHandle(hrec); 7906 MsiViewClose(hview); 7907 MsiCloseHandle(hview); 7908 7909 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7910 r = MsiDatabaseOpenViewA(hdb, query, &hview); 7911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7912 r = MsiViewExecute(hview, 0); 7913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7914 7915 r = MsiViewFetch(hview, &hrec); 7916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7917 7918 size = MAX_PATH; 7919 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7921 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7922 7923 r = MsiRecordGetInteger(hrec, 2); 7924 ok(r == 1, "Expected 1, got %d\n", r); 7925 7926 size = MAX_PATH; 7927 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7929 ok(!lstrcmpA(buf, "B"), "Expected \"B\", got \"%s\"\n", buf); 7930 7931 MsiCloseHandle(hrec); 7932 7933 r = MsiViewFetch(hview, &hrec); 7934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7935 7936 size = MAX_PATH; 7937 r = MsiRecordGetStringA(hrec, 1, buf, &size); 7938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7939 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 7940 7941 r = MsiRecordGetInteger(hrec, 2); 7942 ok(r == 2, "Expected 2, got %d\n", r); 7943 7944 size = MAX_PATH; 7945 r = MsiRecordGetStringA(hrec, 3, buf, &size); 7946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7947 ok(!lstrcmpA(buf, "C"), "Expected \"C\", got \"%s\"\n", buf); 7948 7949 MsiCloseHandle(hrec); 7950 7951 r = MsiViewFetch(hview, &hrec); 7952 ok(r == ERROR_NO_MORE_ITEMS, 7953 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7954 7955 MsiViewClose(hview); 7956 MsiCloseHandle(hview); 7957 7958 query = "DROP TABLE One"; 7959 r = run_query(hdb, 0, query); 7960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7961 7962 query = "SELECT * FROM `One`"; 7963 r = do_query(hdb, query, &hrec); 7964 ok(r == ERROR_BAD_QUERY_SYNTAX, 7965 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 7966 7967 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'"; 7968 r = do_query(hdb, query, &hrec); 7969 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7970 7971 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'"; 7972 r = do_query(hdb, query, &hrec); 7973 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 7974 7975 MsiCloseHandle(hdb); 7976 DeleteFileA(msifile); 7977 } 7978 7979 static void test_dbmerge(void) 7980 { 7981 static const WCHAR refdbW[] = {'r','e','f','d','b','.','m','s','i',0}; 7982 MSIHANDLE hdb, href, hview, hrec; 7983 CHAR buf[MAX_PATH]; 7984 LPCSTR query; 7985 DWORD size; 7986 UINT r; 7987 7988 r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); 7989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7990 7991 r = MsiOpenDatabaseW(refdbW, MSIDBOPEN_CREATE, &href); 7992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 7993 7994 /* hDatabase is invalid */ 7995 r = MsiDatabaseMergeA(0, href, "MergeErrors"); 7996 ok(r == ERROR_INVALID_HANDLE, 7997 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 7998 7999 /* hDatabaseMerge is invalid */ 8000 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors"); 8001 ok(r == ERROR_INVALID_HANDLE, 8002 "Expected ERROR_INVALID_HANDLE, got %d\n", r); 8003 8004 /* szTableName is NULL */ 8005 r = MsiDatabaseMergeA(hdb, href, NULL); 8006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8007 8008 /* szTableName is empty */ 8009 r = MsiDatabaseMergeA(hdb, href, ""); 8010 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r); 8011 8012 /* both DBs empty, szTableName is valid */ 8013 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8015 8016 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )"; 8017 r = run_query(hdb, 0, query); 8018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8019 8020 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )"; 8021 r = run_query(href, 0, query); 8022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8023 8024 /* column types don't match */ 8025 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8026 ok(r == ERROR_DATATYPE_MISMATCH, 8027 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8028 8029 /* nothing in MergeErrors */ 8030 query = "SELECT * FROM `MergeErrors`"; 8031 r = do_query(hdb, query, &hrec); 8032 ok(r == ERROR_BAD_QUERY_SYNTAX, 8033 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8034 8035 query = "DROP TABLE `One`"; 8036 r = run_query(hdb, 0, query); 8037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8038 8039 query = "DROP TABLE `One`"; 8040 r = run_query(href, 0, query); 8041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8042 8043 query = "CREATE TABLE `One` ( " 8044 "`A` CHAR(72), " 8045 "`B` CHAR(56), " 8046 "`C` CHAR(64) LOCALIZABLE, " 8047 "`D` LONGCHAR, " 8048 "`E` CHAR(72) NOT NULL, " 8049 "`F` CHAR(56) NOT NULL, " 8050 "`G` CHAR(64) NOT NULL LOCALIZABLE, " 8051 "`H` LONGCHAR NOT NULL " 8052 "PRIMARY KEY `A` )"; 8053 r = run_query(hdb, 0, query); 8054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8055 8056 query = "CREATE TABLE `One` ( " 8057 "`A` CHAR(64), " 8058 "`B` CHAR(64), " 8059 "`C` CHAR(64), " 8060 "`D` CHAR(64), " 8061 "`E` CHAR(64) NOT NULL, " 8062 "`F` CHAR(64) NOT NULL, " 8063 "`G` CHAR(64) NOT NULL, " 8064 "`H` CHAR(64) NOT NULL " 8065 "PRIMARY KEY `A` )"; 8066 r = run_query(href, 0, query); 8067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8068 8069 /* column string types don't match exactly */ 8070 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8071 ok(r == ERROR_SUCCESS, 8072 "Expected ERROR_SUCCESS, got %d\n", r); 8073 8074 /* nothing in MergeErrors */ 8075 query = "SELECT * FROM `MergeErrors`"; 8076 r = do_query(hdb, query, &hrec); 8077 ok(r == ERROR_BAD_QUERY_SYNTAX, 8078 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8079 8080 query = "DROP TABLE `One`"; 8081 r = run_query(hdb, 0, query); 8082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8083 8084 query = "DROP TABLE `One`"; 8085 r = run_query(href, 0, query); 8086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8087 8088 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8089 r = run_query(hdb, 0, query); 8090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8091 8092 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )"; 8093 r = run_query(href, 0, query); 8094 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8095 8096 /* column names don't match */ 8097 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8098 ok(r == ERROR_DATATYPE_MISMATCH, 8099 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8100 8101 /* nothing in MergeErrors */ 8102 query = "SELECT * FROM `MergeErrors`"; 8103 r = do_query(hdb, query, &hrec); 8104 ok(r == ERROR_BAD_QUERY_SYNTAX, 8105 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8106 8107 query = "DROP TABLE `One`"; 8108 r = run_query(hdb, 0, query); 8109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8110 8111 query = "DROP TABLE `One`"; 8112 r = run_query(href, 0, query); 8113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8114 8115 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8116 r = run_query(hdb, 0, query); 8117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8118 8119 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )"; 8120 r = run_query(href, 0, query); 8121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8122 8123 /* primary keys don't match */ 8124 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8125 ok(r == ERROR_DATATYPE_MISMATCH, 8126 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8127 8128 /* nothing in MergeErrors */ 8129 query = "SELECT * FROM `MergeErrors`"; 8130 r = do_query(hdb, query, &hrec); 8131 ok(r == ERROR_BAD_QUERY_SYNTAX, 8132 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8133 8134 query = "DROP TABLE `One`"; 8135 r = run_query(hdb, 0, query); 8136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8137 8138 query = "DROP TABLE `One`"; 8139 r = run_query(href, 0, query); 8140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8141 8142 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8143 r = run_query(hdb, 0, query); 8144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8145 8146 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )"; 8147 r = run_query(href, 0, query); 8148 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8149 8150 /* number of primary keys doesn't match */ 8151 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8152 ok(r == ERROR_DATATYPE_MISMATCH, 8153 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r); 8154 8155 /* nothing in MergeErrors */ 8156 query = "SELECT * FROM `MergeErrors`"; 8157 r = do_query(hdb, query, &hrec); 8158 ok(r == ERROR_BAD_QUERY_SYNTAX, 8159 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8160 8161 query = "DROP TABLE `One`"; 8162 r = run_query(hdb, 0, query); 8163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8164 8165 query = "DROP TABLE `One`"; 8166 r = run_query(href, 0, query); 8167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8168 8169 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8170 r = run_query(hdb, 0, query); 8171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8172 8173 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8174 r = run_query(href, 0, query); 8175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8176 8177 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8178 r = run_query(href, 0, query); 8179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8180 8181 /* number of columns doesn't match */ 8182 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8184 8185 query = "SELECT * FROM `One`"; 8186 r = do_query(hdb, query, &hrec); 8187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8188 8189 r = MsiRecordGetInteger(hrec, 1); 8190 ok(r == 1, "Expected 1, got %d\n", r); 8191 8192 r = MsiRecordGetInteger(hrec, 2); 8193 ok(r == 2, "Expected 2, got %d\n", r); 8194 8195 r = MsiRecordGetInteger(hrec, 3); 8196 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8197 8198 MsiCloseHandle(hrec); 8199 8200 /* nothing in MergeErrors */ 8201 query = "SELECT * FROM `MergeErrors`"; 8202 r = do_query(hdb, query, &hrec); 8203 ok(r == ERROR_BAD_QUERY_SYNTAX, 8204 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8205 8206 query = "DROP TABLE `One`"; 8207 r = run_query(hdb, 0, query); 8208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8209 8210 query = "DROP TABLE `One`"; 8211 r = run_query(href, 0, query); 8212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8213 8214 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8215 r = run_query(hdb, 0, query); 8216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8217 8218 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )"; 8219 r = run_query(href, 0, query); 8220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8221 8222 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8223 r = run_query(href, 0, query); 8224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8225 8226 /* number of columns doesn't match */ 8227 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8229 8230 query = "SELECT * FROM `One`"; 8231 r = do_query(hdb, query, &hrec); 8232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8233 8234 r = MsiRecordGetInteger(hrec, 1); 8235 ok(r == 1, "Expected 1, got %d\n", r); 8236 8237 r = MsiRecordGetInteger(hrec, 2); 8238 ok(r == 2, "Expected 2, got %d\n", r); 8239 8240 r = MsiRecordGetInteger(hrec, 3); 8241 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); 8242 8243 MsiCloseHandle(hrec); 8244 8245 /* nothing in MergeErrors */ 8246 query = "SELECT * FROM `MergeErrors`"; 8247 r = do_query(hdb, query, &hrec); 8248 ok(r == ERROR_BAD_QUERY_SYNTAX, 8249 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8250 8251 query = "DROP TABLE `One`"; 8252 r = run_query(hdb, 0, query); 8253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8254 8255 query = "DROP TABLE `One`"; 8256 r = run_query(href, 0, query); 8257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8258 8259 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8260 r = run_query(hdb, 0, query); 8261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8262 8263 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )"; 8264 r = run_query(hdb, 0, query); 8265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8266 8267 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )"; 8268 r = run_query(hdb, 0, query); 8269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8270 8271 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )"; 8272 r = run_query(href, 0, query); 8273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8274 8275 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )"; 8276 r = run_query(href, 0, query); 8277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8278 8279 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )"; 8280 r = run_query(href, 0, query); 8281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8282 8283 /* primary keys match, rows do not */ 8284 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8285 ok(r == ERROR_FUNCTION_FAILED, 8286 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8287 8288 /* nothing in MergeErrors */ 8289 query = "SELECT * FROM `MergeErrors`"; 8290 r = do_query(hdb, query, &hrec); 8291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8292 8293 size = MAX_PATH; 8294 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8295 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8296 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf); 8297 8298 r = MsiRecordGetInteger(hrec, 2); 8299 ok(r == 2, "Expected 2, got %d\n", r); 8300 8301 MsiCloseHandle(hrec); 8302 8303 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview); 8304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8305 8306 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec); 8307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8308 8309 size = MAX_PATH; 8310 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8312 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf); 8313 8314 size = MAX_PATH; 8315 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8317 ok(!lstrcmpA(buf, "NumRowMergeConflicts"), 8318 "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf); 8319 8320 MsiCloseHandle(hrec); 8321 8322 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec); 8323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8324 8325 size = MAX_PATH; 8326 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8328 ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf); 8329 8330 size = MAX_PATH; 8331 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8333 ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf); 8334 8335 MsiCloseHandle(hrec); 8336 MsiViewClose(hview); 8337 MsiCloseHandle(hview); 8338 8339 query = "DROP TABLE `MergeErrors`"; 8340 r = run_query(hdb, 0, query); 8341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8342 8343 query = "DROP TABLE `One`"; 8344 r = run_query(hdb, 0, query); 8345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8346 8347 query = "DROP TABLE `One`"; 8348 r = run_query(href, 0, query); 8349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8350 8351 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8352 r = run_query(href, 0, query); 8353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8354 8355 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8356 r = run_query(href, 0, query); 8357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8358 8359 /* table from merged database is not in target database */ 8360 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8362 8363 query = "SELECT * FROM `One`"; 8364 r = do_query(hdb, query, &hrec); 8365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8366 8367 r = MsiRecordGetInteger(hrec, 1); 8368 ok(r == 1, "Expected 1, got %d\n", r); 8369 8370 size = MAX_PATH; 8371 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8373 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8374 8375 MsiCloseHandle(hrec); 8376 8377 /* nothing in MergeErrors */ 8378 query = "SELECT * FROM `MergeErrors`"; 8379 r = do_query(hdb, query, &hrec); 8380 ok(r == ERROR_BAD_QUERY_SYNTAX, 8381 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8382 8383 query = "DROP TABLE `One`"; 8384 r = run_query(hdb, 0, query); 8385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8386 8387 query = "DROP TABLE `One`"; 8388 r = run_query(href, 0, query); 8389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8390 8391 query = "CREATE TABLE `One` ( " 8392 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8393 r = run_query(hdb, 0, query); 8394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8395 8396 query = "CREATE TABLE `One` ( " 8397 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )"; 8398 r = run_query(href, 0, query); 8399 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8400 8401 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )"; 8402 r = run_query(href, 0, query); 8403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8404 8405 /* primary key is string */ 8406 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8408 8409 query = "SELECT * FROM `One`"; 8410 r = do_query(hdb, query, &hrec); 8411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8412 8413 size = MAX_PATH; 8414 r = MsiRecordGetStringA(hrec, 1, buf, &size); 8415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8416 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8417 8418 r = MsiRecordGetInteger(hrec, 2); 8419 ok(r == 1, "Expected 1, got %d\n", r); 8420 8421 MsiCloseHandle(hrec); 8422 8423 /* nothing in MergeErrors */ 8424 query = "SELECT * FROM `MergeErrors`"; 8425 r = do_query(hdb, query, &hrec); 8426 ok(r == ERROR_BAD_QUERY_SYNTAX, 8427 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8428 8429 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0); 8430 8431 GetCurrentDirectoryA(MAX_PATH, buf); 8432 r = MsiDatabaseImportA(hdb, buf, "codepage.idt"); 8433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8434 8435 query = "DROP TABLE `One`"; 8436 r = run_query(hdb, 0, query); 8437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8438 8439 query = "DROP TABLE `One`"; 8440 r = run_query(href, 0, query); 8441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8442 8443 query = "CREATE TABLE `One` ( " 8444 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8445 r = run_query(hdb, 0, query); 8446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8447 8448 query = "CREATE TABLE `One` ( " 8449 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )"; 8450 r = run_query(href, 0, query); 8451 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8452 8453 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )"; 8454 r = run_query(href, 0, query); 8455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8456 8457 /* code page does not match */ 8458 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8460 8461 query = "SELECT * FROM `One`"; 8462 r = do_query(hdb, query, &hrec); 8463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8464 8465 r = MsiRecordGetInteger(hrec, 1); 8466 ok(r == 1, "Expected 1, got %d\n", r); 8467 8468 size = MAX_PATH; 8469 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8471 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf); 8472 8473 MsiCloseHandle(hrec); 8474 8475 /* nothing in MergeErrors */ 8476 query = "SELECT * FROM `MergeErrors`"; 8477 r = do_query(hdb, query, &hrec); 8478 ok(r == ERROR_BAD_QUERY_SYNTAX, 8479 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8480 8481 query = "DROP TABLE `One`"; 8482 r = run_query(hdb, 0, query); 8483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8484 8485 query = "DROP TABLE `One`"; 8486 r = run_query(href, 0, query); 8487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8488 8489 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8490 r = run_query(hdb, 0, query); 8491 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8492 8493 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )"; 8494 r = run_query(href, 0, query); 8495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8496 8497 create_file("binary.dat"); 8498 hrec = MsiCreateRecord(1); 8499 MsiRecordSetStreamA(hrec, 1, "binary.dat"); 8500 8501 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )"; 8502 r = run_query(href, hrec, query); 8503 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8504 8505 MsiCloseHandle(hrec); 8506 8507 /* binary data to merge */ 8508 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8510 8511 query = "SELECT * FROM `One`"; 8512 r = do_query(hdb, query, &hrec); 8513 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8514 8515 r = MsiRecordGetInteger(hrec, 1); 8516 ok(r == 1, "Expected 1, got %d\n", r); 8517 8518 size = MAX_PATH; 8519 ZeroMemory(buf, MAX_PATH); 8520 r = MsiRecordReadStream(hrec, 2, buf, &size); 8521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8522 ok(!lstrcmpA(buf, "binary.dat\n"), 8523 "Expected \"binary.dat\\n\", got \"%s\"\n", buf); 8524 8525 MsiCloseHandle(hrec); 8526 8527 /* nothing in MergeErrors */ 8528 query = "SELECT * FROM `MergeErrors`"; 8529 r = do_query(hdb, query, &hrec); 8530 ok(r == ERROR_BAD_QUERY_SYNTAX, 8531 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8532 8533 query = "DROP TABLE `One`"; 8534 r = run_query(hdb, 0, query); 8535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8536 8537 query = "DROP TABLE `One`"; 8538 r = run_query(href, 0, query); 8539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8540 8541 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )"; 8542 r = run_query(hdb, 0, query); 8543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8544 r = run_query(href, 0, query); 8545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8546 8547 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )"; 8548 r = run_query(href, 0, query); 8549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8550 8551 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )"; 8552 r = run_query(href, 0, query); 8553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8554 8555 r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); 8556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8557 8558 query = "SELECT * FROM `One`"; 8559 r = MsiDatabaseOpenViewA(hdb, query, &hview); 8560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8561 r = MsiViewExecute(hview, 0); 8562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8563 8564 r = MsiViewFetch(hview, &hrec); 8565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8566 8567 r = MsiRecordGetInteger(hrec, 1); 8568 ok(r == 1, "Expected 1, got %d\n", r); 8569 8570 size = MAX_PATH; 8571 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8573 ok(!lstrcmpA(buf, "foo"), "Expected \"foo\", got \"%s\"\n", buf); 8574 8575 MsiCloseHandle(hrec); 8576 8577 r = MsiViewFetch(hview, &hrec); 8578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8579 8580 r = MsiRecordGetInteger(hrec, 1); 8581 ok(r == 2, "Expected 2, got %d\n", r); 8582 8583 size = MAX_PATH; 8584 r = MsiRecordGetStringA(hrec, 2, buf, &size); 8585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8586 ok(!lstrcmpA(buf, "bar"), "Expected \"bar\", got \"%s\"\n", buf); 8587 8588 MsiCloseHandle(hrec); 8589 8590 r = MsiViewFetch(hview, &hrec); 8591 ok(r == ERROR_NO_MORE_ITEMS, 8592 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8593 8594 MsiViewClose(hview); 8595 MsiCloseHandle(hview); 8596 8597 MsiCloseHandle(hdb); 8598 MsiCloseHandle(href); 8599 DeleteFileA(msifile); 8600 DeleteFileW(refdbW); 8601 DeleteFileA("codepage.idt"); 8602 DeleteFileA("binary.dat"); 8603 } 8604 8605 static void test_select_with_tablenames(void) 8606 { 8607 MSIHANDLE hdb, view, rec; 8608 LPCSTR query; 8609 UINT r; 8610 int i; 8611 8612 int vals[4][2] = { 8613 {1,12}, 8614 {4,12}, 8615 {1,15}, 8616 {4,15}}; 8617 8618 hdb = create_db(); 8619 ok(hdb, "failed to create db\n"); 8620 8621 /* Build a pair of tables with the same column names, but unique data */ 8622 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8623 r = run_query(hdb, 0, query); 8624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8625 8626 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )"; 8627 r = run_query(hdb, 0, query); 8628 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8629 8630 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )"; 8631 r = run_query(hdb, 0, query); 8632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8633 8634 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)"; 8635 r = run_query(hdb, 0, query); 8636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8637 8638 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )"; 8639 r = run_query(hdb, 0, query); 8640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8641 8642 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )"; 8643 r = run_query(hdb, 0, query); 8644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8645 8646 8647 /* Test that selection based on prefixing the column with the table 8648 * actually selects the right data */ 8649 8650 query = "SELECT T1.A, T2.B FROM T1,T2"; 8651 r = MsiDatabaseOpenViewA(hdb, query, &view); 8652 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8653 r = MsiViewExecute(view, 0); 8654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8655 8656 for (i = 0; i < 4; i++) 8657 { 8658 r = MsiViewFetch(view, &rec); 8659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8660 8661 r = MsiRecordGetInteger(rec, 1); 8662 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r); 8663 8664 r = MsiRecordGetInteger(rec, 2); 8665 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r); 8666 8667 MsiCloseHandle(rec); 8668 } 8669 8670 r = MsiViewFetch(view, &rec); 8671 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8672 8673 MsiViewClose(view); 8674 MsiCloseHandle(view); 8675 MsiCloseHandle(hdb); 8676 DeleteFileA(msifile); 8677 } 8678 8679 static const UINT ordervals[6][3] = 8680 { 8681 { MSI_NULL_INTEGER, 12, 13 }, 8682 { 1, 2, 3 }, 8683 { 6, 4, 5 }, 8684 { 8, 9, 7 }, 8685 { 10, 11, MSI_NULL_INTEGER }, 8686 { 14, MSI_NULL_INTEGER, 15 } 8687 }; 8688 8689 static void test_insertorder(void) 8690 { 8691 MSIHANDLE hdb, view, rec; 8692 LPCSTR query; 8693 UINT r; 8694 int i; 8695 8696 hdb = create_db(); 8697 ok(hdb, "failed to create db\n"); 8698 8699 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)"; 8700 r = run_query(hdb, 0, query); 8701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8702 8703 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )"; 8704 r = run_query(hdb, 0, query); 8705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8706 8707 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )"; 8708 r = run_query(hdb, 0, query); 8709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8710 8711 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )"; 8712 r = run_query(hdb, 0, query); 8713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8714 8715 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )"; 8716 r = run_query(hdb, 0, query); 8717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8718 8719 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )"; 8720 r = run_query(hdb, 0, query); 8721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8722 8723 /* fails because the primary key already 8724 * has an MSI_NULL_INTEGER value set above 8725 */ 8726 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )"; 8727 r = run_query(hdb, 0, query); 8728 ok(r == ERROR_FUNCTION_FAILED, 8729 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8730 8731 /* replicate the error where primary key is set twice */ 8732 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 14 )"; 8733 r = run_query(hdb, 0, query); 8734 ok(r == ERROR_FUNCTION_FAILED, 8735 "Expected ERROR_FUNCTION_FAILED, got %d\n", r); 8736 8737 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )"; 8738 r = run_query(hdb, 0, query); 8739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8740 8741 query = "INSERT INTO `T` VALUES ( 16 )"; 8742 r = run_query(hdb, 0, query); 8743 ok(r == ERROR_BAD_QUERY_SYNTAX, 8744 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8745 8746 query = "INSERT INTO `T` VALUES ( 17, 18 )"; 8747 r = run_query(hdb, 0, query); 8748 ok(r == ERROR_BAD_QUERY_SYNTAX, 8749 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8750 8751 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )"; 8752 r = run_query(hdb, 0, query); 8753 ok(r == ERROR_BAD_QUERY_SYNTAX, 8754 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r); 8755 8756 query = "SELECT * FROM `T`"; 8757 r = MsiDatabaseOpenViewA(hdb, query, &view); 8758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8759 r = MsiViewExecute(view, 0); 8760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8761 8762 for (i = 0; i < 6; i++) 8763 { 8764 r = MsiViewFetch(view, &rec); 8765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8766 8767 r = MsiRecordGetInteger(rec, 1); 8768 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8769 8770 r = MsiRecordGetInteger(rec, 2); 8771 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8772 8773 r = MsiRecordGetInteger(rec, 3); 8774 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8775 8776 MsiCloseHandle(rec); 8777 } 8778 8779 r = MsiViewFetch(view, &rec); 8780 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8781 8782 MsiViewClose(view); 8783 MsiCloseHandle(view); 8784 8785 query = "DELETE FROM `T` WHERE `A` IS NULL"; 8786 r = run_query(hdb, 0, query); 8787 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8788 8789 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY"; 8790 r = run_query(hdb, 0, query); 8791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8792 8793 query = "SELECT * FROM `T`"; 8794 r = MsiDatabaseOpenViewA(hdb, query, &view); 8795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8796 r = MsiViewExecute(view, 0); 8797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8798 8799 for (i = 0; i < 6; i++) 8800 { 8801 r = MsiViewFetch(view, &rec); 8802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8803 8804 r = MsiRecordGetInteger(rec, 1); 8805 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r); 8806 8807 r = MsiRecordGetInteger(rec, 2); 8808 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r); 8809 8810 r = MsiRecordGetInteger(rec, 3); 8811 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r); 8812 8813 MsiCloseHandle(rec); 8814 } 8815 8816 r = MsiViewFetch(view, &rec); 8817 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 8818 8819 MsiViewClose(view); 8820 MsiCloseHandle(view); 8821 MsiCloseHandle(hdb); 8822 DeleteFileA(msifile); 8823 } 8824 8825 static void test_columnorder(void) 8826 { 8827 MSIHANDLE hdb, view, rec; 8828 char buf[MAX_PATH]; 8829 LPCSTR query; 8830 DWORD sz; 8831 UINT r; 8832 8833 hdb = create_db(); 8834 ok(hdb, "failed to create db\n"); 8835 8836 /* Each column is a slot: 8837 * --------------------- 8838 * | B | C | A | E | D | 8839 * --------------------- 8840 * 8841 * When a column is selected as a primary key, 8842 * the column occupying the nth primary key slot is swapped 8843 * with the current position of the primary key in question: 8844 * 8845 * set primary key `D` 8846 * --------------------- --------------------- 8847 * | B | C | A | E | D | -> | D | C | A | E | B | 8848 * --------------------- --------------------- 8849 * 8850 * set primary key `E` 8851 * --------------------- --------------------- 8852 * | D | C | A | E | B | -> | D | E | A | C | B | 8853 * --------------------- --------------------- 8854 */ 8855 8856 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 8857 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 8858 "PRIMARY KEY `D`, `E`)"; 8859 r = run_query(hdb, 0, query); 8860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8861 8862 query = "SELECT * FROM `T`"; 8863 r = MsiDatabaseOpenViewA(hdb, query, &view); 8864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8865 8866 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 8867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8868 8869 sz = MAX_PATH; 8870 lstrcpyA(buf, "kiwi"); 8871 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8873 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf); 8874 8875 sz = MAX_PATH; 8876 lstrcpyA(buf, "kiwi"); 8877 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8879 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 8880 8881 sz = MAX_PATH; 8882 lstrcpyA(buf, "kiwi"); 8883 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8885 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 8886 8887 sz = MAX_PATH; 8888 lstrcpyA(buf, "kiwi"); 8889 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8891 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 8892 8893 sz = MAX_PATH; 8894 lstrcpyA(buf, "kiwi"); 8895 r = MsiRecordGetStringA(rec, 5, buf, &sz); 8896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8897 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 8898 8899 MsiCloseHandle(rec); 8900 8901 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 8902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8903 8904 sz = MAX_PATH; 8905 lstrcpyA(buf, "kiwi"); 8906 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8908 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 8909 8910 sz = MAX_PATH; 8911 lstrcpyA(buf, "kiwi"); 8912 r = MsiRecordGetStringA(rec, 2, buf, &sz); 8913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8914 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 8915 8916 sz = MAX_PATH; 8917 lstrcpyA(buf, "kiwi"); 8918 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8919 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8920 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 8921 8922 sz = MAX_PATH; 8923 lstrcpyA(buf, "kiwi"); 8924 r = MsiRecordGetStringA(rec, 4, buf, &sz); 8925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8926 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 8927 8928 sz = MAX_PATH; 8929 lstrcpyA(buf, "kiwi"); 8930 r = MsiRecordGetStringA(rec, 5, buf, &sz); 8931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8932 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 8933 8934 MsiCloseHandle(rec); 8935 MsiViewClose(view); 8936 MsiCloseHandle(view); 8937 8938 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) " 8939 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 8940 r = run_query(hdb, 0, query); 8941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8942 8943 query = "SELECT * FROM `T`"; 8944 r = do_query(hdb, query, &rec); 8945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8946 8947 sz = MAX_PATH; 8948 lstrcpyA(buf, "kiwi"); 8949 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8951 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 8952 8953 r = MsiRecordGetInteger(rec, 2); 8954 ok(r == 3, "Expected 3, got %d\n", r); 8955 8956 sz = MAX_PATH; 8957 lstrcpyA(buf, "kiwi"); 8958 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8960 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 8961 8962 r = MsiRecordGetInteger(rec, 4); 8963 ok(r == 2, "Expected 2, got %d\n", r); 8964 8965 r = MsiRecordGetInteger(rec, 5); 8966 ok(r == 1, "Expected 1, got %d\n", r); 8967 8968 MsiCloseHandle(rec); 8969 8970 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 8971 r = MsiDatabaseOpenViewA(hdb, query, &view); 8972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8973 r = MsiViewExecute(view, 0); 8974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8975 8976 r = MsiViewFetch(view, &rec); 8977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8978 8979 sz = MAX_PATH; 8980 lstrcpyA(buf, "kiwi"); 8981 r = MsiRecordGetStringA(rec, 1, buf, &sz); 8982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8983 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 8984 8985 r = MsiRecordGetInteger(rec, 2); 8986 ok(r == 1, "Expected 1, got %d\n", r); 8987 8988 sz = MAX_PATH; 8989 lstrcpyA(buf, "kiwi"); 8990 r = MsiRecordGetStringA(rec, 3, buf, &sz); 8991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8992 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 8993 8994 MsiCloseHandle(rec); 8995 8996 r = MsiViewFetch(view, &rec); 8997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 8998 8999 sz = MAX_PATH; 9000 lstrcpyA(buf, "kiwi"); 9001 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9003 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9004 9005 r = MsiRecordGetInteger(rec, 2); 9006 ok(r == 2, "Expected 2, got %d\n", r); 9007 9008 sz = MAX_PATH; 9009 lstrcpyA(buf, "kiwi"); 9010 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9012 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9013 9014 MsiCloseHandle(rec); 9015 9016 r = MsiViewFetch(view, &rec); 9017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9018 9019 sz = MAX_PATH; 9020 lstrcpyA(buf, "kiwi"); 9021 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9023 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9024 9025 r = MsiRecordGetInteger(rec, 2); 9026 ok(r == 3, "Expected 3, got %d\n", r); 9027 9028 sz = MAX_PATH; 9029 lstrcpyA(buf, "kiwi"); 9030 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9031 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9032 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9033 9034 MsiCloseHandle(rec); 9035 9036 r = MsiViewFetch(view, &rec); 9037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9038 9039 sz = MAX_PATH; 9040 lstrcpyA(buf, "kiwi"); 9041 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9042 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9043 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9044 9045 r = MsiRecordGetInteger(rec, 2); 9046 ok(r == 4, "Expected 4, got %d\n", r); 9047 9048 sz = MAX_PATH; 9049 lstrcpyA(buf, "kiwi"); 9050 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9052 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9053 9054 MsiCloseHandle(rec); 9055 9056 r = MsiViewFetch(view, &rec); 9057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9058 9059 sz = MAX_PATH; 9060 lstrcpyA(buf, "kiwi"); 9061 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9063 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9064 9065 r = MsiRecordGetInteger(rec, 2); 9066 ok(r == 5, "Expected 5, got %d\n", r); 9067 9068 sz = MAX_PATH; 9069 lstrcpyA(buf, "kiwi"); 9070 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9071 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9072 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9073 9074 MsiCloseHandle(rec); 9075 9076 r = MsiViewFetch(view, &rec); 9077 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9078 9079 MsiViewClose(view); 9080 MsiCloseHandle(view); 9081 9082 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, " 9083 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL " 9084 "PRIMARY KEY `C`, `A`, `D`)"; 9085 r = run_query(hdb, 0, query); 9086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9087 9088 query = "SELECT * FROM `Z`"; 9089 r = MsiDatabaseOpenViewA(hdb, query, &view); 9090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9091 9092 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); 9093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9094 9095 sz = MAX_PATH; 9096 lstrcpyA(buf, "kiwi"); 9097 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9099 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 9100 9101 sz = MAX_PATH; 9102 lstrcpyA(buf, "kiwi"); 9103 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9105 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf); 9106 9107 sz = MAX_PATH; 9108 lstrcpyA(buf, "kiwi"); 9109 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9111 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf); 9112 9113 sz = MAX_PATH; 9114 lstrcpyA(buf, "kiwi"); 9115 r = MsiRecordGetStringA(rec, 4, buf, &sz); 9116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9117 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf); 9118 9119 sz = MAX_PATH; 9120 lstrcpyA(buf, "kiwi"); 9121 r = MsiRecordGetStringA(rec, 5, buf, &sz); 9122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9123 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf); 9124 9125 MsiCloseHandle(rec); 9126 9127 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); 9128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9129 9130 sz = MAX_PATH; 9131 lstrcpyA(buf, "kiwi"); 9132 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9134 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9135 9136 sz = MAX_PATH; 9137 lstrcpyA(buf, "kiwi"); 9138 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9140 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9141 9142 sz = MAX_PATH; 9143 lstrcpyA(buf, "kiwi"); 9144 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9146 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9147 9148 sz = MAX_PATH; 9149 lstrcpyA(buf, "kiwi"); 9150 r = MsiRecordGetStringA(rec, 4, buf, &sz); 9151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9152 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9153 9154 sz = MAX_PATH; 9155 lstrcpyA(buf, "kiwi"); 9156 r = MsiRecordGetStringA(rec, 5, buf, &sz); 9157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9158 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9159 9160 MsiCloseHandle(rec); 9161 MsiViewClose(view); 9162 MsiCloseHandle(view); 9163 9164 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) " 9165 "VALUES ( 1, 2, 'a', 3, 'bc' )"; 9166 r = run_query(hdb, 0, query); 9167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9168 9169 query = "SELECT * FROM `Z`"; 9170 r = do_query(hdb, query, &rec); 9171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9172 9173 r = MsiRecordGetInteger(rec, 1); 9174 ok(r == 2, "Expected 2, got %d\n", r); 9175 9176 sz = MAX_PATH; 9177 lstrcpyA(buf, "kiwi"); 9178 r = MsiRecordGetStringA(rec, 2, buf, &sz); 9179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9180 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf); 9181 9182 sz = MAX_PATH; 9183 lstrcpyA(buf, "kiwi"); 9184 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9186 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf); 9187 9188 r = MsiRecordGetInteger(rec, 4); 9189 ok(r == 3, "Expected 3, got %d\n", r); 9190 9191 r = MsiRecordGetInteger(rec, 5); 9192 ok(r == 1, "Expected 1, got %d\n", r); 9193 9194 MsiCloseHandle(rec); 9195 9196 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'"; 9197 r = MsiDatabaseOpenViewA(hdb, query, &view); 9198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9199 r = MsiViewExecute(view, 0); 9200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9201 9202 r = MsiViewFetch(view, &rec); 9203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9204 9205 sz = MAX_PATH; 9206 lstrcpyA(buf, "kiwi"); 9207 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9209 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9210 9211 r = MsiRecordGetInteger(rec, 2); 9212 ok(r == 1, "Expected 1, got %d\n", r); 9213 9214 sz = MAX_PATH; 9215 lstrcpyA(buf, "kiwi"); 9216 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9218 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf); 9219 9220 MsiCloseHandle(rec); 9221 9222 r = MsiViewFetch(view, &rec); 9223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9224 9225 sz = MAX_PATH; 9226 lstrcpyA(buf, "kiwi"); 9227 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9229 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9230 9231 r = MsiRecordGetInteger(rec, 2); 9232 ok(r == 2, "Expected 2, got %d\n", r); 9233 9234 sz = MAX_PATH; 9235 lstrcpyA(buf, "kiwi"); 9236 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9237 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9238 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf); 9239 9240 MsiCloseHandle(rec); 9241 9242 r = MsiViewFetch(view, &rec); 9243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9244 9245 sz = MAX_PATH; 9246 lstrcpyA(buf, "kiwi"); 9247 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9249 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9250 9251 r = MsiRecordGetInteger(rec, 2); 9252 ok(r == 3, "Expected 3, got %d\n", r); 9253 9254 sz = MAX_PATH; 9255 lstrcpyA(buf, "kiwi"); 9256 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9258 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf); 9259 9260 MsiCloseHandle(rec); 9261 9262 r = MsiViewFetch(view, &rec); 9263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9264 9265 sz = MAX_PATH; 9266 lstrcpyA(buf, "kiwi"); 9267 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9269 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9270 9271 r = MsiRecordGetInteger(rec, 2); 9272 ok(r == 4, "Expected 4, got %d\n", r); 9273 9274 sz = MAX_PATH; 9275 lstrcpyA(buf, "kiwi"); 9276 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9278 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf); 9279 9280 MsiCloseHandle(rec); 9281 9282 r = MsiViewFetch(view, &rec); 9283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9284 9285 sz = MAX_PATH; 9286 lstrcpyA(buf, "kiwi"); 9287 r = MsiRecordGetStringA(rec, 1, buf, &sz); 9288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9289 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf); 9290 9291 r = MsiRecordGetInteger(rec, 2); 9292 ok(r == 5, "Expected 5, got %d\n", r); 9293 9294 sz = MAX_PATH; 9295 lstrcpyA(buf, "kiwi"); 9296 r = MsiRecordGetStringA(rec, 3, buf, &sz); 9297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); 9298 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf); 9299 9300 MsiCloseHandle(rec); 9301 9302 r = MsiViewFetch(view, &rec); 9303 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); 9304 9305 MsiViewClose(view); 9306 MsiCloseHandle(view); 9307 9308 MsiCloseHandle(hdb); 9309 DeleteFileA(msifile); 9310 } 9311 9312 static void test_createtable(void) 9313 { 9314 MSIHANDLE hdb, htab = 0, hrec = 0; 9315 LPCSTR query; 9316 UINT res; 9317 DWORD size; 9318 char buffer[0x20]; 9319 9320 hdb = create_db(); 9321 ok(hdb, "failed to create db\n"); 9322 9323 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)"; 9324 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9326 if(res == ERROR_SUCCESS ) 9327 { 9328 res = MsiViewExecute( htab, hrec ); 9329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9330 9331 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9332 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9333 9334 size = sizeof(buffer); 9335 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9336 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9337 MsiCloseHandle( hrec ); 9338 9339 res = MsiViewClose( htab ); 9340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9341 9342 res = MsiCloseHandle( htab ); 9343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9344 } 9345 9346 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)"; 9347 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9349 if(res == ERROR_SUCCESS ) 9350 { 9351 res = MsiViewExecute( htab, 0 ); 9352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9353 9354 res = MsiViewClose( htab ); 9355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9356 9357 res = MsiCloseHandle( htab ); 9358 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9359 9360 query = "SELECT * FROM `a`"; 9361 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9363 9364 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9366 9367 buffer[0] = 0; 9368 size = sizeof(buffer); 9369 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9370 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9371 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9372 MsiCloseHandle( hrec ); 9373 9374 res = MsiViewClose( htab ); 9375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9376 9377 res = MsiCloseHandle( htab ); 9378 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9379 9380 res = MsiDatabaseCommit(hdb); 9381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9382 9383 res = MsiCloseHandle(hdb); 9384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9385 9386 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb ); 9387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9388 9389 query = "SELECT * FROM `a`"; 9390 res = MsiDatabaseOpenViewA( hdb, query, &htab ); 9391 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9392 9393 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec ); 9394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9395 9396 buffer[0] = 0; 9397 size = sizeof(buffer); 9398 res = MsiRecordGetStringA(hrec, 1, buffer, &size ); 9399 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9400 ok(!strcmp(buffer,"b"), "b != %s\n", buffer); 9401 9402 res = MsiCloseHandle( hrec ); 9403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9404 9405 res = MsiViewClose( htab ); 9406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9407 9408 res = MsiCloseHandle( htab ); 9409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9410 } 9411 9412 res = MsiDatabaseCommit(hdb); 9413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9414 9415 res = MsiCloseHandle(hdb); 9416 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); 9417 9418 DeleteFileA(msifile); 9419 } 9420 9421 static void test_embedded_nulls(void) 9422 { 9423 static const char control_table[] = 9424 "Dialog\tText\n" 9425 "s72\tL0\n" 9426 "Control\tDialog\n" 9427 "LicenseAgreementDlg\ttext\x11\x19text\0text"; 9428 UINT r, sz; 9429 MSIHANDLE hdb, hrec; 9430 char buffer[32]; 9431 9432 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9433 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r ); 9434 9435 GetCurrentDirectoryA( MAX_PATH, CURR_DIR ); 9436 write_file( "temp_file", control_table, sizeof(control_table) ); 9437 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" ); 9438 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r ); 9439 DeleteFileA( "temp_file" ); 9440 9441 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec ); 9442 ok( r == ERROR_SUCCESS, "query failed %u\n", r ); 9443 9444 buffer[0] = 0; 9445 sz = sizeof(buffer); 9446 r = MsiRecordGetStringA( hrec, 1, buffer, &sz ); 9447 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r ); 9448 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer ); 9449 9450 MsiCloseHandle( hrec ); 9451 MsiCloseHandle( hdb ); 9452 DeleteFileA( msifile ); 9453 } 9454 9455 static void test_select_column_names(void) 9456 { 9457 MSIHANDLE hdb = 0, rec, rec2, view; 9458 char buffer[32]; 9459 UINT r, size; 9460 9461 DeleteFileA(msifile); 9462 9463 r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb ); 9464 ok( r == ERROR_SUCCESS , "failed to open database: %u\n", r ); 9465 9466 r = try_query( hdb, "CREATE TABLE `t` (`a` CHAR NOT NULL, `b` CHAR PRIMARY KEY `a`)"); 9467 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9468 9469 r = try_query( hdb, "SELECT `t`.`b` FROM `t` WHERE `t`.`b` = `x`" ); 9470 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9471 9472 r = try_query( hdb, "SELECT '', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9473 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9474 9475 r = try_query( hdb, "SELECT *, `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9476 todo_wine ok( r == ERROR_SUCCESS, "query failed: %u\n", r ); 9477 9478 r = try_query( hdb, "SELECT 'b', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" ); 9479 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9480 9481 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x'" ); 9482 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9483 9484 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY `b`" ); 9485 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9486 9487 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY 'b'" ); 9488 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9489 9490 r = try_query( hdb, "SELECT 't'.'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9491 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9492 9493 r = try_query( hdb, "SELECT 'b' FROM `t` WHERE `t`.`b` = 'x'" ); 9494 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9495 9496 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '1', '2' )" ); 9497 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9498 9499 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '3', '4' )" ); 9500 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9501 9502 r = MsiDatabaseOpenViewA( hdb, "SELECT '' FROM `t`", &view ); 9503 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9504 9505 r = MsiViewExecute( view, 0 ); 9506 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9507 9508 r = MsiViewFetch( view, &rec ); 9509 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9510 r = MsiRecordGetFieldCount( rec ); 9511 ok( r == 1, "got %u\n", r ); 9512 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec2 ); 9513 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9514 r = MsiRecordGetFieldCount( rec2 ); 9515 ok( r == 1, "got %u\n", r ); 9516 size = sizeof(buffer); 9517 memset( buffer, 0x55, sizeof(buffer) ); 9518 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9519 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9520 ok( !buffer[0], "got \"%s\"\n", buffer ); 9521 MsiCloseHandle( rec2 ); 9522 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec2 ); 9523 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9524 r = MsiRecordGetFieldCount( rec2 ); 9525 ok( r == 1, "got %u\n", r ); 9526 size = sizeof(buffer); 9527 memset( buffer, 0x55, sizeof(buffer) ); 9528 r = MsiRecordGetStringA( rec2, 1, buffer, &size ); 9529 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9530 ok( !lstrcmpA( buffer, "f0" ), "got \"%s\"\n", buffer ); 9531 MsiCloseHandle( rec2 ); 9532 9533 size = sizeof(buffer); 9534 memset( buffer, 0x55, sizeof(buffer) ); 9535 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9536 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9537 ok( !buffer[0], "got \"%s\"\n", buffer ); 9538 MsiCloseHandle( rec ); 9539 9540 r = MsiViewFetch( view, &rec ); 9541 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9542 size = sizeof(buffer); 9543 memset( buffer, 0x55, sizeof(buffer) ); 9544 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9545 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9546 ok( !buffer[0], "got \"%s\"\n", buffer ); 9547 MsiCloseHandle( rec ); 9548 9549 r = MsiViewFetch( view, &rec ); 9550 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9551 MsiCloseHandle( rec ); 9552 9553 MsiViewClose( view ); 9554 MsiCloseHandle( view ); 9555 9556 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '' FROM `t`", &view ); 9557 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9558 9559 r = MsiViewExecute( view, 0 ); 9560 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9561 9562 r = MsiViewFetch( view, &rec ); 9563 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9564 r = MsiRecordGetFieldCount( rec ); 9565 ok( r == 2, "got %u\n", r ); 9566 size = sizeof(buffer); 9567 memset( buffer, 0x55, sizeof(buffer) ); 9568 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9569 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9570 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9571 MsiCloseHandle( rec ); 9572 9573 r = MsiViewFetch( view, &rec ); 9574 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9575 size = sizeof(buffer); 9576 memset( buffer, 0x55, sizeof(buffer) ); 9577 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9578 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9579 ok( !buffer[0], "got \"%s\"\n", buffer ); 9580 MsiCloseHandle( rec ); 9581 9582 r = MsiViewFetch( view, &rec ); 9583 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9584 MsiCloseHandle( rec ); 9585 9586 MsiViewClose( view ); 9587 MsiCloseHandle( view ); 9588 9589 r = MsiDatabaseOpenViewA( hdb, "SELECT '', `a` FROM `t`", &view ); 9590 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9591 9592 r = MsiViewExecute( view, 0 ); 9593 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9594 9595 r = MsiViewFetch( view, &rec ); 9596 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9597 r = MsiRecordGetFieldCount( rec ); 9598 ok( r == 2, "got %u\n", r ); 9599 size = sizeof(buffer); 9600 memset( buffer, 0x55, sizeof(buffer) ); 9601 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9602 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9603 ok( !buffer[0], "got \"%s\"\n", buffer ); 9604 size = sizeof(buffer); 9605 memset( buffer, 0x55, sizeof(buffer) ); 9606 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9607 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9608 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9609 MsiCloseHandle( rec ); 9610 9611 r = MsiViewFetch( view, &rec ); 9612 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9613 size = sizeof(buffer); 9614 memset( buffer, 0x55, sizeof(buffer) ); 9615 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9616 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9617 ok( !buffer[0], "got \"%s\"\n", buffer ); 9618 size = sizeof(buffer); 9619 memset( buffer, 0x55, sizeof(buffer) ); 9620 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9621 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9622 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9623 MsiCloseHandle( rec ); 9624 9625 r = MsiViewFetch( view, &rec ); 9626 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9627 MsiCloseHandle( rec ); 9628 9629 MsiViewClose( view ); 9630 MsiCloseHandle( view ); 9631 9632 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '', `b` FROM `t`", &view ); 9633 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r ); 9634 9635 r = MsiViewExecute( view, 0 ); 9636 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r ); 9637 9638 r = MsiViewFetch( view, &rec ); 9639 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9640 r = MsiRecordGetFieldCount( rec ); 9641 ok( r == 3, "got %u\n", r ); 9642 size = sizeof(buffer); 9643 memset( buffer, 0x55, sizeof(buffer) ); 9644 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9645 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9646 ok( !lstrcmpA( buffer, "1" ), "got \"%s\"\n", buffer ); 9647 size = sizeof(buffer); 9648 memset( buffer, 0x55, sizeof(buffer) ); 9649 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9650 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9651 ok( !buffer[0], "got \"%s\"\n", buffer ); 9652 size = sizeof(buffer); 9653 memset( buffer, 0x55, sizeof(buffer) ); 9654 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9655 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9656 ok( !lstrcmpA( buffer, "2" ), "got \"%s\"\n", buffer ); 9657 MsiCloseHandle( rec ); 9658 9659 r = MsiViewFetch( view, &rec ); 9660 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9661 size = sizeof(buffer); 9662 memset( buffer, 0x55, sizeof(buffer) ); 9663 r = MsiRecordGetStringA( rec, 1, buffer, &size ); 9664 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9665 ok( !lstrcmpA( buffer, "3" ), "got \"%s\"\n", buffer ); 9666 size = sizeof(buffer); 9667 memset( buffer, 0x55, sizeof(buffer) ); 9668 r = MsiRecordGetStringA( rec, 2, buffer, &size ); 9669 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9670 ok( !buffer[0], "got \"%s\"\n", buffer ); 9671 size = sizeof(buffer); 9672 memset( buffer, 0x55, sizeof(buffer) ); 9673 r = MsiRecordGetStringA( rec, 3, buffer, &size ); 9674 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r ); 9675 ok( !lstrcmpA( buffer, "4" ), "got \"%s\"\n", buffer ); 9676 MsiCloseHandle( rec ); 9677 9678 r = MsiViewFetch( view, &rec ); 9679 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r ); 9680 MsiCloseHandle( rec ); 9681 9682 MsiViewClose( view ); 9683 MsiCloseHandle( view ); 9684 9685 r = try_query( hdb, "SELECT '' FROM `t` WHERE `t`.`b` = 'x'" ); 9686 ok( r == ERROR_SUCCESS , "query failed: %u\n", r ); 9687 9688 r = try_query( hdb, "SELECT `` FROM `t` WHERE `t`.`b` = 'x'" ); 9689 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9690 9691 r = try_query( hdb, "SELECT `b` FROM 't' WHERE `t`.`b` = 'x'" ); 9692 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9693 9694 r = try_query( hdb, "SELECT `b` FROM `t` WHERE 'b' = 'x'" ); 9695 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9696 9697 r = try_query( hdb, "SELECT `t`.`b`, `` FROM `t` WHERE `t`.`b` = 'x'" ); 9698 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r ); 9699 9700 r = MsiCloseHandle( hdb ); 9701 ok(r == ERROR_SUCCESS , "failed to close database: %u\n", r); 9702 } 9703 9704 START_TEST(db) 9705 { 9706 test_msidatabase(); 9707 test_msiinsert(); 9708 test_msidecomposedesc(); 9709 test_msibadqueries(); 9710 test_viewmodify(); 9711 test_viewgetcolumninfo(); 9712 test_getcolinfo(); 9713 test_msiexport(); 9714 test_longstrings(); 9715 test_streamtable(); 9716 test_binary(); 9717 test_where_not_in_selected(); 9718 test_where(); 9719 test_msiimport(); 9720 test_binary_import(); 9721 test_markers(); 9722 test_handle_limit(); 9723 test_try_transform(); 9724 test_join(); 9725 test_temporary_table(); 9726 test_alter(); 9727 test_integers(); 9728 test_update(); 9729 test_special_tables(); 9730 test_tables_order(); 9731 test_rows_order(); 9732 test_select_markers(); 9733 test_viewmodify_update(); 9734 test_viewmodify_assign(); 9735 test_stringtable(); 9736 test_viewmodify_delete(); 9737 test_defaultdatabase(); 9738 test_order(); 9739 test_viewmodify_delete_temporary(); 9740 test_deleterow(); 9741 test_quotes(); 9742 test_carriagereturn(); 9743 test_noquotes(); 9744 test_forcecodepage(); 9745 test_viewmodify_refresh(); 9746 test_where_viewmodify(); 9747 test_storages_table(); 9748 test_dbtopackage(); 9749 test_droptable(); 9750 test_dbmerge(); 9751 test_select_with_tablenames(); 9752 test_insertorder(); 9753 test_columnorder(); 9754 test_suminfo_import(); 9755 test_createtable(); 9756 test_collation(); 9757 test_embedded_nulls(); 9758 test_select_column_names(); 9759 } 9760