|
|
//#include <stdio.h>
//
//#include <string.h>
#include "pre.h"
#include "fdi.h"
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
/*
* Function prototypes */ BOOL fdi(char *cabinet_file, char *dir); int get_percentage(unsigned long a, unsigned long b); char *return_fdi_error_string(int err);
/*
* Destination directory for extracted files */ char dest_dir[256];
/*
* Memory allocation function */ FNALLOC(mem_alloc) { return malloc(cb); }
/*
* Memory free function */ FNFREE(mem_free) { free(pv); }
FNOPEN(file_open) { return _open(pszFile, oflag, pmode); }
FNREAD(file_read) { return _read((int)hf, pv, cb); }
FNWRITE(file_write) { return _write((int)hf, pv, cb); }
FNCLOSE(file_close) { return _close((int)hf); }
FNSEEK(file_seek) { return _lseek((int)hf, dist, seektype); }
FNFDINOTIFY(notification_function) { switch (fdint) { case fdintCABINET_INFO: // general information about the cabinet
/*
printf( "fdintCABINET_INFO\n" " next cabinet = %s\n" " next disk = %s\n" " cabinet path = %s\n" " cabinet set ID = %d\n" " cabinet # in set = %d (zero based)\n" "\n", pfdin->psz1, pfdin->psz2, pfdin->psz3, pfdin->setID, pfdin->iCabinet ); */ return 0;
case fdintPARTIAL_FILE: // first file in cabinet is continuation
/*
printf( "fdintPARTIAL_FILE\n" " name of continued file = %s\n" " name of cabinet where file starts = %s\n" " name of disk where file starts = %s\n", pfdin->psz1, pfdin->psz2, pfdin->psz3 ); */ return 0;
case fdintCOPY_FILE: // file to be copied
{ INT_PTR handle; //int response;
char destination[256]; /*
printf( "fdintCOPY_FILE\n" " file name in cabinet = %s\n" " uncompressed file size = %d\n" " copy this file? (y/n): ", pfdin->psz1, pfdin->cb );
do { response = getc(stdin); response = toupper(response); } while (response != 'Y' && response != 'N');
printf("\n");
if (response == 'Y') { sprintf( destination, "%s%s", dest_dir, pfdin->psz1 );
handle = file_open( destination, _O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL, _S_IREAD | _S_IWRITE );
return handle; } else { return 0; } */ sprintf( destination, "%s%s", dest_dir, pfdin->psz1 );
handle = file_open( destination, _O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL, _S_IREAD | _S_IWRITE );
return handle; }
case fdintCLOSE_FILE_INFO: // close the file, set relevant info
{ HANDLE handle; DWORD attrs; char destination[256]; /*
printf( "fdintCLOSE_FILE_INFO\n" " file name in cabinet = %s\n" "\n", pfdin->psz1 );
sprintf( destination, "%s%s", dest_dir, pfdin->psz1 ); */ sprintf( destination, "%s%s", dest_dir, pfdin->psz1 ); file_close(pfdin->hf);
handle = CreateFileA( destination, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (handle != INVALID_HANDLE_VALUE) { FILETIME datetime;
if (TRUE == DosDateTimeToFileTime( pfdin->date, pfdin->time, &datetime)) { FILETIME local_filetime;
if (TRUE == LocalFileTimeToFileTime( &datetime, &local_filetime)) { (void) SetFileTime( handle, &local_filetime, NULL, &local_filetime ); } }
CloseHandle(handle); }
attrs = pfdin->attribs;
attrs &= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);
(void) SetFileAttributesA( destination, attrs );
return TRUE; }
case fdintNEXT_CABINET: // file continued to next cabinet
/*
printf( "fdintNEXT_CABINET\n" " name of next cabinet where file continued = %s\n" " name of next disk where file continued = %s\n" " cabinet path name = %s\n" "\n", pfdin->psz1, pfdin->psz2, pfdin->psz3 ); */ return 0; } return 0; }
BOOL fdi(char *cabinet_fullpath, char * directory) { HFDI hfdi; ERF erf; FDICABINETINFO fdici; INT_PTR hf; char *p; char cabinet_name[256]; char cabinet_path[256];
strcpy(dest_dir, directory);
hfdi = FDICreate( mem_alloc, mem_free, file_open, file_read, file_write, file_close, file_seek, cpu80386, &erf );
if (hfdi == NULL) { char szErr[255]; sprintf(szErr, "FDICreate() failed: code %d [%s]\n", erf.erfOper, return_fdi_error_string(erf.erfOper) ); MessageBoxA(NULL, szErr, "", MB_OK);
return FALSE; }
/*
* Is this file really a cabinet? */ hf = file_open( cabinet_fullpath, _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0 );
if (hf == -1) { (void) FDIDestroy(hfdi);
char szErr[255]; sprintf(szErr, "Unable to open '%s' for input\n", cabinet_fullpath); MessageBoxA(NULL, szErr, "", MB_OK);
return FALSE; }
if (FALSE == FDIIsCabinet( hfdi, hf, &fdici)) { /*
* No, it's not a cabinet! */ _close((int)hf);
char szErr[255]; sprintf(szErr, "FDIIsCabinet() failed: '%s' is not a cabinet\n", cabinet_fullpath ); MessageBoxA(NULL, szErr, "", MB_OK);
(void) FDIDestroy(hfdi); return FALSE; } else { _close((int)hf);
/*
char szErr[255]; sprintf(szErr, "Information on cabinet file '%s'\n" " Total length of cabinet file : %d\n" " Number of folders in cabinet : %d\n" " Number of files in cabinet : %d\n" " Cabinet set ID : %d\n" " Cabinet number in set : %d\n" " RESERVE area in cabinet? : %s\n" " Chained to prev cabinet? : %s\n" " Chained to next cabinet? : %s\n" "\n", cabinet_fullpath, fdici.cbCabinet, fdici.cFolders, fdici.cFiles, fdici.setID, fdici.iCabinet, fdici.fReserve == TRUE ? "yes" : "no", fdici.hasprev == TRUE ? "yes" : "no", fdici.hasnext == TRUE ? "yes" : "no" ); MessageBox(NULL, szErr, "", MB_OK); */ }
p = strrchr(cabinet_fullpath, '\\');
if (p == NULL) { strcpy(cabinet_name, cabinet_fullpath); strcpy(cabinet_path, ""); } else { strcpy(cabinet_name, p+1);
strncpy(cabinet_path, cabinet_fullpath, (int) (p-cabinet_fullpath)+1); cabinet_path[ (int) (p-cabinet_fullpath)+1 ] = 0; }
if (TRUE != FDICopy( hfdi, cabinet_name, cabinet_path, 0, notification_function, NULL, NULL)) { char szErr[255]; sprintf(szErr, "FDICopy() failed: code %d [%s]\n", erf.erfOper, return_fdi_error_string(erf.erfOper) ); MessageBoxA(NULL, szErr, "", MB_OK);
(void) FDIDestroy(hfdi); return FALSE; }
if (FDIDestroy(hfdi) != TRUE) { char szErr[255]; sprintf(szErr, "FDIDestroy() failed: code %d [%s]\n", erf.erfOper, return_fdi_error_string(erf.erfOper) ); MessageBoxA(NULL, szErr, "", MB_OK);
return FALSE; }
return TRUE; }
char *return_fdi_error_string(int err) { switch (err) { case FDIERROR_NONE: return "No error";
case FDIERROR_CABINET_NOT_FOUND: return "Cabinet not found"; case FDIERROR_NOT_A_CABINET: return "Not a cabinet"; case FDIERROR_UNKNOWN_CABINET_VERSION: return "Unknown cabinet version"; case FDIERROR_CORRUPT_CABINET: return "Corrupt cabinet"; case FDIERROR_ALLOC_FAIL: return "Memory allocation failed"; case FDIERROR_BAD_COMPR_TYPE: return "Unknown compression type"; case FDIERROR_MDI_FAIL: return "Failure decompressing data"; case FDIERROR_TARGET_FILE: return "Failure writing to target file"; case FDIERROR_RESERVE_MISMATCH: return "Cabinets in set have different RESERVE sizes"; case FDIERROR_WRONG_CABINET: return "Cabinet returned on fdintNEXT_CABINET is incorrect"; case FDIERROR_USER_ABORT: return "User aborted"; default: return "Unknown error"; } }
|