diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c index 3252f6a04c0..c31aae1fdcf 100644 --- a/dlls/msi/alter.c +++ b/dlls/msi/alter.c @@ -183,11 +183,11 @@ static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT ALTER_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIALTERVIEW *av = (MSIALTERVIEW*)view; - TRACE("%p %d %p %p\n", av, n, name, type ); + TRACE("%p %d %p %p %p\n", av, n, name, type, temporary ); return ERROR_FUNCTION_FAILED; } diff --git a/dlls/msi/create.c b/dlls/msi/create.c index 8a801f26d89..05c40cf2318 100644 --- a/dlls/msi/create.c +++ b/dlls/msi/create.c @@ -91,11 +91,11 @@ static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT CREATE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSICREATEVIEW *cv = (MSICREATEVIEW*)view; - TRACE("%p %d %p %p\n", cv, n, name, type ); + TRACE("%p %d %p %p %p\n", cv, n, name, type, temporary ); return ERROR_FUNCTION_FAILED; } diff --git a/dlls/msi/delete.c b/dlls/msi/delete.c index 3db2783a9ec..c824d9e0f23 100644 --- a/dlls/msi/delete.c +++ b/dlls/msi/delete.c @@ -127,16 +127,17 @@ static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT DELETE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view; - TRACE("%p %d %p %p\n", dv, n, name, type ); + TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary ); if( !dv->table ) return ERROR_FUNCTION_FAILED; - return dv->table->ops->get_column_info( dv->table, n, name, type ); + return dv->table->ops->get_column_info( dv->table, n, name, + type, temporary ); } static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c index 6c21b8883f2..1e0cc2fba9c 100644 --- a/dlls/msi/distinct.c +++ b/dlls/msi/distinct.c @@ -205,16 +205,17 @@ static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT * } static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view; - TRACE("%p %d %p %p\n", dv, n, name, type ); + TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary ); if( !dv->table ) return ERROR_FUNCTION_FAILED; - return dv->table->ops->get_column_info( dv->table, n, name, type ); + return dv->table->ops->get_column_info( dv->table, n, name, + type, temporary ); } static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c index 85de99a8ea3..0a1fbe6de77 100644 --- a/dlls/msi/insert.c +++ b/dlls/msi/insert.c @@ -114,8 +114,8 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count) for (i = 1; i <= col_count; i++) { - iv->sv->ops->get_column_info(iv->sv, i, &a, NULL); - iv->table->ops->get_column_info(iv->table, i, &b, NULL); + iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL); + iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL); res = lstrcmpW(a, b); msi_free(a); @@ -157,13 +157,13 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values) for (colidx = 1; colidx <= val_count; colidx++) { - r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL); + r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL); if (r != ERROR_SUCCESS) goto err; for (i = 1; i <= col_count; i++) { - r = iv->table->ops->get_column_info(iv->table, i, &b, NULL); + r = iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL); if (r != ERROR_SUCCESS) goto err; @@ -200,7 +200,7 @@ static BOOL row_has_null_primary_keys(MSIINSERTVIEW *iv, MSIRECORD *row) for (i = 1; i <= col_count; i++) { - r = iv->table->ops->get_column_info(iv->table, i, NULL, &type); + r = iv->table->ops->get_column_info(iv->table, i, NULL, &type, NULL); if (r != ERROR_SUCCESS) return FALSE; @@ -291,18 +291,18 @@ static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT INSERT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view; MSIVIEW *sv; - TRACE("%p %d %p %p\n", iv, n, name, type ); + TRACE("%p %d %p %p %p\n", iv, n, name, type, temporary ); sv = iv->sv; if( !sv ) return ERROR_FUNCTION_FAILED; - return sv->ops->get_column_info( sv, n, name, type ); + return sv->ops->get_column_info( sv, n, name, type, temporary ); } static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row) diff --git a/dlls/msi/join.c b/dlls/msi/join.c index 34de3b17fdd..572e84bb0f2 100644 --- a/dlls/msi/join.c +++ b/dlls/msi/join.c @@ -194,13 +194,13 @@ static UINT JOIN_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols } static UINT JOIN_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIJOINVIEW *jv = (MSIJOINVIEW*)view; JOINTABLE *table; UINT cols = 0; - TRACE("%p %d %p %p\n", jv, n, name, type ); + TRACE("%p %d %p %p %p\n", jv, n, name, type, temporary ); if (n == 0 || n > jv->columns) return ERROR_FUNCTION_FAILED; @@ -208,7 +208,8 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view, LIST_FOR_EACH_ENTRY(table, &jv->tables, JOINTABLE, entry) { if (n <= cols + table->columns) - return table->view->ops->get_column_info(table->view, n - cols, name, type); + return table->view->ops->get_column_info(table->view, n - cols, + name, type, temporary); cols += table->columns; } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 307c9f97d75..5ed9a8b33ef 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -231,7 +231,7 @@ typedef struct tagMSIVIEWOPS * the caller. * The column information can be queried at any time. */ - UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type ); + UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary ); /* * modify - not yet implemented properly diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c index 0cfd05e8b1d..43c7b4dc52a 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -70,7 +70,7 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) INT x; col_name = NULL; - r = table->ops->get_column_info( table, i, &col_name, NULL ); + r = table->ops->get_column_info( table, i, &col_name, NULL, NULL ); if( r != ERROR_SUCCESS ) return r; x = lstrcmpW( name, col_name ); @@ -308,7 +308,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec) for (i = 1; i <= col_count; i++) { - ret = view->ops->get_column_info(view, i, NULL, &type); + ret = view->ops->get_column_info(view, i, NULL, &type, NULL); if (ret) { ERR("Error getting column type for %d\n", i); @@ -493,7 +493,8 @@ out: return ret; } -static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, UINT type ) +static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, + UINT type, BOOL temporary ) { static const WCHAR fmt[] = { '%','d',0 }; WCHAR szType[0x10]; @@ -503,9 +504,20 @@ static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, UINT type ) else if (type & MSITYPE_LOCALIZABLE) szType[0] = 'l'; else if (type & MSITYPE_STRING) - szType[0] = 's'; + { + if (temporary) + szType[0] = 'g'; + else + szType[0] = 's'; + } else - szType[0] = 'i'; + { + if (temporary) + szType[0] = 'j'; + else + szType[0] = 'i'; + } + if (type & MSITYPE_NULLABLE) szType[0] &= ~0x20; @@ -522,6 +534,7 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec ) MSIRECORD *rec; MSIVIEW *view = query->view; LPWSTR name; + BOOL temporary; if( !view ) return ERROR_FUNCTION_FAILED; @@ -542,13 +555,13 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec ) for( i=0; iops->get_column_info( view, i+1, &name, &type ); + r = view->ops->get_column_info( view, i+1, &name, &type, &temporary ); if( r != ERROR_SUCCESS ) continue; if (info == MSICOLINFO_NAMES) MSI_RecordSetStringW( rec, i+1, name ); else - msi_set_record_type_string( rec, i+1, type); + msi_set_record_type_string( rec, i+1, type, temporary ); msi_free( name ); } diff --git a/dlls/msi/select.c b/dlls/msi/select.c index a6ffe7c98e6..8fd761ed0dd 100644 --- a/dlls/msi/select.c +++ b/dlls/msi/select.c @@ -209,11 +209,11 @@ static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT SELECT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSISELECTVIEW *sv = (MSISELECTVIEW*)view; - TRACE("%p %d %p %p\n", sv, n, name, type ); + TRACE("%p %d %p %p %p\n", sv, n, name, type, temporary ); if( !sv->table ) return ERROR_FUNCTION_FAILED; @@ -223,7 +223,8 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view, n = sv->cols[ n - 1 ]; - return sv->table->ops->get_column_info( sv->table, n, name, type ); + return sv->table->ops->get_column_info( sv->table, n, name, + type, temporary ); } static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) @@ -246,7 +247,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) { col = sv->cols[i]; - r = SELECT_get_column_info(view, i + 1, &name, &type); + r = SELECT_get_column_info(view, i + 1, &name, &type, NULL); msi_free(name); if (r != ERROR_SUCCESS) { diff --git a/dlls/msi/storages.c b/dlls/msi/storages.c index 9f294ef8516..3a548226040 100644 --- a/dlls/msi/storages.c +++ b/dlls/msi/storages.c @@ -288,15 +288,15 @@ static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *c return ERROR_SUCCESS; } -static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type) +static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n, + LPWSTR *name, UINT *type, BOOL *temporary) { LPCWSTR name_ptr = NULL; static const WCHAR Name[] = {'N','a','m','e',0}; static const WCHAR Data[] = {'D','a','t','a',0}; - TRACE("(%p, %d, %p, %p)\n", view, n, name, type); + TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary); if (n == 0 || n > NUM_STORAGES_COLS) return ERROR_INVALID_PARAMETER; @@ -320,6 +320,9 @@ static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, if (!*name) return ERROR_FUNCTION_FAILED; } + if (temporary) + *temporary = FALSE; + return ERROR_SUCCESS; } diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c index 4e60bd60499..065f8ed1f66 100644 --- a/dlls/msi/streams.c +++ b/dlls/msi/streams.c @@ -254,15 +254,15 @@ static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *co return ERROR_SUCCESS; } -static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type) +static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, UINT n, + LPWSTR *name, UINT *type, BOOL *temporary) { LPCWSTR name_ptr = NULL; static const WCHAR Name[] = {'N','a','m','e',0}; static const WCHAR Data[] = {'D','a','t','a',0}; - TRACE("(%p, %d, %p, %p)\n", view, n, name, type); + TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary); if (n == 0 || n > NUM_STREAMS_COLS) return ERROR_INVALID_PARAMETER; @@ -286,6 +286,9 @@ static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, if (!*name) return ERROR_FUNCTION_FAILED; } + if (temporary) + *temporary = FALSE; + return ERROR_SUCCESS; } diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 1d822e27f08..19a9915f036 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -59,6 +59,7 @@ typedef struct tagMSICOLUMNINFO UINT type; UINT offset; INT ref_count; + BOOL temporary; MSICOLUMNHASHENTRY **hash_table; } MSICOLUMNINFO; @@ -102,14 +103,14 @@ static WCHAR szNumber[] = { 'N','u','m','b','e','r',0 }; static WCHAR szType[] = { 'T','y','p','e',0 }; static const MSICOLUMNINFO _Columns_cols[4] = { - { szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, NULL }, - { szColumns, 2, szNumber, MSITYPE_VALID | MSITYPE_KEY | 2, 2, 0, NULL }, - { szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4, 0, NULL }, - { szColumns, 4, szType, MSITYPE_VALID | 2, 6, 0, NULL }, + { szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, 0, NULL }, + { szColumns, 2, szNumber, MSITYPE_VALID | MSITYPE_KEY | 2, 2, 0, 0, NULL }, + { szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4, 0, 0, NULL }, + { szColumns, 4, szType, MSITYPE_VALID | 2, 6, 0, 0, NULL }, }; static const MSICOLUMNINFO _Tables_cols[1] = { - { szTables, 1, szName, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, NULL }, + { szTables, 1, szName, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, 0, NULL }, }; #define MAX_STREAM_NAME 0x1f @@ -659,6 +660,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info, table->colinfo[ i ].offset = 0; table->colinfo[ i ].ref_count = 0; table->colinfo[ i ].hash_table = NULL; + table->colinfo[ i ].temporary = col->temporary; } table_calc_column_offsets( db, table->colinfo, table->col_count); @@ -1438,7 +1440,7 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT TABLE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; @@ -1453,9 +1455,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view, if( !*name ) return ERROR_FUNCTION_FAILED; } + if( type ) *type = tv->columns[n-1].type; + if( temporary ) + *temporary = tv->columns[n-1].temporary; + return ERROR_SUCCESS; } diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 3cde3163ffd..641202bd1c8 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -3309,12 +3309,12 @@ static void test_temporary_table(void) sz = sizeof buf; r = MsiRecordGetString(rec, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to get string\n"); - todo_wine ok( 0 == strcmp("G255", buf), "wrong column type\n"); + ok( 0 == strcmp("G255", buf), "wrong column type\n"); sz = sizeof buf; r = MsiRecordGetString(rec, 2, buf, &sz); ok(r == ERROR_SUCCESS, "failed to get string\n"); - todo_wine ok( 0 == strcmp("j2", buf), "wrong column type\n"); + ok( 0 == strcmp("j2", buf), "wrong column type\n"); MsiCloseHandle( rec ); MsiCloseHandle( view ); diff --git a/dlls/msi/update.c b/dlls/msi/update.c index d0c466bbd84..31e5e252a8a 100644 --- a/dlls/msi/update.c +++ b/dlls/msi/update.c @@ -155,18 +155,18 @@ static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT UPDATE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view; MSIVIEW *wv; - TRACE("%p %d %p %p\n", uv, n, name, type ); + TRACE("%p %d %p %p %p\n", uv, n, name, type, temporary ); wv = uv->wv; if( !wv ) return ERROR_FUNCTION_FAILED; - return wv->ops->get_column_info( wv, n, name, type ); + return wv->ops->get_column_info( wv, n, name, type, temporary ); } static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/dlls/msi/where.c b/dlls/msi/where.c index 65f1be979f6..fc804a4d68f 100644 --- a/dlls/msi/where.c +++ b/dlls/msi/where.c @@ -490,16 +490,17 @@ static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT WHERE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) { MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; - TRACE("%p %d %p %p\n", wv, n, name, type ); + TRACE("%p %d %p %p %p\n", wv, n, name, type, temporary ); if( !wv->table ) return ERROR_FUNCTION_FAILED; - return wv->table->ops->get_column_info( wv->table, n, name, type ); + return wv->table->ops->get_column_info( wv->table, n, name, + type, temporary ); } static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, @@ -600,7 +601,7 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr if( r == ERROR_SUCCESS ) { UINT type = 0; - r = table->ops->get_column_info( table, val, NULL, &type ); + r = table->ops->get_column_info( table, val, NULL, &type, NULL ); if( r == ERROR_SUCCESS ) { if (type&MSITYPE_STRING)