Hans Leidekker : expand.exe: Add support for cabinet files.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Apr 26 10:23:54 CDT 2007
Module: wine
Branch: master
Commit: 3d2670ea3215cfd0b827b62b284e0fe4034df2d8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3d2670ea3215cfd0b827b62b284e0fe4034df2d8
Author: Hans Leidekker <hans at it.vu.nl>
Date: Wed Apr 25 20:50:13 2007 +0200
expand.exe: Add support for cabinet files.
---
programs/expand/Makefile.in | 2 +-
programs/expand/expand.c | 117 ++++++++++++++++++++++++++++++++++--------
2 files changed, 95 insertions(+), 24 deletions(-)
diff --git a/programs/expand/Makefile.in b/programs/expand/Makefile.in
index ac35d43..7e4f982 100644
--- a/programs/expand/Makefile.in
+++ b/programs/expand/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = expand.exe
APPMODE = -mconsole
-IMPORTS = lz32 kernel32
+IMPORTS = setupapi kernel32
C_SRCS = expand.c
diff --git a/programs/expand/expand.c b/programs/expand/expand.c
index 9f2af8e..6022fe2 100644
--- a/programs/expand/expand.c
+++ b/programs/expand/expand.c
@@ -1,6 +1,7 @@
/*
* Copyright 1997 Victor Schneider
* Copyright 2002 Alexandre Julliard
+ * 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
@@ -23,30 +24,100 @@
#include <string.h>
#include <windows.h>
#include <lzexpand.h>
+#include <setupapi.h>
+
+static UINT CALLBACK extract_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 )
+{
+ FILE_IN_CABINET_INFO_A *info = (FILE_IN_CABINET_INFO_A *)param1;
+
+ switch (notification)
+ {
+ case SPFILENOTIFY_FILEINCABINET:
+ {
+ LPCSTR targetname = context;
+
+ strcpy( info->FullTargetName, targetname );
+ return FILEOP_DOIT;
+ }
+ default: return NO_ERROR;
+ }
+}
int main(int argc, char *argv[])
{
- OFSTRUCT SourceOpenStruct1, SourceOpenStruct2;
- LONG ret;
- HFILE hSourceFile, hDestFile;
-
- if (argc < 2)
- {
- fprintf( stderr, "Usage: %s infile [outfile]\n", argv[0] );
- return 1;
- }
- hSourceFile = LZOpenFile(argv[1], &SourceOpenStruct1, OF_READ);
- if (argv[2])
- hDestFile = LZOpenFile(argv[2], &SourceOpenStruct2, OF_CREATE | OF_WRITE);
- else
- {
- char OriginalName[MAX_PATH];
- GetExpandedName(argv[1], OriginalName);
- hDestFile = LZOpenFile(OriginalName, &SourceOpenStruct2, OF_CREATE | OF_WRITE);
- }
- ret = LZCopy(hSourceFile, hDestFile);
- LZClose(hSourceFile);
- LZClose(hDestFile);
- if (ret <= 0) fprintf(stderr,"LZCopy failed: return is %d\n",ret);
- return (ret <= 0);
+ int ret = 0;
+ char infile[MAX_PATH], outfile[MAX_PATH], actual_name[MAX_PATH];
+ UINT comp;
+
+ if (argc < 3)
+ {
+ fprintf( stderr, "Usage: %s infile outfile\n", argv[0] );
+ return 1;
+ }
+
+ GetFullPathNameA( argv[1], sizeof(infile), infile, NULL );
+ GetFullPathNameA( argv[2], sizeof(outfile), outfile, NULL );
+
+ if (!lstrcmpiA( infile, outfile ))
+ {
+ fprintf( stderr, "%s: can't expand file to itself\n", argv[0] );
+ return 1;
+ }
+ if (!SetupGetFileCompressionInfoExA( infile, actual_name, sizeof(actual_name), NULL, NULL, NULL, &comp ))
+ {
+ fprintf( stderr, "%s: can't open input file %s\n", argv[0], infile );
+ return 1;
+ }
+
+ switch (comp)
+ {
+ case FILE_COMPRESSION_MSZIP:
+ {
+ if (!SetupIterateCabinetA( infile, 0, extract_callback, (PVOID)outfile ))
+ {
+ fprintf( stderr, "%s: cabinet extraction failed\n", argv[0] );
+ return 1;
+ }
+ break;
+ }
+ case FILE_COMPRESSION_WINLZA:
+ {
+ INT hin, hout;
+ OFSTRUCT ofin, ofout;
+ LONG error;
+
+ if ((hin = LZOpenFile( infile, &ofin, OF_READ )) < 0)
+ {
+ fprintf( stderr, "%s: can't open input file %s\n", argv[0], infile );
+ return 1;
+ }
+ if ((hout = LZOpenFile( outfile, &ofout, OF_CREATE | OF_WRITE )) < 0)
+ {
+ LZClose( hin );
+ fprintf( stderr, "%s: can't open output file %s\n", argv[0], outfile );
+ return 1;
+ }
+ error = LZCopy( hin, hout );
+
+ LZClose( hin );
+ LZClose( hout );
+
+ if (error < 0)
+ {
+ fprintf( stderr, "%s: LZCopy failed, error is %d\n", argv[0], error );
+ return 1;
+ }
+ break;
+ }
+ default:
+ {
+ if (!CopyFileA( infile, outfile, FALSE ))
+ {
+ fprintf( stderr, "%s: CopyFileA failed\n", argv[0] );
+ return 1;
+ }
+ break;
+ }
+ }
+ return ret;
}
More information about the wine-cvs
mailing list