Module: wine Branch: master Commit: 8ccc19c74c43d81965ecffdaf9bce9d965a25f1b URL: http://source.winehq.org/git/wine.git/?a=commit;h=8ccc19c74c43d81965ecffdaf9...
Author: Hans Leidekker hans@it.vu.nl Date: Sun Apr 8 13:18:54 2007 +0200
setupapi: Implement SetupGetFileCompressionInfoEx{A, W}.
---
dlls/setupapi/misc.c | 216 +++++++++++++++++++++++++++++++++++++++++++ dlls/setupapi/setupapi.spec | 2 + include/setupapi.h | 8 ++ 3 files changed, 226 insertions(+), 0 deletions(-)
diff --git a/dlls/setupapi/misc.c b/dlls/setupapi/misc.c index 04941a5..f760f11 100644 --- a/dlls/setupapi/misc.c +++ b/dlls/setupapi/misc.c @@ -2,6 +2,7 @@ * Setupapi miscellaneous functions * * Copyright 2005 Eric Kohl + * Copyright 2007 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +27,7 @@ #include "winuser.h" #include "winreg.h" #include "setupapi.h" +#include "lzexpand.h"
#include "wine/unicode.h" #include "wine/debug.h" @@ -994,3 +996,217 @@ DWORD WINAPI InstallCatalog( LPCSTR catalog, LPCSTR basename, LPSTR fullname ) FIXME("%s, %s, %p\n", debugstr_a(catalog), debugstr_a(basename), fullname); return 0; } + +static UINT detect_compression_type( LPCWSTR file ) +{ + DWORD size; + HANDLE handle; + UINT type = FILE_COMPRESSION_NONE; + static const BYTE LZ_MAGIC[] = { 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33 }; + static const BYTE MSZIP_MAGIC[] = { 0x4b, 0x57, 0x41, 0x4a }; + static const BYTE NTCAB_MAGIC[] = { 0x4d, 0x53, 0x43, 0x46 }; + BYTE buffer[8]; + + handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); + if (handle == INVALID_HANDLE_VALUE) + { + ERR("cannot open file %s\n", debugstr_w(file)); + return FILE_COMPRESSION_NONE; + } + if (!ReadFile( handle, buffer, sizeof(buffer), &size, NULL ) || size != sizeof(buffer)) + { + CloseHandle( handle ); + return FILE_COMPRESSION_NONE; + } + if (!memcmp( buffer, LZ_MAGIC, sizeof(LZ_MAGIC) )) type = FILE_COMPRESSION_WINLZA; + else if (!memcmp( buffer, MSZIP_MAGIC, sizeof(MSZIP_MAGIC) )) type = FILE_COMPRESSION_MSZIP; + else if (!memcmp( buffer, NTCAB_MAGIC, sizeof(NTCAB_MAGIC) )) type = FILE_COMPRESSION_MSZIP; /* not a typo */ + + CloseHandle( handle ); + return type; +} + +static BOOL get_file_size( LPCWSTR file, DWORD *size ) +{ + HANDLE handle; + + handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); + if (handle == INVALID_HANDLE_VALUE) + { + ERR("cannot open file %s\n", debugstr_w(file)); + return FALSE; + } + *size = GetFileSize( handle, NULL ); + CloseHandle( handle ); + return TRUE; +} + +static BOOL get_file_sizes_none( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + + if (!get_file_size( source, &size )) return FALSE; + if (source_size) *source_size = size; + if (target_size) *target_size = size; + return TRUE; +} + +static BOOL get_file_sizes_lz( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + BOOL ret = TRUE; + + if (source_size) + { + if (!get_file_size( source, &size )) ret = FALSE; + else *source_size = size; + } + if (target_size) + { + INT file; + OFSTRUCT of; + + if ((file = LZOpenFileW( (LPWSTR)source, &of, OF_READ )) < 0) + { + ERR("cannot open source file for reading\n"); + return FALSE; + } + *target_size = LZSeek( file, 0, 2 ); + LZClose( file ); + } + return ret; +} + +static UINT CALLBACK file_compression_info_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 ) +{ + DWORD *size = context; + FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; + + switch (notification) + { + case SPFILENOTIFY_FILEINCABINET: + { + *size = info->FileSize; + return FILEOP_SKIP; + } + default: return NO_ERROR; + } +} + +static BOOL get_file_sizes_cab( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + BOOL ret = TRUE; + + if (source_size) + { + if (!get_file_size( source, &size )) ret = FALSE; + else *source_size = size; + } + if (target_size) + { + ret = SetupIterateCabinetW( source, 0, file_compression_info_callback, target_size ); + } + return ret; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoExA (SETUPAPI.@) + * + * See SetupGetFileCompressionInfoExW. + */ +BOOL WINAPI SetupGetFileCompressionInfoExA( PCSTR source, PSTR name, DWORD len, PDWORD required, + PDWORD source_size, PDWORD target_size, PUINT type ) +{ + BOOL ret; + WCHAR *nameW = NULL, *sourceW = NULL; + DWORD nb_chars = 0; + LPSTR nameA; + + TRACE("%s, %p, %d, %p, %p, %p, %p\n", debugstr_a(source), name, len, required, + source_size, target_size, type); + + if (!source || !(sourceW = MultiByteToUnicode( source, CP_ACP ))) return FALSE; + + if (name) + { + ret = SetupGetFileCompressionInfoExW( sourceW, NULL, 0, &nb_chars, NULL, NULL, NULL ); + if (!(nameW = HeapAlloc( GetProcessHeap(), 0, nb_chars * sizeof(WCHAR) ))) + { + MyFree( sourceW ); + return FALSE; + } + } + ret = SetupGetFileCompressionInfoExW( sourceW, nameW, nb_chars, &nb_chars, source_size, target_size, type ); + if (ret) + { + if ((nameA = UnicodeToMultiByte( nameW, CP_ACP ))) + { + if (name && len >= nb_chars) lstrcpyA( name, nameA ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + ret = FALSE; + } + MyFree( nameA ); + } + } + if (required) *required = nb_chars; + HeapFree( GetProcessHeap(), 0, nameW ); + MyFree( sourceW ); + + return ret; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoExW (SETUPAPI.@) + * + * Get compression type and compressed/uncompressed sizes of a given file. + * + * PARAMS + * source [I] File to examine. + * name [O] Actual filename used. + * len [I] Length in characters of 'name' buffer. + * required [O] Number of characters written to 'name'. + * source_size [O] Size of compressed file. + * target_size [O] Size of uncompressed file. + * type [O] Compression type. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI SetupGetFileCompressionInfoExW( PCWSTR source, PWSTR name, DWORD len, PDWORD required, + PDWORD source_size, PDWORD target_size, PUINT type ) +{ + UINT comp; + BOOL ret = FALSE; + DWORD source_len; + + TRACE("%s, %p, %d, %p, %p, %p, %p\n", debugstr_w(source), name, len, required, + source_size, target_size, type); + + if (!source) return FALSE; + + source_len = lstrlenW( source ) + 1; + if (required) *required = source_len; + if (name && len >= source_len) + { + lstrcpyW( name, source ); + ret = TRUE; + } + else return FALSE; + + comp = detect_compression_type( source ); + if (type) *type = comp; + + switch (comp) + { + case FILE_COMPRESSION_MSZIP: + case FILE_COMPRESSION_NTCAB: ret = get_file_sizes_cab( source, source_size, target_size ); break; + case FILE_COMPRESSION_NONE: ret = get_file_sizes_none( source, source_size, target_size ); break; + case FILE_COMPRESSION_WINLZA: ret = get_file_sizes_lz( source, source_size, target_size ); break; + default: break; + } + return ret; +} diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index c44d1d0..ef92bc0 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -396,6 +396,8 @@ @ stdcall SetupGetBinaryField(ptr long ptr long ptr) @ stdcall SetupGetFieldCount(ptr) @ stub SetupGetFileCompressionInfoA +@ stdcall SetupGetFileCompressionInfoExA(str ptr long ptr ptr ptr ptr) +@ stdcall SetupGetFileCompressionInfoExW(wstr ptr long ptr ptr ptr ptr) @ stub SetupGetFileCompressionInfoW @ stdcall SetupGetFileQueueCount(long long ptr) @ stdcall SetupGetFileQueueFlags(long ptr) diff --git a/include/setupapi.h b/include/setupapi.h index 81d97e0..b6d57b2 100644 --- a/include/setupapi.h +++ b/include/setupapi.h @@ -701,6 +701,11 @@ DECL_WINELIB_SETUPAPI_TYPE_AW(PFILEPATHS) #define SRCINFO_TAGFILE 2 #define SRCINFO_DESCRIPTION 3
+#define FILE_COMPRESSION_NONE 0 +#define FILE_COMPRESSION_WINLZA 1 +#define FILE_COMPRESSION_MSZIP 2 +#define FILE_COMPRESSION_NTCAB 3 + LONG WINAPI AddTagToGroupOrderList(PCWSTR lpGroupName, DWORD dwUnknown2, DWORD dwUnknown3); DWORD WINAPI CaptureAndConvertAnsiArg(PCSTR lpSrc, PWSTR *lpDst); DWORD WINAPI CaptureStringArg(PCWSTR lpSrc, PWSTR *lpDst); @@ -811,6 +816,9 @@ BOOL WINAPI SetupFindNextMatchLineW( PINFCONTEXT context_in, PCWSTR key, PIN #define SetupFindNextMatchLine WINELIB_NAME_AW(SetupFindNextMatchLine) BOOL WINAPI SetupGetBinaryField( PINFCONTEXT context, DWORD index, BYTE *buffer, DWORD size, LPDWORD required ); DWORD WINAPI SetupGetFieldCount( PINFCONTEXT context ); +BOOL WINAPI SetupGetFileCompressionInfoExA(PCSTR, PSTR, DWORD, PDWORD, PDWORD, PDWORD, PUINT); +BOOL WINAPI SetupGetFileCompressionInfoExW(PCWSTR, PWSTR, DWORD, PDWORD, PDWORD, PDWORD, PUINT); +#define SetupGetFileCompressionInfoEx WINELIB_NAME_AW(SetupGetFileCompressionInfoEx) BOOL WINAPI SetupGetFileQueueCount( HSPFILEQ, UINT, PUINT ); BOOL WINAPI SetupGetFileQueueFlags( HSPFILEQ, PDWORD ); BOOL WINAPI SetupGetInfInformationA( LPCVOID, DWORD, PSP_INF_INFORMATION, DWORD, PDWORD);