Windows2003-3790/inetcore/connectionwizard/icwconn1/fdi.cpp
2020-09-30 16:53:55 +02:00

471 lines
9.2 KiB
C++

//#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";
}
}