Код
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "crc32.h"
typedef struct
{
DWORD csig;
DWORD clen;
DWORD crc;
DWORD off;
DWORD flen;
DWORD cflen;
DWORD strlen;
CHAR string[1];
}
CHUNK_HEADER;
typedef struct
{
HANDLE file;
HANDLE memory;
LPCVOID pdata;
SIZE_T len;
}
MEMORY_FILE;
static MEMORY_FILE* open_memory_file( const char* name )
{
MEMORY_FILE* handle;
LARGE_INTEGER length;
BOOL result;
handle = malloc( sizeof( MEMORY_FILE ) );
handle->file = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle->file == INVALID_HANDLE_VALUE)
return 0;
result = GetFileSizeEx(handle->file, &length);
assert(result != FALSE);
if (result == FALSE)
return 0;
handle->memory = CreateFileMapping(handle->file, NULL, PAGE_READONLY, length.HighPart, length.LowPart, NULL);
assert(handle->memory != NULL);
if (handle->memory == NULL)
return 0;
handle->len = (size_t)length.QuadPart;
handle->pdata = MapViewOfFile(handle->memory, FILE_MAP_READ, 0, 0, handle->len);
assert(handle->pdata != NULL);
return handle;
}
static void close_memory_file( MEMORY_FILE* handle )
{
assert( handle != NULL );
UnmapViewOfFile(handle->pdata);
CloseHandle(handle->memory);
CloseHandle(handle->file);
free( handle );
}
static void pack(HANDLE file, const char *path, const unsigned char *p, unsigned len)
{
CHUNK_HEADER* header;
unsigned size, slen;
DWORD out, fptr;
int i;
slen = strlen( path ) + 1;
size = 28 + slen + len;
fptr = SetFilePointer( file, 0, 0, FILE_CURRENT );
header = malloc( size );
header->csig = 1;
header->clen = size;
header->crc = crc32( p, len );
header->off = fptr + 28 + slen;
header->flen = len;
header->cflen = len;
header->strlen = slen;
for( i = 0; i < slen; i++ )
header->string[i] = (path[i] & 0xFF) ^ header->crc;
WriteFile( file, header, size, &out, NULL );
WriteFile( file, p, len, &out, NULL );
}
int __cdecl main(int argc, char *argv[])
{
HANDLE find, target;
MEMORY_FILE* source;
WIN32_FIND_DATA data;
BOOL result;
char path[255], fname[255];
const char *filename;
if( argc < 2 )
return -1;
sprintf( path, "%s\\*.*", argv[1] );
find = FindFirstFileA( path, &data );
assert( find != INVALID_HANDLE_VALUE );
if( find == INVALID_HANDLE_VALUE )
return -1;
result = find ? TRUE : FALSE;
if( result == TRUE )
{
target = CreateFileA( argv[2], GENERIC_WRITE, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if( target == 0 )
return -1;
}
while( result )
{
while( (strcmp( data.cFileName, "." ) == 0) || (strcmp( data.cFileName, ".." ) == 0) )
{
result = FindNextFile( find, &data );
if( result == FALSE )
return 0;
}
sprintf( path, "%s\\%s", argv[1], data.cFileName );
sprintf( fname, "content\\%s", data.cFileName );
source = open_memory_file( path );
pack( target, fname, source->pdata, source->len );
close_memory_file( source );
result = FindNextFile( find, &data );
}
FindClose( find );
CloseHandle( target );
return 0;
}