/*
 * 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
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <lzexpand.h>
#include <setupapi.h>

static UINT CALLBACK set_outfile( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 )
{
    FILE_IN_CABINET_INFO_A *info = (FILE_IN_CABINET_INFO_A *)param1;
    char buffer[MAX_PATH];
    char* basename;

    switch (notification)
    {
    case SPFILENOTIFY_FILEINCABINET:
    {
        LPSTR outfile = context;
        if (outfile[0] != 0)
        {
            SetLastError( ERROR_NOT_SUPPORTED );
            return FILEOP_ABORT;
        }
        GetFullPathNameA( info->NameInCabinet, sizeof(buffer), buffer, &basename );
        strcpy( outfile, basename );
        return FILEOP_SKIP;
    }
    default: return NO_ERROR;
    }
}

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;
    }
}

static BOOL option_equal(LPCSTR str1, LPCSTR str2)
{
    if (str1[0] != '/' && str1[0] != '-')
        return FALSE;
    return !lstrcmpA( str1 + 1, str2 );
}

int main(int argc, char *argv[])
{
    int ret = 0;
    char infile[MAX_PATH], outfile[MAX_PATH], actual_name[MAX_PATH];
    char outfile_basename[MAX_PATH], *basename_index;
    UINT comp;

    if (argc < 3)
    {
        fprintf( stderr, "Usage:\n" );
        fprintf( stderr, "\t%s infile outfile\n", argv[0] );
        fprintf( stderr, "\t%s /r infile \n", argv[0] );
        return 1;
    }

    if (argc == 3 && (option_equal(argv[1], "R") || option_equal(argv[1], "r")))
        GetFullPathNameA( argv[2], sizeof(infile), infile, NULL );
    else
        GetFullPathNameA( argv[1], sizeof(infile), infile, NULL );

    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;
    }

    if (argc == 3 && (option_equal(argv[1], "R") || option_equal(argv[1], "r")))
    {
        switch (comp)
        {
        case FILE_COMPRESSION_MSZIP:
        {
            outfile_basename[0] = 0;
            if (!SetupIterateCabinetA( infile, 0, set_outfile, (PVOID)outfile_basename ))
            {
                fprintf( stderr, "%s: can't determine original name\n", argv[0] );
                return 1;
            }
            GetFullPathNameA( infile, sizeof(outfile), outfile, &basename_index );
            *basename_index = 0;
            strcat( outfile, outfile_basename );
            break;
        }
        case FILE_COMPRESSION_WINLZA:
        {
            GetExpandedNameA( infile, outfile_basename );
            break;
        }
        default:
        {
            fprintf( stderr, "%s: can't determine original\n", argv[0] );
            return 1;
        }
        }
    }
    else
        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;
    }

    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 = LZOpenFileA( infile, &ofin, OF_READ )) < 0)
        {
            fprintf( stderr, "%s: can't open input file %s\n", argv[0], infile );
            return 1;
        }
        if ((hout = LZOpenFileA( 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;
}
