📄 db.c
字号:
MSIHANDLE hview = 0, rec = 0;
UINT r, type = 0;
char query[0x100];
sprintf(query, "select * from `_Columns` where `Table` = '%s'", table );
r = MsiDatabaseOpenView(hdb, query, &hview);
if( r != ERROR_SUCCESS )
return r;
r = MsiViewExecute(hview, 0);
if( r == ERROR_SUCCESS )
{
while (1)
{
r = MsiViewFetch( hview, &rec );
if( r != ERROR_SUCCESS)
break;
r = MsiRecordGetInteger( rec, 2 );
if (r == field)
type = MsiRecordGetInteger( rec, 4 );
MsiCloseHandle( rec );
}
MsiViewClose(hview);
}
MsiCloseHandle(hview);
return type;
}
static BOOL check_record( MSIHANDLE rec, UINT field, LPCSTR val )
{
CHAR buffer[0x20];
UINT r;
DWORD sz;
sz = sizeof buffer;
r = MsiRecordGetString( rec, field, buffer, &sz );
return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
}
static void test_viewgetcolumninfo(void)
{
MSIHANDLE hdb = 0, rec;
UINT r;
hdb = create_db();
ok( hdb, "failed to create db\n");
r = run_query( hdb, 0,
"CREATE TABLE `Properties` "
"( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" );
ok( r == ERROR_SUCCESS , "Failed to create table\n" );
/* check the column types */
rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "S255"), "wrong record type\n");
ok( check_record( rec, 2, "S1"), "wrong record type\n");
MsiCloseHandle( rec );
/* check the type in _Columns */
ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n");
ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n");
/* now try the names */
rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "Property"), "wrong record type\n");
ok( check_record( rec, 2, "Value"), "wrong record type\n");
MsiCloseHandle( rec );
r = run_query( hdb, 0,
"CREATE TABLE `Binary` "
"( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" );
ok( r == ERROR_SUCCESS , "Failed to create table\n" );
/* check the column types */
rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "S255"), "wrong record type\n");
ok( check_record( rec, 2, "V0"), "wrong record type\n");
MsiCloseHandle( rec );
/* check the type in _Columns */
ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n");
ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n");
/* now try the names */
rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "Name"), "wrong record type\n");
ok( check_record( rec, 2, "Data"), "wrong record type\n");
MsiCloseHandle( rec );
r = run_query( hdb, 0,
"CREATE TABLE `UIText` "
"( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" );
ok( r == ERROR_SUCCESS , "Failed to create table\n" );
ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n");
ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n");
rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "Key"), "wrong record type\n");
ok( check_record( rec, 2, "Text"), "wrong record type\n");
MsiCloseHandle( rec );
rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES );
ok( rec, "failed to get column info record\n" );
ok( check_record( rec, 1, "s72"), "wrong record type\n");
ok( check_record( rec, 2, "L255"), "wrong record type\n");
MsiCloseHandle( rec );
MsiCloseHandle( hdb );
}
static void test_msiexport(void)
{
MSIHANDLE hdb = 0, hview = 0;
UINT r;
const char *query;
char path[MAX_PATH];
const char file[] = "phone.txt";
HANDLE handle;
char buffer[0x100];
DWORD length;
const char expected[] =
"id\tname\tnumber\r\n"
"I2\tS32\tS32\r\n"
"phone\tid\r\n"
"1\tAbe\t8675309\r\n";
DeleteFile(msifile);
/* just MsiOpenDatabase should not create a file */
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
/* create a table */
query = "CREATE TABLE `phone` ( "
"`id` INT, `name` CHAR(32), `number` CHAR(32) "
"PRIMARY KEY `id`)";
r = MsiDatabaseOpenView(hdb, query, &hview);
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
r = MsiViewExecute(hview, 0);
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
r = MsiViewClose(hview);
ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
r = MsiCloseHandle(hview);
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
/* insert a value into it */
query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
"VALUES('1', 'Abe', '8675309')";
r = MsiDatabaseOpenView(hdb, query, &hview);
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
r = MsiViewExecute(hview, 0);
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
r = MsiViewClose(hview);
ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
r = MsiCloseHandle(hview);
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
GetCurrentDirectory(MAX_PATH, path);
todo_wine {
r = MsiDatabaseExport(hdb, "phone", path, file);
ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n");
MsiCloseHandle(hdb);
lstrcat(path, "\\");
lstrcat(path, file);
/* check the data that was written */
length = 0;
memset(buffer, 0, sizeof buffer);
handle = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
ReadFile(handle, buffer, sizeof buffer, &length, NULL);
CloseHandle(handle);
DeleteFile(path);
}
else
ok(0, "failed to open file %s\n", path);
ok( length == strlen(expected), "length of data wrong\n");
ok( !lstrcmp(buffer, expected), "data doesn't match\n");
}
DeleteFile(msifile);
}
static void test_longstrings(void)
{
const char insert_query[] =
"INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')";
char *str;
MSIHANDLE hdb = 0, hview = 0, hrec = 0;
DWORD len;
UINT r;
const DWORD STRING_LENGTH = 0x10005;
DeleteFile(msifile);
/* just MsiOpenDatabase should not create a file */
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
/* create a table */
r = try_query( hdb,
"CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)");
ok(r == ERROR_SUCCESS, "query failed\n");
/* try a insert a very long string */
str = HeapAlloc(GetProcessHeap(), 0, STRING_LENGTH+sizeof insert_query);
len = strchr(insert_query, 'Z') - insert_query;
strcpy(str, insert_query);
memset(str+len, 'Z', STRING_LENGTH);
strcpy(str+len+STRING_LENGTH, insert_query+len+1);
r = try_query( hdb, str );
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
HeapFree(GetProcessHeap(), 0, str);
MsiDatabaseCommit(hdb);
ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
MsiCloseHandle(hdb);
r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
r = MsiDatabaseOpenView(hdb, "select * from `strings` where `id` = 1", &hview);
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
r = MsiViewExecute(hview, 0);
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
r = MsiViewFetch(hview, &hrec);
ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
MsiCloseHandle(hview);
r = MsiRecordGetString(hrec, 2, NULL, &len);
ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
todo_wine {
ok(len == STRING_LENGTH, "string length wrong\n");
}
MsiCloseHandle(hrec);
MsiCloseHandle(hdb);
DeleteFile(msifile);
}
static void test_streamtable(void)
{
MSIHANDLE hdb = 0, rec;
UINT r;
hdb = create_db();
ok( hdb, "failed to create db\n");
r = run_query( hdb, 0,
"CREATE TABLE `Properties` "
"( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" );
ok( r == ERROR_SUCCESS , "Failed to create table\n" );
/* check the column types */
rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES );
ok( rec, "failed to get column info record\n" );
todo_wine {
ok( check_record( rec, 1, "s62"), "wrong record type\n");
ok( check_record( rec, 2, "V0"), "wrong record type\n");
}
MsiCloseHandle( rec );
/* now try the names */
rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES );
ok( rec, "failed to get column info record\n" );
todo_wine {
ok( check_record( rec, 1, "Name"), "wrong record type\n");
ok( check_record( rec, 2, "Data"), "wrong record type\n");
}
MsiCloseHandle( rec );
MsiCloseHandle( hdb );
DeleteFile(msifile);
}
static void test_where(void)
{
MSIHANDLE hdb = 0, rec;
LPCSTR query;
UINT r;
hdb = create_db();
ok( hdb, "failed to create db\n");
r = run_query( hdb, 0,
"CREATE TABLE `Media` ("
"`DiskId` SHORT NOT NULL, "
"`LastSequence` LONG, "
"`DiskPrompt` CHAR(64) LOCALIZABLE, "
"`Cabinet` CHAR(255), "
"`VolumeLabel` CHAR(32), "
"`Source` CHAR(72) "
"PRIMARY KEY `DiskId`)" );
ok( r == S_OK, "cannot create Media table: %d\n", r );
r = run_query( hdb, 0, "INSERT INTO `Media` "
"( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
"VALUES ( 1, 0, '', 'zero.cab', '', '' )" );
ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
r = run_query( hdb, 0, "INSERT INTO `Media` "
"( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
"VALUES ( 2, 1, '', 'one.cab', '', '' )" );
ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
r = run_query( hdb, 0, "INSERT INTO `Media` "
"( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
"VALUES ( 3, 2, '', 'two.cab', '', '' )" );
ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
query = "SELECT * FROM `Media`";
r = do_query(hdb, query, &rec);
ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
ok( check_record( rec, 4, "zero.cab"), "wrong cabinet\n");
MsiCloseHandle( rec );
query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1";
r = do_query(hdb, query, &rec);
ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
ok( check_record( rec, 4, "one.cab"), "wrong cabinet\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -