diff --git a/reactos/dll/win32/advpack/advpack.spec b/reactos/dll/win32/advpack/advpack.spec index 2ba1057332f..665d1e11158 100644 --- a/reactos/dll/win32/advpack/advpack.spec +++ b/reactos/dll/win32/advpack/advpack.spec @@ -17,7 +17,7 @@ @ stdcall ExecuteCabW(ptr ptr ptr) @ stdcall ExecuteCab(ptr ptr ptr) ExecuteCabA @ stdcall ExtractFilesA(str str long ptr ptr long) -# stdcall ExtractFilesW(wstr wstr long ptr ptr long) +@ stdcall ExtractFilesW(wstr wstr long ptr ptr long) @ stdcall ExtractFiles(str str long ptr ptr long) ExtractFilesA @ stdcall FileSaveMarkNotExistA(str str str) @ stdcall FileSaveMarkNotExistW(wstr wstr wstr) diff --git a/reactos/dll/win32/advpack/files.c b/reactos/dll/win32/advpack/files.c index 63f4080b934..216b8632dc7 100644 --- a/reactos/dll/win32/advpack/files.c +++ b/reactos/dll/win32/advpack/files.c @@ -748,6 +748,44 @@ done: return res; } +/*********************************************************************** + * ExtractFilesW (ADVPACK.@) + * + * Extracts the specified files from a cab archive into + * a destination directory. + * + * PARAMS + * CabName [I] Filename of the cab archive. + * ExpandDir [I] Destination directory for the extracted files. + * Flags [I] Reserved. + * FileList [I] Optional list of files to extract. See NOTES. + * LReserved [I] Reserved. Must be NULL. + * Reserved [I] Reserved. Must be 0. + * + * RETURNS + * Success: S_OK. + * Failure: E_FAIL. + * + * NOTES + * FileList is a colon-separated list of filenames. If FileList is + * non-NULL, only the files in the list will be extracted from the + * cab file, otherwise all files will be extracted. Any number of + * spaces, tabs, or colons can be before or after the list, but + * the list itself must only be separated by colons. + * + * BUGS + * Unimplemented. + */ +HRESULT WINAPI ExtractFilesW(LPCWSTR CabName, LPCWSTR ExpandDir, DWORD Flags, + LPCWSTR FileList, LPVOID LReserved, DWORD Reserved) +{ + + FIXME("(%s, %s, %d, %s, %p, %d) stub!\n", debugstr_w(CabName), debugstr_w(ExpandDir), + Flags, debugstr_w(FileList), LReserved, Reserved); + + return E_FAIL; +} + /*********************************************************************** * FileSaveMarkNotExistA (ADVPACK.@) * diff --git a/reactos/dll/win32/msi/streams.c b/reactos/dll/win32/msi/streams.c index 2d869cc0d29..12f707e5e57 100644 --- a/reactos/dll/win32/msi/streams.c +++ b/reactos/dll/win32/msi/streams.c @@ -60,7 +60,7 @@ static BOOL streams_set_table_size(MSISTREAMSVIEW *sv, UINT size) if (size >= sv->max_streams) { sv->max_streams *= 2; - sv->streams = msi_realloc(sv->streams, sv->max_streams * sizeof(STREAM *)); + sv->streams = msi_realloc_zero(sv->streams, sv->max_streams * sizeof(STREAM *)); if (!sv->streams) return FALSE; } @@ -387,7 +387,7 @@ static UINT STREAMS_delete(struct tagMSIVIEW *view) for (i = 0; i < sv->num_rows; i++) { - if (sv->streams[i]->stream) + if (sv->streams[i] && sv->streams[i]->stream) IStream_Release(sv->streams[i]->stream); msi_free(sv->streams[i]); } @@ -462,7 +462,7 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv) return -1; sv->max_streams = 1; - sv->streams = msi_alloc(sizeof(STREAM *)); + sv->streams = msi_alloc_zero(sizeof(STREAM *)); if (!sv->streams) return -1; diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 885c0ddf796..0b5b99164b9 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -73,9 +73,8 @@ typedef struct tagMSIORDERINFO struct tagMSITABLE { BYTE **data; + BOOL *data_persistent; UINT row_count; - BYTE **nonpersistent_data; - UINT nonpersistent_row_count; struct list entry; MSICOLUMNINFO *colinfo; UINT col_count; @@ -476,9 +475,7 @@ static void free_table( MSITABLE *table ) for( i=0; irow_count; i++ ) msi_free( table->data[i] ); msi_free( table->data ); - for( i=0; inonpersistent_row_count; i++ ) - msi_free( table->nonpersistent_data[i] ); - msi_free( table->nonpersistent_data ); + msi_free( table->data_persistent ); msi_free_colinfo( table->colinfo, table->col_count ); msi_free( table->colinfo ); msi_free( table ); @@ -520,6 +517,9 @@ static UINT read_table_from_storage( MSIDATABASE *db, MSITABLE *t, IStorage *stg t->data = msi_alloc_zero( t->row_count * sizeof (USHORT*) ); if( !t->data ) goto err; + t->data_persistent = msi_alloc_zero( t->row_count * sizeof(BOOL)); + if ( !t->data_persistent ) + goto err; /* transpose all the data */ TRACE("Transposing data from %d rows\n", t->row_count ); @@ -528,6 +528,7 @@ static UINT read_table_from_storage( MSIDATABASE *db, MSITABLE *t, IStorage *stg t->data[i] = msi_alloc( row_size ); if( !t->data[i] ) goto err; + t->data_persistent[i] = TRUE; for( j=0; jcol_count; j++ ) { @@ -634,8 +635,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info, table->ref_count = 1; table->row_count = 0; table->data = NULL; - table->nonpersistent_row_count = 0; - table->nonpersistent_data = NULL; + table->data_persistent = NULL; table->colinfo = NULL; table->col_count = 0; table->persistent = persistent; @@ -783,8 +783,7 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret ) table->row_count = 0; table->data = NULL; - table->nonpersistent_row_count = 0; - table->nonpersistent_data = NULL; + table->data_persistent = NULL; table->colinfo = NULL; table->col_count = 0; table->persistent = MSICONDITION_TRUE; @@ -833,6 +832,7 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t ) goto err; } + rawsize = 0; p = rawdata; for( i=0; icol_count; i++ ) { @@ -840,6 +840,10 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t ) { UINT offset = t->colinfo[i].offset; + if (!t->data_persistent[j]) continue; + if (i == 0) + rawsize += row_size; + *p++ = t->data[j][offset]; *p++ = t->data[j][offset + 1]; if( 4 == bytes_per_column( db, &t->colinfo[i] ) ) @@ -1087,11 +1091,6 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ) if( table->data[ i ][ 0 ] == table_id ) return TRUE; - count = table->nonpersistent_row_count; - for( i=0; inonpersistent_data[ i ][ 0 ] == table_id ) - return TRUE; - return FALSE; } @@ -1113,7 +1112,6 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; UINT offset, n; - BYTE **data; if( !tv->table ) return ERROR_INVALID_PARAMETER; @@ -1122,7 +1120,7 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * return ERROR_INVALID_PARAMETER; /* how many rows are there ? */ - if( row >= tv->table->row_count + tv->table->nonpersistent_row_count ) + if( row >= tv->table->row_count ) return ERROR_NO_MORE_ITEMS; if( tv->columns[col-1].offset >= tv->row_size ) @@ -1135,14 +1133,6 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * if (tv->order) row = tv->order->reorder[row]; - if (row >= tv->table->row_count) - { - row -= tv->table->row_count; - data = tv->table->nonpersistent_data; - } - else - data = tv->table->data; - n = bytes_per_column( tv->db, &tv->columns[col-1] ); if (n != 2 && n != 3 && n != 4) { @@ -1151,7 +1141,7 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * } offset = tv->columns[col-1].offset; - *val = read_table_int(data, row, offset, n); + *val = read_table_int(tv->table->data, row, offset, n); /* TRACE("Data [%d][%d] = %d\n", row, col, *val ); */ @@ -1277,7 +1267,6 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val ) { UINT offset, n, i; - BYTE **data; if( !tv->table ) return ERROR_INVALID_PARAMETER; @@ -1285,7 +1274,7 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val ) if( (col==0) || (col>tv->num_cols) ) return ERROR_INVALID_PARAMETER; - if( row >= tv->table->row_count + tv->table->nonpersistent_row_count ) + if( row >= tv->table->row_count ) return ERROR_INVALID_PARAMETER; if( tv->columns[col-1].offset >= tv->row_size ) @@ -1298,14 +1287,6 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val ) msi_free( tv->columns[col-1].hash_table ); tv->columns[col-1].hash_table = NULL; - if (row >= tv->table->row_count) - { - row -= tv->table->row_count; - data = tv->table->nonpersistent_data; - } - else - data = tv->table->data; - n = bytes_per_column( tv->db, &tv->columns[col-1] ); if ( n != 2 && n != 3 && n != 4 ) { @@ -1315,7 +1296,7 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val ) offset = tv->columns[col-1].offset; for ( i = 0; i < n; i++ ) - data[row][offset + i] = (val >> i * 8) & 0xff; + tv->table->data[row][offset + i] = (val >> i * 8) & 0xff; return ERROR_SUCCESS; } @@ -1393,9 +1374,8 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI if ( !(mask&(1<= tv->table->row_count then it is a non-persistent row */ persistent = (tv->table->persistent != MSICONDITION_FALSE) && - (row < tv->table->row_count); + (tv->table->data_persistent[row]); /* FIXME: should we allow updating keys? */ val = 0; @@ -1469,8 +1449,10 @@ static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num, BOOL tempo { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; BYTE **p, *row; + BOOL *b; UINT sz; BYTE ***data_ptr; + BOOL **data_persist_ptr; UINT *row_count; TRACE("%p %s\n", view, temporary ? "TRUE" : "FALSE"); @@ -1482,20 +1464,11 @@ static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num, BOOL tempo if( !row ) return ERROR_NOT_ENOUGH_MEMORY; - if( temporary ) - { - row_count = &tv->table->nonpersistent_row_count; - data_ptr = &tv->table->nonpersistent_data; - if (*num == -1) - *num = tv->table->row_count + tv->table->nonpersistent_row_count; - } - else - { - row_count = &tv->table->row_count; - data_ptr = &tv->table->data; - if (*num == -1) - *num = tv->table->row_count; - } + row_count = &tv->table->row_count; + data_ptr = &tv->table->data; + data_persist_ptr = &tv->table->data_persistent; + if (*num == -1) + *num = tv->table->row_count; sz = (*row_count + 1) * sizeof (BYTE*); if( *data_ptr ) @@ -1508,8 +1481,24 @@ static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num, BOOL tempo return ERROR_NOT_ENOUGH_MEMORY; } + sz = (*row_count + 1) * sizeof (BOOL); + if( *data_persist_ptr ) + b = msi_realloc( *data_persist_ptr, sz ); + else + b = msi_alloc( sz ); + if( !b ) + { + msi_free( row ); + msi_free( p ); + return ERROR_NOT_ENOUGH_MEMORY; + } + *data_ptr = p; (*data_ptr)[*row_count] = row; + + *data_persist_ptr = b; + (*data_persist_ptr)[*row_count] = !temporary; + (*row_count)++; return ERROR_SUCCESS; @@ -1545,7 +1534,7 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col { if( !tv->table ) return ERROR_INVALID_PARAMETER; - *rows = tv->table->row_count + tv->table->nonpersistent_row_count; + *rows = tv->table->row_count; } return ERROR_SUCCESS; @@ -1620,8 +1609,7 @@ static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec ) static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary ) { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; - UINT i, r, idx, size; - BYTE **data; + UINT i, r; TRACE("%p %p %s\n", tv, rec, temporary ? "TRUE" : "FALSE" ); @@ -1635,27 +1623,16 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, if( r != ERROR_SUCCESS ) return r; - idx = row; - if( temporary ) - { - data = tv->table->nonpersistent_data; - size = tv->table->nonpersistent_row_count; - idx -= tv->table->row_count; - } - else - { - data = tv->table->data; - size = tv->table->row_count; - } - /* shift the rows to make room for the new row */ - if( idx != size - 1 ) + for (i = tv->table->row_count - 1; i > row; i--) { - for (i = 1; i < size - idx; i++) - memmove(&(data[size - i][0]), - &(data[size - i - 1][0]), tv->row_size); + memmove(&(tv->table->data[i][0]), + &(tv->table->data[i - 1][0]), tv->row_size); + tv->table->data_persistent[i] = tv->table->data_persistent[i - 1]; } + /* Re-set the persistence flag */ + tv->table->data_persistent[row] = !temporary; return TABLE_set_row( view, row, rec, (1<num_cols) - 1 ); } @@ -1663,7 +1640,6 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; UINT r, num_rows, num_cols, i; - BYTE **data; TRACE("%p %d\n", tv, row); @@ -1677,19 +1653,8 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) if ( row >= num_rows ) return ERROR_FUNCTION_FAILED; - if ( row < tv->table->row_count ) - { - num_rows = tv->table->row_count; - tv->table->row_count--; - data = tv->table->data; - } - else - { - num_rows = tv->table->nonpersistent_row_count; - row -= tv->table->row_count; - tv->table->nonpersistent_row_count--; - data = tv->table->nonpersistent_data; - } + num_rows = tv->table->row_count; + tv->table->row_count--; /* reset the hash tables */ for (i = 0; i < tv->num_cols; i++) @@ -1702,7 +1667,10 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) return ERROR_SUCCESS; for (i = row + 1; i < num_rows; i++) - memcpy(data[i - 1], data[i], tv->row_size); + { + memcpy(tv->table->data[i - 1], tv->table->data[i], tv->row_size); + tv->table->data_persistent[i - 1] = tv->table->data_persistent[i]; + } return ERROR_SUCCESS; } @@ -1856,7 +1824,7 @@ static UINT TABLE_find_matching_rows( struct tagMSIVIEW *view, UINT col, if( !tv->columns[col-1].hash_table ) { UINT i; - UINT num_rows = tv->table->row_count + tv->table->nonpersistent_row_count; + UINT num_rows = tv->table->row_count; MSICOLUMNHASHENTRY **hash_table; MSICOLUMNHASHENTRY *new_entry; @@ -2625,7 +2593,7 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row ) data = msi_record_to_row( tv, rec ); if( !data ) return r; - for( i = 0; i < tv->table->row_count + tv->table->nonpersistent_row_count; i++ ) + for( i = 0; i < tv->table->row_count; i++ ) { r = msi_row_matches( tv, i, data ); if( r == ERROR_SUCCESS )