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