Hans Leidekker : setupapi: Implement SetupDecompressOrCopyFile{A, W}.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Apr 9 07:36:12 CDT 2007
Module: wine
Branch: master
Commit: c1950e2dccb0d16398997a228c3716a332d827d2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c1950e2dccb0d16398997a228c3716a332d827d2
Author: Hans Leidekker <hans at it.vu.nl>
Date: Sun Apr 8 13:19:13 2007 +0200
setupapi: Implement SetupDecompressOrCopyFile{A, W}.
---
dlls/setupapi/misc.c | 136 +++++++++++++++++++++++++++++++++++++++++++
dlls/setupapi/setupapi.spec | 4 +-
include/setupapi.h | 3 +
3 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/dlls/setupapi/misc.c b/dlls/setupapi/misc.c
index f760f11..dcc76bf 100644
--- a/dlls/setupapi/misc.c
+++ b/dlls/setupapi/misc.c
@@ -1210,3 +1210,139 @@ BOOL WINAPI SetupGetFileCompressionInfoExW( PCWSTR source, PWSTR name, DWORD len
}
return ret;
}
+
+static DWORD decompress_file_lz( LPCWSTR source, LPCWSTR target )
+{
+ DWORD ret;
+ LONG error;
+ INT src, dst;
+ OFSTRUCT sof, dof;
+
+ if ((src = LZOpenFileW( (LPWSTR)source, &sof, OF_READ )) < 0)
+ {
+ ERR("cannot open source file for reading\n");
+ return ERROR_FILE_NOT_FOUND;
+ }
+ if ((dst = LZOpenFileW( (LPWSTR)target, &dof, OF_CREATE )) < 0)
+ {
+ ERR("cannot open target file for writing\n");
+ LZClose( src );
+ return ERROR_FILE_NOT_FOUND;
+ }
+ if ((error = LZCopy( src, dst )) >= 0) ret = ERROR_SUCCESS;
+ else
+ {
+ WARN("failed to decompress file %d\n", error);
+ ret = ERROR_INVALID_DATA;
+ }
+
+ LZClose( src );
+ LZClose( dst );
+ return ret;
+}
+
+static UINT CALLBACK decompress_or_copy_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 )
+{
+ FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1;
+
+ switch (notification)
+ {
+ case SPFILENOTIFY_FILEINCABINET:
+ {
+ LPCWSTR filename, targetname = context;
+ WCHAR *p;
+
+ if ((p = strrchrW( targetname, '\\' ))) filename = p + 1;
+ else filename = targetname;
+
+ if (!lstrcmpiW( filename, info->NameInCabinet ))
+ {
+ strcpyW( info->FullTargetName, targetname );
+ return FILEOP_DOIT;
+ }
+ return FILEOP_SKIP;
+ }
+ default: return NO_ERROR;
+ }
+}
+
+static DWORD decompress_file_cab( LPCWSTR source, LPCWSTR target )
+{
+ BOOL ret;
+
+ ret = SetupIterateCabinetW( source, 0, decompress_or_copy_callback, (PVOID)target );
+
+ if (ret) return ERROR_SUCCESS;
+ else return GetLastError();
+}
+
+/***********************************************************************
+ * SetupDecompressOrCopyFileA (SETUPAPI.@)
+ *
+ * See SetupDecompressOrCopyFileW.
+ */
+DWORD WINAPI SetupDecompressOrCopyFileA( PCSTR source, PCSTR target, PUINT type )
+{
+ DWORD ret = FALSE;
+ WCHAR *sourceW = NULL, *targetW = NULL;
+
+ if (source && !(sourceW = MultiByteToUnicode( source, CP_ACP ))) return FALSE;
+ if (target && !(targetW = MultiByteToUnicode( target, CP_ACP )))
+ {
+ MyFree( sourceW );
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ ret = SetupDecompressOrCopyFileW( sourceW, targetW, type );
+
+ MyFree( sourceW );
+ MyFree( targetW );
+
+ return ret;
+}
+
+/***********************************************************************
+ * SetupDecompressOrCopyFileW (SETUPAPI.@)
+ *
+ * Copy a file and decompress it if needed.
+ *
+ * PARAMS
+ * source [I] File to copy.
+ * target [I] Filename of the copy.
+ * type [I] Compression type.
+ *
+ * RETURNS
+ * Success: ERROR_SUCCESS
+ * Failure: Win32 error code.
+ */
+DWORD WINAPI SetupDecompressOrCopyFileW( PCWSTR source, PCWSTR target, PUINT type )
+{
+ UINT comp;
+ DWORD ret = ERROR_INVALID_PARAMETER;
+
+ if (!source || !target) return ERROR_INVALID_PARAMETER;
+
+ if (!type) comp = detect_compression_type( source );
+ else comp = *type;
+
+ switch (comp)
+ {
+ case FILE_COMPRESSION_NONE:
+ if (CopyFileW( source, target, FALSE )) ret = ERROR_SUCCESS;
+ else ret = GetLastError();
+ break;
+ case FILE_COMPRESSION_WINLZA:
+ ret = decompress_file_lz( source, target );
+ break;
+ case FILE_COMPRESSION_NTCAB:
+ case FILE_COMPRESSION_MSZIP:
+ ret = decompress_file_cab( source, target );
+ break;
+ default:
+ WARN("unknown compression type %d\n", comp);
+ break;
+ }
+
+ TRACE("%s -> %s %d\n", debugstr_w(source), debugstr_w(target), comp);
+ return ret;
+}
diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec
index ef92bc0..1669cc4 100644
--- a/dlls/setupapi/setupapi.spec
+++ b/dlls/setupapi/setupapi.spec
@@ -257,8 +257,8 @@
@ stdcall SetupCopyOEMInfW(wstr wstr long long ptr long ptr ptr)
@ stdcall SetupCreateDiskSpaceListA(ptr long long)
@ stdcall SetupCreateDiskSpaceListW(ptr long long)
-@ stub SetupDecompressOrCopyFileA
-@ stub SetupDecompressOrCopyFileW
+@ stdcall SetupDecompressOrCopyFileA(str str ptr)
+@ stdcall SetupDecompressOrCopyFileW(wstr wstr ptr)
@ stub SetupDefaultQueueCallback
@ stdcall SetupDefaultQueueCallbackA(ptr long long long)
@ stdcall SetupDefaultQueueCallbackW(ptr long long long)
diff --git a/include/setupapi.h b/include/setupapi.h
index b6d57b2..dd20435 100644
--- a/include/setupapi.h
+++ b/include/setupapi.h
@@ -736,6 +736,9 @@ UINT WINAPI SetupCopyErrorW( HWND, PCWSTR, PCWSTR, PCWSTR, PCWSTR, PCWSTR, U
BOOL WINAPI SetupCopyOEMInfA( PCSTR, PCSTR, DWORD, DWORD, PSTR, DWORD, PDWORD, PSTR * );
BOOL WINAPI SetupCopyOEMInfW( PCWSTR, PCWSTR, DWORD, DWORD, PWSTR, DWORD, PDWORD, PWSTR * );
#define SetupCopyOEMInf WINELIB_NAME_AW(SetupCopyOEMInf)
+DWORD WINAPI SetupDecompressOrCopyFileA( PCSTR, PCSTR, PUINT );
+DWORD WINAPI SetupDecompressOrCopyFileW( PCWSTR, PCWSTR, PUINT );
+#define SetupDecompressOrCopyFile WINELIB_NAME_AW(SetupDecompressOrCopyFile)
UINT WINAPI SetupDefaultQueueCallbackA( PVOID, UINT, UINT_PTR, UINT_PTR );
UINT WINAPI SetupDefaultQueueCallbackW( PVOID, UINT, UINT_PTR, UINT_PTR );
#define SetupDefaultQueueCallback WINELIB_NAME_AW(SetupDefaultQueueCallback)
More information about the wine-cvs
mailing list