UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, UINT iField, LPCSTR szFilename) { LPWSTR wstr = NULL; UINT ret; TRACE("%d %d %s\n", hRecord, iField, debugstr_a(szFilename)); if( szFilename ) { wstr = strdupAtoW( szFilename ); if( !wstr ) return ERROR_OUTOFMEMORY; } ret = MsiRecordSetStreamW(hRecord, iField, wstr); msi_free(wstr); return ret; }
BOOL WINAPI SetupGetSourceFileLocationA( HINF hinf, PINFCONTEXT context, PCSTR filename, PUINT source_id, PSTR buffer, DWORD buffer_size, PDWORD required_size ) { BOOL ret = FALSE; WCHAR *filenameW = NULL, *bufferW = NULL; DWORD required; INT size; TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_a(filename), source_id, buffer, buffer_size, required_size); if (filename && *filename && !(filenameW = strdupAtoW( filename ))) return FALSE; if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, NULL, 0, &required )) goto done; if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) ))) goto done; if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, bufferW, required, NULL )) goto done; size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); if (required_size) *required_size = size; if (buffer) { if (buffer_size >= size) WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL ); else { SetLastError( ERROR_INSUFFICIENT_BUFFER ); goto done; } } ret = TRUE; done: HeapFree( GetProcessHeap(), 0, filenameW ); HeapFree( GetProcessHeap(), 0, bufferW ); return ret; }
BOOL WINAPI SetupGetTargetPathA( HINF hinf, PINFCONTEXT context, PCSTR section, PSTR buffer, DWORD buffer_size, PDWORD required_size ) { BOOL ret = FALSE; WCHAR *sectionW = NULL, *bufferW = NULL; DWORD required; INT size; TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_a(section), buffer, buffer_size, required_size); if (section && !(sectionW = strdupAtoW( section ))) return FALSE; if (!SetupGetTargetPathW( hinf, context, sectionW, NULL, 0, &required )) goto done; if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) ))) goto done; if (!SetupGetTargetPathW( hinf, context, sectionW, bufferW, required, NULL )) goto done; size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); if (required_size) *required_size = size; if (buffer) { if (buffer_size >= size) WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL ); else { SetLastError( ERROR_INSUFFICIENT_BUFFER ); goto done; } } ret = TRUE; done: HeapFree( GetProcessHeap(), 0, sectionW ); HeapFree( GetProcessHeap(), 0, bufferW ); return ret; }
UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct, LPSTR szFeature, LPSTR szComponent, LPDWORD pUsed ) { WCHAR product[MAX_FEATURE_CHARS+1]; WCHAR feature[MAX_FEATURE_CHARS+1]; WCHAR component[MAX_FEATURE_CHARS+1]; LPWSTR str = NULL, p = NULL, f = NULL, c = NULL; UINT r; TRACE("%s %p %p %p %p\n", debugstr_a(szDescriptor), szProduct, szFeature, szComponent, pUsed); str = strdupAtoW( szDescriptor ); if( szDescriptor && !str ) return ERROR_OUTOFMEMORY; if (szProduct) p = product; if (szFeature) f = feature; if (szComponent) c = component; r = MsiDecomposeDescriptorW( str, p, f, c, pUsed ); if (r == ERROR_SUCCESS) { WideCharToMultiByte( CP_ACP, 0, p, -1, szProduct, MAX_FEATURE_CHARS+1, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, f, -1, szFeature, MAX_FEATURE_CHARS+1, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, c, -1, szComponent, MAX_FEATURE_CHARS+1, NULL, NULL ); } msi_free( str ); return r; }
UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, UINT iField, LPCSTR szValue ) { WCHAR *valueW = NULL; MSIRECORD *rec; UINT ret; TRACE("%d %d %s\n", handle, iField, debugstr_a(szValue)); if (szValue && !(valueW = strdupAtoW( szValue ))) return ERROR_OUTOFMEMORY; rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) { msi_free( valueW ); return ERROR_INVALID_HANDLE; } msiobj_lock( &rec->hdr ); ret = MSI_RecordSetStringW( rec, iField, valueW ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); msi_free( valueW ); return ret; }
static UINT MSI_RecordSetStringA( MSIRECORD *rec, UINT iField, LPCSTR szValue ) { LPWSTR str; TRACE("%p %d %s\n", rec, iField, debugstr_a(szValue)); if( iField > rec->count ) return ERROR_INVALID_FIELD; MSI_FreeField( &rec->fields[iField] ); if( szValue && szValue[0] ) { str = strdupAtoW( szValue ); rec->fields[iField].type = MSIFIELD_WSTR; rec->fields[iField].u.szwVal = str; } else { rec->fields[iField].type = MSIFIELD_NULL; rec->fields[iField].u.szwVal = NULL; } return 0; }
static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count) { #include "pshpack1.h" struct logical_screen_descriptor { char signature[6]; USHORT width; USHORT height; BYTE packed; /* global_color_table_flag : 1; * color_resolution : 3; * sort_flag : 1; * global_color_table_size : 3; */ BYTE background_color_index; BYTE pixel_aspect_ratio; } lsd_data; #include "poppack.h" HRESULT hr; ULONG bytesread, i; MetadataItem *result; *items = NULL; *count = 0; hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK; result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 9); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 9; i++) { PropVariantInit(&result[i].schema); PropVariantInit(&result[i].id); PropVariantInit(&result[i].value); } result[0].id.vt = VT_LPWSTR; result[0].id.u.pwszVal = strdupAtoW("Signature"); result[0].value.vt = VT_UI1|VT_VECTOR; result[0].value.u.caub.cElems = sizeof(lsd_data.signature); result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(lsd_data.signature)); memcpy(result[0].value.u.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature)); result[1].id.vt = VT_LPWSTR; result[1].id.u.pwszVal = strdupAtoW("Width"); result[1].value.vt = VT_UI2; result[1].value.u.uiVal = lsd_data.width; result[2].id.vt = VT_LPWSTR; result[2].id.u.pwszVal = strdupAtoW("Height"); result[2].value.vt = VT_UI2; result[2].value.u.uiVal = lsd_data.height; result[3].id.vt = VT_LPWSTR; result[3].id.u.pwszVal = strdupAtoW("GlobalColorTableFlag"); result[3].value.vt = VT_BOOL; result[3].value.u.boolVal = (lsd_data.packed >> 7) & 1; result[4].id.vt = VT_LPWSTR; result[4].id.u.pwszVal = strdupAtoW("ColorResolution"); result[4].value.vt = VT_UI1; result[4].value.u.bVal = (lsd_data.packed >> 4) & 7; result[5].id.vt = VT_LPWSTR; result[5].id.u.pwszVal = strdupAtoW("SortFlag"); result[5].value.vt = VT_BOOL; result[5].value.u.boolVal = (lsd_data.packed >> 3) & 1; result[6].id.vt = VT_LPWSTR; result[6].id.u.pwszVal = strdupAtoW("GlobalColorTableSize"); result[6].value.vt = VT_UI1; result[6].value.u.bVal = lsd_data.packed & 7; result[7].id.vt = VT_LPWSTR; result[7].id.u.pwszVal = strdupAtoW("BackgroundColorIndex"); result[7].value.vt = VT_UI1; result[7].value.u.bVal = lsd_data.background_color_index; result[8].id.vt = VT_LPWSTR; result[8].id.u.pwszVal = strdupAtoW("PixelAspectRatio"); result[8].value.vt = VT_UI1; result[8].value.u.bVal = lsd_data.pixel_aspect_ratio; *items = result; *count = 9; return S_OK; }
/*********************************************************************** * msidbImportTables * * Takes a list of tables or '*' (for all) to import from text archive * files in specified folder * * For each table, a file called <tablename>.idt is imported containing * tab separated ASCII. * * Examples (note wildcard escape for *nix/bash): * msidb -d <pathtomsi>.msi -f <workdir> -i \* * msidb -d <pathtomsi>.msi -f <workdir> -i File Directory Binary **********************************************************************/ static BOOL msidbImportTables(LPCWSTR dbfile, LPCWSTR wdir, LPWSTR tables[], BOOL create) { static const WCHAR ext[] = {'.', 'i', 'd', 't', 0}; static const WCHAR all[] = {'*', 0}; UINT r, len; char *dirNameA; char *fileName; DIR *dir; struct dirent *ent; int i = 0; MSIHANDLE dbhandle; LPWSTR tableFile = 0; LPCWSTR oFlag = (LPCWSTR) MSIDBOPEN_TRANSACT; if (create == TRUE) oFlag = (LPCWSTR) MSIDBOPEN_CREATE; r = MsiOpenDatabaseW(dbfile, oFlag, &dbhandle); if (r != ERROR_SUCCESS) { return FALSE; } if (strcmpW(tables[0], all) == 0) { dirNameA = strdupWtoA(CP_ACP, wdir); dir = opendir(dirNameA); if (dir) { while ((ent = readdir(dir)) != NULL) { if (ent->d_type != DT_REG) continue; fileName = ent->d_name; if (strcmp(fileName+strlen(fileName)-4*sizeof(fileName[0]), ".idt") != 0) continue; if (strcmp(fileName, ".") == 0 || strcmp(fileName, "..") == 0) continue; tableFile = strdupAtoW(CP_ACP, fileName); r = MsiDatabaseImportW(dbhandle, wdir, tableFile); free(tableFile); } } else return FALSE; closedir(dir); free(dirNameA); } else { for (i = 0; i < MAX_TABLES && tables[i] != 0; ++i) { len = lstrlenW(tables[i]) + 5; tableFile = malloc(len * sizeof (WCHAR)); if (tableFile == NULL) return FALSE; lstrcpyW(tableFile, tables[i]); lstrcatW(tableFile, ext); r = MsiDatabaseImportW(dbhandle, wdir, tableFile); free(tableFile); if (r != ERROR_SUCCESS) { return FALSE; } } } MsiDatabaseCommit(dbhandle); MsiCloseHandle(dbhandle); return TRUE; }
/* * Code based off of code located here * http://www.codeproject.com/gdi/fontnamefromfile.asp */ WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) { TT_TABLE_DIRECTORY tblDir; BOOL bFound = FALSE; TT_OFFSET_TABLE ttOffsetTable; TT_NAME_TABLE_HEADER ttNTHeader; TT_NAME_RECORD ttRecord; DWORD dwRead; HANDLE handle; LPWSTR ret = NULL; int i; handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if (handle == INVALID_HANDLE_VALUE) { ERR("Unable to open font file %s\n", debugstr_w(filename)); return NULL; } if (!ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL)) goto end; ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion); if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) goto end; for (i=0; i< ttOffsetTable.uNumOfTables; i++) { if (!ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL)) break; if (memcmp(tblDir.szTag,"name",4)==0) { bFound = TRUE; tblDir.uLength = SWAPLONG(tblDir.uLength); tblDir.uOffset = SWAPLONG(tblDir.uOffset); break; } } if (!bFound) goto end; SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN); if (!ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), &dwRead,NULL)) goto end; ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset); bFound = FALSE; for(i=0; i<ttNTHeader.uNRCount; i++) { if (!ReadFile(handle,&ttRecord, sizeof(TT_NAME_RECORD),&dwRead,NULL)) break; ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); if (ttRecord.uNameID == id) { int nPos; LPSTR buf; ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT); SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, NULL, FILE_BEGIN); buf = msi_alloc_zero( ttRecord.uStringLength + 1 ); ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL); if (strlen(buf) > 0) { ret = strdupAtoW(buf); msi_free(buf); break; } msi_free(buf); SetFilePointer(handle,nPos, NULL, FILE_BEGIN); } } end: CloseHandle(handle); TRACE("Returning %s\n", debugstr_w(ret)); return ret; }
static INT_PTR CDECL extract_notify( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin ) { WCHAR *file, *nameW, *path = NULL; INT_PTR ret; switch (fdint) { case fdintCABINET_INFO: return 0; case fdintCOPY_FILE: nameW = strdupAtoW( (pfdin->attribs & _A_NAME_IS_UTF) ? CP_UTF8 : CP_ACP, pfdin->psz1 ); if (opt_preserve_paths) { file = nameW; while (*file == '\\') file++; /* remove leading backslashes */ } else { if ((file = strrchrW( nameW, '\\' ))) file++; else file = nameW; } if (opt_dest_dir) { path = cab_alloc( (strlenW(opt_dest_dir) + strlenW(file) + 1) * sizeof(WCHAR) ); strcpyW( path, opt_dest_dir ); strcatW( path, file ); } else path = file; if (match_files( file )) { if (opt_verbose) { char *nameU = strdupWtoA( CP_UNIXCP, path ); printf( "extracting %s\n", nameU ); cab_free( nameU ); } create_directories( path ); /* FIXME: check for existing file and overwrite mode */ ret = (INT_PTR)CreateFileW( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); } else ret = 0; cab_free( nameW ); if (path != file) cab_free( path ); return ret; case fdintCLOSE_FILE_INFO: CloseHandle( (HANDLE)pfdin->hf ); return 0; case fdintNEXT_CABINET: WINE_TRACE("Next cab: status %u, path '%s', file '%s'\n", pfdin->fdie, pfdin->psz3, pfdin->psz1); return pfdin->fdie == FDIERROR_NONE ? 0 : -1; case fdintENUMERATE: return 0; default: WINE_FIXME( "Unexpected notification type %d.\n", fdint ); return 0; } }
static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { TRACE("(%d)\n", fdint); switch (fdint) { case fdintPARTIAL_FILE: { CabData *data = (CabData *)pfdin->pv; data->mi->is_continuous = FALSE; return 0; } case fdintNEXT_CABINET: { CabData *data = (CabData *)pfdin->pv; struct media_info *mi = data->mi; LPWSTR cab = strdupAtoW(pfdin->psz1); UINT rc; msi_free(mi->disk_prompt); msi_free(mi->cabinet); msi_free(mi->volume_label); mi->disk_prompt = NULL; mi->cabinet = NULL; mi->volume_label = NULL; mi->disk_id++; mi->is_continuous = TRUE; rc = msi_media_get_disk_info(data->package, mi); if (rc != ERROR_SUCCESS) { msi_free(cab); ERR("Failed to get next cabinet information: %d\n", rc); return -1; } if (lstrcmpiW(mi->cabinet, cab)) { msi_free(cab); ERR("Continuous cabinet does not match the next cabinet in the Media table\n"); return -1; } msi_free(cab); TRACE("Searching for %s\n", debugstr_w(mi->source)); if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) rc = msi_change_media(data->package, mi); if (rc != ERROR_SUCCESS) return -1; return 0; } case fdintCOPY_FILE: { CabData *data = (CabData*) pfdin->pv; HANDLE handle; LPWSTR file; MSIFILE *f; DWORD attrs; file = strdupAtoW(pfdin->psz1); f = get_loaded_file(data->package, file); msi_free(file); if (!f) { WARN("unknown file in cabinet (%s)\n",debugstr_a(pfdin->psz1)); return 0; } if (f->state != msifs_missing && f->state != msifs_overwrite) { TRACE("Skipping extraction of %s\n",debugstr_a(pfdin->psz1)); return 0; } msi_file_update_ui( data->package, f, szInstallFiles ); TRACE("extracting %s\n", debugstr_w(f->TargetPath) ); attrs = f->Attributes & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL; handle = CreateFileW( f->TargetPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL ); if ( handle == INVALID_HANDLE_VALUE ) { if ( GetFileAttributesW( f->TargetPath ) != INVALID_FILE_ATTRIBUTES ) f->state = msifs_installed; else ERR("failed to create %s (error %d)\n", debugstr_w( f->TargetPath ), GetLastError() ); return 0; } f->state = msifs_installed; return (INT_PTR) handle; } case fdintCLOSE_FILE_INFO: { CabData *data = (CabData*) pfdin->pv; FILETIME ft; FILETIME ftLocal; HANDLE handle = (HANDLE) pfdin->hf; data->mi->is_continuous = FALSE; if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft)) return -1; if (!LocalFileTimeToFileTime(&ft, &ftLocal)) return -1; if (!SetFileTime(handle, &ftLocal, 0, &ftLocal)) return -1; CloseHandle(handle); return 1; } default: return 0; } }
static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { switch (fdint) { case fdintCOPY_FILE: { CabData *data = (CabData*) pfdin->pv; HANDLE handle; LPWSTR file; MSIFILE *f; DWORD attrs; file = strdupAtoW(pfdin->psz1); f = get_loaded_file(data->package, file); msi_free(file); if (!f) { WARN("unknown file in cabinet (%s)\n",debugstr_a(pfdin->psz1)); return 0; } if (f->state != msifs_missing && f->state != msifs_overwrite) { TRACE("Skipping extraction of %s\n",debugstr_a(pfdin->psz1)); return 0; } msi_file_update_ui( data->package, f, szInstallFiles ); TRACE("extracting %s\n", debugstr_w(f->TargetPath) ); attrs = f->Attributes & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL; handle = CreateFileW( f->TargetPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL ); if ( handle == INVALID_HANDLE_VALUE ) { ERR("failed to create %s (error %ld)\n", debugstr_w( f->TargetPath ), GetLastError() ); return 0; } f->state = msifs_installed; return (INT_PTR) handle; } case fdintCLOSE_FILE_INFO: { FILETIME ft; FILETIME ftLocal; HANDLE handle = (HANDLE) pfdin->hf; if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft)) return -1; if (!LocalFileTimeToFileTime(&ft, &ftLocal)) return -1; if (!SetFileTime(handle, &ftLocal, 0, &ftLocal)) return -1; CloseHandle(handle); return 1; } default: return 0; } }