Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

564 lines
12 KiB

#include "stdafx.h"
#include "Compress.h"
char cCabName [MAX_PATH];
char CabPath[256];
ULONG g_CompressedPercentage=0;
BOOL g_CancelCompression = FALSE;
/*
* Memory allocation function
*/
FNFCIALLOC(mem_alloc)
{
return malloc(cb);
}
/*
* Memory free function
*/
FNFCIFREE(mem_free)
{
free(memory);
}
/*
* File i/o functions
*/
FNFCIOPEN(fci_open)
{
int result;
result = _open(pszFile, oflag, pmode);
if (result == -1)
*err = errno;
return result;
}
FNFCIREAD(fci_read)
{
unsigned int result;
result = (unsigned int) _read((int)hf, memory, cb);
if (result != cb)
*err = errno;
return result;
}
FNFCIWRITE(fci_write)
{
unsigned int result;
result = (unsigned int) _write((int)hf, memory, cb);
if (result != cb)
*err = errno;
return result;
}
FNFCICLOSE(fci_close)
{
int result;
result = _close((int)hf);
if (result != 0)
*err = errno;
return result;
}
FNFCISEEK(fci_seek)
{
long result;
result = _lseek((int)hf, dist, seektype);
if (result == -1)
*err = errno;
return result;
}
FNFCIDELETE(fci_delete)
{
int result;
result = remove(pszFile);
if (result != 0)
*err = errno;
return result;
}
/*
* File placed function called when a file has been committed
* to a cabinet
*/
FNFCIFILEPLACED(file_placed)
{
/*printf(
" placed file '%s' (size %d) on cabinet '%s'\n",
pszFile,
cbFile,
pccab->szCab
);
if (fContinuation)
printf(" (Above file is a later segment of a continued file)\n");
*/
return 0;
}
/*
* Function to obtain temporary files
*/
FNFCIGETTEMPFILE(get_temp_file)
{
char *psz;
psz = _tempnam("","xx"); // Get a name
if ((psz != NULL) && (strlen(psz) < (unsigned)cbTempName)) {
strcpy(pszTempName,psz); // Copy to caller's buffer
free(psz); // Free temporary name buffer
return TRUE; // Success
}
//** Failed
if (psz) {
free(psz);
}
return FALSE;
}
/*
* Progress function
*/
FNFCISTATUS(progress)
{
client_state *cs;
cs = (client_state *) pv;
if (typeStatus == statusFile)
{
cs->total_compressed_size += cb1;
cs->total_uncompressed_size += cb2;
/*
* Compressing a block into a folder
*
* cb2 = uncompressed size of block
*/
/* printf(
"Compressing: %9ld -> %9ld \r",
cs->total_uncompressed_size,
cs->total_compressed_size
);
fflush(stdout);
*/
g_CompressedPercentage
= get_percentage(cs->total_uncompressed_size,cs->start_uncompressed_size);
}
else if (typeStatus == statusFolder)
{
int percentage;
/*
* Adding a folder to a cabinet
*
* cb1 = amount of folder copied to cabinet so far
* cb2 = total size of folder
*/
percentage = get_percentage(cb1, cb2);
cs->start_uncompressed_size = cb2;
// printf("Copying folder to cabinet: %d%% \r", percentage);
fflush(stdout);
}
if (g_CancelCompression)
{
// Abort the compression
return -1;
}
return 0;
}
void store_cab_name(char *cabname, int iCab)
{
sprintf(cabname, cCabName, iCab);
}
FNFCIGETNEXTCABINET(get_next_cabinet)
{
/*
* Cabinet counter has been incremented already by FCI
*/
/*
* Store next cabinet name
*/
store_cab_name(pccab->szCab, pccab->iCab);
/*
* You could change the disk name here too, if you wanted
*/
return TRUE;
}
FNFCIGETOPENINFO(get_open_info)
{
BY_HANDLE_FILE_INFORMATION finfo;
FILETIME filetime;
HANDLE handle;
DWORD attrs;
int hf;
client_state *cs;
cs = (client_state *) pv;
/*
* Need a Win32 type handle to get file date/time
* using the Win32 APIs, even though the handle we
* will be returning is of the type compatible with
* _open
*/
handle = CreateFileA(
pszName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (handle == INVALID_HANDLE_VALUE)
{
return -1;
}
if (GetFileInformationByHandle(handle, &finfo) == FALSE)
{
CloseHandle(handle);
return -1;
}
cs->start_uncompressed_size = finfo.nFileSizeLow;
FileTimeToLocalFileTime(
&finfo.ftLastWriteTime,
&filetime
);
FileTimeToDosDateTime(
&filetime,
pdate,
ptime
);
attrs = GetFileAttributesA(pszName);
if (attrs == 0xFFFFFFFF)
{
/* failure */
*pattribs = 0;
}
else
{
/*
* Mask out all other bits except these four, since other
* bits are used by the cabinet format to indicate a
* special meaning.
*/
*pattribs = (int) (attrs & (_A_RDONLY | _A_SYSTEM | _A_HIDDEN | _A_ARCH));
}
CloseHandle(handle);
/*
* Return handle using _open
*/
hf = _open( pszName, _O_RDONLY | _O_BINARY );
if (hf == -1)
return -1; // abort on error
return hf;
}
void set_cab_parameters(PCCAB cab_parms)
{
memset(cab_parms, 0, sizeof(CCAB));
cab_parms->cb = MEDIA_SIZE;
cab_parms->cbFolderThresh = FOLDER_THRESHOLD;
/*
* Don't reserve space for any extensions
*/
cab_parms->cbReserveCFHeader = 0;
cab_parms->cbReserveCFFolder = 0;
cab_parms->cbReserveCFData = 0;
/*
* We use this to create the cabinet name
*/
cab_parms->iCab = 1;
/*
* If you want to use disk names, use this to
* count disks
*/
cab_parms->iDisk = 0;
/*
* Choose your own number
*/
cab_parms->setID = 12345;
/*
* Only important if CABs are spanning multiple
* disks, in which case you will want to use a
* real disk name.
*
* Can be left as an empty string.
*/
strcpy(cab_parms->szDisk, "");
/* where to store the created CAB files */
strcpy(cab_parms->szCabPath, CabPath);
/* store name of first CAB file */
store_cab_name(cab_parms->szCab, cab_parms->iCab);
}
BOOL Compress (wchar_t *CabName, wchar_t *fileName, DWORD *UploadTime)
{
HFCI hfci;
ERF erf;
CCAB cab_parameters;
int i;
client_state cs;
char FileName [MAX_PATH];
int num_files = 1;
g_CompressedPercentage = 0;
g_CancelCompression = FALSE;
UnicodeToAnsi1(fileName,FileName);
UnicodeToAnsi1(CabName,cCabName);
/*
* Initialise our internal state
*/
cs.total_compressed_size = 0;
cs.total_uncompressed_size = 0;
cs.start_uncompressed_size = 0;
set_cab_parameters(&cab_parameters);
hfci = FCICreate(
&erf,
file_placed,
mem_alloc,
mem_free,
fci_open,
fci_read,
fci_write,
fci_close,
fci_seek,
fci_delete,
get_temp_file,
&cab_parameters,
&cs
);
if (hfci == NULL)
{
//printf("FCICreate() failed: code %d [%s]\n",
// erf.erfOper, return_fci_error_string(erf.erfOper)
//);
return FALSE;
}
for (i = 0; i < num_files; i++)
{
char stripped_name[256];
/*
* Don't store the path name in the cabinet file!
*/
strip_path(FileName, stripped_name);
if (FALSE == FCIAddFile(
hfci,
FileName, /* file to add */
stripped_name, /* file name in cabinet file */
FALSE, /* file is not executable */
get_next_cabinet,
progress,
get_open_info,
COMPRESSION_TYPE))
{
// printf("FCIAddFile() failed: code %d [%s]\n",
// erf.erfOper, return_fci_error_string(erf.erfOper)
// );
(void) FCIDestroy(hfci);
return FALSE;
}
}
/*
* This will automatically flush the folder first
*/
if (FALSE == FCIFlushCabinet(
hfci,
FALSE,
get_next_cabinet,
progress))
{
// printf("FCIFlushCabinet() failed: code %d [%s]\n",
// erf.erfOper, return_fci_error_string(erf.erfOper)
// );
(void) FCIDestroy(hfci);
return FALSE;
}
if (FCIDestroy(hfci) != TRUE)
{
// printf("FCIDestroy() failed: code %d [%s]\n",
// erf.erfOper, return_fci_error_string(erf.erfOper)
// );
return FALSE;
}
//printf(" \r");
// ***************** Add Upload Estimate Here ******************
return TRUE;
}
void strip_path(char *filename, char *stripped_name)
{
char *p;
p = strrchr(filename, '\\');
if (p == NULL)
strcpy(stripped_name, filename);
else
strcpy(stripped_name, p+1);
}
int get_percentage(unsigned long a, unsigned long b)
{
while (a > 10000000)
{
a >>= 3;
b >>= 3;
}
if (b == 0)
return 0;
return ((a*100)/b);
}
char *return_fci_error_string(FCIERROR err)
{
switch (err)
{
case FCIERR_NONE:
return "No error";
case FCIERR_OPEN_SRC:
return "Failure opening file to be stored in cabinet";
case FCIERR_READ_SRC:
return "Failure reading file to be stored in cabinet";
case FCIERR_ALLOC_FAIL:
return "Insufficient memory in FCI";
case FCIERR_TEMP_FILE:
return "Could not create a temporary file";
case FCIERR_BAD_COMPR_TYPE:
return "Unknown compression type";
case FCIERR_CAB_FILE:
return "Could not create cabinet file";
case FCIERR_USER_ABORT:
return "Client requested abort";
case FCIERR_MCI_FAIL:
return "Failure compressing data";
default:
return "Unknown error";
}
}
void UnicodeToAnsi1(wchar_t * pszW, LPSTR ppszA)
{
ULONG cbAnsi, cCharacters;
DWORD dwError;
// If input is null then just return the same.
// return;// NOERROR;
cCharacters = wcslen(pszW)+1;
// Determine number of bytes to be allocated for ANSI string. An
// ANSI string can have at most 2 bytes per character (for Double
// Byte Character Strings.)
cbAnsi = cCharacters*2;
// Use of the OLE allocator is not required because the resultant
// ANSI string will never be passed to another COM component. You
// can use your own allocator.
/// *ppszA = (LPSTR) CoTaskMemAlloc(cbAnsi);
// if (NULL == *ppszA)
// return E_OUTOFMEMORY;
// Convert to ANSI.
if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, ppszA,
cbAnsi, NULL, NULL))
{
dwError = GetLastError();
return;// HRESULT_FROM_WIN32(dwError);
}
//MessageBoxW(NULL,pszW,L"String conversion function recieved",MB_OK);
// MessageBox(NULL,*ppszA,"String Convert Function is returning.",MB_OK);
return;// NOERROR;
}