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.
 
 
 
 
 
 

450 lines
8.4 KiB

#include "stdinc.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
int get_percentage(unsigned long a, unsigned long b);
/*
In a merge module, there can only be one CAB file, and its name must be 'MergeModule.CABinet'
Every call to this function must fail if iCab!=1
*/
#define CABINET_NUMBER 1
/*
* When a CAB file reaches this size, a new CAB will be created
* automatically. This is useful for fitting CAB files onto disks.
*
* If you want to create just one huge CAB file with everything in
* it, change this to a very very large number.
*/
#define MEDIA_SIZE (LONG_MAX)
/*
* When a folder has this much compressed data inside it,
* automatically flush the folder.
*
* Flushing the folder hurts compression a little bit, but
* helps random access significantly.
*/
#define FOLDER_THRESHOLD (LONG_MAX)
/*
* Compression type to use
*/
#define COMPRESSION_TYPE tcompTYPE_MSZIP
/*
* Our internal state
*
* The FCI APIs allow us to pass back a state pointer of our own
*/
typedef struct
{
ULONG total_compressed_size; /* total compressed size so far */
ULONG total_uncompressed_size; /* total uncompressed size so far */
} client_state;
//
// helper functions for FCI
//
/*
* Memory allocation function
*/
FNFCIALLOC(fci_mem_alloc)
{
return malloc(cb);
}
/*
* Memory free function
*/
FNFCIFREE(fci_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, (INT)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)
{
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
*/
}
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);
}
return 0;
}
FNFCIGETNEXTCABINET(get_next_cabinet)
{
if (pccab->iCab != CABINET_NUMBER)
{
return -1;
}
/*
* Cabinet counter has been incremented already by FCI
*/
/*
* Store next cabinet name
*/
WideCharToMultiByte(
CP_ACP, 0, MERGEMODULE_CABINET_FILENAME, NUMBER_OF(MERGEMODULE_CABINET_FILENAME) -1 ,
pccab->szCab, sizeof(pccab->szCab), NULL, NULL);
/*
* 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 = INVALID_HANDLE_VALUE;
DWORD attrs;
INT_PTR hf;
/*
* 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;
}
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 = (USHORT) (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 = CABINET_NUMBER;
/*
* If you want to use disk names, use this to
* count disks
*/
cab_parms->iDisk = 0;
/*
* Choose your own number
*/
cab_parms->setID = 1965;
/*
* 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, "win32.fusion.tools");
/* where to store the created CAB files */
CSmallStringBuffer buf;
if (! buf.Win32Assign(g_MsmInfo.m_sbCabinet))
{
fprintf(stderr, "error happened in set_cab_parameters");
goto Exit; // void function
}
if (!buf.Win32RemoveLastPathElement())
{
goto Exit;
}
if ( ! buf.Win32EnsureTrailingPathSeparator())
{
fprintf(stderr, "error happened in set_cab_parameters");
goto Exit; // void function
}
WideCharToMultiByte(
CP_ACP, 0, buf, buf.GetCchAsDWORD(),
cab_parms->szCabPath, sizeof(cab_parms->szCabPath), NULL, NULL);
/* store name of first CAB file */
WideCharToMultiByte(
CP_ACP, 0, MERGEMODULE_CABINET_FILENAME, NUMBER_OF(MERGEMODULE_CABINET_FILENAME) -1 ,
cab_parms->szCab, sizeof(cab_parms->szCab), NULL, NULL);
Exit:
return;
}
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(int 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";
}
}